diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-09-06 05:06:35 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-09-06 05:06:35 -0700 |
commit | 78984959cb385388e29dcc88dc169449344f22d7 (patch) | |
tree | 728839140d195a3653a3e33e5957ecab476f09e8 /bfd/elf64-x86-64.c | |
parent | 419414eafcee7cd749ee4622ef25020e48b52cc4 (diff) | |
download | binutils-78984959cb385388e29dcc88dc169449344f22d7.zip binutils-78984959cb385388e29dcc88dc169449344f22d7.tar.gz binutils-78984959cb385388e29dcc88dc169449344f22d7.tar.bz2 |
x86-64: Add R_X86_64_converted_reloc_bit
Add R_X86_64_converted_reloc_bit to relocation type to indicate if a
relocation is converted from a GOTPCREL relocation. Linker now generates
failed to convert GOTPCREL relocation; relink with --no-relax
for all cases, including relocations against local symbols.
bfd/
* elf64-x86-64.c (R_X86_64_converted_reloc_bit): New.
(elf_x86_64_info_to_howto): Get the real relocation type by
masking out R_X86_64_converted_reloc_bit.
(elf_x86_64_check_tls_transition): Get the real relocation type
by masking out R_X86_64_converted_reloc_bit.
(elf_x86_64_convert_load_reloc): Set R_X86_64_converted_reloc_bit
instead of setting converted_reloc.
(elf_x86_64_relocate_section): Check R_X86_64_converted_reloc_bit
instead of converted_reloc. Get the real relocation type by
masking out R_X86_64_converted_reloc_bit.
(elf_x86_64_link_setup_gnu_properties): Verify that the value of
R_X86_64_converted_reloc_bit is valid.
* elfxx-x86.h (converted_reloc): Removed.
ld/
* testsuite/ld-x86-64/pr19609-2a.d: Updated.
* testsuite/ld-x86-64/pr19609-2b.d: Likewise.
* testsuite/ld-x86-64/pr19609-4a.d: Likewise.
* testsuite/ld-x86-64/pr19609-4c.d: Likewise.
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r-- | bfd/elf64-x86-64.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 8807447..8f1ac1a 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -196,6 +196,9 @@ static reloc_howto_type x86_64_elf_howto_table[] = FALSE) }; +/* Set if a relocation is converted from a GOTPCREL relocation. */ +#define R_X86_64_converted_reloc_bit (1 << 7) + #define IS_X86_64_PCREL_TYPE(TYPE) \ ( ((TYPE) == R_X86_64_PC8) \ || ((TYPE) == R_X86_64_PC16) \ @@ -337,6 +340,9 @@ elf_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, unsigned r_type; r_type = ELF32_R_TYPE (dst->r_info); + if (r_type != (unsigned int) R_X86_64_GNU_VTINHERIT + && r_type != (unsigned int) R_X86_64_GNU_VTENTRY) + r_type &= ~R_X86_64_converted_reloc_bit; cache_ptr->howto = elf_x86_64_rtype_to_howto (abfd, r_type); BFD_ASSERT (r_type == cache_ptr->howto->type); } @@ -1145,13 +1151,17 @@ elf_x86_64_check_tls_transition (bfd *abfd, if (h == NULL || !((struct elf_x86_link_hash_entry *) h)->tls_get_addr) return FALSE; - else if (largepic) - return ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLTOFF64; - else if (indirect_call) - return ELF32_R_TYPE (rel[1].r_info) == R_X86_64_GOTPCRELX; else - return (ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PC32 - || ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLT32); + { + r_type = (ELF32_R_TYPE (rel[1].r_info) + & ~R_X86_64_converted_reloc_bit); + if (largepic) + return r_type == R_X86_64_PLTOFF64; + else if (indirect_call) + return r_type == R_X86_64_GOTPCRELX; + else + return (r_type == R_X86_64_PC32 || r_type == R_X86_64_PLT32); + } case R_X86_64_GOTTPOFF: /* Check transition from IE access model: @@ -1598,9 +1608,6 @@ elf_x86_64_convert_load_reloc (bfd *abfd, return TRUE; convert: - if (h != NULL) - ((struct elf_x86_link_hash_entry *) h)->converted_reloc = 1; - if (opcode == 0xff) { /* We have "call/jmp *foo@GOTPCREL(%rip)". */ @@ -1742,7 +1749,8 @@ rewrite_modrm_rex: bfd_put_8 (abfd, opcode, contents + roff - 2); } - irel->r_info = htab->r_info (r_symndx, r_type); + irel->r_info = htab->r_info (r_symndx, + r_type | R_X86_64_converted_reloc_bit); *converted = TRUE; @@ -2527,6 +2535,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, bfd_vma st_size; bfd_boolean resolved_to_zero; bfd_boolean relative_reloc; + bfd_boolean converted_reloc; r_type = ELF32_R_TYPE (rel->r_info); if (r_type == (int) R_X86_64_GNU_VTINHERIT @@ -2537,6 +2546,9 @@ elf_x86_64_relocate_section (bfd *output_bfd, continue; } + converted_reloc = (r_type & R_X86_64_converted_reloc_bit) != 0; + r_type &= ~R_X86_64_converted_reloc_bit; + if (r_type >= (int) R_X86_64_standard) return _bfd_unrecognized_reloc (input_bfd, input_section, r_type); @@ -4011,7 +4023,7 @@ check_relocation_error: if (r == bfd_reloc_overflow) { - if (eh != NULL && eh->converted_reloc) + if (converted_reloc) { info->callbacks->einfo (_("%F%P: failed to convert GOTPCREL relocation; relink with --no-relax\n")); @@ -5250,6 +5262,14 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info) { struct elf_x86_plt_layout_table plt_layout; + if ((int) R_X86_64_standard >= (int) R_X86_64_converted_reloc_bit + || (int) R_X86_64_max <= (int) R_X86_64_converted_reloc_bit + || ((int) (R_X86_64_GNU_VTINHERIT | R_X86_64_converted_reloc_bit) + != (int) R_X86_64_GNU_VTINHERIT) + || ((int) (R_X86_64_GNU_VTENTRY | R_X86_64_converted_reloc_bit) + != (int) R_X86_64_GNU_VTENTRY)) + abort (); + plt_layout.is_vxworks = FALSE; if (get_elf_x86_64_backend_data (info->output_bfd)->os == is_normal) { |