[S/390] Add null ptr check + port GOTOFF handling from 32 bit over to 64 bit
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Thu, 19 Nov 2015 10:10:06 +0000 (11:10 +0100)
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Thu, 19 Nov 2015 10:10:06 +0000 (11:10 +0100)
bfd/ChangeLog:

2015-11-19  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

PR ld/19263
* elf32-s390.c (elf_s390_gc_sweep_hook): Add null ptr check.
* elf64-s390.c (elf_s390_check_relocs): Port the GOTOFF handling
over from the 32 bit code.
(elf_s390_relocate_section): Likewise.

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

index b580b89c708dcea80bd705ac013f3eddbbea061c..87d2d90a0ed7ded0f030f9bce11541470a39719f 100644 (file)
@@ -1,3 +1,11 @@
+2015-11-19  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
+
+       PR ld/19263
+       * elf32-s390.c (elf_s390_gc_sweep_hook): Add null ptr check.
+       * elf64-s390.c (elf_s390_check_relocs): Port the GOTOFF handling
+       over from the 32 bit code.
+       (elf_s390_relocate_section): Likewise.
+
 2015-11-18  Alan Modra  <amodra@gmail.com>
 
        PR 19256
index 3fad6b3ccde038be4b56d726e8ec12b6694d220f..8a830051209fb9f41d6ef3a3d2ce8ca3c6b92ad7 100644 (file)
@@ -1531,7 +1531,7 @@ elf_s390_gc_sweep_hook (bfd *abfd,
 
        case R_390_GOTOFF16:
        case R_390_GOTOFF32:
-         if (s390_is_ifunc_symbol_p (h) && h->def_regular)
+         if (h != NULL && s390_is_ifunc_symbol_p (h) && h->def_regular)
            {
              h->plt.refcount--;
              break;
index bd9c0829e83974fda678d734422664b5e98449dc..06f0d8817dbbf0f66bff2771bce7dd9fb0f2c4f6 100644 (file)
@@ -1040,9 +1040,6 @@ elf_s390_check_relocs (bfd *abfd,
 
       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
@@ -1050,6 +1047,11 @@ elf_s390_check_relocs (bfd *abfd,
             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:
@@ -1465,6 +1467,12 @@ elf_s390_gc_sweep_hook (bfd *abfd,
        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;
@@ -2641,6 +2649,18 @@ elf_s390_relocate_section (bfd *output_bfd,
          /* 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