S/390: ifunc: Fix function pointers to hidden ifunc symbols.

bfd/ChangeLog:
	* elf32-s390.c (elf_s390_adjust_dynamic_symbol): Set the PLT
	reference counters for local IFUNC calls.
	* elf64-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
This commit is contained in:
Andreas Krebbel
2015-10-16 21:49:43 +02:00
parent 01a5358479
commit d8ee9e44cc
3 changed files with 88 additions and 2 deletions

View File

@ -1,3 +1,9 @@
2015-10-22 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elf32-s390.c (elf_s390_adjust_dynamic_symbol): Set the PLT
reference counters for local IFUNC calls.
* elf64-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
2015-10-22 Andreas Krebbel <krebbel@linux.vnet.ibm.com> 2015-10-22 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elf32-s390.c (elf_s390_check_relocs): Fallthrough to the PLT * elf32-s390.c (elf_s390_check_relocs): Fallthrough to the PLT

View File

@ -1658,7 +1658,47 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
/* STT_GNU_IFUNC symbol must go through PLT. */ /* STT_GNU_IFUNC symbol must go through PLT. */
if (s390_is_ifunc_symbol_p (h)) if (s390_is_ifunc_symbol_p (h))
return TRUE; {
/* All local STT_GNU_IFUNC references must be treated as local
calls via local PLT. */
if (h->ref_regular && SYMBOL_CALLS_LOCAL (info, h))
{
bfd_size_type pc_count = 0, count = 0;
struct elf_dyn_relocs **pp;
struct elf_s390_link_hash_entry *eh;
struct elf_dyn_relocs *p;
eh = (struct elf_s390_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{
pc_count += p->pc_count;
p->count -= p->pc_count;
p->pc_count = 0;
count += p->count;
if (p->count == 0)
*pp = p->next;
else
pp = &p->next;
}
if (pc_count || count)
{
h->needs_plt = 1;
h->non_got_ref = 1;
if (h->plt.refcount <= 0)
h->plt.refcount = 1;
else
h->plt.refcount += 1;
}
}
if (h->plt.refcount <= 0)
{
h->plt.offset = (bfd_vma) -1;
h->needs_plt = 0;
}
return TRUE;
}
/* If this is a function, put it in the procedure linkage table. We /* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later will fill in the contents of the procedure linkage table later

View File

@ -1592,7 +1592,47 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
/* STT_GNU_IFUNC symbol must go through PLT. */ /* STT_GNU_IFUNC symbol must go through PLT. */
if (s390_is_ifunc_symbol_p (h)) if (s390_is_ifunc_symbol_p (h))
return TRUE; {
/* All local STT_GNU_IFUNC references must be treated as local
calls via local PLT. */
if (h->ref_regular && SYMBOL_CALLS_LOCAL (info, h))
{
bfd_size_type pc_count = 0, count = 0;
struct elf_dyn_relocs **pp;
struct elf_s390_link_hash_entry *eh;
struct elf_dyn_relocs *p;
eh = (struct elf_s390_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{
pc_count += p->pc_count;
p->count -= p->pc_count;
p->pc_count = 0;
count += p->count;
if (p->count == 0)
*pp = p->next;
else
pp = &p->next;
}
if (pc_count || count)
{
h->needs_plt = 1;
h->non_got_ref = 1;
if (h->plt.refcount <= 0)
h->plt.refcount = 1;
else
h->plt.refcount += 1;
}
}
if (h->plt.refcount <= 0)
{
h->plt.offset = (bfd_vma) -1;
h->needs_plt = 0;
}
return TRUE;
}
/* If this is a function, put it in the procedure linkage table. We /* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later will fill in the contents of the procedure linkage table later