diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2020-01-20 06:58:51 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2020-01-20 07:01:07 -0800 |
commit | 14470f0755dbc942aa684ed647df978ddfc7cff2 (patch) | |
tree | c19e873d9c8c86cc24fe568ec473f7bd8c2b18e2 /gas | |
parent | b9ca1af69e097b8dc15b23a4e12194f9567c4ad7 (diff) | |
download | gdb-14470f0755dbc942aa684ed647df978ddfc7cff2.zip gdb-14470f0755dbc942aa684ed647df978ddfc7cff2.tar.gz gdb-14470f0755dbc942aa684ed647df978ddfc7cff2.tar.bz2 |
x86-64: Fix TLSDESC relaxation for x32
For x32, we must encode "lea x@TLSDESC(%rip), %reg" with a REX prefix
even if it isn't required. Otherwise linker can’t safely perform
GDesc -> IE/LE optimization. X32 TLSDESC sequences can be:
40 8d 05 00 00 00 00 rex lea x@TLSDESC(%rip), %reg
...
67 ff 10 call *x@TLSCALL(%eax)
or the same sequence as LP64:
48 8d 05 00 00 00 00 lea foo@TLSDESC(%rip), %reg
...
ff 10 call *foo@TLSCALL(%rax)
We need to support both sequences for x32. For both GDesc -> IE/LE
transitions,
67 ff 10 call *x@TLSCALL(%eax)
should relaxed to
0f 1f 00 nopl (%rax)
For GDesc -> LE transition,
40 8d 05 00 00 00 00 rex lea x@TLSDESC(%rip), %reg
should relaxed to
40 c7 c0 fc ff ff ff rex movl $x@tpoff, %reg
For GDesc -> IE transition,
40 8d 05 00 00 00 00 rex lea x@TLSDESC(%rip), %reg
should relaxed to
40 8b 05 00 00 00 00 rex movl x@gottpoff(%rip), %eax
bfd/
PR ld/25416
* elf64-x86-64.c (elf_x86_64_check_tls_transition): Support
"rex leal x@tlsdesc(%rip), %reg" and "call *x@tlsdesc(%eax)" in
X32 mode.
(elf_x86_64_relocate_section): In x32 mode, for GDesc -> LE
transition, relax "rex leal x@tlsdesc(%rip), %reg" to
"rex movl $x@tpoff, %reg", for GDesc -> IE transition, relax
"rex leal x@tlsdesc(%rip), %reg" to
"rex movl x@gottpoff(%rip), %eax". For both transitions, relax
"call *(%eax)" to "nopl (%rax)".
gas/
PR ld/25416
* config/tc-i386.c (output_insn): Add a dummy REX_OPCODE prefix
for lea with R_X86_64_GOTPC32_TLSDESC relocation when generating
x32 object.
* testsuite/gas/i386/ilp32/x32-tls.d: Updated.
* testsuite/gas/i386/ilp32/x32-tls.s: Add tests for lea with
R_X86_64_GOTPC32_TLSDESC relocation.
ld/
PR ld/25416
* testsuite/ld-x86-64/pr25416-1.s: New file
* testsuite/ld-x86-64/pr25416-1a.d: Likewise.
* testsuite/ld-x86-64/pr25416-1b.d: Likewise.
* testsuite/ld-x86-64/pr25416-1.s: Likewise.
* testsuite/ld-x86-64/pr25416-2.s: Likewise.
* testsuite/ld-x86-64/pr25416-2a.d: Likewise.
* testsuite/ld-x86-64/pr25416-2b.d: Likewise.
* testsuite/ld-x86-64/pr25416-3.d: Likewise.
* testsuite/ld-x86-64/pr25416-3.s: Likewise.
* testsuite/ld-x86-64/pr25416-4.d: Likewise.
* testsuite/ld-x86-64/pr25416-4.s: Likewise.
* testsuite/ld-x86-64/pr25416-5a.c: Likewise.
* testsuite/ld-x86-64/pr25416-5b.s: Likewise.
* testsuite/ld-x86-64/pr25416-5c.s: Likewise.
* testsuite/ld-x86-64/pr25416-5d.s: Likewise.
* testsuite/ld-x86-64/pr25416-5e.s: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run PR ld/25416 tests.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 10 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 7 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/ilp32/x32-tls.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/ilp32/x32-tls.s | 2 |
4 files changed, 19 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 426e484..0220948 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2020-01-20 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/25416 + * config/tc-i386.c (output_insn): Add a dummy REX_OPCODE prefix + for lea with R_X86_64_GOTPC32_TLSDESC relocation when generating + x32 object. + * testsuite/gas/i386/ilp32/x32-tls.d: Updated. + * testsuite/gas/i386/ilp32/x32-tls.s: Add tests for lea with + R_X86_64_GOTPC32_TLSDESC relocation. + 2020-01-18 Nick Clifton <nickc@redhat.com> * configure: Regenerate. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 8728725..87ab43b 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -8713,10 +8713,13 @@ output_insn (void) #if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF) /* For x32, add a dummy REX_OPCODE prefix for mov/add with R_X86_64_GOTTPOFF relocation so that linker can safely - perform IE->LE optimization. */ + perform IE->LE optimization. A dummy REX_OPCODE prefix + 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 && i.operands == 2 - && i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF + && (i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF + || i.reloc[0] == BFD_RELOC_X86_64_GOTPC32_TLSDESC) && i.prefix[REX_PREFIX] == 0) add_prefix (REX_OPCODE); #endif diff --git a/gas/testsuite/gas/i386/ilp32/x32-tls.d b/gas/testsuite/gas/i386/ilp32/x32-tls.d index 1255829..ab4da5c 100644 --- a/gas/testsuite/gas/i386/ilp32/x32-tls.d +++ b/gas/testsuite/gas/i386/ilp32/x32-tls.d @@ -10,4 +10,6 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 4c 8b 25 00 00 00 00 mov 0x0\(%rip\),%r12 # e <_start\+0xe> [ ]*[a-f0-9]+: 40 03 05 00 00 00 00 rex add 0x0\(%rip\),%eax # 15 <_start\+0x15> [ ]*[a-f0-9]+: 44 03 25 00 00 00 00 add 0x0\(%rip\),%r12d # 1c <_start\+0x1c> +[ ]*[a-f0-9]+: 40 8d 05 00 00 00 00 rex lea 0x0\(%rip\),%eax # 23 <_start\+0x23> +[ ]*[a-f0-9]+: 44 8d 25 00 00 00 00 lea 0x0\(%rip\),%r12d # 2a <_start\+0x2a> #pass diff --git a/gas/testsuite/gas/i386/ilp32/x32-tls.s b/gas/testsuite/gas/i386/ilp32/x32-tls.s index f9626cd..e1599be 100644 --- a/gas/testsuite/gas/i386/ilp32/x32-tls.s +++ b/gas/testsuite/gas/i386/ilp32/x32-tls.s @@ -4,6 +4,8 @@ _start: mov foo@gottpoff(%rip), %r12 add foo@gottpoff(%rip), %eax add foo@gottpoff(%rip), %r12d + lea foo@tlsdesc(%rip), %eax + lea foo@tlsdesc(%rip), %r12d .globl foo .section .tdata,"awT",@progbits .align 4 |