This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ppc_elf_relax_section ifunc changes
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Tue, 4 Aug 2009 17:36:37 +0930
- Subject: ppc_elf_relax_section ifunc changes
Yesterday's patch to support relaxation of branches to ifuncs
left a little to be desired. The comment below says it all.
Committed.
* elf32-ppc.c (ppc_elf_relax_section): Correct conditions under
which find_plt_ent is called. Delete redundant code.
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.263
diff -c -r1.263 elf32-ppc.c
*** bfd/elf32-ppc.c 3 Aug 2009 12:10:46 -0000 1.263
--- bfd/elf32-ppc.c 4 Aug 2009 05:50:09 -0000
***************
*** 5934,5939 ****
--- 5934,5940 ----
bfd_byte *hit_addr;
unsigned long t0;
struct elf_link_hash_entry *h;
+ struct plt_entry **plist;
unsigned char sym_type;
switch (r_type)
***************
*** 5997,6008 ****
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
! tsec = NULL;
! toff = 0;
! if (tsec != NULL)
! ;
! else if (h->root.type == bfd_link_hash_defined
! || h->root.type == bfd_link_hash_defweak)
{
tsec = h->root.u.def.section;
toff = h->root.u.def.value;
--- 5998,6005 ----
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
! if (h->root.type == bfd_link_hash_defined
! || h->root.type == bfd_link_hash_defweak)
{
tsec = h->root.u.def.section;
toff = h->root.u.def.value;
***************
*** 6019,6060 ****
sym_type = h->type;
}
! if (is_branch_reloc (r_type))
{
! struct plt_entry **plist = NULL;
!
! if (h != NULL)
plist = &h->plt.plist;
! else if (sym_type == STT_GNU_IFUNC)
{
! bfd_vma *local_got_offsets = elf_local_got_offsets (abfd);
! struct plt_entry **local_plt = (struct plt_entry **)
! (local_got_offsets + symtab_hdr->sh_info);
! plist = local_plt + ELF32_R_SYM (irel->r_info);
! }
! if (plist != NULL)
! {
! bfd_vma addend = 0;
! struct plt_entry *ent;
!
! if (r_type == R_PPC_PLTREL24 && link_info->shared)
! addend = irel->r_addend;
! ent = find_plt_ent (plist, got2, addend);
! if (ent != NULL)
{
! if (htab->plt_type == PLT_NEW
! || h == NULL
! || !htab->elf.dynamic_sections_created
! || h->dynindx == -1)
! {
! tsec = htab->glink;
! toff = ent->glink_offset;
! }
! else
! {
! tsec = htab->plt;
! toff = ent->plt.offset;
! }
}
}
}
--- 6016,6063 ----
sym_type = h->type;
}
! /* The condition here under which we call find_plt_ent must
! match that in relocate_section. If we call find_plt_ent here
! but not in relocate_section, or vice versa, then the branch
! destination used here may be incorrect. */
! plist = NULL;
! if (h != NULL)
{
! /* We know is_branch_reloc (r_type) is true. */
! if (h->type == STT_GNU_IFUNC
! || r_type == R_PPC_PLTREL24)
plist = &h->plt.plist;
! }
! else if (sym_type == STT_GNU_IFUNC
! && elf_local_got_offsets (abfd) != NULL)
! {
! bfd_vma *local_got_offsets = elf_local_got_offsets (abfd);
! struct plt_entry **local_plt = (struct plt_entry **)
! (local_got_offsets + symtab_hdr->sh_info);
! plist = local_plt + ELF32_R_SYM (irel->r_info);
! }
! if (plist != NULL)
! {
! bfd_vma addend = 0;
! struct plt_entry *ent;
!
! if (r_type == R_PPC_PLTREL24 && link_info->shared)
! addend = irel->r_addend;
! ent = find_plt_ent (plist, got2, addend);
! if (ent != NULL)
{
! if (htab->plt_type == PLT_NEW
! || h == NULL
! || !htab->elf.dynamic_sections_created
! || h->dynindx == -1)
{
! tsec = htab->glink;
! toff = ent->glink_offset;
! }
! else
! {
! tsec = htab->plt;
! toff = ent->plt.offset;
}
}
}
--
Alan Modra
Australia Development Lab, IBM