From 43417696fe32416607940258ded622c121872515 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 18 Aug 2015 16:43:18 +0930 Subject: [PATCH] PPC64: Allow .TOC. in linker script to override backend calculated value bfd/ * elf64-ppc.c (ppc64_elf_func_desc_adjust): Don't redefine .TOC. if already defined, and set linker_def. (ppc64_elf_set_toc): Use .TOC. value if defined other than by the backend. ld/ * ldexp.c (exp_fold_tree_1): Clear linker_def on symbol assignment. --- bfd/ChangeLog | 7 +++++++ bfd/elf64-ppc.c | 41 +++++++++++++++++++++++++++++++++++++---- ld/ChangeLog | 4 ++++ ld/ldexp.c | 1 + 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 09f7650..fb48800 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2015-08-18 Alan Modra + + * elf64-ppc.c (ppc64_elf_func_desc_adjust): Don't redefine .TOC. + if already defined, and set linker_def. + (ppc64_elf_set_toc): Use .TOC. value if defined other than by + the backend. + 2015-08-14 Alan Modra PR ld/18759 diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index e153ee4..4db5344 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -6945,11 +6945,16 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED, _bfd_elf_link_hash_hide_symbol (info, htab->elf.hgot, TRUE); /* Make .TOC. defined so as to prevent it being made dynamic. The wrong value here is fixed later in ppc64_elf_set_toc. */ + if (!htab->elf.hgot->def_regular + || htab->elf.hgot->root.type != bfd_link_hash_defined) + { + htab->elf.hgot->root.type = bfd_link_hash_defined; + htab->elf.hgot->root.u.def.value = 0; + htab->elf.hgot->root.u.def.section = bfd_abs_section_ptr; + htab->elf.hgot->def_regular = 1; + htab->elf.hgot->root.linker_def = 1; + } htab->elf.hgot->type = STT_OBJECT; - htab->elf.hgot->root.type = bfd_link_hash_defined; - htab->elf.hgot->root.u.def.value = 0; - htab->elf.hgot->root.u.def.section = bfd_abs_section_ptr; - htab->elf.hgot->def_regular = 1; htab->elf.hgot->other = ((htab->elf.hgot->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN); } @@ -12539,6 +12544,34 @@ ppc64_elf_set_toc (struct bfd_link_info *info, bfd *obfd) asection *s; bfd_vma TOCstart, adjust; + if (info != NULL) + { + struct elf_link_hash_entry *h; + struct elf_link_hash_table *htab = elf_hash_table (info); + + if (is_elf_hash_table (htab) + && htab->hgot != NULL) + h = htab->hgot; + else + { + h = elf_link_hash_lookup (htab, ".TOC.", FALSE, FALSE, TRUE); + if (is_elf_hash_table (htab)) + htab->hgot = h; + } + if (h != NULL + && h->root.type == bfd_link_hash_defined + && !h->root.linker_def + && (!is_elf_hash_table (htab) + || h->def_regular)) + { + TOCstart = (h->root.u.def.value - TOC_BASE_OFF + + h->root.u.def.section->output_offset + + h->root.u.def.section->output_section->vma); + _bfd_set_gp_value (obfd, TOCstart); + return TOCstart; + } + } + /* The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The TOC starts where the first of these sections starts. */ s = bfd_get_section_by_name (obfd, ".got"); diff --git a/ld/ChangeLog b/ld/ChangeLog index 5f1094a..62ad6f3 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,7 @@ +2015-08-18 Alan Modra + + * ldexp.c (exp_fold_tree_1): Clear linker_def on symbol assignment. + 2015-08-06 Alan Modra * ldexp.c (align_dot_val): Delete. diff --git a/ld/ldexp.c b/ld/ldexp.c index 1d4da9a..1140881 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -1144,6 +1144,7 @@ exp_fold_tree_1 (etree_type *tree) h->type = bfd_link_hash_defined; h->u.def.value = expld.result.value; h->u.def.section = expld.result.section; + h->linker_def = 0; if (tree->type.node_class == etree_provide) tree->type.node_class = etree_provided; -- 2.7.4