[5/8] gas: don't lose addend in snapshot_symbol() when hitting a local symbol

Message ID b703d052-b76a-4f9a-9b82-efd22e8282d6@suse.com
State New
Headers
Series gas/x86: towards better Intel syntax expression evaluation |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply

Commit Message

Jan Beulich March 27, 2026, 2:12 p.m. UTC
  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.
  

Patch

--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -1871,20 +1871,32 @@  snapshot_symbol (symbolS **symbolPP, val
 	}
 
       *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;
 	}
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -361,6 +361,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.
--- /dev/null
+++ b/gas/testsuite/gas/elf/equ-rept.l
@@ -0,0 +1,3 @@ 
+# The line should appear exactly twice.
+>output<
+>output<
--- /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