From 1c865ab2fb392216c5e46cc9019b9c4c6929dfc5 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 1 Jul 2013 03:45:05 +0000 Subject: [PATCH] bfd/ * elf64-ppc.h (ppc64_elf_toc): Delete. (ppc64_elf_set_toc): Declare. * elf64-ppc.c (ppc64_elf_toc_reloc): Replace call to ppc64_elf_toc with call the ppc64_elf_set_toc. (ppc64_elf_toc_ha_reloc, ppc64_elf_toc64_reloc): Likewise. (ppc64_elf_start_multitoc_partition): Likewise. (struct ppc_link_hash_table): Delete dot_toc_dot. Replace all uses with elf.hgot. (ppc64_elf_process_dot_syms): Don't make a fake function descriptor for ".TOC.". (ppc64_elf_check_relocs): Mark sections with a reference to .TOC. as needing a toc pointer. (ppc64_elf_size_stubs): Don't set dot_toc_dot here. (ppc64_elf_set_toc): Rename from ppc64_elf_toc. Add info param. Set elf.hgot value. ld/ * emultempl/ppc64elf.em: (ppc_layout_sections_again): Call ppc64_elf_set_toc rather than ppc64_elf_toc/_bfd_set_gp_value. (gld${EMULATION_NAME}_after_allocation): Likewise. --- bfd/ChangeLog | 18 +++++++++++++++++ bfd/elf64-ppc.c | 43 +++++++++++++++++++++++++++------------- bfd/elf64-ppc.h | 4 ++-- ld/ChangeLog | 6 ++++++ ld/emultempl/ppc64elf.em | 6 ++---- 5 files changed, 57 insertions(+), 20 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a5928171d65..1bbbb87a2d5 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,21 @@ +2013-07-01 Alan Modra + + * elf64-ppc.h (ppc64_elf_toc): Delete. + (ppc64_elf_set_toc): Declare. + * elf64-ppc.c (ppc64_elf_toc_reloc): Replace call to ppc64_elf_toc + with call the ppc64_elf_set_toc. + (ppc64_elf_toc_ha_reloc, ppc64_elf_toc64_reloc): Likewise. + (ppc64_elf_start_multitoc_partition): Likewise. + (struct ppc_link_hash_table): Delete dot_toc_dot. Replace all uses + with elf.hgot. + (ppc64_elf_process_dot_syms): Don't make a fake function descriptor + for ".TOC.". + (ppc64_elf_check_relocs): Mark sections with a reference to .TOC. + as needing a toc pointer. + (ppc64_elf_size_stubs): Don't set dot_toc_dot here. + (ppc64_elf_set_toc): Rename from ppc64_elf_toc. Add info param. + Set elf.hgot value. + 2013-06-28 H.J. Lu PR ld/15685 diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index d4415e4576b..fb808d649fa 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -2472,7 +2472,7 @@ ppc64_elf_toc_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, TOCstart = _bfd_get_gp_value (input_section->output_section->owner); if (TOCstart == 0) - TOCstart = ppc64_elf_toc (input_section->output_section->owner); + TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner); /* Subtract the TOC base address. */ reloc_entry->addend -= TOCstart + TOC_BASE_OFF; @@ -2495,7 +2495,7 @@ ppc64_elf_toc_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, TOCstart = _bfd_get_gp_value (input_section->output_section->owner); if (TOCstart == 0) - TOCstart = ppc64_elf_toc (input_section->output_section->owner); + TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner); /* Subtract the TOC base address. */ reloc_entry->addend -= TOCstart + TOC_BASE_OFF; @@ -2522,7 +2522,7 @@ ppc64_elf_toc64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, TOCstart = _bfd_get_gp_value (input_section->output_section->owner); if (TOCstart == 0) - TOCstart = ppc64_elf_toc (input_section->output_section->owner); + TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner); octets = reloc_entry->address * bfd_octets_per_byte (abfd); bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets); @@ -3772,9 +3772,6 @@ struct ppc_link_hash_table struct ppc_link_hash_entry *tls_get_addr; struct ppc_link_hash_entry *tls_get_addr_fd; - /* The special .TOC. symbol. */ - struct ppc_link_hash_entry *dot_toc_dot; - /* The size of reliplt used by got entry relocs. */ bfd_size_type got_reli_size; @@ -4774,7 +4771,12 @@ ppc64_elf_process_dot_syms (bfd *ibfd, struct bfd_link_info *info) while ((eh = *p) != NULL) { *p = NULL; - if (!add_symbol_adjust (eh, info)) + if (&eh->elf == htab->elf.hgot) + ; + else if (htab->elf.hgot == NULL + && strcmp (eh->elf.root.root.string, ".TOC.") == 0) + htab->elf.hgot = &eh->elf; + else if (!add_symbol_adjust (eh, info)) return FALSE; p = &eh->u.next_dot_sym; } @@ -5007,6 +5009,9 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, /* PR15323, ref flags aren't set for references in the same object. */ h->root.non_ir_ref = 1; + + if (h == htab->elf.hgot) + sec->has_toc_reloc = 1; } tls_type = 0; @@ -10617,8 +10622,7 @@ ppc64_elf_start_multitoc_partition (struct bfd_link_info *info) { struct ppc_link_hash_table *htab = ppc_hash_table (info); - elf_gp (info->output_bfd) = ppc64_elf_toc (info->output_bfd); - htab->toc_curr = elf_gp (info->output_bfd); + htab->toc_curr = ppc64_elf_set_toc (info, info->output_bfd); htab->toc_bfd = NULL; htab->toc_first_sec = NULL; } @@ -11450,9 +11454,6 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size, } } htab->plt_thread_safe = plt_thread_safe; - htab->dot_toc_dot = ((struct ppc_link_hash_entry *) - elf_link_hash_lookup (&htab->elf, ".TOC.", - FALSE, FALSE, TRUE)); stubs_always_before_branch = group_size < 0; if (group_size < 0) stub_group_size = -group_size; @@ -11853,7 +11854,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size, move, we'll be called again. Provide a value for TOCstart. */ bfd_vma -ppc64_elf_toc (bfd *obfd) +ppc64_elf_set_toc (struct bfd_link_info *info, bfd *obfd) { asection *s; bfd_vma TOCstart; @@ -11904,6 +11905,20 @@ ppc64_elf_toc (bfd *obfd) if (s != NULL) TOCstart = s->output_section->vma + s->output_offset; + _bfd_set_gp_value (obfd, TOCstart); + + if (info != NULL && s != NULL && is_ppc64_elf (obfd)) + { + struct ppc_link_hash_table *htab = ppc_hash_table (info); + + if (htab != NULL + && htab->elf.hgot != NULL) + { + htab->elf.hgot->root.type = bfd_link_hash_defined; + htab->elf.hgot->root.u.def.value = TOC_BASE_OFF; + htab->elf.hgot->root.u.def.section = s; + } + } return TOCstart; } @@ -12452,7 +12467,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, } } } - if (h_elf == &htab->dot_toc_dot->elf) + if (h_elf == htab->elf.hgot) { relocation = (TOCstart + htab->stub_group[input_section->id].toc_off); diff --git a/bfd/elf64-ppc.h b/bfd/elf64-ppc.h index 89495bcfc0f..06c655f746a 100644 --- a/bfd/elf64-ppc.h +++ b/bfd/elf64-ppc.h @@ -31,8 +31,8 @@ bfd_boolean ppc64_elf_edit_toc (struct bfd_link_info *); bfd_boolean ppc64_elf_has_small_toc_reloc (asection *); -bfd_vma ppc64_elf_toc - (bfd *); +bfd_vma ppc64_elf_set_toc + (struct bfd_link_info *, bfd *); int ppc64_elf_setup_section_lists (struct bfd_link_info *, asection *(*) (const char *, asection *), void (*) (void)); diff --git a/ld/ChangeLog b/ld/ChangeLog index a42de634d0b..28bf16effbb 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2013-07-01 Alan Modra + + * emultempl/ppc64elf.em: (ppc_layout_sections_again): Call + ppc64_elf_set_toc rather than ppc64_elf_toc/_bfd_set_gp_value. + (gld${EMULATION_NAME}_after_allocation): Likewise. + 2013-06-26 Yufeng Zhang * emulparams/aarch64elf32.sh: New file. diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em index 43f9b6106fd..f2085d7dcf7 100644 --- a/ld/emultempl/ppc64elf.em +++ b/ld/emultempl/ppc64elf.em @@ -423,8 +423,7 @@ ppc_layout_sections_again (void) gld${EMULATION_NAME}_map_segments (TRUE); if (!link_info.relocatable) - _bfd_set_gp_value (link_info.output_bfd, - ppc64_elf_toc (link_info.output_bfd)); + ppc64_elf_set_toc (&link_info, link_info.output_bfd); need_laying_out = -1; } @@ -525,8 +524,7 @@ gld${EMULATION_NAME}_after_allocation (void) gld${EMULATION_NAME}_map_segments (need_laying_out); if (!link_info.relocatable) - _bfd_set_gp_value (link_info.output_bfd, - ppc64_elf_toc (link_info.output_bfd)); + ppc64_elf_set_toc (&link_info, link_info.output_bfd); } } -- 2.30.2