From 78984959cb385388e29dcc88dc169449344f22d7 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 6 Sep 2017 05:06:35 -0700 Subject: [PATCH] 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. --- bfd/ChangeLog | 16 ++++++++++++++ bfd/elf64-x86-64.c | 42 +++++++++++++++++++++++++++---------- bfd/elfxx-x86.h | 5 ----- ld/ChangeLog | 7 +++++++ ld/testsuite/ld-x86-64/pr19609-2a.d | 2 +- ld/testsuite/ld-x86-64/pr19609-2b.d | 2 +- ld/testsuite/ld-x86-64/pr19609-4a.d | 3 +-- ld/testsuite/ld-x86-64/pr19609-4c.d | 3 +-- 8 files changed, 58 insertions(+), 22 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f323dfa..9622383 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,21 @@ 2017-09-06 H.J. Lu + * 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. + +2017-09-06 H.J. Lu + * elf32-i386.c (elf_i386_relocate_section): Don't change r_type when calling elf_i386_tls_transition. Don't use ELF32_R_TYPE to get the relocation type again. 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) { diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index 775e025..9c0dcbbe 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -110,11 +110,6 @@ struct elf_x86_link_hash_entry is only used by x86-64. */ unsigned int needs_copy : 1; - /* TRUE if a symbol with GOTPCREL relocations which have been converted - to R_X86_64_PC32, R_X86_64_32 or R_X86_64_32S. This is only used by - x86-64 for now. */ - unsigned int converted_reloc : 1; - /* Reference count of C/C++ function pointer relocations in read-write section which can be resolved at run-time. */ bfd_signed_vma func_pointer_refcount; diff --git a/ld/ChangeLog b/ld/ChangeLog index 7313795..98318e9 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2017-09-06 H.J. Lu + + * 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. + 2017-09-05 H.J. Lu * testsuite/ld-x86-64/pr19609-5d.d: Updated. diff --git a/ld/testsuite/ld-x86-64/pr19609-2a.d b/ld/testsuite/ld-x86-64/pr19609-2a.d index e2c6c89..2bed641 100644 --- a/ld/testsuite/ld-x86-64/pr19609-2a.d +++ b/ld/testsuite/ld-x86-64/pr19609-2a.d @@ -1,4 +1,4 @@ #source: pr19609-2.s #as: --64 -mrelax-relocations=yes #ld: -melf_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000 -#error: .*relocation truncated to fit: R_X86_64_32S .* +#error: failed to convert GOTPCREL relocation; relink with --no-relax diff --git a/ld/testsuite/ld-x86-64/pr19609-2b.d b/ld/testsuite/ld-x86-64/pr19609-2b.d index ead4987..3741ebb 100644 --- a/ld/testsuite/ld-x86-64/pr19609-2b.d +++ b/ld/testsuite/ld-x86-64/pr19609-2b.d @@ -1,4 +1,4 @@ #source: pr19609-2.s #as: --x32 -mrelax-relocations=yes #ld: -melf32_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000 -#error: .*relocation truncated to fit: R_X86_64_32S .* +#error: failed to convert GOTPCREL relocation; relink with --no-relax diff --git a/ld/testsuite/ld-x86-64/pr19609-4a.d b/ld/testsuite/ld-x86-64/pr19609-4a.d index ce952ed..f08843c 100644 --- a/ld/testsuite/ld-x86-64/pr19609-4a.d +++ b/ld/testsuite/ld-x86-64/pr19609-4a.d @@ -1,5 +1,4 @@ #source: pr19609-4.s #as: --64 -mrelax-relocations=yes #ld: -melf_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000 -#error: .*relocation truncated to fit: R_X86_64_32S .* -#error: .*relocation truncated to fit: R_X86_64_32S .* +#error: failed to convert GOTPCREL relocation; relink with --no-relax diff --git a/ld/testsuite/ld-x86-64/pr19609-4c.d b/ld/testsuite/ld-x86-64/pr19609-4c.d index ce952ed..f08843c 100644 --- a/ld/testsuite/ld-x86-64/pr19609-4c.d +++ b/ld/testsuite/ld-x86-64/pr19609-4c.d @@ -1,5 +1,4 @@ #source: pr19609-4.s #as: --64 -mrelax-relocations=yes #ld: -melf_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000 -#error: .*relocation truncated to fit: R_X86_64_32S .* -#error: .*relocation truncated to fit: R_X86_64_32S .* +#error: failed to convert GOTPCREL relocation; relink with --no-relax -- 2.7.4