From: Alan Modra Date: Mon, 31 Jan 2011 22:38:26 +0000 (+0000) Subject: * elf64-ppc.c (ppc64_elf_next_input_section): Use elf_gp value X-Git-Tag: sid-snapshot-20110201~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6683a28dfa81c11b68c50228b4a8bbd99d931754;p=platform%2Fupstream%2Fbinutils.git * elf64-ppc.c (ppc64_elf_next_input_section): Use elf_gp value for toc pointer on any section having makes_toc_func_call set. (check_pasted_section): Ensure pasted .init/.fini fragments use the same toc if any has makes_toc_func_call set. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c643fb7..35d534f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2011-02-01 Alan Modra + + * elf64-ppc.c (ppc64_elf_next_input_section): Use elf_gp value + for toc pointer on any section having makes_toc_func_call set. + (check_pasted_section): Ensure pasted .init/.fini fragments use + the same toc if any has makes_toc_func_call set. + 2011-01-28 Joseph Myers * elf32-ppc.c (ppc_elf_link_hash_newfunc): Initialize has_sda_refs diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 5c35dc1..d020928 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -10580,14 +10580,28 @@ ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec) if (elf_gp (isec->owner) != 0) htab->toc_curr = elf_gp (isec->owner); } - else if (!isec->call_check_done - && toc_adjusting_stub_needed (info, isec) < 0) - return FALSE; + else + { + if (!isec->call_check_done + && toc_adjusting_stub_needed (info, isec) < 0) + return FALSE; + /* If we make a local call from this section, ie. a branch + without a following nop, then we have no place to put a + toc restoring insn. We must use the same toc group as + the callee. + Testing makes_toc_func_call actually tests for *any* + calls to functions that need a good toc pointer. A more + precise test would be better, as this one will set + incorrect values for pasted .init/.fini fragments. + (Fixed later in check_pasted_section.) */ + if (isec->makes_toc_func_call + && elf_gp (isec->owner) != 0) + htab->toc_curr = elf_gp (isec->owner); + } } /* Functions that don't use the TOC can belong in any TOC group. - Use the last TOC base. This happens to make _init and _fini - pasting work, because the fragments generally don't use the TOC. */ + Use the last TOC base. */ htab->stub_group[isec->id].toc_off = htab->toc_curr; return TRUE; } @@ -10614,6 +10628,15 @@ check_pasted_section (struct bfd_link_info *info, const char *name) else if (toc_off != htab->stub_group[i->id].toc_off) return FALSE; } + + if (toc_off == 0) + for (i = o->map_head.s; i != NULL; i = i->map_head.s) + if (i->makes_toc_func_call) + { + toc_off = htab->stub_group[i->id].toc_off; + break; + } + /* Make sure the whole pasted function uses the same toc offset. */ if (toc_off != 0) for (i = o->map_head.s; i != NULL; i = i->map_head.s)