This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: powerpc64 toc pointer value
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Mon, 1 Jul 2013 12:46:42 +0930
- Subject: Re: powerpc64 toc pointer value
- References: <20121106051720 dot GK31965 at bubble dot grove dot modra dot org>
On Tue, Nov 06, 2012 at 03:47:20PM +1030, Alan Modra wrote:
> This patch provides another solution by making .TOC., a symbol
> mentioned in the ppc64 ABI, a real symbol.
This fixes two problems with ld handling of ".TOC.". Firstly, the
symbol was emitted as undefined, confusing some package builds.
Secondly, ld also emitted a "TOC." symbol (fake function descriptor
for this dot-symbol).
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.
Index: bfd/elf64-ppc.h
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.h,v
retrieving revision 1.33
diff -u -p -r1.33 elf64-ppc.h
--- bfd/elf64-ppc.h 22 Apr 2013 03:11:39 -0000 1.33
+++ bfd/elf64-ppc.h 30 Jun 2013 06:30:03 -0000
@@ -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));
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.411
diff -u -p -r1.411 elf64-ppc.c
--- bfd/elf64-ppc.c 6 May 2013 09:32:55 -0000 1.411
+++ bfd/elf64-ppc.c 30 Jun 2013 06:30:03 -0000
@@ -2472,7 +2472,7 @@ ppc64_elf_toc_reloc (bfd *abfd, arelent
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, arele
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, arelen
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, s
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, struc
/* 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 (stru
{
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_in
}
}
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_in
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_
}
}
}
- if (h_elf == &htab->dot_toc_dot->elf)
+ if (h_elf == htab->elf.hgot)
{
relocation = (TOCstart
+ htab->stub_group[input_section->id].toc_off);
Index: ld/emultempl/ppc64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc64elf.em,v
retrieving revision 1.85
diff -u -p -r1.85 ppc64elf.em
--- ld/emultempl/ppc64elf.em 22 Apr 2013 03:11:39 -0000 1.85
+++ ld/emultempl/ppc64elf.em 30 Jun 2013 06:30:03 -0000
@@ -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 (v
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);
}
}
--
Alan Modra
Australia Development Lab, IBM