diff options
author | Alan Modra <amodra@gmail.com> | 2012-08-31 02:42:57 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2012-08-31 02:42:57 +0000 |
commit | b69fdb4ec950776d74fb10ed44a624089dbb23af (patch) | |
tree | 835e07f6418d3d287bfa494748e7138bd3dbf4a4 /bfd/elf64-ppc.c | |
parent | dd93cd0ae8d749f8d2fdbf6d6c9f5d51c2cbdc01 (diff) | |
download | gdb-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.c | 27 |
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; |