PR ld/11375
authorAlan Modra <amodra@gmail.com>
Fri, 26 Mar 2010 00:35:57 +0000 (00:35 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 26 Mar 2010 00:35:57 +0000 (00:35 +0000)
* elf64-ppc.c (ppc64_elf_relocate_section): Always look up a
possible stub on branches.

bfd/ChangeLog
bfd/elf64-ppc.c

index 0e1b2fa0fb3a875c5873961fe0cceaf6721fc580..e0061dce78c086c03551e726493f3fe3b94993da 100644 (file)
@@ -1,3 +1,9 @@
+2010-03-26  Alan Modra  <amodra@gmail.com>
+
+       PR ld/11375
+       * elf64-ppc.c (ppc64_elf_relocate_section): Always look up a
+       possible stub on branches.
+
 2010-03-25  Joseph Myers  <joseph@codesourcery.com>
 
        * Makefile.am (ALL_MACHINES): Add cpu-tic6x.lo.
index b1527f9318175476644a51fe01211eef3c6da2c2..306c15e97a2cddc5ec7c7168c19e19b075e6b6bf 100644 (file)
@@ -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)
            {