diff options
author | Alan Modra <amodra@gmail.com> | 2013-10-30 17:30:43 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2013-11-02 11:57:55 +1030 |
commit | 8b974ba3e8216b7f6659d2803444e0ddceaeded7 (patch) | |
tree | 3ce731dc47ca0ec349a2bb20994348cf3774fddd /bfd/elf64-ppc.c | |
parent | eab88b547c358493cd81c5336fa9f296cc5a0483 (diff) | |
download | gdb-8b974ba3e8216b7f6659d2803444e0ddceaeded7.zip gdb-8b974ba3e8216b7f6659d2803444e0ddceaeded7.tar.gz gdb-8b974ba3e8216b7f6659d2803444e0ddceaeded7.tar.bz2 |
Simplify ppc64 code setting toc_off.
Every function has a nominal toc pointer value, even if it isn't used,
so set toc_off for every code section to the value used in that object
file. The thinking here was that if a code section didn't use the toc
it could use the previous object file's toc pointer value. It can,
but doing so is only a gain if functions in that section are called
mostly from previous objects sharing the same toc. We lose if the
functions in question are called mostly from the current object or
following objects, and it's a good bet they will probably mostly be
called from the current object.
* elf64-ppc.c (ppc64_elf_next_input_section): Always set toc_off
to value for object file.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r-- | bfd/elf64-ppc.c | 53 |
1 files changed, 18 insertions, 35 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 6a8ec51..7f690ef 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -11508,42 +11508,25 @@ ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec) if (htab->multi_toc_needed) { - /* If a code section has a function that uses the TOC then we need - to use the right TOC (obviously). Also, make sure that .opd gets - the correct TOC value for R_PPC64_TOC relocs that don't have or - can't find their function symbol (shouldn't ever happen now). - Also specially treat .fixup for the linux kernel. .fixup - contains branches, but only back to the function that hit an - exception. */ - if (isec->has_toc_reloc - || (isec->flags & SEC_CODE) == 0 - || strcmp (isec->name, ".fixup") == 0) - { - 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) + /* Analyse sections that aren't already flagged as needing a + valid toc pointer. Exclude .fixup for the linux kernel. + .fixup contains branches, but only back to the function that + hit an exception. */ + if (!(isec->has_toc_reloc + || (isec->flags & SEC_CODE) == 0 + || strcmp (isec->name, ".fixup") == 0 + || isec->call_check_done)) + { + if (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. */ + } + /* Make all sections use the TOC assigned for this object file. + This will be wrong for pasted sections; We fix that in + check_pasted_section(). */ + if (elf_gp (isec->owner) != 0) + htab->toc_curr = elf_gp (isec->owner); + } + htab->stub_group[isec->id].toc_off = htab->toc_curr; return TRUE; } |