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.
This commit is contained in:
Jan Beulich
2025-07-04 10:41:34 +02:00
parent 52be9c1ba3
commit 7b40f4c658
10 changed files with 115 additions and 2 deletions

View File

@@ -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.

View File

@@ -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 ();

View File

@@ -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);

View 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

View 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

View 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"
}
}
}

View File

@@ -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]* .*

View File

@@ -0,0 +1,4 @@
.data
.ifdef "GAS(version)"
.dc.l "GAS(version)"
.endif

View File

@@ -0,0 +1,3 @@
#nm: --quiet
#name: pre-defined version symbol (empty symbol table)
#source: version.s

View File

@@ -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