diff options
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 38 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/tlsie4.dd | 18 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/tlsie4.s | 16 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/x86-64.exp | 3 |
6 files changed, 80 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 407738e..36908e4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2011-03-03 H.J. Lu <hongjiu.lu@intel.com> + + * elf64-x86-64.c (elf_x86_64_check_tls_transition): Supprt TLS + x32 IE->LE transition. + (elf_x86_64_relocate_section): Likewise. + 2011-03-02 Bernd Schmidt <bernds@codesourcery.com> * elflink.c (is_reloc_section): Remove function. diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 343abce..56eb62e 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -913,16 +913,29 @@ elf_x86_64_check_tls_transition (bfd *abfd, case R_X86_64_GOTTPOFF: /* Check transition from IE access model: - movq foo@gottpoff(%rip), %reg - addq foo@gottpoff(%rip), %reg + mov foo@gottpoff(%rip), %reg + add foo@gottpoff(%rip), %reg */ - if (offset < 3 || (offset + 4) > sec->size) - return FALSE; - - val = bfd_get_8 (abfd, contents + offset - 3); - if (val != 0x48 && val != 0x4c) - return FALSE; + /* Check REX prefix first. */ + if (offset >= 3 && (offset + 4) <= sec->size) + { + val = bfd_get_8 (abfd, contents + offset - 3); + if (val != 0x48 && val != 0x4c) + { + /* X32 may have 0x44 REX prefix or no REX prefix. */ + if (ABI_64_P (abfd)) + return FALSE; + } + } + else + { + /* X32 may not have any REX prefix. */ + if (ABI_64_P (abfd)) + return FALSE; + if (offset < 2 || (offset + 3) > sec->size) + return FALSE; + } val = bfd_get_8 (abfd, contents + offset - 2); if (val != 0x8b && val != 0x03) @@ -3505,6 +3518,9 @@ elf_x86_64_relocate_section (bfd *output_bfd, if (val == 0x4c) bfd_put_8 (output_bfd, 0x49, contents + roff - 3); + else if (!ABI_64_P (output_bfd) && val == 0x44) + bfd_put_8 (output_bfd, 0x41, + contents + roff - 3); bfd_put_8 (output_bfd, 0xc7, contents + roff - 2); bfd_put_8 (output_bfd, 0xc0 | reg, @@ -3517,6 +3533,9 @@ elf_x86_64_relocate_section (bfd *output_bfd, if (val == 0x4c) bfd_put_8 (output_bfd, 0x49, contents + roff - 3); + else if (!ABI_64_P (output_bfd) && val == 0x44) + bfd_put_8 (output_bfd, 0x41, + contents + roff - 3); bfd_put_8 (output_bfd, 0x81, contents + roff - 2); bfd_put_8 (output_bfd, 0xc0 | reg, @@ -3528,6 +3547,9 @@ elf_x86_64_relocate_section (bfd *output_bfd, if (val == 0x4c) bfd_put_8 (output_bfd, 0x4d, contents + roff - 3); + else if (!ABI_64_P (output_bfd) && val == 0x44) + bfd_put_8 (output_bfd, 0x45, + contents + roff - 3); bfd_put_8 (output_bfd, 0x8d, contents + roff - 2); bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3), diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 4ff663f..c5bad13 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-03-03 H.J. Lu <hongjiu.lu@intel.com> + + * ld-x86-64/tlsie4.dd: New. + * ld-x86-64/tlsie4.s: Likewise. + + * ld-x86-64/x86-64.exp (x86_64tests): Add tlsie4. + 2011-02-25 H.J. Lu <hongjiu.lu@intel.com> PR ld/12516 diff --git a/ld/testsuite/ld-x86-64/tlsie4.dd b/ld/testsuite/ld-x86-64/tlsie4.dd new file mode 100644 index 0000000..d52e337 --- /dev/null +++ b/ld/testsuite/ld-x86-64/tlsie4.dd @@ -0,0 +1,18 @@ +#source: tlsie4.s +#as: --x32 +#ld: -melf32_x86_64 tmpdir/tlsie4 +#objdump: -drw +#target: x86_64-*-linux* + +.*: +file format .* + +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]+: 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 +[ ]*[a-f0-9]+: 41 81 c4 fc ff ff ff add \$0xfffffffc,%r12d +#pass diff --git a/ld/testsuite/ld-x86-64/tlsie4.s b/ld/testsuite/ld-x86-64/tlsie4.s new file mode 100644 index 0000000..ca63546 --- /dev/null +++ b/ld/testsuite/ld-x86-64/tlsie4.s @@ -0,0 +1,16 @@ + .text + .globl _start +_start: + mov foo@GOTTPOFF(%rip), %eax + add foo@GOTTPOFF(%rip), %eax + mov foo@GOTTPOFF(%rip), %r8d + add foo@GOTTPOFF(%rip), %r8d + mov foo@GOTTPOFF(%rip), %r12d + 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/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index a82a56f..43b9c39 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -87,6 +87,9 @@ set x86_64tests { {"Split by file with 'l' flag on section." "-split-by-file -r" "--64" {split-by-file1.s split-by-file2.s} {{readelf -SW split-by-file.rd}} "split-by-file.o"} + {"TLS X32 IE->LE transition" "-melf32_x86_64" + "--x32" {tlsie4.s} + {{objdump -dwr tlsie4.dd}} "tlsie4"} } run_ld_link_tests $x86_64tests |