S/390: ifunc: Redirect local function calls to the IPLT.
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Mon, 19 Oct 2015 13:44:35 +0000 (15:44 +0200)
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Thu, 22 Oct 2015 08:14:15 +0000 (10:14 +0200)
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.

bfd/ChangeLog
bfd/elf32-s390.c
bfd/elf64-s390.c

index b7f42cd6d3c22775a557d46f7f225acc287bafdc..3956966a664c3e8c3cb160f0f01aac210c274552 100644 (file)
@@ -1,3 +1,14 @@
+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
index d154fb78aff1ed49cd77e85adf138ef2461a7d21..3fad6b3ccde038be4b56d726e8ec12b6694d220f 100644 (file)
@@ -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,15 +2776,35 @@ 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:
        case R_390_PC24DBL:
        case R_390_PC32DBL:
        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)
index 2b6227148d276c92967eb5ee0138578808c1cf6b..bd9c0829e83974fda678d734422664b5e98449dc 100644 (file)
@@ -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)