[binutils-gdb] x86/AT&T: make GOT-relative expressions work
Jan Beulich
jbeulich@sourceware.org
Fri Apr 10 06:44:19 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=65e4798d49afe18c20acd5f5830e706b175ba844
commit 65e4798d49afe18c20acd5f5830e706b175ba844
Author: Jan Beulich <jbeulich@suse.com>
Date: Fri Apr 10 08:43:22 2026 +0200
x86/AT&T: make GOT-relative expressions work
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.)
Diff:
---
gas/config/tc-i386.c | 15 ++++++++++++++-
gas/testsuite/gas/i386/x86-64-gotpcrel-2.d | 2 ++
gas/testsuite/gas/i386/x86-64-gotpcrel-2.s | 4 ++++
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 2a2d95bdd26..bc759b2573a 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -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)
diff --git a/gas/testsuite/gas/i386/x86-64-gotpcrel-2.d b/gas/testsuite/gas/i386/x86-64-gotpcrel-2.d
index 3d07631bd6a..3e9d46eaca7 100644
--- a/gas/testsuite/gas/i386/x86-64-gotpcrel-2.d
+++ b/gas/testsuite/gas/i386/x86-64-gotpcrel-2.d
@@ -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
diff --git a/gas/testsuite/gas/i386/x86-64-gotpcrel-2.s b/gas/testsuite/gas/i386/x86-64-gotpcrel-2.s
index db5ddf579a0..2706272b5eb 100644
--- a/gas/testsuite/gas/i386/x86-64-gotpcrel-2.s
+++ b/gas/testsuite/gas/i386/x86-64-gotpcrel-2.s
@@ -1,3 +1,7 @@
.text
foo:
movq foo@GOTPCREL(%rip), %rax
+ push foo@GOTPCREL + eight(%rip)
+ push foo@GOTPCREL - eight(%rip)
+
+ .equ eight, 8
More information about the Binutils-cvs
mailing list