aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2012-08-31 02:42:57 +0000
committerAlan Modra <amodra@gmail.com>2012-08-31 02:42:57 +0000
commitb69fdb4ec950776d74fb10ed44a624089dbb23af (patch)
tree835e07f6418d3d287bfa494748e7138bd3dbf4a4 /bfd/elf64-ppc.c
parentdd93cd0ae8d749f8d2fdbf6d6c9f5d51c2cbdc01 (diff)
downloadgdb-b69fdb4ec950776d74fb10ed44a624089dbb23af.zip
gdb-b69fdb4ec950776d74fb10ed44a624089dbb23af.tar.gz
gdb-b69fdb4ec950776d74fb10ed44a624089dbb23af.tar.bz2
PR ld/14464
* elf64-ppc.c (ppc64_elf_relocate_section): Map symbols defined by a linker script in .opd to corresponding input .opd section.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 71403c3..27574b9 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -12328,6 +12328,33 @@ ppc64_elf_relocate_section (bfd *output_bfd,
unresolved_reloc, warned);
sym_name = h_elf->root.root.string;
sym_type = h_elf->type;
+ if (sec != NULL
+ && sec->owner == output_bfd
+ && strcmp (sec->name, ".opd") == 0)
+ {
+ /* This is a symbol defined in a linker script. All
+ such are defined in output sections, even those
+ defined by simple assignment from a symbol defined in
+ an input section. Transfer the symbol to an
+ appropriate input .opd section, so that a branch to
+ this symbol will be mapped to the location specified
+ by the opd entry. */
+ struct bfd_link_order *lo;
+ for (lo = sec->map_head.link_order; lo != NULL; lo = lo->next)
+ if (lo->type == bfd_indirect_link_order)
+ {
+ asection *isec = lo->u.indirect.section;
+ if (h_elf->root.u.def.value >= isec->output_offset
+ && h_elf->root.u.def.value < (isec->output_offset
+ + isec->size))
+ {
+ h_elf->root.u.def.value -= isec->output_offset;
+ h_elf->root.u.def.section = isec;
+ sec = isec;
+ break;
+ }
+ }
+ }
}
h = (struct ppc_link_hash_entry *) h_elf;