]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas: add a means to programmatically determine the assembler version
authorJan Beulich <jbeulich@suse.com>
Fri, 4 Jul 2025 08:41:34 +0000 (10:41 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 4 Jul 2025 08:41:34 +0000 (10:41 +0200)
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.

gas/NEWS
gas/as.c
gas/as.h
gas/doc/as.texi
gas/symbols.c
gas/testsuite/gas/all/gas.exp
gas/testsuite/gas/all/version.d [new file with mode: 0644]
gas/testsuite/gas/all/version.s [new file with mode: 0644]
gas/testsuite/gas/all/version2.d [new file with mode: 0644]
gas/testsuite/gas/all/version3.d [new file with mode: 0644]

index f0ffe2db54ba9a36e7caf96ee4ec5352bec4b215..e48cee30bac449e745158b4fadb6019e7dd9f6be 100644 (file)
--- 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.
 
index a37d59d4649eedb49ee473a69718dd2983a1e2ff..c7de3a9f4e837b7e6cd39cc7ea82a81f66ccee16 100644 (file)
--- 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 ();
index 4b5f78b53d09c663b18975d9ff403705551a80ff..872c6ddf393d8549437ac30acaaa5f2b21626684 100644 (file)
--- 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);
index 7d6cdcb0a731802c61f92cfca6340a92979232d3..e17c2df40db6c4fb1ecb3a1190b8fa1b60b92a92 100644 (file)
@@ -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
 
index 45b7d9b95e6a1db50e0bc3ed092a2ec350e63a49..02ea741bde2ac941ff098dca31db3aec8ad9d9e6 100644 (file)
@@ -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
index 780838d246dc85e842f1f6f1ee130bdb23b76dcf..41d35285c7beb7765502d05ddf78d108a94204db 100644 (file)
@@ -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 (file)
index 0000000..9803619
--- /dev/null
@@ -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 (file)
index 0000000..3f3d824
--- /dev/null
@@ -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 (file)
index 0000000..9b211c0
--- /dev/null
@@ -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 (file)
index 0000000..aff9ad6
--- /dev/null
@@ -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