mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
* 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.
This commit is contained in:
parent
d3f0f85341
commit
6683a28dfa
@ -1,3 +1,10 @@
|
||||
2011-02-01 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* 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 <joseph@codesourcery.com>
|
||||
|
||||
* elf32-ppc.c (ppc_elf_link_hash_newfunc): Initialize has_sda_refs
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user