aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2023-06-09 13:50:22 -0700
committerH.J. Lu <hjl.tools@gmail.com>2023-12-28 08:47:17 -0800
commita533c8df598b5ef99c54a13e2b137c98b34b043c (patch)
treecb019f462896604b2b48bb1f40dfe01bc0437051 /gas
parent4a54cb06585f568031dfd291d0fe45979ad75e98 (diff)
downloadgdb-a533c8df598b5ef99c54a13e2b137c98b34b043c.zip
gdb-a533c8df598b5ef99c54a13e2b137c98b34b043c.tar.gz
gdb-a533c8df598b5ef99c54a13e2b137c98b34b043c.tar.bz2
x86-64: Add R_X86_64_CODE_4_GOTTPOFF/R_X86_64_CODE_4_GOTPC32_TLSDESC
For add name@gottpoff(%rip), %reg mov name@gottpoff(%rip), %reg add # define R_X86_64_CODE_4_GOTTPOFF 44 and for lea name@tlsdesc(%rip), %reg add # define R_X86_64_CODE_4_GOTPC32_TLSDESC 45 if the instruction starts at 4 bytes before the relocation offset. They are similar to R_X86_64_GOTTPOFF and R_X86_64_GOTPC32_TLSDESC, respectively. Linker can covert GOTTPOFF to add $name@tpoff, %reg mov $name@tpoff, %reg and GOTPC32_TLSDESC to mov $name@tpoff, %reg mov name@gottpoff(%rip), %reg if the instruction is encoded with the REX2 prefix when possible. bfd/ * elf64-x86-64.c (x86_64_elf_howto_table): Add R_X86_64_CODE_4_GOTTPOFF and R_X86_64_CODE_4_GOTPC32_TLSDESC. (R_X86_64_standard): Updated. (x86_64_reloc_map): Add BFD_RELOC_X86_64_CODE_4_GOTTPOFF and BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC. (elf_x86_64_check_tls_transition): Handle R_X86_64_CODE_4_GOTTPOFF and R_X86_64_CODE_4_GOTPC32_TLSDESC. (elf_x86_64_tls_transition): Likewise. (elf_x86_64_scan_relocs): Likewise. (elf_x86_64_relocate_section): Likewise. * reloc.c (bfd_reloc_code_real): Add BFD_RELOC_X86_64_CODE_4_GOTTPOFF and BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. gas/ * config/tc-i386.c (tc_i386_fix_adjustable): Handle BFD_RELOC_X86_64_CODE_4_GOTTPOFF and BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC. (md_assemble): Handle BFD_RELOC_X86_64_CODE_4_GOTTPOFF. (output_insn): Don't add empty REX prefix with REX2 prefix. (output_disp): Handle BFD_RELOC_X86_64_CODE_4_GOTTPOFF and BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC. (md_apply_fix): Likewise. (i386_validate_fix): Generate BFD_RELOC_X86_64_CODE_4_GOTTPOFF or BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC if ixp->fx_tcbit3 is set. (tc_gen_reloc): Handle BFD_RELOC_X86_64_CODE_4_GOTTPOFF and BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC. * testsuite/gas/i386/x86-64-gottpoff.d: New file. * testsuite/gas/i386/x86-64-gottpoff.s: Likewise. * testsuite/gas/i386/x86-64-tlsdesc.d: Likewise. * testsuite/gas/i386/x86-64-tlsdesc.s: Likewise. include/ * elf/x86-64.h (elf_x86_64_reloc_type): Add R_X86_64_CODE_4_GOTTPOFF and R_X86_64_CODE_4_GOTPC32_TLSDESC ld/ * testsuite/ld-x86-64/tlsbindesc.d: Updated. * testsuite/ld-x86-64/tlsbindesc.rd: Likewise. * testsuite/ld-x86-64/tlsbindesc.s: Add R_X86_64_CODE_4_GOTTPOFF and R_X86_64_CODE_4_GOTPC32_TLSDESC tests.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-i386.c20
-rw-r--r--gas/testsuite/gas/i386/x86-64-gottpoff.d19
-rw-r--r--gas/testsuite/gas/i386/x86-64-gottpoff.s15
-rw-r--r--gas/testsuite/gas/i386/x86-64-tlsdesc.d17
-rw-r--r--gas/testsuite/gas/i386/x86-64-tlsdesc.s13
-rw-r--r--gas/testsuite/gas/i386/x86-64.exp3
6 files changed, 87 insertions, 0 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 8d76446..694c494 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -3601,10 +3601,12 @@ tc_i386_fix_adjustable (fixS *fixP)
|| fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF32
|| fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF64
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF
+ || fixP->fx_r_type == BFD_RELOC_X86_64_CODE_4_GOTTPOFF
|| fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32
|| fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF64
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOTOFF64
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOTPC32_TLSDESC
+ || fixP->fx_r_type == BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC
|| fixP->fx_r_type == BFD_RELOC_X86_64_TLSDESC_CALL
|| fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
@@ -5632,6 +5634,7 @@ md_assemble (char *line)
case BFD_RELOC_386_TLS_GOTIE:
case BFD_RELOC_386_TLS_LE_32:
case BFD_RELOC_X86_64_GOTTPOFF:
+ case BFD_RELOC_X86_64_CODE_4_GOTTPOFF:
case BFD_RELOC_X86_64_TLSLD:
as_bad (_("TLS relocation cannot be used with `%s'"), insn_name (&i.tm));
return;
@@ -10477,6 +10480,7 @@ output_insn (const struct last_insn *last_insn)
is also needed for lea with R_X86_64_GOTPC32_TLSDESC
relocation for GDesc -> IE/LE optimization. */
if (x86_elf_abi == X86_64_X32_ABI
+ && !is_apx_rex2_encoding ()
&& i.operands == 2
&& (i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF
|| i.reloc[0] == BFD_RELOC_X86_64_GOTPC32_TLSDESC)
@@ -10842,7 +10846,9 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_off)
case BFD_RELOC_X86_64_TLSGD:
case BFD_RELOC_X86_64_TLSLD:
case BFD_RELOC_X86_64_GOTTPOFF:
+ case BFD_RELOC_X86_64_CODE_4_GOTTPOFF:
case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
+ case BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC:
case BFD_RELOC_X86_64_TLSDESC_CALL:
i.has_gotpc_tls_reloc = true;
default:
@@ -14356,7 +14362,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_X86_64_TLSGD:
case BFD_RELOC_X86_64_TLSLD:
case BFD_RELOC_X86_64_GOTTPOFF:
+ case BFD_RELOC_X86_64_CODE_4_GOTTPOFF:
case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
+ case BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC:
value = 0; /* Fully resolved at runtime. No addend. */
/* Fallthrough */
case BFD_RELOC_386_TLS_LE:
@@ -15929,6 +15937,14 @@ i386_validate_fix (fixS *fixp)
return IS_ELF && fixp->fx_addsy
&& (!S_IS_DEFINED (fixp->fx_addsy)
|| S_IS_EXTERNAL (fixp->fx_addsy));
+
+ if (fixp->fx_tcbit3)
+ {
+ if (fixp->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF)
+ fixp->fx_r_type = BFD_RELOC_X86_64_CODE_4_GOTTPOFF;
+ else if (fixp->fx_r_type == BFD_RELOC_X86_64_GOTPC32_TLSDESC)
+ fixp->fx_r_type = BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC;
+ }
#endif
if (fixp->fx_subsy)
@@ -16073,6 +16089,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
case BFD_RELOC_X86_64_DTPOFF32:
case BFD_RELOC_X86_64_DTPOFF64:
case BFD_RELOC_X86_64_GOTTPOFF:
+ case BFD_RELOC_X86_64_CODE_4_GOTTPOFF:
case BFD_RELOC_X86_64_TPOFF32:
case BFD_RELOC_X86_64_TPOFF64:
case BFD_RELOC_X86_64_GOTOFF64:
@@ -16083,6 +16100,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
case BFD_RELOC_X86_64_GOTPLT64:
case BFD_RELOC_X86_64_PLTOFF64:
case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
+ case BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC:
case BFD_RELOC_X86_64_TLSDESC_CALL:
case BFD_RELOC_RVA:
case BFD_RELOC_VTABLE_ENTRY:
@@ -16215,7 +16233,9 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
case BFD_RELOC_X86_64_TLSGD:
case BFD_RELOC_X86_64_TLSLD:
case BFD_RELOC_X86_64_GOTTPOFF:
+ case BFD_RELOC_X86_64_CODE_4_GOTTPOFF:
case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
+ case BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC:
case BFD_RELOC_X86_64_TLSDESC_CALL:
rel->addend = fixp->fx_offset - fixp->fx_size;
break;
diff --git a/gas/testsuite/gas/i386/x86-64-gottpoff.d b/gas/testsuite/gas/i386/x86-64-gottpoff.d
new file mode 100644
index 0000000..d42abcc
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-gottpoff.d
@@ -0,0 +1,19 @@
+#as:
+#objdump: -dwr
+#name: x86-64 gottpoff
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+: 48 03 05 00 00 00 00 add 0x0\(%rip\),%rax # 7 <_start\+0x7> 3: R_X86_64_GOTTPOFF foo-0x4
+ +[a-f0-9]+: 48 8b 05 00 00 00 00 mov 0x0\(%rip\),%rax # e <_start\+0xe> a: R_X86_64_GOTTPOFF foo-0x4
+ +[a-f0-9]+: d5 48 03 05 00 00 00 00 add 0x0\(%rip\),%r16 # 16 <_start\+0x16> 12: R_X86_64_CODE_4_GOTTPOFF foo-0x4
+ +[a-f0-9]+: d5 48 8b 25 00 00 00 00 mov 0x0\(%rip\),%r20 # 1e <_start\+0x1e> 1a: R_X86_64_CODE_4_GOTTPOFF foo-0x4
+ +[a-f0-9]+: 48 03 05 00 00 00 00 add 0x0\(%rip\),%rax # 25 <_start\+0x25> 21: R_X86_64_GOTTPOFF foo-0x4
+ +[a-f0-9]+: 48 8b 05 00 00 00 00 mov 0x0\(%rip\),%rax # 2c <_start\+0x2c> 28: R_X86_64_GOTTPOFF foo-0x4
+ +[a-f0-9]+: d5 48 03 05 00 00 00 00 add 0x0\(%rip\),%r16 # 34 <_start\+0x34> 30: R_X86_64_CODE_4_GOTTPOFF foo-0x4
+ +[a-f0-9]+: d5 48 8b 25 00 00 00 00 mov 0x0\(%rip\),%r20 # 3c <_start\+0x3c> 38: R_X86_64_CODE_4_GOTTPOFF foo-0x4
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-gottpoff.s b/gas/testsuite/gas/i386/x86-64-gottpoff.s
new file mode 100644
index 0000000..6f8f9d1
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-gottpoff.s
@@ -0,0 +1,15 @@
+ .text
+_start:
+ addq foo@GOTTPOFF(%rip), %rax
+ movq foo@GOTTPOFF(%rip), %rax
+
+ addq foo@GOTTPOFF(%rip), %r16
+ movq foo@GOTTPOFF(%rip), %r20
+
+ .intel_syntax noprefix
+
+ addq rax, QWORD PTR [rip + foo@GOTTPOFF]
+ movq rax, QWORD PTR [rip + foo@GOTTPOFF]
+
+ addq r16, QWORD PTR [rip + foo@GOTTPOFF]
+ movq r20, QWORD PTR [rip + foo@GOTTPOFF]
diff --git a/gas/testsuite/gas/i386/x86-64-tlsdesc.d b/gas/testsuite/gas/i386/x86-64-tlsdesc.d
new file mode 100644
index 0000000..50c04e1
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-tlsdesc.d
@@ -0,0 +1,17 @@
+#as:
+#objdump: -dwr
+#name: x86-64 tlsdesc
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+: 48 8d 05 00 00 00 00 lea 0x0\(%rip\),%rax # 7 <_start\+0x7> 3: R_X86_64_GOTPC32_TLSDESC foo-0x4
+ +[a-f0-9]+: d5 48 8d 05 00 00 00 00 lea 0x0\(%rip\),%r16 # f <_start\+0xf> b: R_X86_64_CODE_4_GOTPC32_TLSDESC foo-0x4
+ +[a-f0-9]+: d5 48 8d 25 00 00 00 00 lea 0x0\(%rip\),%r20 # 17 <_start\+0x17> 13: R_X86_64_CODE_4_GOTPC32_TLSDESC foo-0x4
+ +[a-f0-9]+: 48 8d 05 00 00 00 00 lea 0x0\(%rip\),%rax # 1e <_start\+0x1e> 1a: R_X86_64_GOTPC32_TLSDESC foo-0x4
+ +[a-f0-9]+: d5 48 8d 05 00 00 00 00 lea 0x0\(%rip\),%r16 # 26 <_start\+0x26> 22: R_X86_64_CODE_4_GOTPC32_TLSDESC foo-0x4
+ +[a-f0-9]+: d5 48 8d 25 00 00 00 00 lea 0x0\(%rip\),%r20 # 2e <_start\+0x2e> 2a: R_X86_64_CODE_4_GOTPC32_TLSDESC foo-0x4
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-tlsdesc.s b/gas/testsuite/gas/i386/x86-64-tlsdesc.s
new file mode 100644
index 0000000..91f8d23
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-tlsdesc.s
@@ -0,0 +1,13 @@
+ .text
+_start:
+ leaq foo@TLSDESC(%rip), %rax
+
+ leaq foo@TLSDESC(%rip), %r16
+ leaq foo@TLSDESC(%rip), %r20
+
+ .intel_syntax noprefix
+
+ leaq rax, QWORD PTR [rip + foo@TLSDESC]
+
+ leaq r16, QWORD PTR [rip + foo@TLSDESC]
+ leaq r20, QWORD PTR [rip + foo@TLSDESC]
diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86-64.exp
index fa6a1c3..cd28846 100644
--- a/gas/testsuite/gas/i386/x86-64.exp
+++ b/gas/testsuite/gas/i386/x86-64.exp
@@ -665,6 +665,9 @@ if [is_elf_format] then {
run_dump_test "x86-64-gotpcrel-no-relax"
run_dump_test "x86-64-gotpcrel-2"
+ run_dump_test "x86-64-gottpoff"
+ run_dump_test "x86-64-tlsdesc"
+
run_dump_test "x86-64-no-got"
run_dump_test "x86-64-addend"