diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2023-06-09 13:50:22 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2023-12-28 08:47:17 -0800 |
commit | a533c8df598b5ef99c54a13e2b137c98b34b043c (patch) | |
tree | cb019f462896604b2b48bb1f40dfe01bc0437051 /gas | |
parent | 4a54cb06585f568031dfd291d0fe45979ad75e98 (diff) | |
download | gdb-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.c | 20 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-gottpoff.d | 19 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-gottpoff.s | 15 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-tlsdesc.d | 17 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-tlsdesc.s | 13 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64.exp | 3 |
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" |