aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-09-20 12:21:50 +0930
committerAlan Modra <amodra@gmail.com>2019-09-20 12:51:19 +0930
commite59a1001222d853f0517c7e974bb51589ba86710 (patch)
treed31bde00fd91d48b7367a4ed9eb83984cdcd97bb /bfd/elf64-ppc.c
parente4153ae630fcc779ba414fdcea960394cb479e04 (diff)
downloadgdb-e59a1001222d853f0517c7e974bb51589ba86710.zip
gdb-e59a1001222d853f0517c7e974bb51589ba86710.tar.gz
gdb-e59a1001222d853f0517c7e974bb51589ba86710.tar.bz2
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.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 14119dd..ed80775 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