aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-s390.c
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>2015-10-16 21:07:17 +0200
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2015-10-22 10:11:57 +0200
commit01a53584798606cf6329e8a86134cb9b47d1de11 (patch)
treeddde096897ea6935d2ec0d1ca7f63b93d030ca24 /bfd/elf32-s390.c
parent0f042c67a04d5d0c8f879c27d651a7ed5aa6566f (diff)
downloadgdb-01a53584798606cf6329e8a86134cb9b47d1de11.zip
gdb-01a53584798606cf6329e8a86134cb9b47d1de11.tar.gz
gdb-01a53584798606cf6329e8a86134cb9b47d1de11.tar.bz2
S/390: ifunc: Handle GOTOFF relocs on ifunc symbols.
Normally a GOTOFF reloc only uses the GOT pointer to address something relativ to it without actually requiring a GOT or PLT slot. Things change if the target is an ifunc symbol though. bfd/ChangeLog: * elf32-s390.c (elf_s390_check_relocs): Fallthrough to the PLT slot allocating code for GOTOFF relocs on ifunc symbols. (elf_s390_gc_sweep_hook): Decrement plt refcount for GOTOFF relocs on ifunc symbols. (elf_s390_relocate_section): Redirect a GOTOFF reloc to an iplt slot.
Diffstat (limited to 'bfd/elf32-s390.c')
-rw-r--r--bfd/elf32-s390.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index b1f9dbc..fcdade0 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -1112,8 +1112,6 @@ elf_s390_check_relocs (bfd *abfd,
}
switch (r_type)
{
- case R_390_GOTOFF16:
- case R_390_GOTOFF32:
case R_390_GOTPC:
case R_390_GOTPCDBL:
/* These relocs do not need a GOT slot. They just load the
@@ -1121,6 +1119,10 @@ elf_s390_check_relocs (bfd *abfd,
the GOT. Since the GOT pointer has been set up above we
are done. */
break;
+ case R_390_GOTOFF16:
+ case R_390_GOTOFF32:
+ if (h == NULL || !s390_is_ifunc_symbol_p (h) || !h->def_regular)
+ break;
case R_390_PLT12DBL:
case R_390_PLT16DBL:
@@ -1529,6 +1531,12 @@ elf_s390_gc_sweep_hook (bfd *abfd,
case R_390_GOTOFF16:
case R_390_GOTOFF32:
+ if (s390_is_ifunc_symbol_p (h) && h->def_regular)
+ {
+ h->plt.refcount--;
+ break;
+ }
+
case R_390_GOTPC:
case R_390_GOTPCDBL:
break;
@@ -2640,6 +2648,18 @@ elf_s390_relocate_section (bfd *output_bfd,
/* Relocation is relative to the start of the global offset
table. */
+ if (h != NULL
+ && s390_is_ifunc_symbol_p (h)
+ && h->def_regular
+ && !bfd_link_executable (info))
+ {
+ relocation = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + h->plt.offset
+ - htab->elf.sgot->output_section->vma);
+ goto do_relocation;
+ }
+
/* Note that sgot->output_offset is not involved in this
calculation. We always want the start of .got. If we
defined _GLOBAL_OFFSET_TABLE in a different way, as is