From: Jan Beulich Date: Mon, 20 Apr 2026 06:37:47 +0000 (+0200) Subject: gas: don't lose addend in snapshot_symbol() when hitting a local symbol X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d1b63466b9ebbe0fcf00409ff473cbc97b365a66;p=thirdparty%2Fbinutils-gdb.git gas: don't lose addend in snapshot_symbol() when hitting a local symbol Unlike the one in PR gas/20941, input doesn't need to be entirely bogus for a local symbol to appear here: Local symbols can be created for various reasons. If we find one, we have to take exp.X_add_number into account. Plus, like for "normal" symbols, we should not add in the symbol's value if the result (in resolve_expression()) is still going to be O_symbol: The returned value then is relative to the returned symbol. --- diff --git a/gas/symbols.c b/gas/symbols.c index ef02f1dcc60..3fc0a97927c 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -1871,20 +1871,32 @@ snapshot_symbol (symbolS **symbolPP, valueT *valueP, segT *segP, fragS **fragPP) } *symbolPP = symbolP; + *valueP = exp.X_add_number; - /* A bogus input file can result in resolve_expression() - generating a local symbol, so we have to check again. */ + /* We may have picked up a local symbol above: Check again. */ if (symbolP->flags.local_symbol) { struct local_symbol *locsym = (struct local_symbol *) symbolP; - *valueP = locsym->value; + if (locsym->section == expr_section + || locsym->section == absolute_section + || locsym->section == reg_section) + { + switch (exp.X_op) + { + case O_constant: + case O_register: + *valueP += locsym->value; + break; + default: + break; + } + } *segP = locsym->section; *fragPP = locsym->frag; } else { - *valueP = exp.X_add_number; *segP = symbolP->bsym->section; *fragPP = symbolP->frag; } diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp index b8c12711942..cf983057bf6 100644 --- a/gas/testsuite/gas/elf/elf.exp +++ b/gas/testsuite/gas/elf/elf.exp @@ -364,6 +364,8 @@ if { [is_elf_format] } then { run_list_test "line2" -I${srcdir}/$subdir + run_list_test "equ-rept" + run_dump_test "pr25917" run_dump_test "bss" # Some targets treat .bss similar to .lcomm. diff --git a/gas/testsuite/gas/elf/equ-rept.l b/gas/testsuite/gas/elf/equ-rept.l new file mode 100644 index 00000000000..90cc3de01de --- /dev/null +++ b/gas/testsuite/gas/elf/equ-rept.l @@ -0,0 +1,3 @@ +# The line should appear exactly twice. +>output< +>output< diff --git a/gas/testsuite/gas/elf/equ-rept.s b/gas/testsuite/gas/elf/equ-rept.s new file mode 100644 index 00000000000..fee6e98f4db --- /dev/null +++ b/gas/testsuite/gas/elf/equ-rept.s @@ -0,0 +1,7 @@ + .equiv n, (.L1+2) + null - .L2 + .equiv null, 0 +.L1: .L2: + + .rept n + .print ">output<" + .endr