diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2015-10-22 10:11:07 +0200 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2015-10-22 10:11:07 +0200 |
commit | 0f042c67a04d5d0c8f879c27d651a7ed5aa6566f (patch) | |
tree | 7220234d1443d887d6a1c7fcecab66e584cdcc80 /bfd | |
parent | 0a511368e2b896fe84f3b4bce5390e6269bcc57b (diff) | |
download | gdb-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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elf32-s390.c | 17 | ||||
-rw-r--r-- | bfd/elf64-s390.c | 17 |
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: |