From cf115d606eea814d659588953cbaa5b0b16e234c Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 7 Nov 2014 12:22:53 -0800 Subject: [PATCH] X32: Add REX prefix to encode R_X86_64_GOTTPOFF Structions with R_X86_64_GOTTPOFF relocation must be encoded with REX prefix even if it isn't required by destination register. Otherwise linker can't safely perform IE -> LE optimization. bfd/ PR ld/17482 * elf64-x86-64.c (elf_x86_64_relocate_section): Update comments for IE->LE transition. gas/ PR ld/17482 * config/tc-i386.c (output_insn): Add a dummy REX_OPCODE prefix for structions with R_X86_64_GOTTPOFF relocation for x32 if needed. gas/testsuite/ PR ld/17482 * gas/i386/ilp32/x32-tls.d: New file. * gas/i386/ilp32/x32-tls.s: Likewise. ld/testsuite/ PR ld/17482 * ld-x86-64/tlsie4.dd: Updated. --- bfd/ChangeLog | 9 +++++++++ bfd/elf64-x86-64.c | 22 ++++++++++++++++------ gas/ChangeLog | 9 +++++++++ gas/config/tc-i386.c | 9 +++++++++ gas/testsuite/ChangeLog | 9 +++++++++ gas/testsuite/gas/i386/ilp32/x32-tls.d | 13 +++++++++++++ gas/testsuite/gas/i386/ilp32/x32-tls.s | 13 +++++++++++++ ld/testsuite/ChangeLog | 8 ++++++++ ld/testsuite/ld-x86-64/tlsie4.dd | 4 ++-- 9 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 gas/testsuite/gas/i386/ilp32/x32-tls.d create mode 100644 gas/testsuite/gas/i386/ilp32/x32-tls.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index eff716e..91bbd61 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2014-11-07 H.J. Lu + + Apply trunk patch: + 2014-11-07 H.J. Lu + + PR ld/17482 + * elf64-x86-64.c (elf_x86_64_relocate_section): Update comments + for IE->LE transition. + 2014-11-04 Tristan Gingold * development.sh: Set development to false. diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index dcd4ffa..b210403 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -4281,17 +4281,27 @@ direct: else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF) { /* IE->LE transition: - Originally it can be one of: + For 64bit, originally it can be one of: movq foo@gottpoff(%rip), %reg addq foo@gottpoff(%rip), %reg We change it into: movq $foo, %reg leaq foo(%reg), %reg - addq $foo, %reg. */ + addq $foo, %reg. + For 32bit, originally it can be one of: + movq foo@gottpoff(%rip), %reg + addl foo@gottpoff(%rip), %reg + We change it into: + movq $foo, %reg + leal foo(%reg), %reg + addl $foo, %reg. */ unsigned int val, type, reg; - val = bfd_get_8 (input_bfd, contents + roff - 3); + if (roff >= 3) + val = bfd_get_8 (input_bfd, contents + roff - 3); + else + val = 0; type = bfd_get_8 (input_bfd, contents + roff - 2); reg = bfd_get_8 (input_bfd, contents + roff - 1); reg >>= 3; @@ -4311,8 +4321,8 @@ direct: } else if (reg == 4) { - /* addq -> addq - addressing with %rsp/%r12 is - special */ + /* addq/addl -> addq/addl - addressing with %rsp/%r12 + is special */ if (val == 0x4c) bfd_put_8 (output_bfd, 0x49, contents + roff - 3); @@ -4326,7 +4336,7 @@ direct: } else { - /* addq -> leaq */ + /* addq/addl -> leaq/leal */ if (val == 0x4c) bfd_put_8 (output_bfd, 0x4d, contents + roff - 3); diff --git a/gas/ChangeLog b/gas/ChangeLog index fde4a52..cb1829d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2014-11-07 H.J. Lu + + Apply trunk patch: + 2014-11-07 H.J. Lu + + PR ld/17482 + * config/tc-i386.c (output_insn): Add a dummy REX_OPCODE prefix + for structions with R_X86_64_GOTTPOFF relocation for x32 if needed. + 2014-11-03 Nick Clifton Apply trunk patch: diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 2e34ce3..cdd4ed4 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -6997,6 +6997,15 @@ check_prefix: abort (); } + /* 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. */ + if (x86_elf_abi == X86_64_X32_ABI + && i.operands == 2 + && i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF + && i.prefix[REX_PREFIX] == 0) + add_prefix (REX_OPCODE); + /* The prefix bytes. */ for (j = ARRAY_SIZE (i.prefix), q = i.prefix; j > 0; j--, q++) if (*q) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 90c9d57..e39be36 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2014-11-07 H.J. Lu + + Apply trunk patch: + 2014-11-07 H.J. Lu + + PR ld/17482 + * gas/i386/ilp32/x32-tls.d: New file. + * gas/i386/ilp32/x32-tls.s: Likewise. + 2014-10-28 Matthew Fortune Apply trunk patches diff --git a/gas/testsuite/gas/i386/ilp32/x32-tls.d b/gas/testsuite/gas/i386/ilp32/x32-tls.d new file mode 100644 index 0000000..1255829 --- /dev/null +++ b/gas/testsuite/gas/i386/ilp32/x32-tls.d @@ -0,0 +1,13 @@ +#objdump: -dw +#name: x86-64 (ILP32) TLS + +.*: +file format .* + +Disassembly of section .text: + +0+ <_start>: +[ ]*[a-f0-9]+: 48 8b 05 00 00 00 00 mov 0x0\(%rip\),%rax # 7 <_start\+0x7> +[ ]*[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> +#pass diff --git a/gas/testsuite/gas/i386/ilp32/x32-tls.s b/gas/testsuite/gas/i386/ilp32/x32-tls.s new file mode 100644 index 0000000..f9626cd --- /dev/null +++ b/gas/testsuite/gas/i386/ilp32/x32-tls.s @@ -0,0 +1,13 @@ + .text +_start: + mov foo@gottpoff(%rip), %rax + mov foo@gottpoff(%rip), %r12 + add foo@gottpoff(%rip), %eax + add foo@gottpoff(%rip), %r12d + .globl foo + .section .tdata,"awT",@progbits + .align 4 + .type foo, @object + .size foo, 4 +foo: + .long 100 diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 131e585..1453b04 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2014-11-07 H.J. Lu + + Apply trunk patch: + 2014-11-07 H.J. Lu + + PR ld/17482 + * ld-x86-64/tlsie4.dd: Updated. + 2014-10-24 Tejas Belagod * ld-aarch64/aarch64-elf.exp (aarch64elftests): Drive erratum diff --git a/ld/testsuite/ld-x86-64/tlsie4.dd b/ld/testsuite/ld-x86-64/tlsie4.dd index d52e337..e40b917 100644 --- a/ld/testsuite/ld-x86-64/tlsie4.dd +++ b/ld/testsuite/ld-x86-64/tlsie4.dd @@ -9,8 +9,8 @@ Disassembly of section .text: [a-f0-9]+ <_start>: -[ ]*[a-f0-9]+: c7 c0 fc ff ff ff mov \$0xfffffffc,%eax -[ ]*[a-f0-9]+: 8d 80 fc ff ff ff lea -0x4\(%rax\),%eax +[ ]*[a-f0-9]+: 40 c7 c0 fc ff ff ff rex mov \$0xfffffffc,%eax +[ ]*[a-f0-9]+: 40 8d 80 fc ff ff ff rex lea -0x4\(%rax\),%eax [ ]*[a-f0-9]+: 41 c7 c0 fc ff ff ff mov \$0xfffffffc,%r8d [ ]*[a-f0-9]+: 45 8d 80 fc ff ff ff lea -0x4\(%r8\),%r8d [ ]*[a-f0-9]+: 41 c7 c4 fc ff ff ff mov \$0xfffffffc,%r12d -- 2.7.4