[binutils-gdb] gas: add a means to programmatically determine the assembler version

Jan Beulich jbeulich@sourceware.org
Fri Jul 4 08:42:45 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7b40f4c6587c04794d08e805eb17c61c629ab662

commit 7b40f4c6587c04794d08e805eb17c61c629ab662
Author: Jan Beulich <jbeulich@suse.com>
Date:   Fri Jul 4 10:41:34 2025 +0200

    gas: add a means to programmatically determine the assembler version
    
    It has been more than once that I would have wanted to have a way to
    know the gas version in assembly sources, perhaps for use with .if. Add
    such a pre-defined symbol, introducing the common pattern GAS(<symbol>)
    for any such symbols. The use of parentheses is to keep the risk of
    collisions with users' symbols as low as possible. (Possible future
    arch-specific symbols may want to use GAS(<arch>:<symbol>).)
    
    Similarly permit determining whether the assembler is a released
    version. The exact value probably isn't of much use, it's more the
    defined-ness that one might care about. Yet the symbol needs to have
    some value anyway.
    
    While by default pre-defined symbols won't be emitted to the symbol
    table, introduce -emit-local-absolute to allow requesting this. Re-
    purpose flag_strip_local_absolute to become tristate, with a negative
    value indicating to also emit pre-defined symbols.

Diff:
---
 gas/NEWS                         |  3 +++
 gas/as.c                         | 30 ++++++++++++++++++++++++++++++
 gas/as.h                         |  4 +++-
 gas/doc/as.texi                  | 29 +++++++++++++++++++++++++++++
 gas/symbols.c                    |  2 +-
 gas/testsuite/gas/all/gas.exp    | 27 +++++++++++++++++++++++++++
 gas/testsuite/gas/all/version.d  |  7 +++++++
 gas/testsuite/gas/all/version.s  |  4 ++++
 gas/testsuite/gas/all/version2.d |  3 +++
 gas/testsuite/gas/all/version3.d |  8 ++++++++
 10 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/gas/NEWS b/gas/NEWS
index f0ffe2db54b..e48cee30bac 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Predefined symbols "GAS(version)" and, on non-release builds, "GAS(date)" are
+  now being made available.
+
 * Support for x86 AVX10.2 256 bit rounding has been dropped, as all the
   hardware would directly support 512 bit vecotr width.
 
diff --git a/gas/as.c b/gas/as.c
index a37d59d4649..c7de3a9f4e8 100644
--- a/gas/as.c
+++ b/gas/as.c
@@ -486,6 +486,7 @@ parse_args (int * pargc, char *** pargv)
       OPTION_GDWARF_CIE_VERSION,
       OPTION_GCODEVIEW,
       OPTION_STRIP_LOCAL_ABSOLUTE,
+      OPTION_EMIT_LOCAL_ABSOLUTE,
       OPTION_TRADITIONAL_FORMAT,
       OPTION_WARN,
       OPTION_TARGET_HELP,
@@ -590,6 +591,7 @@ parse_args (int * pargc, char *** pargv)
     ,{"reduce-memory-overheads", no_argument, NULL, OPTION_REDUCE_MEMORY_OVERHEADS}
     ,{"statistics", no_argument, NULL, OPTION_STATISTICS}
     ,{"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE}
+    ,{"emit-local-absolute", no_argument, NULL, OPTION_EMIT_LOCAL_ABSOLUTE}
     ,{"version", no_argument, NULL, OPTION_VERSION}
     ,{"verbose", no_argument, NULL, 'v'}
     ,{"target-help", no_argument, NULL, OPTION_TARGET_HELP}
@@ -688,6 +690,10 @@ parse_args (int * pargc, char *** pargv)
 	  flag_strip_local_absolute = 1;
 	  break;
 
+	case OPTION_EMIT_LOCAL_ABSOLUTE:
+	  flag_strip_local_absolute = -1;
+	  break;
+
 	case OPTION_TRADITIONAL_FORMAT:
 	  flag_traditional_format = 1;
 	  break;
@@ -1163,6 +1169,26 @@ This program has absolutely no warranty.\n"));
 #endif
 }
 
+/* Pre-define a symbol with its name derived from TMPL (wrapping in
+   GAS(...)), to value VAL.  */
+
+void
+predefine_symbol (const char *tmpl, valueT val)
+{
+  char *name = xasprintf ("GAS(%s)", tmpl);
+  symbolS *s;
+
+  /* Also put the symbol in the symbol table, if requested.  */
+  if (flag_strip_local_absolute < 0)
+    s = symbol_new (name, absolute_section, &zero_address_frag, val);
+  else
+    s = symbol_create (name, absolute_section, &zero_address_frag, val);
+  S_CLEAR_EXTERNAL (s);
+  symbol_table_insert (s);
+
+  xfree (name);
+}
+
 static void
 dump_statistics (void)
 {
@@ -1205,6 +1231,10 @@ perform_an_assembly_pass (int argc, char ** argv)
   subseg_set (text_section, 0);
 #endif
 
+  predefine_symbol ("version", BFD_VERSION);
+  if (strstr (BFD_VERSION_STRING, "." XSTRING (BFD_VERSION_DATE)) != NULL)
+    predefine_symbol ("date", BFD_VERSION_DATE);
+
   /* This may add symbol table entries, which requires having an open BFD,
      and sections already created.  */
   md_begin ();
diff --git a/gas/as.h b/gas/as.h
index 4b5f78b53d0..872c6ddf393 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -339,7 +339,8 @@ COMMON enum synth_cfi_type flag_synth_cfi;
 /* This is true if the assembler should output time and space usage.  */
 COMMON unsigned char flag_print_statistics;
 
-/* True if local absolute symbols are to be stripped.  */
+/* True (positive) if local absolute symbols are to be stripped.  Negative if
+   even pre-defined symbols should be emitted.  */
 COMMON int flag_strip_local_absolute;
 
 /* True if we should generate a traditional format object file.  */
@@ -514,6 +515,7 @@ void   as_report_context (void);
 const char * as_where (unsigned int *);
 const char * as_where_top (unsigned int *);
 const char * as_where_physical (unsigned int *);
+void   predefine_symbol (const char *, valueT);
 void   bump_line_counters (void);
 void   do_scrub_begin (int);
 void   input_scrub_begin (void);
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 7d6cdcb0a73..e17c2df40db 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -779,6 +779,10 @@ symbols with the @code{STT_COMMON} type.  The default can be controlled
 by a configure option @option{--enable-elf-stt-common}.
 @end ifset
 
+@item --emit-local-absolute
+Emit even pre-defined (local) absolute symbols to the outgoing symbol table.
+Note that this isn't the exact opposite of @samp{--strip-local-absolute}.
+
 @item --emulation=@var{name}
 If the assembler is configured to support multiple different target
 configurations then this option can be used to select the desired form.
@@ -3909,6 +3913,7 @@ the same order they were declared.  This may break some debuggers.
 * Symbol Names::                Symbol Names
 * Dot::                         The Special Dot Symbol
 * Symbol Attributes::           Symbol Attributes
+* Predefined Symbols::          Predefined Symbols
 @end menu
 
 @node Labels
@@ -4250,6 +4255,30 @@ Language Reference Manual} (HP 92432-90001) under the @code{IMPORT} and
 @code{EXPORT} assembler directive documentation.
 @end ifset
 
+@node Predefined Symbols
+@section Predefined Symbols
+
+Certain pre-defined symbols will be made available for use, and possibly also
+inserted in the symbol table.  Because of the use of parentheses, access to
+these symbols will require quotation.
+
+Independent of the specific target, the following symbols will (perhaps
+conditionally; see each individual item) be made available:
+@itemize @bullet
+
+@item @code{GAS(version)}
+The version of the assembler, expressed as @samp{major} @code{*} 100000000
+@code{+} @samp{minor} @code{*} 1000000 @code{+} @samp{rev} @code{*} 10000.
+
+@item @code{GAS(date)}
+The date of the assembler sources (which may not be the date the assembler was
+built).  This is added only for non-release versions of gas.  The specific
+value probably better isn't checked for, just its defined-ness.
+
+@end itemize
+
+All symbols of the form @code{GAS(...)} are reserved for use by GNU @value{AS}.
+
 @node Expressions
 @chapter Expressions
 
diff --git a/gas/symbols.c b/gas/symbols.c
index 45b7d9b95e6..02ea741bde2 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -2428,7 +2428,7 @@ S_IS_LOCAL (const symbolS *s)
 
   flags = s->bsym->flags;
 
-  if (flag_strip_local_absolute
+  if (flag_strip_local_absolute > 0
       /* Keep BSF_FILE symbols in order to allow debuggers to identify
 	 the source file even when the object file is stripped.  */
       && (flags & (BSF_GLOBAL | BSF_FILE)) == 0
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 780838d246d..41d35285c7b 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -566,3 +566,30 @@ run_dump_test "multibyte1"
 run_dump_test "multibyte2"
 run_list_test "multibyte3" "--multibyte-handling=warn"
 run_list_test "multibyte3" "-f --multibyte-handling=warn"
+
+# EVAX has an extra line printed by objdump when there are no relocations,
+# and doesn't appear to enter absolute symbols into the symbol table.
+# SOM (HPPA) won't properly handle at least the latter two tests.
+switch -glob $target_triplet {
+    alpha-*-*vms* { }
+    hppa-*-hpux* { }
+    default {
+	run_dump_test "version"
+	# Non-ELF symbol tables may include section symbols.
+	# MSP430 adds references to library symbols.
+	# RL78 includes a special absolute symbol.
+	if { [is_elf_format]
+	     && ![istarget "msp430*-*-*"]
+	     && ![istarget "rl78*-*-*"] } {
+	    run_dump_test "version2"
+	}
+	# ECOFF/XCOFF don't look to (reliably) emit local absolute symbols.
+	# IA64, when targeting HPUX, deliberately omits unreferenced symbols.
+	if { ![is_xcoff_format]
+	     && ![istarget "alpha-*-linux*ecoff*"]
+	     && ![istarget "alpha-*-osf*"]
+	     && ![istarget "ia64-*-hpux*"] } {
+	    run_dump_test "version3"
+	}
+    }
+}
diff --git a/gas/testsuite/gas/all/version.d b/gas/testsuite/gas/all/version.d
new file mode 100644
index 00000000000..9803619b529
--- /dev/null
+++ b/gas/testsuite/gas/all/version.d
@@ -0,0 +1,7 @@
+#objdump: -rsj .data
+#name: pre-defined version symbol
+
+.*: +file format .*
+
+Contents of section .data:
+ 0+ [0-9a-f]*[1-9a-f][0-9a-f]* .*
diff --git a/gas/testsuite/gas/all/version.s b/gas/testsuite/gas/all/version.s
new file mode 100644
index 00000000000..3f3d8243186
--- /dev/null
+++ b/gas/testsuite/gas/all/version.s
@@ -0,0 +1,4 @@
+	.data
+	.ifdef "GAS(version)"
+	.dc.l "GAS(version)"
+	.endif
diff --git a/gas/testsuite/gas/all/version2.d b/gas/testsuite/gas/all/version2.d
new file mode 100644
index 00000000000..9b211c0ebb9
--- /dev/null
+++ b/gas/testsuite/gas/all/version2.d
@@ -0,0 +1,3 @@
+#nm: --quiet
+#name: pre-defined version symbol (empty symbol table)
+#source: version.s
diff --git a/gas/testsuite/gas/all/version3.d b/gas/testsuite/gas/all/version3.d
new file mode 100644
index 00000000000..aff9ad65702
--- /dev/null
+++ b/gas/testsuite/gas/all/version3.d
@@ -0,0 +1,8 @@
+#as: -emit-local-absolute
+#nm: -f bsd
+#name: pre-defined version symbol (non-empty symbol table)
+#source: version.s
+
+#...
+.* a GAS\(version\)
+#pass


More information about the Binutils-cvs mailing list