aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>2015-10-22 10:11:07 +0200
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2015-10-22 10:11:07 +0200
commit0f042c67a04d5d0c8f879c27d651a7ed5aa6566f (patch)
tree7220234d1443d887d6a1c7fcecab66e584cdcc80
parent0a511368e2b896fe84f3b4bce5390e6269bcc57b (diff)
downloadgdb-0f042c67a04d5d0c8f879c27d651a7ed5aa6566f.zip
gdb-0f042c67a04d5d0c8f879c27d651a7ed5aa6566f.tar.gz
gdb-0f042c67a04d5d0c8f879c27d651a7ed5aa6566f.tar.bz2
S/390: ifunc: Fix PR18841.
In order to get the ifunc relocs properly sorted the correct class needs to be returned. The code mimics what has been done for x86. bfd/ChangeLog: PR ld/18841 * elf32-s390.c (elf_s390_reloc_type_class): Return reloc_class_ifunc for ifunc symbols. * elf64-s390.c (elf_s390_reloc_type_class): Likewise.
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf32-s390.c17
-rw-r--r--bfd/elf64-s390.c17
3 files changed, 41 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 44dd4d2..0ab1aed 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,12 @@
2015-10-22 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+ PR ld/18841
+ * elf32-s390.c (elf_s390_reloc_type_class): Return
+ reloc_class_ifunc for ifunc symbols.
+ * elf64-s390.c (elf_s390_reloc_type_class): Likewise.
+
+2015-10-22 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
* elf32-s390.c (elf_s390_finish_dynamic_symbol): Call
elf_s390_finish_ifunc_symbol only for actually defined symbols.
* elf64-s390.c (elf_s390_finish_dynamic_symbol): Likewise.
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index 85ac298..b1f9dbc 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -3805,6 +3805,23 @@ elf_s390_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
const asection *rel_sec ATTRIBUTE_UNUSED,
const Elf_Internal_Rela *rela)
{
+ bfd *abfd = info->output_bfd;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
+ unsigned long r_symndx = ELF32_R_SYM (rela->r_info);
+ Elf_Internal_Sym sym;
+
+ if (htab->elf.dynsym == NULL
+ || !bed->s->swap_symbol_in (abfd,
+ (htab->elf.dynsym->contents
+ + r_symndx * bed->s->sizeof_sym),
+ 0, &sym))
+ abort ();
+
+ /* Check relocation against STT_GNU_IFUNC symbol. */
+ if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
+ return reloc_class_ifunc;
+
switch ((int) ELF32_R_TYPE (rela->r_info))
{
case R_390_RELATIVE:
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
index 1add8d5..588892f 100644
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -3604,6 +3604,23 @@ elf_s390_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
const asection *rel_sec ATTRIBUTE_UNUSED,
const Elf_Internal_Rela *rela)
{
+ bfd *abfd = info->output_bfd;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
+ unsigned long r_symndx = ELF64_R_SYM (rela->r_info);
+ Elf_Internal_Sym sym;
+
+ if (htab->elf.dynsym == NULL
+ || !bed->s->swap_symbol_in (abfd,
+ (htab->elf.dynsym->contents
+ + r_symndx * bed->s->sizeof_sym),
+ 0, &sym))
+ abort ();
+
+ /* Check relocation against STT_GNU_IFUNC symbol. */
+ if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
+ return reloc_class_ifunc;
+
switch ((int) ELF64_R_TYPE (rela->r_info))
{
case R_390_RELATIVE: