diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2011-03-03 22:11:33 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2011-03-03 22:11:33 +0000 |
commit | 4a4c5f250b2251c4f6a11b748061d044a6919b9b (patch) | |
tree | cb051b2d2a71ebfed2896442b9ef706a81f75fd5 /bfd/elf64-x86-64.c | |
parent | 2e3fd7679d44288bc1f0e9cf28fe3a04c854e08d (diff) | |
download | gdb-4a4c5f250b2251c4f6a11b748061d044a6919b9b.zip gdb-4a4c5f250b2251c4f6a11b748061d044a6919b9b.tar.gz gdb-4a4c5f250b2251c4f6a11b748061d044a6919b9b.tar.bz2 |
Supprt TLS x32 IE->LE transition.
bfd/
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.
ld/testsuite/
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.
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r-- | bfd/elf64-x86-64.c | 38 |
1 files changed, 30 insertions, 8 deletions
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), |