aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2010-03-26 00:35:57 +0000
committerAlan Modra <amodra@gmail.com>2010-03-26 00:35:57 +0000
commit6abec6bce3a041b05efe8b3581574ee4b4bfcd42 (patch)
treeeea7ad5ef6a659137b74231ac0d2b037222545f7 /bfd/elf64-ppc.c
parent93620fdb761848359e7023583169bf00c2a3b791 (diff)
downloadgdb-6abec6bce3a041b05efe8b3581574ee4b4bfcd42.zip
gdb-6abec6bce3a041b05efe8b3581574ee4b4bfcd42.tar.gz
gdb-6abec6bce3a041b05efe8b3581574ee4b4bfcd42.tar.bz2
PR ld/11375
* elf64-ppc.c (ppc64_elf_relocate_section): Always look up a possible stub on branches.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c34
1 files changed, 14 insertions, 20 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index b1527f9..306c15e 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -11914,23 +11914,13 @@ ppc64_elf_relocate_section (bfd *output_bfd,
linkage stubs needs to be followed by a nop, as the nop
will be replaced with an instruction to restore the TOC
base pointer. */
- stub_entry = NULL;
fdh = h;
if (h != NULL
&& h->oh != NULL
&& h->oh->is_func_descriptor)
fdh = ppc_follow_link (h->oh);
- if (((fdh != NULL
- && fdh->elf.plt.plist != NULL)
- || (sec != NULL
- && sec->output_section != NULL
- && sec->id <= htab->top_id
- && (htab->stub_group[sec->id].toc_off
- != htab->stub_group[input_section->id].toc_off))
- || (h == NULL
- && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC))
- && (stub_entry = ppc_get_stub_entry (input_section, sec, fdh,
- rel, htab)) != NULL
+ stub_entry = ppc_get_stub_entry (input_section, sec, fdh, rel, htab);
+ if (stub_entry != NULL
&& (stub_entry->stub_type == ppc_stub_plt_call
|| stub_entry->stub_type == ppc_stub_plt_branch_r2off
|| stub_entry->stub_type == ppc_stub_long_branch_r2off))
@@ -12015,7 +12005,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
unresolved_reloc = FALSE;
}
- if (stub_entry == NULL
+ if ((stub_entry == NULL
+ || stub_entry->stub_type == ppc_stub_long_branch
+ || stub_entry->stub_type == ppc_stub_plt_branch)
&& get_opd_info (sec) != NULL)
{
/* The branch destination is the value of the opd entry. */
@@ -12036,13 +12028,15 @@ ppc64_elf_relocate_section (bfd *output_bfd,
+ input_section->output_offset
+ input_section->output_section->vma);
- if (stub_entry == NULL
- && (relocation + addend - from + max_br_offset
- >= 2 * max_br_offset)
- && r_type != R_PPC64_ADDR14_BRTAKEN
- && r_type != R_PPC64_ADDR14_BRNTAKEN)
- stub_entry = ppc_get_stub_entry (input_section, sec, fdh, rel,
- htab);
+ if (stub_entry != NULL
+ && (stub_entry->stub_type == ppc_stub_long_branch
+ || stub_entry->stub_type == ppc_stub_plt_branch)
+ && (r_type == R_PPC64_ADDR14_BRTAKEN
+ || r_type == R_PPC64_ADDR14_BRNTAKEN
+ || (relocation + addend - from + max_br_offset
+ < 2 * max_br_offset)))
+ /* Don't use the stub if this branch is in range. */
+ stub_entry = NULL;
if (stub_entry != NULL)
{