aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>2015-10-19 15:44:35 +0200
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2015-10-22 10:14:15 +0200
commit99ba51255402201c6e193d803ee1f1fc3f2de0e6 (patch)
treeedd16747de26e7b2966162e6c96f13e126999624 /bfd
parentd8ee9e44cc9a986b063a6ea6c91d39217cce65a1 (diff)
downloadgdb-99ba51255402201c6e193d803ee1f1fc3f2de0e6.zip
gdb-99ba51255402201c6e193d803ee1f1fc3f2de0e6.tar.gz
gdb-99ba51255402201c6e193d803ee1f1fc3f2de0e6.tar.bz2
S/390: ifunc: Redirect local function calls to the IPLT.
bfd/ChangeLog: * elf32-s390.c (elf_s390_check_relocs): Set the non_got_ref marker only when linking an executable. (elf_s390_relocate_section): Redirect PC-relative relocs to a IPLT slot. * elf64-s390.c (elf_s390_check_relocs): Set the non_got_ref marker only when linking an executable. (elf_s390_relocate_section): Redirect PC-relative relocs to a IPLT slot.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elf32-s390.c28
-rw-r--r--bfd/elf64-s390.c24
3 files changed, 54 insertions, 9 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b7f42cd..3956966 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,16 @@
2015-10-22 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+ * elf32-s390.c (elf_s390_check_relocs): Set the non_got_ref marker
+ only when linking an executable.
+ (elf_s390_relocate_section): Redirect PC-relative relocs to a IPLT
+ slot.
+ * elf64-s390.c (elf_s390_check_relocs): Set the non_got_ref marker
+ only when linking an executable.
+ (elf_s390_relocate_section): Redirect PC-relative relocs to a IPLT
+ slot.
+
+2015-10-22 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
* elf32-s390.c (elf_s390_adjust_dynamic_symbol): Set the PLT
reference counters for local IFUNC calls.
* elf64-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index d154fb7..3fad6b3 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -1272,7 +1272,7 @@ elf_s390_check_relocs (bfd *abfd,
case R_390_PC24DBL:
case R_390_PC32DBL:
case R_390_PC32:
- 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
@@ -2776,9 +2776,6 @@ elf_s390_relocate_section (bfd *output_bfd,
unresolved_reloc = FALSE;
break;
- case R_390_8:
- case R_390_16:
- case R_390_32:
case R_390_PC16:
case R_390_PC12DBL:
case R_390_PC16DBL:
@@ -2787,6 +2784,29 @@ elf_s390_relocate_section (bfd *output_bfd,
case R_390_PC32:
if (h != NULL
&& s390_is_ifunc_symbol_p (h)
+ && h->def_regular
+ && !bfd_link_executable (info))
+ {
+ /* This will not work our if the function does not
+ happen to set up the GOT pointer for some other
+ reason. 31 bit PLT entries require r12 to hold the
+ GOT pointer.
+ FIXME: Implement an errorcheck.
+ NOTE: It will work when brasl is not available
+ (e.g. with -m31 -march=g5) since a local function
+ call then does use GOTOFF which implies r12 being set
+ up. */
+ 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:
+ if (h != NULL
+ && s390_is_ifunc_symbol_p (h)
&& h->def_regular)
{
if (!bfd_link_pic (info) || !h->non_got_ref)
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
index 2b62271..bd9c082 100644
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -1205,7 +1205,7 @@ elf_s390_check_relocs (bfd *abfd,
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
@@ -2718,10 +2718,6 @@ elf_s390_relocate_section (bfd *output_bfd,
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:
@@ -2729,6 +2725,24 @@ elf_s390_relocate_section (bfd *output_bfd,
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)