]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PowerPC64, error on unsupported dynamic relocation
authorAlan Modra <amodra@gmail.com>
Fri, 20 Sep 2019 02:51:50 +0000 (12:21 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 20 Sep 2019 03:21:19 +0000 (12:51 +0930)
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
bfd/elf64-ppc.c
gold/ChangeLog
gold/powerpc.cc

index 8fff6a67523d9920b4c2cb3d21f2fd7796ecb4da..6fa38eef4561b59e9e3b96d4fcc834f64564a403 100644 (file)
@@ -1,3 +1,9 @@
+2019-09-20  Alan Modra  <amodra@gmail.com>
+
+       * elf64-ppc.c (ppc64_glibc_dynamic_reloc): New function.
+       (ppc64_elf_relocate_section): Warn if emitting unsupported dynamic
+       relocations.
+
 2019-09-18  Alan Modra  <amodra@gmail.com>
 
        * bfd-in.h (bfd_get_section_name, bfd_get_section_vma),
index 14119dd259a984b3272099eec55137baf09018b8..ed8077586bb383beabd32cd85d49671d08925902 100644 (file)
@@ -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
index 9e45c0fb07970b501c70fbcd99a72772710ee0d1..8ec7014b2a984975f5c18d6030abc57a23549c97 100644 (file)
@@ -1,3 +1,8 @@
+2019-09-20  Alan Modra  <amodra@gmail.com>
+
+       * powerpc.cc (Target_powerpc::Scan::check_non_pic): Move REL24
+       to 32-bit supported.
+
 2019-09-18  Simon Marchi  <simon.marchi@polymtl.ca>
 
        * testsuite/Makefile.in: Re-generate.
index e69ce192e364db854eb6746aa62cc583aaf71d1b..ad35095ccd585412619ff62b72d05c318c1c639c 100644 (file)
@@ -7355,7 +7355,6 @@ Target_powerpc<size, big_endian>::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<size, big_endian>::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: