mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-25 21:41:47 +08:00
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:
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user