/* IBM S/390-specific support for 64-bit ELF
- Copyright (C) 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 2000-2016 Free Software Foundation, Inc.
Contributed Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of BFD, the Binary File Descriptor library.
&& strcasecmp (elf_howto_table[i].name, r_name) == 0)
return &elf_howto_table[i];
- if (strcasecmp (elf64_s390_vtinherit_howto.name, r_name) == 0)
- return &elf64_s390_vtinherit_howto;
- if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0)
- return &elf64_s390_vtentry_howto;
+ if (strcasecmp (elf64_s390_vtinherit_howto.name, r_name) == 0)
+ return &elf64_s390_vtinherit_howto;
+ if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0)
+ return &elf64_s390_vtentry_howto;
return NULL;
}
switch (r_type)
{
- case R_390_GOTOFF16:
- case R_390_GOTOFF32:
- case R_390_GOTOFF64:
case R_390_GOTPC:
case R_390_GOTPCDBL:
/* These relocs do not need a GOT slot. They just load the
the GOT. Since the GOT pointer has been set up above we
are done. */
break;
+ case R_390_GOTOFF16:
+ case R_390_GOTOFF32:
+ case R_390_GOTOFF64:
+ if (h == NULL || !s390_is_ifunc_symbol_p (h) || !h->def_regular)
+ break;
case R_390_PLT12DBL:
case R_390_PLT16DBL:
case R_390_PC32:
case R_390_PC32DBL:
case R_390_PC64:
- if (h != NULL)
+ if (h != NULL && bfd_link_executable (info))
{
/* If this reloc is in a read-only section, we might
need a copy reloc. We can't check reliably at this
case R_390_GOTOFF16:
case R_390_GOTOFF32:
case R_390_GOTOFF64:
+ if (h != NULL && s390_is_ifunc_symbol_p (h) && h->def_regular)
+ {
+ h->plt.refcount--;
+ break;
+ }
+
case R_390_GOTPC:
case R_390_GOTPCDBL:
break;
/* 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
unresolved_reloc = FALSE;
break;
- case R_390_8:
- case R_390_16:
- case R_390_32:
- case R_390_64:
case R_390_PC16:
case R_390_PC12DBL:
case R_390_PC16DBL:
case R_390_PC32:
case R_390_PC32DBL:
case R_390_PC64:
+ /* The target of these relocs are instruction operands
+ residing in read-only sections. We cannot emit a runtime
+ reloc for it. */
+ if (h != NULL
+ && s390_is_ifunc_symbol_p (h)
+ && h->def_regular
+ && bfd_link_pic (info))
+ {
+ relocation = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + h->plt.offset);
+ goto do_relocation;
+ }
+
+ case R_390_8:
+ case R_390_16:
+ case R_390_32:
+ case R_390_64:
if (h != NULL
&& s390_is_ifunc_symbol_p (h)