From e59a1001222d853f0517c7e974bb51589ba86710 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 20 Sep 2019 12:21:50 +0930 Subject: PowerPC64, error on unsupported dynamic relocation This patch corrects the set of dynamic relocations recognised by gold as supported by glibc, and teaches ld.bfd to report an error similar to the gold error. Note that ld --noinhibit-exec can be used to produce an output, supporting older ld with newer glibc if the set of supported glibc dynamic relocations changes. bfd/ * elf64-ppc.c (ppc64_glibc_dynamic_reloc): New function. (ppc64_elf_relocate_section): Error if emitting unsupported dynamic relocations. gold/ * powerpc.cc (Target_powerpc::Scan::check_non_pic): Move REL24 to 32-bit supported. --- bfd/ChangeLog | 6 +++++ bfd/elf64-ppc.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gold/ChangeLog | 5 ++++ gold/powerpc.cc | 2 +- 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8fff6a67523..6fa38eef456 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2019-09-20 Alan Modra + + * elf64-ppc.c (ppc64_glibc_dynamic_reloc): New function. + (ppc64_elf_relocate_section): Warn if emitting unsupported dynamic + relocations. + 2019-09-18 Alan Modra * bfd-in.h (bfd_get_section_name, bfd_get_section_vma), diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 14119dd259a..ed8077586bb 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -14148,6 +14148,66 @@ ppc64_elf_action_discarded (asection *sec) return _bfd_elf_default_action_discarded (sec); } +/* These are the dynamic relocations supported by glibc. */ + +static bfd_boolean +ppc64_glibc_dynamic_reloc (enum elf_ppc64_reloc_type r_type) +{ + switch (r_type) + { + case R_PPC64_RELATIVE: + case R_PPC64_NONE: + case R_PPC64_ADDR64: + case R_PPC64_GLOB_DAT: + case R_PPC64_IRELATIVE: + case R_PPC64_JMP_IREL: + case R_PPC64_JMP_SLOT: + case R_PPC64_DTPMOD64: + case R_PPC64_DTPREL64: + case R_PPC64_TPREL64: + case R_PPC64_TPREL16_LO_DS: + case R_PPC64_TPREL16_DS: + case R_PPC64_TPREL16: + case R_PPC64_TPREL16_LO: + case R_PPC64_TPREL16_HI: + case R_PPC64_TPREL16_HIGH: + case R_PPC64_TPREL16_HA: + case R_PPC64_TPREL16_HIGHA: + case R_PPC64_TPREL16_HIGHER: + case R_PPC64_TPREL16_HIGHEST: + case R_PPC64_TPREL16_HIGHERA: + case R_PPC64_TPREL16_HIGHESTA: + case R_PPC64_ADDR16_LO_DS: + case R_PPC64_ADDR16_LO: + case R_PPC64_ADDR16_HI: + case R_PPC64_ADDR16_HIGH: + case R_PPC64_ADDR16_HA: + case R_PPC64_ADDR16_HIGHA: + case R_PPC64_REL30: + case R_PPC64_COPY: + case R_PPC64_UADDR64: + case R_PPC64_UADDR32: + case R_PPC64_ADDR32: + case R_PPC64_ADDR24: + case R_PPC64_ADDR16: + case R_PPC64_UADDR16: + case R_PPC64_ADDR16_DS: + case R_PPC64_ADDR16_HIGHER: + case R_PPC64_ADDR16_HIGHEST: + case R_PPC64_ADDR16_HIGHERA: + case R_PPC64_ADDR16_HIGHESTA: + case R_PPC64_ADDR14: + case R_PPC64_ADDR14_BRTAKEN: + case R_PPC64_ADDR14_BRNTAKEN: + case R_PPC64_REL32: + case R_PPC64_REL64: + return TRUE; + + default: + return FALSE; + } +} + /* The RELOCATE_SECTION function is called by the ELF backend linker to handle the relocations for a section. @@ -14201,6 +14261,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, bfd_boolean is_opd; /* Assume 'at' branch hints. */ bfd_boolean is_isa_v2 = TRUE; + bfd_boolean warned_dynamic = FALSE; bfd_vma d_offset = (bfd_big_endian (input_bfd) ? 2 : 0); /* Initialize howto table if needed. */ @@ -16166,6 +16227,19 @@ ppc64_elf_relocate_section (bfd *output_bfd, loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela); bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); + if (!warned_dynamic + && !ppc64_glibc_dynamic_reloc (ELF64_R_TYPE (outrel.r_info))) + { + info->callbacks->einfo + /* xgettext:c-format */ + (_("%X%P: %pB: %s against %pT " + "is not supported by glibc as a dynamic relocation\n"), + input_bfd, + ppc64_elf_howto_table[ELF64_R_TYPE (outrel.r_info)]->name, + sym_name); + warned_dynamic = TRUE; + } + /* If this reloc is against an external symbol, it will be computed at runtime, so there's no need to do anything now. However, for the sake of prelink ensure diff --git a/gold/ChangeLog b/gold/ChangeLog index 9e45c0fb079..8ec7014b2a9 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,8 @@ +2019-09-20 Alan Modra + + * powerpc.cc (Target_powerpc::Scan::check_non_pic): Move REL24 + to 32-bit supported. + 2019-09-18 Simon Marchi * testsuite/Makefile.in: Re-generate. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index e69ce192e36..ad35095ccd5 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -7355,7 +7355,6 @@ Target_powerpc::Scan::check_non_pic(Relobj* object, case elfcpp::R_POWERPC_ADDR14_BRTAKEN: case elfcpp::R_POWERPC_ADDR14_BRNTAKEN: case elfcpp::R_POWERPC_REL32: - case elfcpp::R_POWERPC_REL24: case elfcpp::R_POWERPC_TPREL16: case elfcpp::R_POWERPC_TPREL16_LO: case elfcpp::R_POWERPC_TPREL16_HI: @@ -7404,6 +7403,7 @@ Target_powerpc::Scan::check_non_pic(Relobj* object, { // These are the relocation types supported only on 32-bit. // ??? glibc ld.so doesn't need to support these. + case elfcpp::R_POWERPC_REL24: case elfcpp::R_POWERPC_DTPREL16: case elfcpp::R_POWERPC_DTPREL16_LO: case elfcpp::R_POWERPC_DTPREL16_HI: -- cgit v1.2.3-65-gdbad