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.
This commit is contained in:
Andreas Krebbel 2015-10-22 10:11:07 +02:00
parent 0a511368e2
commit 0f042c67a0
3 changed files with 41 additions and 0 deletions

View File

@ -1,3 +1,10 @@
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

View File

@ -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:

View File

@ -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: