[binutils-gdb] gas: don't lose addend in snapshot_symbol() when hitting a local symbol
Jan Beulich
jbeulich@sourceware.org
Mon Apr 20 06:40:04 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d1b63466b9ebbe0fcf00409ff473cbc97b365a66
commit d1b63466b9ebbe0fcf00409ff473cbc97b365a66
Author: Jan Beulich <jbeulich@suse.com>
Date: Mon Apr 20 08:37:47 2026 +0200
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:
---
gas/symbols.c | 20 ++++++++++++++++----
gas/testsuite/gas/elf/elf.exp | 2 ++
gas/testsuite/gas/elf/equ-rept.l | 3 +++
gas/testsuite/gas/elf/equ-rept.s | 7 +++++++
4 files changed, 28 insertions(+), 4 deletions(-)
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
More information about the Binutils-cvs
mailing list