x86-64: Fix TLSDESC relaxation for x32
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 20 Jan 2020 14:58:51 +0000 (06:58 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 20 Jan 2020 15:01:07 +0000 (07:01 -0800)
commit14470f0755dbc942aa684ed647df978ddfc7cff2
treec19e873d9c8c86cc24fe568ec473f7bd8c2b18e2
parentb9ca1af69e097b8dc15b23a4e12194f9567c4ad7
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.
23 files changed:
bfd/ChangeLog
bfd/elf64-x86-64.c
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/gas/i386/ilp32/x32-tls.d
gas/testsuite/gas/i386/ilp32/x32-tls.s
ld/ChangeLog
ld/testsuite/ld-x86-64/pr25416-1.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-1a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-1b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-2.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-2a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-2b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-3.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-3.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-4.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-4.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-5a.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-5b.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-5c.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-5d.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr25416-5e.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp