]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86/AT&T: make GOT-relative expressions work master
authorJan Beulich <jbeulich@suse.com>
Fri, 10 Apr 2026 06:43:22 +0000 (08:43 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 10 Apr 2026 06:43:22 +0000 (08:43 +0200)
The expressions used in intel-got{32,64}.s should equally work (or not) in
AT&T mode. Changing the Intel syntax parser such that O_symbol wouldn't
happen to be wrapped around such expressions breaks it there, too. It
really isn't correct to limit this to just O_symbol. Permitting O_add and
O_subtract as well requires taking care of the other operand as well then.
(Strictly speaking non-zero offsets aren't very useful here, but then at
least with an equate of 0 this ought to work. The non-zero offset in the
testcase helps demonstrate that this offset isn't lost.)

gas/config/tc-i386.c
gas/testsuite/gas/i386/x86-64-gotpcrel-2.d
gas/testsuite/gas/i386/x86-64-gotpcrel-2.s

index 2a2d95bdd261c887ff40e205ab08751814699aba..bc759b2573a904e1cb8d760b919d7f339c87d96e 100644 (file)
@@ -15083,13 +15083,26 @@ i386_finalize_displacement (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
       || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL
       || i.reloc[this_operand] == BFD_RELOC_64_GOTOFF)
     {
-      if (exp->X_op != O_symbol)
+      if (exp->X_op != O_symbol
+         && exp->X_op != O_add
+         && exp->X_op != O_subtract)
        goto inv_disp;
 
       if (S_IS_LOCAL (exp->X_add_symbol)
          && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section
          && S_GET_SEGMENT (exp->X_add_symbol) != expr_section)
        section_symbol (S_GET_SEGMENT (exp->X_add_symbol));
+
+      if (exp->X_op != O_symbol)
+       {
+         if (S_IS_LOCAL (exp->X_op_symbol)
+             && S_GET_SEGMENT (exp->X_op_symbol) != undefined_section
+             && S_GET_SEGMENT (exp->X_op_symbol) != expr_section)
+           section_symbol (S_GET_SEGMENT (exp->X_op_symbol));
+
+         exp->X_add_symbol = make_expr_symbol (exp);
+       }
+
       exp->X_op = O_subtract;
       exp->X_op_symbol = GOT_symbol;
       if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
index 3d07631bd6ac868097b3a8f649ec963630199dd2..3e9d46eaca7b02dd9248386824ad09d123c3be50 100644 (file)
@@ -8,4 +8,6 @@ Disassembly of section .text:
 
 0+ <foo>:
  +[a-f0-9]+:   48 8b 05 00 00 00 00    mov    0x0\(%rip\),%rax        # 7 <foo\+0x7>   3: R_X86_64_GOTPCREL    foo-0x4
+ +[a-f0-9]+:   ff 35 00 00 00 00       push   0x0\(%rip\)        # .*  9: R_X86_64_GOTPCREL    foo\+0x4
+ +[a-f0-9]+:   ff 35 00 00 00 00       push   0x0\(%rip\)        # .*  f: R_X86_64_GOTPCREL    foo-0xc
 #pass
index db5ddf579a005db317da95f882ce64cb454354bb..2706272b5eba5ad18605aa9eed2ee75654122478 100644 (file)
@@ -1,3 +1,7 @@
        .text
 foo:
        movq    foo@GOTPCREL(%rip), %rax
+       push    foo@GOTPCREL + eight(%rip)
+       push    foo@GOTPCREL - eight(%rip)
+
+       .equ eight, 8