Merge branch 'master' into merge-job
[deliverable/binutils-gdb.git] / bfd / elf32-s390.c
index fcdade0461ecd14233c1bb4a48e0fe4150b75926..7990996bad884584a24a570818a6f98cc09bb503 100644 (file)
@@ -1,5 +1,5 @@
 /* IBM S/390-specific support for 32-bit ELF
 /* IBM S/390-specific support for 32-bit ELF
-   Copyright (C) 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 2000-2020 Free Software Foundation, Inc.
    Contributed by Carl B. Pedersen and Martin Schwidefsky.
 
    This file is part of BFD, the Binary File Descriptor library.
    Contributed by Carl B. Pedersen and Martin Schwidefsky.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -25,6 +25,7 @@
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/s390.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/s390.h"
+#include <stdarg.h>
 
 static bfd_reloc_status_type
 s390_tls_reloc (bfd *, arelent *, asymbol *, void *,
 
 static bfd_reloc_status_type
 s390_tls_reloc (bfd *, arelent *, asymbol *, void *,
@@ -51,69 +52,69 @@ static reloc_howto_type elf_howto_table[] =
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
 
-  HOWTO(R_390_8,         0, 0,  8, FALSE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_8",        FALSE, 0,0x000000ff, FALSE),
-  HOWTO(R_390_12,        0, 1, 12, FALSE, 0, complain_overflow_dont,
-       bfd_elf_generic_reloc, "R_390_12",       FALSE, 0,0x00000fff, FALSE),
-  HOWTO(R_390_16,        0, 1, 16, FALSE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_16",       FALSE, 0,0x0000ffff, FALSE),
-  HOWTO(R_390_32,        0, 2, 32, FALSE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_32",       FALSE, 0,0xffffffff, FALSE),
+  HOWTO(R_390_8,        0, 0,  8, FALSE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_8",        FALSE, 0,0x000000ff, FALSE),
+  HOWTO(R_390_12,       0, 1, 12, FALSE, 0, complain_overflow_dont,
+       bfd_elf_generic_reloc, "R_390_12",       FALSE, 0,0x00000fff, FALSE),
+  HOWTO(R_390_16,       0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_16",       FALSE, 0,0x0000ffff, FALSE),
+  HOWTO(R_390_32,       0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_32",       FALSE, 0,0xffffffff, FALSE),
   HOWTO(R_390_PC32,     0, 2, 32,  TRUE, 0, complain_overflow_bitfield,
   HOWTO(R_390_PC32,     0, 2, 32,  TRUE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_PC32",     FALSE, 0,0xffffffff, TRUE),
+       bfd_elf_generic_reloc, "R_390_PC32",     FALSE, 0,0xffffffff, TRUE),
   HOWTO(R_390_GOT12,    0, 1, 12, FALSE, 0, complain_overflow_bitfield,
   HOWTO(R_390_GOT12,    0, 1, 12, FALSE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_GOT12",    FALSE, 0,0x00000fff, FALSE),
+       bfd_elf_generic_reloc, "R_390_GOT12",    FALSE, 0,0x00000fff, FALSE),
   HOWTO(R_390_GOT32,    0, 2, 32, FALSE, 0, complain_overflow_bitfield,
   HOWTO(R_390_GOT32,    0, 2, 32, FALSE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_GOT32",    FALSE, 0,0xffffffff, FALSE),
+       bfd_elf_generic_reloc, "R_390_GOT32",    FALSE, 0,0xffffffff, FALSE),
   HOWTO(R_390_PLT32,    0, 2, 32,  TRUE, 0, complain_overflow_bitfield,
   HOWTO(R_390_PLT32,    0, 2, 32,  TRUE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_PLT32",    FALSE, 0,0xffffffff, TRUE),
-  HOWTO(R_390_COPY,      0, 2, 32, FALSE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_COPY",     FALSE, 0,0xffffffff, FALSE),
-  HOWTO(R_390_GLOB_DAT,  0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_PLT32",    FALSE, 0,0xffffffff, TRUE),
+  HOWTO(R_390_COPY,     0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_COPY",     FALSE, 0,0xffffffff, FALSE),
+  HOWTO(R_390_GLOB_DAT,         0, 2, 32, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_GLOB_DAT", FALSE, 0,0xffffffff, FALSE),
        bfd_elf_generic_reloc, "R_390_GLOB_DAT", FALSE, 0,0xffffffff, FALSE),
-  HOWTO(R_390_JMP_SLOT,  0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+  HOWTO(R_390_JMP_SLOT,         0, 2, 32, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_JMP_SLOT", FALSE, 0,0xffffffff, FALSE),
        bfd_elf_generic_reloc, "R_390_JMP_SLOT", FALSE, 0,0xffffffff, FALSE),
-  HOWTO(R_390_RELATIVE,  0, 2, 32,  TRUE, 0, complain_overflow_bitfield,
+  HOWTO(R_390_RELATIVE,         0, 2, 32,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_RELATIVE", FALSE, 0,0xffffffff, FALSE),
        bfd_elf_generic_reloc, "R_390_RELATIVE", FALSE, 0,0xffffffff, FALSE),
-  HOWTO(R_390_GOTOFF32,  0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+  HOWTO(R_390_GOTOFF32,         0, 2, 32, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_GOTOFF32", FALSE, 0,0xffffffff, FALSE),
        bfd_elf_generic_reloc, "R_390_GOTOFF32", FALSE, 0,0xffffffff, FALSE),
-  HOWTO(R_390_GOTPC,     0, 2, 32,  TRUE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_GOTPC",    FALSE, 0,0xffffffff, TRUE),
-  HOWTO(R_390_GOT16,     0, 1, 16, FALSE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_GOT16",    FALSE, 0,0x0000ffff, FALSE),
-  HOWTO(R_390_PC16,      0, 1, 16,  TRUE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_PC16",     FALSE, 0,0x0000ffff, TRUE),
-  HOWTO(R_390_PC16DBL,   1, 1, 16,  TRUE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_PC16DBL",  FALSE, 0,0x0000ffff, TRUE),
-  HOWTO(R_390_PLT16DBL,  1, 1, 16,  TRUE, 0, complain_overflow_bitfield,
+  HOWTO(R_390_GOTPC,    0, 2, 32,  TRUE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_GOTPC",    FALSE, 0,0xffffffff, TRUE),
+  HOWTO(R_390_GOT16,    0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_GOT16",    FALSE, 0,0x0000ffff, FALSE),
+  HOWTO(R_390_PC16,     0, 1, 16,  TRUE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_PC16",     FALSE, 0,0x0000ffff, TRUE),
+  HOWTO(R_390_PC16DBL,  1, 1, 16,  TRUE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_PC16DBL",  FALSE, 0,0x0000ffff, TRUE),
+  HOWTO(R_390_PLT16DBL,         1, 1, 16,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_PLT16DBL", FALSE, 0,0x0000ffff, TRUE),
   HOWTO(R_390_PC32DBL,  1, 2, 32,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_PLT16DBL", FALSE, 0,0x0000ffff, TRUE),
   HOWTO(R_390_PC32DBL,  1, 2, 32,  TRUE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_PC32DBL",  FALSE, 0,0xffffffff, TRUE),
+       bfd_elf_generic_reloc, "R_390_PC32DBL",  FALSE, 0,0xffffffff, TRUE),
   HOWTO(R_390_PLT32DBL,         1, 2, 32,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_PLT32DBL", FALSE, 0,0xffffffff, TRUE),
   HOWTO(R_390_PLT32DBL,         1, 2, 32,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_PLT32DBL", FALSE, 0,0xffffffff, TRUE),
-  HOWTO(R_390_GOTPCDBL,  1, 2, 32,  TRUE, 0, complain_overflow_bitfield,
+  HOWTO(R_390_GOTPCDBL,         1, 2, 32,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_GOTPCDBL", FALSE, 0,0xffffffff, TRUE),
   EMPTY_HOWTO (R_390_64),      /* Empty entry for R_390_64.  */
   EMPTY_HOWTO (R_390_PC64),    /* Empty entry for R_390_PC64.  */
   EMPTY_HOWTO (R_390_GOT64),   /* Empty entry for R_390_GOT64.  */
   EMPTY_HOWTO (R_390_PLT64),   /* Empty entry for R_390_PLT64.  */
   HOWTO(R_390_GOTENT,   1, 2, 32,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_GOTPCDBL", FALSE, 0,0xffffffff, TRUE),
   EMPTY_HOWTO (R_390_64),      /* Empty entry for R_390_64.  */
   EMPTY_HOWTO (R_390_PC64),    /* Empty entry for R_390_PC64.  */
   EMPTY_HOWTO (R_390_GOT64),   /* Empty entry for R_390_GOT64.  */
   EMPTY_HOWTO (R_390_PLT64),   /* Empty entry for R_390_PLT64.  */
   HOWTO(R_390_GOTENT,   1, 2, 32,  TRUE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_GOTENT",   FALSE, 0,0xffffffff, TRUE),
-  HOWTO(R_390_GOTOFF16,  0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_GOTENT",   FALSE, 0,0xffffffff, TRUE),
+  HOWTO(R_390_GOTOFF16,         0, 1, 16, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_GOTOFF16", FALSE, 0,0x0000ffff, FALSE),
   EMPTY_HOWTO (R_390_GOTOFF64),        /* Empty entry for R_390_GOTOFF64.  */
        bfd_elf_generic_reloc, "R_390_GOTOFF16", FALSE, 0,0x0000ffff, FALSE),
   EMPTY_HOWTO (R_390_GOTOFF64),        /* Empty entry for R_390_GOTOFF64.  */
-  HOWTO(R_390_GOTPLT12,  0, 1, 12, FALSE, 0, complain_overflow_dont,
+  HOWTO(R_390_GOTPLT12,         0, 1, 12, FALSE, 0, complain_overflow_dont,
        bfd_elf_generic_reloc, "R_390_GOTPLT12", FALSE, 0,0x00000fff, FALSE),
        bfd_elf_generic_reloc, "R_390_GOTPLT12", FALSE, 0,0x00000fff, FALSE),
-  HOWTO(R_390_GOTPLT16,  0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+  HOWTO(R_390_GOTPLT16,         0, 1, 16, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_GOTPLT16", FALSE, 0,0x0000ffff, FALSE),
        bfd_elf_generic_reloc, "R_390_GOTPLT16", FALSE, 0,0x0000ffff, FALSE),
-  HOWTO(R_390_GOTPLT32,  0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+  HOWTO(R_390_GOTPLT32,         0, 2, 32, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_GOTPLT32", FALSE, 0,0xffffffff, FALSE),
   EMPTY_HOWTO (R_390_GOTPLT64),        /* Empty entry for R_390_GOTPLT64.  */
   HOWTO(R_390_GOTPLTENT, 1, 2, 32,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_GOTPLTENT",FALSE, 0,0xffffffff, TRUE),
        bfd_elf_generic_reloc, "R_390_GOTPLT32", FALSE, 0,0xffffffff, FALSE),
   EMPTY_HOWTO (R_390_GOTPLT64),        /* Empty entry for R_390_GOTPLT64.  */
   HOWTO(R_390_GOTPLTENT, 1, 2, 32,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_GOTPLTENT",FALSE, 0,0xffffffff, TRUE),
-  HOWTO(R_390_PLTOFF16,  0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+  HOWTO(R_390_PLTOFF16,         0, 1, 16, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_PLTOFF16", FALSE, 0,0x0000ffff, FALSE),
        bfd_elf_generic_reloc, "R_390_PLTOFF16", FALSE, 0,0x0000ffff, FALSE),
-  HOWTO(R_390_PLTOFF32,  0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+  HOWTO(R_390_PLTOFF32,         0, 2, 32, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_PLTOFF32", FALSE, 0,0xffffffff, FALSE),
   EMPTY_HOWTO (R_390_PLTOFF64),        /* Empty entry for R_390_PLTOFF64.  */
   HOWTO(R_390_TLS_LOAD, 0, 0, 0, FALSE, 0, complain_overflow_dont,
        bfd_elf_generic_reloc, "R_390_PLTOFF32", FALSE, 0,0xffffffff, FALSE),
   EMPTY_HOWTO (R_390_PLTOFF64),        /* Empty entry for R_390_PLTOFF64.  */
   HOWTO(R_390_TLS_LOAD, 0, 0, 0, FALSE, 0, complain_overflow_dont,
@@ -150,22 +151,22 @@ static reloc_howto_type elf_howto_table[] =
        bfd_elf_generic_reloc, "R_390_TLS_DTPOFF", FALSE, 0, 0xffffffff, FALSE),
   HOWTO(R_390_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_TLS_TPOFF", FALSE, 0, 0xffffffff, FALSE),
        bfd_elf_generic_reloc, "R_390_TLS_DTPOFF", FALSE, 0, 0xffffffff, FALSE),
   HOWTO(R_390_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_TLS_TPOFF", FALSE, 0, 0xffffffff, FALSE),
-  HOWTO(R_390_20,        0, 2, 20, FALSE, 8, complain_overflow_dont,
+  HOWTO(R_390_20,       0, 2, 20, FALSE, 8, complain_overflow_dont,
        s390_elf_ldisp_reloc, "R_390_20",      FALSE, 0,0x0fffff00, FALSE),
   HOWTO(R_390_GOT20,    0, 2, 20, FALSE, 8, complain_overflow_dont,
        s390_elf_ldisp_reloc, "R_390_GOT20",   FALSE, 0,0x0fffff00, FALSE),
        s390_elf_ldisp_reloc, "R_390_20",      FALSE, 0,0x0fffff00, FALSE),
   HOWTO(R_390_GOT20,    0, 2, 20, FALSE, 8, complain_overflow_dont,
        s390_elf_ldisp_reloc, "R_390_GOT20",   FALSE, 0,0x0fffff00, FALSE),
-  HOWTO(R_390_GOTPLT20,  0, 2, 20, FALSE, 8, complain_overflow_dont,
+  HOWTO(R_390_GOTPLT20,         0, 2, 20, FALSE, 8, complain_overflow_dont,
        s390_elf_ldisp_reloc, "R_390_GOTPLT20", FALSE, 0,0x0fffff00, FALSE),
   HOWTO(R_390_TLS_GOTIE20, 0, 2, 20, FALSE, 8, complain_overflow_dont,
        s390_elf_ldisp_reloc, "R_390_TLS_GOTIE20", FALSE, 0,0x0fffff00, FALSE),
   HOWTO(R_390_IRELATIVE, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_IRELATIVE", FALSE, 0, 0xffffffff, FALSE),
        s390_elf_ldisp_reloc, "R_390_GOTPLT20", FALSE, 0,0x0fffff00, FALSE),
   HOWTO(R_390_TLS_GOTIE20, 0, 2, 20, FALSE, 8, complain_overflow_dont,
        s390_elf_ldisp_reloc, "R_390_TLS_GOTIE20", FALSE, 0,0x0fffff00, FALSE),
   HOWTO(R_390_IRELATIVE, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_IRELATIVE", FALSE, 0, 0xffffffff, FALSE),
-  HOWTO(R_390_PC12DBL,   1, 1, 12,  TRUE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_PC12DBL",  FALSE, 0,0x00000fff, TRUE),
+  HOWTO(R_390_PC12DBL,  1, 1, 12,  TRUE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_PC12DBL",  FALSE, 0,0x00000fff, TRUE),
   HOWTO(R_390_PLT12DBL,         1, 1, 12,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_PLT12DBL", FALSE, 0,0x00000fff, TRUE),
   HOWTO(R_390_PLT12DBL,         1, 1, 12,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_PLT12DBL", FALSE, 0,0x00000fff, TRUE),
-  HOWTO(R_390_PC24DBL,   1, 2, 24,  TRUE, 0, complain_overflow_bitfield,
-       bfd_elf_generic_reloc, "R_390_PC24DBL",  FALSE, 0,0x00ffffff, TRUE),
+  HOWTO(R_390_PC24DBL,  1, 2, 24,  TRUE, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_390_PC24DBL",  FALSE, 0,0x00ffffff, TRUE),
   HOWTO(R_390_PLT24DBL,         1, 2, 24,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_PLT24DBL", FALSE, 0,0x00ffffff, TRUE),
 };
   HOWTO(R_390_PLT24DBL,         1, 2, 24,  TRUE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_390_PLT24DBL", FALSE, 0,0x00ffffff, TRUE),
 };
@@ -322,12 +323,13 @@ elf_s390_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 /* We need to use ELF32_R_TYPE so we have our own copy of this function,
    and elf32-s390.c has its own copy.  */
 
 /* We need to use ELF32_R_TYPE so we have our own copy of this function,
    and elf32-s390.c has its own copy.  */
 
-static void
-elf_s390_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+static bfd_boolean
+elf_s390_info_to_howto (bfd *abfd,
                        arelent *cache_ptr,
                        Elf_Internal_Rela *dst)
 {
   unsigned int r_type = ELF32_R_TYPE(dst->r_info);
                        arelent *cache_ptr,
                        Elf_Internal_Rela *dst)
 {
   unsigned int r_type = ELF32_R_TYPE(dst->r_info);
+
   switch (r_type)
     {
     case R_390_GNU_VTINHERIT:
   switch (r_type)
     {
     case R_390_GNU_VTINHERIT:
@@ -341,12 +343,16 @@ elf_s390_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
     default:
       if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0]))
        {
     default:
       if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0]))
        {
-         (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
-                                abfd, (int) r_type);
-         r_type = R_390_NONE;
+         /* xgettext:c-format */
+         _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                             abfd, r_type);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
        }
       cache_ptr->howto = &elf_howto_table[r_type];
     }
        }
       cache_ptr->howto = &elf_howto_table[r_type];
     }
+
+  return TRUE;
 }
 
 /* A relocation function which doesn't do anything.  */
 }
 
 /* A relocation function which doesn't do anything.  */
@@ -476,100 +482,100 @@ elf_s390_is_local_label_name (bfd *abfd, const char *name)
    and insert the address in the GOT.
 
   Note: 390 can only address +- 64 K relative.
    and insert the address in the GOT.
 
   Note: 390 can only address +- 64 K relative.
-        We check if offset > 65536, then make a relative branch -64xxx
-        back to a previous defined branch
-
-PLT1: BASR 1,0         # 2 bytes
-      L    1,22(1)     # 4 bytes  Load offset in GOT in r 1
-      L    1,(1,12)    # 4 bytes  Load address from GOT in r1
-      BCR  15,1        # 2 bytes  Jump to address
-RET1: BASR 1,0         # 2 bytes  Return from GOT 1st time
-      L    1,14(1)     # 4 bytes  Load offset in symol table in r1
+       We check if offset > 65536, then make a relative branch -64xxx
+       back to a previous defined branch
+
+PLT1: BASR 1,0        # 2 bytes
+      L           1,22(1)     # 4 bytes  Load offset in GOT in r 1
+      L           1,(1,12)    # 4 bytes  Load address from GOT in r1
+      BCR  15,1               # 2 bytes  Jump to address
+RET1: BASR 1,0        # 2 bytes  Return from GOT 1st time
+      L           1,14(1)     # 4 bytes  Load offset in symol table in r1
       BRC  15,-x       # 4 bytes  Jump to start of PLT
       BRC  15,-x       # 4 bytes  Jump to start of PLT
-      .word 0          # 2 bytes filler
-      .long ?          # 4 bytes  offset in GOT
-      .long ?          # 4 bytes  offset into rela.plt
+      .word 0         # 2 bytes filler
+      .long ?         # 4 bytes  offset in GOT
+      .long ?         # 4 bytes  offset into rela.plt
 
   This was the general case. There are two additional, optimizes PLT
   definitions. One for GOT offsets < 4096 and one for GOT offsets < 32768.
   First the one for GOT offsets < 4096:
 
 
   This was the general case. There are two additional, optimizes PLT
   definitions. One for GOT offsets < 4096 and one for GOT offsets < 32768.
   First the one for GOT offsets < 4096:
 
-PLT1: L    1,<offset>(12) # 4 bytes  Load address from GOT in R1
-      BCR  15,1           # 2 bytes  Jump to address
-      .word 0,0,0         # 6 bytes  filler
-RET1: BASR 1,0            # 2 bytes  Return from GOT 1st time
-      L    1,14(1)        # 4 bytes  Load offset in rela.plt in r1
-      BRC  15,-x          # 4 bytes  Jump to start of PLT
-      .word 0,0,0         # 6 bytes  filler
-      .long ?             # 4 bytes  offset into rela.plt
+PLT1: L           1,<offset>(12) # 4 bytes  Load address from GOT in R1
+      BCR  15,1                  # 2 bytes  Jump to address
+      .word 0,0,0        # 6 bytes  filler
+RET1: BASR 1,0           # 2 bytes  Return from GOT 1st time
+      L           1,14(1)        # 4 bytes  Load offset in rela.plt in r1
+      BRC  15,-x         # 4 bytes  Jump to start of PLT
+      .word 0,0,0        # 6 bytes  filler
+      .long ?            # 4 bytes  offset into rela.plt
 
   Second the one for GOT offsets < 32768:
 
 
   Second the one for GOT offsets < 32768:
 
-PLT1: LHI  1,<offset>     # 4 bytes  Load offset in GOT to r1
-      L    1,(1,12)       # 4 bytes  Load address from GOT to r1
-      BCR  15,1           # 2 bytes  Jump to address
-      .word 0             # 2 bytes  filler
-RET1: BASR 1,0            # 2 bytes  Return from GOT 1st time
-      L    1,14(1)        # 4 bytes  Load offset in rela.plt in r1
-      BRC  15,-x          # 4 bytes  Jump to start of PLT
-      .word 0,0,0         # 6 bytes  filler
-      .long ?             # 4 bytes  offset into rela.plt
+PLT1: LHI  1,<offset>    # 4 bytes  Load offset in GOT to r1
+      L           1,(1,12)       # 4 bytes  Load address from GOT to r1
+      BCR  15,1                  # 2 bytes  Jump to address
+      .word 0            # 2 bytes  filler
+RET1: BASR 1,0           # 2 bytes  Return from GOT 1st time
+      L           1,14(1)        # 4 bytes  Load offset in rela.plt in r1
+      BRC  15,-x         # 4 bytes  Jump to start of PLT
+      .word 0,0,0        # 6 bytes  filler
+      .long ?            # 4 bytes  offset into rela.plt
 
 Total = 32 bytes per PLT entry
 
    The code for static build PLT entries looks like this:
 
 
 Total = 32 bytes per PLT entry
 
    The code for static build PLT entries looks like this:
 
-PLT1: BASR 1,0         # 2 bytes
-      L    1,22(1)     # 4 bytes  Load address of GOT entry
-      L    1,0(0,1)    # 4 bytes  Load address from GOT in r1
-      BCR  15,1        # 2 bytes  Jump to address
-RET1: BASR 1,0         # 2 bytes  Return from GOT 1st time
-      L    1,14(1)     # 4 bytes  Load offset in symbol table in r1
+PLT1: BASR 1,0        # 2 bytes
+      L           1,22(1)     # 4 bytes  Load address of GOT entry
+      L           1,0(0,1)    # 4 bytes  Load address from GOT in r1
+      BCR  15,1               # 2 bytes  Jump to address
+RET1: BASR 1,0        # 2 bytes  Return from GOT 1st time
+      L           1,14(1)     # 4 bytes  Load offset in symbol table in r1
       BRC  15,-x       # 4 bytes  Jump to start of PLT
       BRC  15,-x       # 4 bytes  Jump to start of PLT
-      .word 0          # 2 bytes  filler
-      .long ?          # 4 bytes  address of GOT entry
-      .long ?          # 4 bytes  offset into rela.plt  */
+      .word 0         # 2 bytes  filler
+      .long ?         # 4 bytes  address of GOT entry
+      .long ?         # 4 bytes  offset into rela.plt  */
 
 static const bfd_byte elf_s390_plt_entry[PLT_ENTRY_SIZE] =
   {
 
 static const bfd_byte elf_s390_plt_entry[PLT_ENTRY_SIZE] =
   {
-    0x0d, 0x10,                             /* basr    %r1,%r0     */
-    0x58, 0x10, 0x10, 0x16,                 /* l       %r1,22(%r1) */
-    0x58, 0x10, 0x10, 0x00,                 /* l       %r1,0(%r1)  */
-    0x07, 0xf1,                             /* br      %r1         */
-    0x0d, 0x10,                             /* basr    %r1,%r0     */
-    0x58, 0x10, 0x10, 0x0e,                 /* l       %r1,14(%r1) */
-    0xa7, 0xf4, 0x00, 0x00,                 /* j       first plt   */
-    0x00, 0x00,                             /* padding             */
-    0x00, 0x00, 0x00, 0x00,                 /* GOT offset          */
-    0x00, 0x00, 0x00, 0x00                  /* rela.plt offset     */
+    0x0d, 0x10,                                    /* basr    %r1,%r0     */
+    0x58, 0x10, 0x10, 0x16,                /* l       %r1,22(%r1) */
+    0x58, 0x10, 0x10, 0x00,                /* l       %r1,0(%r1)  */
+    0x07, 0xf1,                                    /* br      %r1         */
+    0x0d, 0x10,                                    /* basr    %r1,%r0     */
+    0x58, 0x10, 0x10, 0x0e,                /* l       %r1,14(%r1) */
+    0xa7, 0xf4, 0x00, 0x00,                /* j       first plt   */
+    0x00, 0x00,                                    /* padding             */
+    0x00, 0x00, 0x00, 0x00,                /* GOT offset          */
+    0x00, 0x00, 0x00, 0x00                 /* rela.plt offset     */
   };
 
 /* Generic PLT pic entry.  */
 static const bfd_byte elf_s390_plt_pic_entry[PLT_ENTRY_SIZE] =
   {
   };
 
 /* Generic PLT pic entry.  */
 static const bfd_byte elf_s390_plt_pic_entry[PLT_ENTRY_SIZE] =
   {
-    0x0d, 0x10,                             /* basr    %r1,%r0         */
-    0x58, 0x10, 0x10, 0x16,                 /* l       %r1,22(%r1)     */
-    0x58, 0x11, 0xc0, 0x00,                 /* l       %r1,0(%r1,%r12) */
-    0x07, 0xf1,                             /* br      %r1             */
-    0x0d, 0x10,                             /* basr    %r1,%r0         */
-    0x58, 0x10, 0x10, 0x0e,                 /* l       %r1,14(%r1)     */
-    0xa7, 0xf4, 0x00, 0x00,                 /* j       first plt       */
-    0x00, 0x00,                             /* padding                 */
-    0x00, 0x00, 0x00, 0x00,                 /* GOT offset              */
-    0x00, 0x00, 0x00, 0x00                  /* rela.plt offset         */
+    0x0d, 0x10,                                    /* basr    %r1,%r0         */
+    0x58, 0x10, 0x10, 0x16,                /* l       %r1,22(%r1)     */
+    0x58, 0x11, 0xc0, 0x00,                /* l       %r1,0(%r1,%r12) */
+    0x07, 0xf1,                                    /* br      %r1             */
+    0x0d, 0x10,                                    /* basr    %r1,%r0         */
+    0x58, 0x10, 0x10, 0x0e,                /* l       %r1,14(%r1)     */
+    0xa7, 0xf4, 0x00, 0x00,                /* j       first plt       */
+    0x00, 0x00,                                    /* padding                 */
+    0x00, 0x00, 0x00, 0x00,                /* GOT offset              */
+    0x00, 0x00, 0x00, 0x00                 /* rela.plt offset         */
   };
 
 /* Optimized PLT pic entry for GOT offset < 4k.  xx will be replaced
    when generating the PLT slot with the GOT offset.  */
 static const bfd_byte elf_s390_plt_pic12_entry[PLT_ENTRY_SIZE] =
   {
   };
 
 /* Optimized PLT pic entry for GOT offset < 4k.  xx will be replaced
    when generating the PLT slot with the GOT offset.  */
 static const bfd_byte elf_s390_plt_pic12_entry[PLT_ENTRY_SIZE] =
   {
-    0x58, 0x10, 0xc0, 0x00,                 /* l       %r1,xx(%r12) */
-    0x07, 0xf1,                             /* br      %r1          */
-    0x00, 0x00, 0x00, 0x00,                 /* padding              */
+    0x58, 0x10, 0xc0, 0x00,                /* l       %r1,xx(%r12) */
+    0x07, 0xf1,                                    /* br      %r1          */
+    0x00, 0x00, 0x00, 0x00,                /* padding              */
     0x00, 0x00,
     0x00, 0x00,
-    0x0d, 0x10,                             /* basr    %r1,%r0      */
-    0x58, 0x10, 0x10, 0x0e,                 /* l       %r1,14(%r1)  */
-    0xa7, 0xf4, 0x00, 0x00,                 /* j       first plt    */
+    0x0d, 0x10,                                    /* basr    %r1,%r0      */
+    0x58, 0x10, 0x10, 0x0e,                /* l       %r1,14(%r1)  */
+    0xa7, 0xf4, 0x00, 0x00,                /* j       first plt    */
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00
   };
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00
   };
@@ -578,13 +584,13 @@ static const bfd_byte elf_s390_plt_pic12_entry[PLT_ENTRY_SIZE] =
    when generating the PLT slot with the GOT offset.  */
 static const bfd_byte elf_s390_plt_pic16_entry[PLT_ENTRY_SIZE] =
   {
    when generating the PLT slot with the GOT offset.  */
 static const bfd_byte elf_s390_plt_pic16_entry[PLT_ENTRY_SIZE] =
   {
-    0xa7, 0x18, 0x00, 0x00,                 /* lhi     %r1,xx          */
-    0x58, 0x11, 0xc0, 0x00,                 /* l       %r1,0(%r1,%r12) */
-    0x07, 0xf1,                             /* br      %r1             */
+    0xa7, 0x18, 0x00, 0x00,                /* lhi     %r1,xx          */
+    0x58, 0x11, 0xc0, 0x00,                /* l       %r1,0(%r1,%r12) */
+    0x07, 0xf1,                                    /* br      %r1             */
     0x00, 0x00,
     0x00, 0x00,
-    0x0d, 0x10,                             /* basr    %r1,%r0         */
-    0x58, 0x10, 0x10, 0x0e,                 /* l       %r1,14(%r1)     */
-    0xa7, 0xf4, 0x00, 0x00,                 /* j       first plt       */
+    0x0d, 0x10,                                    /* basr    %r1,%r0         */
+    0x58, 0x10, 0x10, 0x0e,                /* l       %r1,14(%r1)     */
+    0xa7, 0xf4, 0x00, 0x00,                /* j       first plt       */
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00
@@ -597,32 +603,32 @@ static const bfd_byte elf_s390_plt_pic16_entry[PLT_ENTRY_SIZE] =
 /* The first entry in the PLT for PIC code:
 
 PLT0:
 /* The first entry in the PLT for PIC code:
 
 PLT0:
-   ST   1,28(15)  # R1 has offset into rela.plt
-   L    1,4(12)   # Get loader ino(object struct address)
-   ST   1,24(15)  # Store address
-   L    1,8(12)   # Entry address of loader in R1
-   BR   1         # Jump to loader
+   ST  1,28(15)  # R1 has offset into rela.plt
+   L   1,4(12)   # Get loader ino(object struct address)
+   ST  1,24(15)  # Store address
+   L   1,8(12)   # Entry address of loader in R1
+   BR  1         # Jump to loader
 
    The first entry in the PLT for static code:
 
 PLT0:
 
    The first entry in the PLT for static code:
 
 PLT0:
-   ST   1,28(15)      # R1 has offset into rela.plt
+   ST  1,28(15)      # R1 has offset into rela.plt
    BASR 1,0
    BASR 1,0
-   L    1,18(0,1)     # Get address of GOT
-   MVC  24(4,15),4(1) # Move loader ino to stack
-   L    1,8(1)        # Get address of loader
-   BR   1             # Jump to loader
-   .word 0            # filler
-   .long got          # address of GOT  */
+   L   1,18(0,1)     # Get address of GOT
+   MVC 24(4,15),4(1) # Move loader ino to stack
+   L   1,8(1)        # Get address of loader
+   BR  1             # Jump to loader
+   .word 0           # filler
+   .long got         # address of GOT  */
 
 static const bfd_byte elf_s390_plt_first_entry[PLT_FIRST_ENTRY_SIZE] =
   {
 
 static const bfd_byte elf_s390_plt_first_entry[PLT_FIRST_ENTRY_SIZE] =
   {
-    0x50, 0x10, 0xf0, 0x1c,                   /* st      %r1,28(%r15)      */
-    0x0d, 0x10,                               /* basr    %r1,%r0           */
-    0x58, 0x10, 0x10, 0x12,                   /* l       %r1,18(%r1)       */
-    0xd2, 0x03, 0xf0, 0x18, 0x10, 0x04,       /* mvc     24(4,%r15),4(%r1) */
-    0x58, 0x10, 0x10, 0x08,                   /* l       %r1,8(%r1)        */
-    0x07, 0xf1,                               /* br      %r1               */
+    0x50, 0x10, 0xf0, 0x1c,                  /* st      %r1,28(%r15)      */
+    0x0d, 0x10,                                      /* basr    %r1,%r0           */
+    0x58, 0x10, 0x10, 0x12,                  /* l       %r1,18(%r1)       */
+    0xd2, 0x03, 0xf0, 0x18, 0x10, 0x04,              /* mvc     24(4,%r15),4(%r1) */
+    0x58, 0x10, 0x10, 0x08,                  /* l       %r1,8(%r1)        */
+    0x07, 0xf1,                                      /* br      %r1               */
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00
@@ -630,11 +636,11 @@ static const bfd_byte elf_s390_plt_first_entry[PLT_FIRST_ENTRY_SIZE] =
 
 static const bfd_byte elf_s390_plt_pic_first_entry[PLT_FIRST_ENTRY_SIZE] =
   {
 
 static const bfd_byte elf_s390_plt_pic_first_entry[PLT_FIRST_ENTRY_SIZE] =
   {
-    0x50, 0x10, 0xf0, 0x1c,                     /* st      %r1,28(%r15)  */
-    0x58, 0x10, 0xc0, 0x04,                     /* l       %r1,4(%r12)   */
-    0x50, 0x10, 0xf0, 0x18,                     /* st      %r1,24(%r15)  */
-    0x58, 0x10, 0xc0, 0x08,                     /* l       %r1,8(%r12)   */
-    0x07, 0xf1,                                 /* br      %r1           */
+    0x50, 0x10, 0xf0, 0x1c,                    /* st      %r1,28(%r15)  */
+    0x58, 0x10, 0xc0, 0x04,                    /* l       %r1,4(%r12)   */
+    0x50, 0x10, 0xf0, 0x18,                    /* st      %r1,24(%r15)  */
+    0x58, 0x10, 0xc0, 0x08,                    /* l       %r1,8(%r12)   */
+    0x07, 0xf1,                                        /* br      %r1           */
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00,
@@ -736,8 +742,6 @@ struct elf_s390_link_hash_table
   struct elf_link_hash_table elf;
 
   /* Short-cuts to get to dynamic linker sections.  */
   struct elf_link_hash_table elf;
 
   /* Short-cuts to get to dynamic linker sections.  */
-  asection *sdynbss;
-  asection *srelbss;
   asection *irelifunc;
 
   union
   asection *irelifunc;
 
   union
@@ -816,56 +820,6 @@ elf_s390_link_hash_table_create (bfd *abfd)
   return &ret->elf.root;
 }
 
   return &ret->elf.root;
 }
 
-/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
-   shortcuts to them in our hash table.  */
-
-static bfd_boolean
-create_got_section (bfd *dynobj, struct bfd_link_info *info)
-{
-  struct elf_s390_link_hash_table *htab;
-
-  if (! _bfd_elf_create_got_section (dynobj, info))
-    return FALSE;
-
-  htab = elf_s390_hash_table (info);
-  htab->elf.sgot = bfd_get_linker_section (dynobj, ".got");
-  htab->elf.sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
-  htab->elf.srelgot = bfd_get_linker_section (dynobj, ".rela.got");
-  if (!htab->elf.sgot || !htab->elf.sgotplt || !htab->elf.srelgot)
-    abort ();
-
-  return TRUE;
-}
-
-/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
-   .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
-   hash table.  */
-
-static bfd_boolean
-elf_s390_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
-{
-  struct elf_s390_link_hash_table *htab;
-
-  htab = elf_s390_hash_table (info);
-  if (!htab->elf.sgot && !create_got_section (dynobj, info))
-    return FALSE;
-
-  if (!_bfd_elf_create_dynamic_sections (dynobj, info))
-    return FALSE;
-
-  htab->elf.splt = bfd_get_linker_section (dynobj, ".plt");
-  htab->elf.srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
-  htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
-  if (!bfd_link_pic (info))
-    htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
-
-  if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
-      || (!bfd_link_pic (info) && !htab->srelbss))
-    abort ();
-
-  return TRUE;
-}
-
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
@@ -923,7 +877,8 @@ elf_s390_copy_indirect_symbol (struct bfd_link_info *info,
       /* If called to transfer flags for a weakdef during processing
         of elf_adjust_dynamic_symbol, don't copy non_got_ref.
         We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
       /* If called to transfer flags for a weakdef during processing
         of elf_adjust_dynamic_symbol, don't copy non_got_ref.
         We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
-      dir->ref_dynamic |= ind->ref_dynamic;
+      if (dir->versioned != versioned_hidden)
+       dir->ref_dynamic |= ind->ref_dynamic;
       dir->ref_regular |= ind->ref_regular;
       dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
       dir->needs_plt |= ind->needs_plt;
       dir->ref_regular |= ind->ref_regular;
       dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
       dir->needs_plt |= ind->needs_plt;
@@ -994,15 +949,16 @@ elf_s390_check_relocs (bfd *abfd,
   for (rel = relocs; rel < rel_end; rel++)
     {
       unsigned int r_type;
   for (rel = relocs; rel < rel_end; rel++)
     {
       unsigned int r_type;
-      unsigned long r_symndx;
+      unsigned int r_symndx;
       struct elf_link_hash_entry *h;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
 
       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
        {
       struct elf_link_hash_entry *h;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
 
       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
        {
-         (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
-                                abfd, r_symndx);
+         /* xgettext:c-format */
+         _bfd_error_handler (_("%pB: bad symbol index: %d"),
+                             abfd, r_symndx);
          return FALSE;
        }
 
          return FALSE;
        }
 
@@ -1041,10 +997,6 @@ elf_s390_check_relocs (bfd *abfd,
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
-         /* PR15323, ref flags aren't set for references in the same
-            object.  */
-         h->root.non_ir_ref = 1;
        }
 
       /* Create got section and local_got_refcounts array if they
        }
 
       /* Create got section and local_got_refcounts array if they
@@ -1087,7 +1039,7 @@ elf_s390_check_relocs (bfd *abfd,
            {
              if (htab->elf.dynobj == NULL)
                htab->elf.dynobj = abfd;
            {
              if (htab->elf.dynobj == NULL)
                htab->elf.dynobj = abfd;
-             if (!create_got_section (htab->elf.dynobj, info))
+             if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
                return FALSE;
            }
        }
                return FALSE;
            }
        }
@@ -1123,6 +1075,7 @@ elf_s390_check_relocs (bfd *abfd,
        case R_390_GOTOFF32:
          if (h == NULL || !s390_is_ifunc_symbol_p (h) || !h->def_regular)
            break;
        case R_390_GOTOFF32:
          if (h == NULL || !s390_is_ifunc_symbol_p (h) || !h->def_regular)
            break;
+         /* Fall through.  */
 
        case R_390_PLT12DBL:
        case R_390_PLT16DBL:
 
        case R_390_PLT12DBL:
        case R_390_PLT16DBL:
@@ -1230,8 +1183,9 @@ elf_s390_check_relocs (bfd *abfd,
            {
              if (old_tls_type == GOT_NORMAL || tls_type == GOT_NORMAL)
                {
            {
              if (old_tls_type == GOT_NORMAL || tls_type == GOT_NORMAL)
                {
-                 (*_bfd_error_handler)
-                   (_("%B: `%s' accessed both as normal and thread local symbol"),
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB: `%s' accessed both as normal and thread local symbol"),
                     abfd, h->root.root.string);
                  return FALSE;
                }
                     abfd, h->root.root.string);
                  return FALSE;
                }
@@ -1272,7 +1226,7 @@ elf_s390_check_relocs (bfd *abfd,
        case R_390_PC24DBL:
        case R_390_PC32DBL:
        case R_390_PC32:
        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
            {
              /* If this reloc is in a read-only section, we might
                 need a copy reloc.  We can't check reliably at this
@@ -1412,9 +1366,7 @@ elf_s390_check_relocs (bfd *abfd,
          /* This relocation describes which C++ vtable entries are actually
             used.  Record for later use during GC.  */
        case R_390_GNU_VTENTRY:
          /* This relocation describes which C++ vtable entries are actually
             used.  Record for later use during GC.  */
        case R_390_GNU_VTENTRY:
-         BFD_ASSERT (h != NULL);
-         if (h != NULL
-             && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;
 
            return FALSE;
          break;
 
@@ -1447,180 +1399,6 @@ elf_s390_gc_mark_hook (asection *sec,
 
 }
 
 
 }
 
-/* Update the got entry reference counts for the section being removed.  */
-
-static bfd_boolean
-elf_s390_gc_sweep_hook (bfd *abfd,
-                       struct bfd_link_info *info,
-                       asection *sec,
-                       const Elf_Internal_Rela *relocs)
-{
-  struct elf_s390_link_hash_table *htab;
-  Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes;
-  bfd_signed_vma *local_got_refcounts;
-  const Elf_Internal_Rela *rel, *relend;
-
-  if (bfd_link_relocatable (info))
-    return TRUE;
-
-  htab = elf_s390_hash_table (info);
-  if (htab == NULL)
-    return FALSE;
-
-  elf_section_data (sec)->local_dynrel = NULL;
-
-  symtab_hdr = &elf_symtab_hdr (abfd);
-  sym_hashes = elf_sym_hashes (abfd);
-  local_got_refcounts = elf_local_got_refcounts (abfd);
-
-  relend = relocs + sec->reloc_count;
-  for (rel = relocs; rel < relend; rel++)
-    {
-      unsigned long r_symndx;
-      unsigned int r_type;
-      struct elf_link_hash_entry *h = NULL;
-
-      r_symndx = ELF32_R_SYM (rel->r_info);
-      if (r_symndx >= symtab_hdr->sh_info)
-       {
-         struct elf_s390_link_hash_entry *eh;
-         struct elf_dyn_relocs **pp;
-         struct elf_dyn_relocs *p;
-
-         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-         while (h->root.type == bfd_link_hash_indirect
-                || h->root.type == bfd_link_hash_warning)
-           h = (struct elf_link_hash_entry *) h->root.u.i.link;
-         eh = (struct elf_s390_link_hash_entry *) h;
-
-         for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-           if (p->sec == sec)
-             {
-               /* Everything must go for SEC.  */
-               *pp = p->next;
-               break;
-             }
-       }
-      else
-       {
-         Elf_Internal_Sym *isym;
-
-         /* A local symbol.  */
-         isym = bfd_sym_from_r_symndx (&htab->sym_cache,
-                                       abfd, r_symndx);
-         if (isym == NULL)
-           return FALSE;
-
-         if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
-           {
-             struct plt_entry *plt = elf_s390_local_plt (abfd);
-             if (plt[r_symndx].plt.refcount > 0)
-               plt[r_symndx].plt.refcount--;
-           }
-       }
-
-      r_type = ELF32_R_TYPE (rel->r_info);
-      r_type = elf_s390_tls_transition (info, r_type, h != NULL);
-      switch (r_type)
-       {
-       case R_390_TLS_LDM32:
-         if (elf_s390_hash_table (info)->tls_ldm_got.refcount > 0)
-           elf_s390_hash_table (info)->tls_ldm_got.refcount -= 1;
-         break;
-
-       case R_390_GOTOFF16:
-       case R_390_GOTOFF32:
-         if (s390_is_ifunc_symbol_p (h) && h->def_regular)
-           {
-             h->plt.refcount--;
-             break;
-           }
-
-       case R_390_GOTPC:
-       case R_390_GOTPCDBL:
-         break;
-
-       case R_390_TLS_GD32:
-       case R_390_TLS_IE32:
-       case R_390_TLS_GOTIE12:
-       case R_390_TLS_GOTIE20:
-       case R_390_TLS_GOTIE32:
-       case R_390_TLS_IEENT:
-       case R_390_GOT12:
-       case R_390_GOT16:
-       case R_390_GOT20:
-       case R_390_GOT32:
-       case R_390_GOTENT:
-         if (h != NULL)
-           {
-             if (h->got.refcount > 0)
-               h->got.refcount -= 1;
-           }
-         else if (local_got_refcounts != NULL)
-           {
-             if (local_got_refcounts[r_symndx] > 0)
-               local_got_refcounts[r_symndx] -= 1;
-           }
-         break;
-
-       case R_390_8:
-       case R_390_12:
-       case R_390_16:
-       case R_390_20:
-       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 (bfd_link_pic (info))
-           break;
-         /* Fall through.  */
-
-       case R_390_PLT12DBL:
-       case R_390_PLT16DBL:
-       case R_390_PLT24DBL:
-       case R_390_PLT32DBL:
-       case R_390_PLT32:
-       case R_390_PLTOFF16:
-       case R_390_PLTOFF32:
-         if (h != NULL)
-           {
-             if (h->plt.refcount > 0)
-               h->plt.refcount -= 1;
-           }
-         break;
-
-       case R_390_GOTPLT12:
-       case R_390_GOTPLT16:
-       case R_390_GOTPLT20:
-       case R_390_GOTPLT32:
-       case R_390_GOTPLTENT:
-         if (h != NULL)
-           {
-             if (h->plt.refcount > 0)
-               {
-                 ((struct elf_s390_link_hash_entry *) h)->gotplt_refcount--;
-                 h->plt.refcount -= 1;
-               }
-           }
-         else if (local_got_refcounts != NULL)
-           {
-             if (local_got_refcounts[r_symndx] > 0)
-               local_got_refcounts[r_symndx] -= 1;
-           }
-         break;
-
-       default:
-         break;
-       }
-    }
-
-  return TRUE;
-}
-
 /* Make sure we emit a GOT entry if the symbol was supposed to have a PLT
    entry but we found we will not create any.  Called when we find we will
    not have any PLT for this symbol, by for example
 /* Make sure we emit a GOT entry if the symbol was supposed to have a PLT
    entry but we found we will not create any.  Called when we find we will
    not have any PLT for this symbol, by for example
@@ -1643,6 +1421,23 @@ elf_s390_adjust_gotplt (struct elf_s390_link_hash_entry *h)
   h->gotplt_refcount = -1;
 }
 
   h->gotplt_refcount = -1;
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_dyn_relocs *p;
+
+  for (p = elf_s390_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+       return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -1654,11 +1449,51 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
                                struct elf_link_hash_entry *h)
 {
   struct elf_s390_link_hash_table *htab;
                                struct elf_link_hash_entry *h)
 {
   struct elf_s390_link_hash_table *htab;
-  asection *s;
+  asection *s, *srel;
 
   /* STT_GNU_IFUNC symbol must go through PLT. */
   if (s390_is_ifunc_symbol_p (h))
 
   /* STT_GNU_IFUNC symbol must go through PLT. */
   if (s390_is_ifunc_symbol_p (h))
-    return TRUE;
+    {
+      /* All local STT_GNU_IFUNC references must be treated as local
+        calls via local PLT.  */
+      if (h->ref_regular && SYMBOL_CALLS_LOCAL (info, h))
+       {
+         bfd_size_type pc_count = 0, count = 0;
+         struct elf_dyn_relocs **pp;
+         struct elf_s390_link_hash_entry *eh;
+         struct elf_dyn_relocs *p;
+
+         eh = (struct elf_s390_link_hash_entry *) h;
+         for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+           {
+             pc_count += p->pc_count;
+             p->count -= p->pc_count;
+             p->pc_count = 0;
+             count += p->count;
+             if (p->count == 0)
+               *pp = p->next;
+             else
+               pp = &p->next;
+           }
+
+         if (pc_count || count)
+           {
+             h->needs_plt = 1;
+             h->non_got_ref = 1;
+             if (h->plt.refcount <= 0)
+               h->plt.refcount = 1;
+             else
+               h->plt.refcount += 1;
+           }
+       }
+
+      if (h->plt.refcount <= 0)
+       {
+         h->plt.offset = (bfd_vma) -1;
+         h->needs_plt = 0;
+       }
+      return TRUE;
+    }
 
   /* If this is a function, put it in the procedure linkage table.  We
      will fill in the contents of the procedure linkage table later
 
   /* If this is a function, put it in the procedure linkage table.  We
      will fill in the contents of the procedure linkage table later
@@ -1694,14 +1529,14 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
-  if (h->u.weakdef != NULL)
+  if (h->is_weakalias)
     {
     {
-      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
-                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
-      h->root.u.def.section = h->u.weakdef->root.u.def.section;
-      h->root.u.def.value = h->u.weakdef->root.u.def.value;
+      struct elf_link_hash_entry *def = weakdef (h);
+      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+      h->root.u.def.section = def->root.u.def.section;
+      h->root.u.def.value = def->root.u.def.value;
       if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
       if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
-       h->non_got_ref = h->u.weakdef->non_got_ref;
+       h->non_got_ref = def->non_got_ref;
       return TRUE;
     }
 
       return TRUE;
     }
 
@@ -1727,26 +1562,12 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
       return TRUE;
     }
 
       return TRUE;
     }
 
-  if (ELIMINATE_COPY_RELOCS)
+  /* If we don't find any dynamic relocs in read-only sections, then
+     we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
+  if (ELIMINATE_COPY_RELOCS && !readonly_dynrelocs (h))
     {
     {
-      struct elf_s390_link_hash_entry * eh;
-      struct elf_dyn_relocs *p;
-
-      eh = (struct elf_s390_link_hash_entry *) h;
-      for (p = eh->dyn_relocs; p != NULL; p = p->next)
-       {
-         s = p->sec->output_section;
-         if (s != NULL && (s->flags & SEC_READONLY) != 0)
-           break;
-       }
-
-      /* If we didn't find any dynamic relocs in read-only sections, then
-        we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
-      if (p == NULL)
-       {
-         h->non_got_ref = 0;
-         return TRUE;
-       }
+      h->non_got_ref = 0;
+      return TRUE;
     }
 
   /* We must allocate the symbol in our .dynbss section, which will
     }
 
   /* We must allocate the symbol in our .dynbss section, which will
@@ -1764,14 +1585,22 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a R_390_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
   /* We must generate a R_390_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->srelbss->size += sizeof (Elf32_External_Rela);
+      srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
 
       h->needs_copy = 1;
     }
 
-  s = htab->sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -1844,7 +1673,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
        }
       else
        {
        }
       else
        {
-         h->plt.offset = (bfd_vma) -1;
+         h->plt.offset = (bfd_vma) -1;
          h->needs_plt = 0;
          elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
        }
          h->needs_plt = 0;
          elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
        }
@@ -1877,7 +1706,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
        h->got.offset = (bfd_vma) -1;
     }
   else if (h->got.refcount > 0)
        h->got.offset = (bfd_vma) -1;
     }
   else if (h->got.refcount > 0)
-   {
+    {
       asection *s;
       bfd_boolean dyn;
       int tls_type = elf_s390_hash_entry(h)->tls_type;
       asection *s;
       bfd_boolean dyn;
       int tls_type = elf_s390_hash_entry(h)->tls_type;
@@ -1945,7 +1774,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
       if (eh->dyn_relocs != NULL
          && h->root.type == bfd_link_hash_undefweak)
        {
       if (eh->dyn_relocs != NULL
          && h->root.type == bfd_link_hash_undefweak)
        {
-         if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+         if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+             || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
            eh->dyn_relocs = NULL;
 
          /* Make sure undefined weak symbols are output as a dynamic
            eh->dyn_relocs = NULL;
 
          /* Make sure undefined weak symbols are output as a dynamic
@@ -2002,28 +1832,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   return TRUE;
 }
 
   return TRUE;
 }
 
-/* Find any dynamic relocs that apply to read-only sections.  */
+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
+   read-only sections.  */
 
 static bfd_boolean
 
 static bfd_boolean
-readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
 {
 {
-  struct elf_s390_link_hash_entry *eh;
-  struct elf_dyn_relocs *p;
+  asection *sec;
 
 
-  eh = (struct elf_s390_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec->output_section;
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
 
 
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-       {
-         struct bfd_link_info *info = (struct bfd_link_info *) inf;
+  sec = readonly_dynrelocs (h);
+  if (sec != NULL)
+    {
+      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
 
 
-         info->flags |= DF_TEXTREL;
+      info->flags |= DF_TEXTREL;
+      info->callbacks->minfo
+       (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
+        sec->owner, h->root.root.string, sec);
 
 
-         /* Not an error, just cut short the traversal.  */
-         return FALSE;
-       }
+      /* Not an error, just cut short the traversal.  */
+      return FALSE;
     }
   return TRUE;
 }
     }
   return TRUE;
 }
@@ -2133,7 +1964,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
              htab->elf.irelplt->size += RELA_ENTRY_SIZE;
            }
          else
              htab->elf.irelplt->size += RELA_ENTRY_SIZE;
            }
          else
-            local_plt[i].plt.offset = (bfd_vma) -1;
+           local_plt[i].plt.offset = (bfd_vma) -1;
        }
     }
 
        }
     }
 
@@ -2163,7 +1994,8 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (s == htab->elf.splt
          || s == htab->elf.sgot
          || s == htab->elf.sgotplt
       if (s == htab->elf.splt
          || s == htab->elf.sgot
          || s == htab->elf.sgotplt
-         || s == htab->sdynbss
+         || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro
          || s == htab->elf.iplt
          || s == htab->elf.igotplt
          || s == htab->irelifunc)
          || s == htab->elf.iplt
          || s == htab->elf.igotplt
          || s == htab->irelifunc)
@@ -2171,7 +2003,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          /* Strip this section if we don't need it; see the
             comment below.  */
        }
          /* Strip this section if we don't need it; see the
             comment below.  */
        }
-      else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+      else if (CONST_STRNEQ (bfd_section_name (s), ".rela"))
        {
          if (s->size != 0)
            relocs = TRUE;
        {
          if (s->size != 0)
            relocs = TRUE;
@@ -2250,7 +2082,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          /* If any dynamic relocs apply to a read-only section,
             then we need a DT_TEXTREL entry.  */
          if ((info->flags & DF_TEXTREL) == 0)
          /* If any dynamic relocs apply to a read-only section,
             then we need a DT_TEXTREL entry.  */
          if ((info->flags & DF_TEXTREL) == 0)
-           elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
+           elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
 
          if ((info->flags & DF_TEXTREL) != 0)
            {
 
          if ((info->flags & DF_TEXTREL) != 0)
            {
@@ -2302,11 +2134,12 @@ invalid_tls_insn (bfd *input_bfd,
   reloc_howto_type *howto;
 
   howto = elf_howto_table + ELF32_R_TYPE (rel->r_info);
   reloc_howto_type *howto;
 
   howto = elf_howto_table + ELF32_R_TYPE (rel->r_info);
-  (*_bfd_error_handler)
-    (_("%B(%A+0x%lx): invalid instruction for TLS relocation %s"),
+  _bfd_error_handler
+    /* xgettext:c-format */
+    (_("%pB(%pA+%#" PRIx64 "): invalid instruction for TLS relocation %s"),
      input_bfd,
      input_section,
      input_bfd,
      input_section,
-     (long) rel->r_offset,
+     (uint64_t) rel->r_offset,
      howto->name);
   bfd_set_error (bfd_error_bad_value);
 }
      howto->name);
   bfd_set_error (bfd_error_bad_value);
 }
@@ -2330,7 +2163,11 @@ elf_s390_relocate_section (bfd *output_bfd,
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  BFD_ASSERT (is_s390_elf (input_bfd));
+  if (!is_s390_elf (input_bfd))
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return FALSE;
+    }
 
   htab = elf_s390_hash_table (info);
   symtab_hdr = &elf_symtab_hdr (input_bfd);
 
   htab = elf_s390_hash_table (info);
   symtab_hdr = &elf_symtab_hdr (input_bfd);
@@ -2353,6 +2190,7 @@ elf_s390_relocate_section (bfd *output_bfd,
       bfd_reloc_status_type r;
       int tls_type;
       asection *base_got = htab->elf.sgot;
       bfd_reloc_status_type r;
       int tls_type;
       asection *base_got = htab->elf.sgot;
+      bfd_boolean resolved_to_zero;
 
       r_type = ELF32_R_TYPE (rel->r_info);
       if (r_type == (int) R_390_GNU_VTINHERIT
 
       r_type = ELF32_R_TYPE (rel->r_info);
       if (r_type == (int) R_390_GNU_VTINHERIT
@@ -2444,6 +2282,9 @@ elf_s390_relocate_section (bfd *output_bfd,
       if (bfd_link_relocatable (info))
        continue;
 
       if (bfd_link_relocatable (info))
        continue;
 
+      resolved_to_zero = (h != NULL
+                         && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
+
       switch (r_type)
        {
        case R_390_GOTPLT12:
       switch (r_type)
        {
        case R_390_GOTPLT12:
@@ -2699,7 +2540,7 @@ elf_s390_relocate_section (bfd *output_bfd,
 
          if (s390_is_ifunc_symbol_p (h))
            relocation = (htab->elf.iplt->output_section->vma
 
          if (s390_is_ifunc_symbol_p (h))
            relocation = (htab->elf.iplt->output_section->vma
-                          + htab->elf.iplt->output_offset
+                         + htab->elf.iplt->output_offset
                          + h->plt.offset);
          else
            relocation = (htab->elf.splt->output_section->vma
                          + h->plt.offset);
          else
            relocation = (htab->elf.splt->output_section->vma
@@ -2736,20 +2577,44 @@ elf_s390_relocate_section (bfd *output_bfd,
          unresolved_reloc = FALSE;
          break;
 
          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:
        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;
+           }
+         /* Fall through.  */
+
+       case R_390_8:
+       case R_390_16:
+       case R_390_32:
+         if ((input_section->flags & SEC_ALLOC) == 0)
+           break;
+
          if (h != NULL
              && s390_is_ifunc_symbol_p (h)
              && h->def_regular)
            {
          if (h != NULL
              && s390_is_ifunc_symbol_p (h)
              && h->def_regular)
            {
-             if (!bfd_link_pic (info) || !h->non_got_ref)
+             if (!bfd_link_pic (info))
                {
                  /* For a non-shared object STT_GNU_IFUNC symbol must
                     go through PLT.  */
                {
                  /* For a non-shared object STT_GNU_IFUNC symbol must
                     go through PLT.  */
@@ -2806,12 +2671,10 @@ elf_s390_relocate_section (bfd *output_bfd,
                }
            }
 
                }
            }
 
-         if ((input_section->flags & SEC_ALLOC) == 0)
-           break;
-
          if ((bfd_link_pic (info)
               && (h == NULL
          if ((bfd_link_pic (info)
               && (h == NULL
-                  || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                  || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                      && !resolved_to_zero)
                   || h->root.type != bfd_link_hash_undefweak)
               && ((r_type != R_390_PC16
                    && r_type != R_390_PC12DBL
                   || h->root.type != bfd_link_hash_undefweak)
               && ((r_type != R_390_PC16
                    && r_type != R_390_PC12DBL
@@ -3206,7 +3069,6 @@ elf_s390_relocate_section (bfd *output_bfd,
                  unsigned int insn, ry;
 
                  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
                  unsigned int insn, ry;
 
                  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
-                 ry = 0;
                  if ((insn & 0xff00f000) == 0x58000000)
                    /* l %rx,0(%ry,0) -> lr %rx,%ry + bcr 0,0  */
                    ry = (insn & 0x000f0000);
                  if ((insn & 0xff00f000) == 0x58000000)
                    /* l %rx,0(%ry,0) -> lr %rx,%ry + bcr 0,0  */
                    ry = (insn & 0x000f0000);
@@ -3220,7 +3082,10 @@ elf_s390_relocate_section (bfd *output_bfd,
                    /* l %rx,0(%r12,%ry) -> lr %rx,%ry + bcr 0,0  */
                    ry = (insn & 0x0000f000) << 4;
                  else
                    /* l %rx,0(%r12,%ry) -> lr %rx,%ry + bcr 0,0  */
                    ry = (insn & 0x0000f000) << 4;
                  else
-                   invalid_tls_insn (input_bfd, input_section, rel);
+                   {
+                     invalid_tls_insn (input_bfd, input_section, rel);
+                     return FALSE;
+                   }
                  insn = 0x18000700 | (insn & 0x00f00000) | ry;
                  bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
                }
                  insn = 0x18000700 | (insn & 0x00f00000) | ry;
                  bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
                }
@@ -3233,7 +3098,10 @@ elf_s390_relocate_section (bfd *output_bfd,
              if ((insn & 0xff000fff) != 0x4d000000 &&
                  (insn & 0xffff0000) != 0xc0e50000 &&
                  (insn & 0xff000000) != 0x0d000000)
              if ((insn & 0xff000fff) != 0x4d000000 &&
                  (insn & 0xffff0000) != 0xc0e50000 &&
                  (insn & 0xff000000) != 0x0d000000)
-               invalid_tls_insn (input_bfd, input_section, rel);
+               {
+                 invalid_tls_insn (input_bfd, input_section, rel);
+                 return FALSE;
+               }
              if (!bfd_link_pic (info) && (h == NULL || h->dynindx == -1))
                {
                  if ((insn & 0xff000000) == 0x0d000000)
              if (!bfd_link_pic (info) && (h == NULL || h->dynindx == -1))
                {
                  if ((insn & 0xff000000) == 0x0d000000)
@@ -3262,7 +3130,10 @@ elf_s390_relocate_section (bfd *output_bfd,
                  /* If basr is used in the pic case to invoke
                     _tls_get_offset, something went wrong before.  */
                  if ((insn & 0xff000000) == 0x0d000000)
                  /* If basr is used in the pic case to invoke
                     _tls_get_offset, something went wrong before.  */
                  if ((insn & 0xff000000) == 0x0d000000)
-                   invalid_tls_insn (input_bfd, input_section, rel);
+                   {
+                     invalid_tls_insn (input_bfd, input_section, rel);
+                     return FALSE;
+                   }
 
                  if ((insn & 0xff000000) == 0x4d000000)
                    {
 
                  if ((insn & 0xff000000) == 0x4d000000)
                    {
@@ -3274,7 +3145,7 @@ elf_s390_relocate_section (bfd *output_bfd,
                    {
                      /* GD->IE transition.
                         brasl %r14,__tls_get_addr@plt ->
                    {
                      /* GD->IE transition.
                         brasl %r14,__tls_get_addr@plt ->
-                               l %r2,0(%r2,%r12) ; bcr 0,0 */
+                               l %r2,0(%r2,%r12) ; bcr 0,0 */
                      insn = 0x5822c000;
                      bfd_put_16 (output_bfd, 0x0700,
                                  contents + rel->r_offset + 4);
                      insn = 0x5822c000;
                      bfd_put_16 (output_bfd, 0x0700,
                                  contents + rel->r_offset + 4);
@@ -3292,7 +3163,10 @@ elf_s390_relocate_section (bfd *output_bfd,
                  if ((insn & 0xff000fff) != 0x4d000000 &&
                      (insn & 0xffff0000) != 0xc0e50000 &&
                      (insn & 0xff000000) != 0x0d000000)
                  if ((insn & 0xff000fff) != 0x4d000000 &&
                      (insn & 0xffff0000) != 0xc0e50000 &&
                      (insn & 0xff000000) != 0x0d000000)
-                   invalid_tls_insn (input_bfd, input_section, rel);
+                   {
+                     invalid_tls_insn (input_bfd, input_section, rel);
+                     return FALSE;
+                   }
 
                  if ((insn & 0xff000000) == 0x0d000000)
                    {
 
                  if ((insn & 0xff000000) == 0x0d000000)
                    {
@@ -3331,11 +3205,13 @@ elf_s390_relocate_section (bfd *output_bfd,
               && h->def_dynamic)
          && _bfd_elf_section_offset (output_bfd, info, input_section,
                                      rel->r_offset) != (bfd_vma) -1)
               && h->def_dynamic)
          && _bfd_elf_section_offset (output_bfd, info, input_section,
                                      rel->r_offset) != (bfd_vma) -1)
-       (*_bfd_error_handler)
-         (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+       _bfd_error_handler
+         /* xgettext:c-format */
+         (_("%pB(%pA+%#" PRIx64 "): "
+            "unresolvable %s relocation against symbol `%s'"),
           input_bfd,
           input_section,
           input_bfd,
           input_section,
-          (long) rel->r_offset,
+          (uint64_t) rel->r_offset,
           howto->name,
           h->root.root.string);
 
           howto->name,
           h->root.root.string);
 
@@ -3378,24 +3254,20 @@ elf_s390_relocate_section (bfd *output_bfd,
              if (name == NULL)
                return FALSE;
              if (*name == '\0')
              if (name == NULL)
                return FALSE;
              if (*name == '\0')
-               name = bfd_section_name (input_bfd, sec);
+               name = bfd_section_name (sec);
            }
 
          if (r == bfd_reloc_overflow)
            }
 
          if (r == bfd_reloc_overflow)
-           {
-
-             if (! ((*info->callbacks->reloc_overflow)
-                    (info, (h ? &h->root : NULL), name, howto->name,
-                     (bfd_vma) 0, input_bfd, input_section,
-                     rel->r_offset)))
-               return FALSE;
-           }
+           (*info->callbacks->reloc_overflow)
+             (info, (h ? &h->root : NULL), name, howto->name,
+              (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
          else
            {
          else
            {
-             (*_bfd_error_handler)
-               (_("%B(%A+0x%lx): reloc against `%s': error %d"),
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB(%pA+%#" PRIx64 "): reloc against `%s': error %d"),
                 input_bfd, input_section,
                 input_bfd, input_section,
-                (long) rel->r_offset, name, (int) r);
+                (uint64_t) rel->r_offset, name, (int) r);
              return FALSE;
            }
        }
              return FALSE;
            }
        }
@@ -3442,8 +3314,8 @@ elf_s390_finish_ifunc_symbol (bfd *output_bfd,
   /* S390 uses halfwords for relative branch calc!  */
   relative_offset = - (plt->output_offset +
                       (PLT_ENTRY_SIZE * iplt_index) + 18) / 2;
   /* S390 uses halfwords for relative branch calc!  */
   relative_offset = - (plt->output_offset +
                       (PLT_ENTRY_SIZE * iplt_index) + 18) / 2;
-/* If offset is > 32768, branch to a previous branch
-   390 can only handle +-64 K jumps.  */
+  /* If offset is > 32768, branch to a previous branch
+     390 can only handle +-64 K jumps.  */
   if ( -32768 > (int) relative_offset )
     relative_offset
       = -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2);
   if ( -32768 > (int) relative_offset )
     relative_offset
       = -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2);
@@ -3636,7 +3508,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
 
              /* Put in the GOT offset as displacement value.  The 0xc000
                 value comes from the first word of the plt entry.  Look
 
              /* Put in the GOT offset as displacement value.  The 0xc000
                 value comes from the first word of the plt entry.  Look
-                at the elf_s390_plt_pic16_entry content.  */
+                at the elf_s390_plt_pic12_entry content.  */
              bfd_put_16 (output_bfd, (bfd_vma)0xc000 | got_offset,
                          htab->elf.splt->contents + h->plt.offset + 2);
 
              bfd_put_16 (output_bfd, (bfd_vma)0xc000 | got_offset,
                          htab->elf.splt->contents + h->plt.offset + 2);
 
@@ -3755,7 +3627,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
            }
        }
       else if (bfd_link_pic (info)
            }
        }
       else if (bfd_link_pic (info)
-         && SYMBOL_REFERENCES_LOCAL (info, h))
+              && SYMBOL_REFERENCES_LOCAL (info, h))
        {
          /* If this is a static link, or it is a -Bsymbolic link and
             the symbol is defined locally or was forced to be local
        {
          /* If this is a static link, or it is a -Bsymbolic link and
             the symbol is defined locally or was forced to be local
@@ -3763,7 +3635,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
             RELATIVE reloc.  The entry in the global offset table
             will already have been initialized in the
             relocate_section function.  */
             RELATIVE reloc.  The entry in the global offset table
             will already have been initialized in the
             relocate_section function.  */
-         if (!h->def_regular)
+         if (!(h->def_regular || ELF_COMMON_DEF_P (h)))
            return FALSE;
          BFD_ASSERT((h->got.offset & 1) != 0);
          rela.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
            return FALSE;
          BFD_ASSERT((h->got.offset & 1) != 0);
          rela.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
@@ -3788,6 +3660,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
   if (h->needs_copy)
     {
       Elf_Internal_Rela rela;
   if (h->needs_copy)
     {
       Elf_Internal_Rela rela;
+      asection *s;
       bfd_byte *loc;
 
       /* This symbols needs a copy reloc.  Set it up.  */
       bfd_byte *loc;
 
       /* This symbols needs a copy reloc.  Set it up.  */
@@ -3795,7 +3668,8 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
       if (h->dynindx == -1
          || (h->root.type != bfd_link_hash_defined
              && h->root.type != bfd_link_hash_defweak)
       if (h->dynindx == -1
          || (h->root.type != bfd_link_hash_defined
              && h->root.type != bfd_link_hash_defweak)
-         || htab->srelbss == NULL)
+         || htab->elf.srelbss == NULL
+         || htab->elf.sreldynrelro == NULL)
        abort ();
 
       rela.r_offset = (h->root.u.def.value
        abort ();
 
       rela.r_offset = (h->root.u.def.value
@@ -3803,8 +3677,11 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_390_COPY);
       rela.r_addend = 0;
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_390_COPY);
       rela.r_addend = 0;
-      loc = htab->srelbss->contents;
-      loc += htab->srelbss->reloc_count++ * sizeof (Elf32_External_Rela);
+      if (h->root.u.def.section == htab->elf.sdynrelro)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
+      loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
 
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
 
@@ -3893,16 +3770,19 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
              continue;
 
            case DT_PLTGOT:
              continue;
 
            case DT_PLTGOT:
-             dyn.d_un.d_ptr = htab->elf.sgot->output_section->vma;
+             s = htab->elf.sgotplt;
+             dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              break;
 
            case DT_JMPREL:
              break;
 
            case DT_JMPREL:
-             dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
+             s = htab->elf.srelplt;
+             dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              break;
 
            case DT_PLTRELSZ:
              break;
 
            case DT_PLTRELSZ:
-             s = htab->elf.srelplt->output_section;
-             dyn.d_un.d_val = s->size;
+             dyn.d_un.d_val = htab->elf.srelplt->size;
+             if (htab->elf.irelplt)
+               dyn.d_un.d_val += htab->elf.irelplt->size;
              break;
            }
 
              break;
            }
 
@@ -3926,7 +3806,7 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
                          htab->elf.sgotplt->output_section->vma
                          + htab->elf.sgotplt->output_offset,
                          htab->elf.splt->contents + 24);
                          htab->elf.sgotplt->output_section->vma
                          + htab->elf.sgotplt->output_offset,
                          htab->elf.splt->contents + 24);
-          }
+           }
          elf_section_data (htab->elf.splt->output_section)
            ->this_hdr.sh_entsize = 4;
        }
          elf_section_data (htab->elf.splt->output_section)
            ->this_hdr.sh_entsize = 4;
        }
@@ -3960,6 +3840,9 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
 
       symtab_hdr = &elf_symtab_hdr (ibfd);
 
 
       symtab_hdr = &elf_symtab_hdr (ibfd);
 
+      if (!is_s390_elf (ibfd))
+       continue;
+
       local_plt = elf_s390_local_plt (ibfd);
       if (local_plt != NULL)
        for (i = 0; i < symtab_hdr->sh_info; i++)
       local_plt = elf_s390_local_plt (ibfd);
       if (local_plt != NULL)
        for (i = 0; i < symtab_hdr->sh_info; i++)
@@ -3983,6 +3866,8 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
     }
   return TRUE;
 }
     }
   return TRUE;
 }
+\f
+/* Support for core dump NOTE sections.  */
 
 static bfd_boolean
 elf_s390_grok_prstatus (bfd * abfd, Elf_Internal_Note * note)
 
 static bfd_boolean
 elf_s390_grok_prstatus (bfd * abfd, Elf_Internal_Note * note)
@@ -3992,20 +3877,20 @@ elf_s390_grok_prstatus (bfd * abfd, Elf_Internal_Note * note)
 
   switch (note->descsz)
     {
 
   switch (note->descsz)
     {
-      default:
-       return FALSE;
+    default:
+      return FALSE;
 
 
-      case 224:                /* S/390 Linux.  */
-       /* pr_cursig */
-       elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+    case 224:                  /* S/390 Linux.  */
+      /* pr_cursig */
+      elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
 
 
-       /* pr_pid */
-       elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+      /* pr_pid */
+      elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
 
 
-       /* pr_reg */
-       offset = 72;
-       size = 144;
-       break;
+      /* pr_reg */
+      offset = 72;
+      size = 144;
+      break;
     }
 
   /* Make a ".reg/999" section.  */
     }
 
   /* Make a ".reg/999" section.  */
@@ -4013,6 +3898,100 @@ elf_s390_grok_prstatus (bfd * abfd, Elf_Internal_Note * note)
                                          size, note->descpos + offset);
 }
 
                                          size, note->descpos + offset);
 }
 
+static bfd_boolean
+elf_s390_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+  switch (note->descsz)
+    {
+    default:
+      return FALSE;
+
+    case 124:                  /* sizeof(struct elf_prpsinfo) on s390 */
+      elf_tdata (abfd)->core->pid
+       = bfd_get_32 (abfd, note->descdata + 12);
+      elf_tdata (abfd)->core->program
+       = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+      elf_tdata (abfd)->core->command
+       = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+      break;
+    }
+
+  /* Note that for some reason, a spurious space is tacked
+     onto the end of the args in some (at least one anyway)
+     implementations, so strip it off if it exists.  */
+
+  {
+    char *command = elf_tdata (abfd)->core->command;
+    int n = strlen (command);
+
+    if (0 < n && command[n - 1] == ' ')
+      command[n - 1] = '\0';
+  }
+
+  return TRUE;
+}
+
+static char *
+elf_s390_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+                         int note_type, ...)
+{
+  va_list ap;
+
+  switch (note_type)
+    {
+    default:
+      return NULL;
+
+    case NT_PRPSINFO:
+      {
+       char data[124] ATTRIBUTE_NONSTRING = { 0 };
+       const char *fname, *psargs;
+
+       va_start (ap, note_type);
+       fname = va_arg (ap, const char *);
+       psargs = va_arg (ap, const char *);
+       va_end (ap);
+
+       strncpy (data + 28, fname, 16);
+#if GCC_VERSION == 8000 || GCC_VERSION == 8001
+       DIAGNOSTIC_PUSH;
+       /* GCC 8.0 and 8.1 warn about 80 equals destination size with
+          -Wstringop-truncation:
+          https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85643
+        */
+       DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION;
+#endif
+       strncpy (data + 44, psargs, 80);
+#if GCC_VERSION == 8000 || GCC_VERSION == 8001
+       DIAGNOSTIC_POP;
+#endif
+       return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+                                  &data, sizeof (data));
+      }
+
+    case NT_PRSTATUS:
+      {
+       char data[224] = { 0 };
+       long pid;
+       int cursig;
+       const void *gregs;
+
+       va_start (ap, note_type);
+       pid = va_arg (ap, long);
+       cursig = va_arg (ap, int);
+       gregs = va_arg (ap, const void *);
+       va_end (ap);
+
+       bfd_put_16 (abfd, cursig, data + 12);
+       bfd_put_32 (abfd, pid, data + 24);
+       memcpy (data + 72, gregs, 144);
+       return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+                                  &data, sizeof (data));
+      }
+    }
+  /* NOTREACHED */
+}
+\f
 /* Return address for Ith PLT stub in section PLT, for relocation REL
    or (bfd_vma) -1 if it should not be included.  */
 
 /* Return address for Ith PLT stub in section PLT, for relocation REL
    or (bfd_vma) -1 if it should not be included.  */
 
@@ -4027,12 +4006,14 @@ elf_s390_plt_sym_val (bfd_vma i, const asection *plt,
    object file when linking.  */
 
 static bfd_boolean
    object file when linking.  */
 
 static bfd_boolean
-elf32_s390_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+elf32_s390_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
 {
+  bfd *obfd = info->output_bfd;
+
   if (!is_s390_elf (ibfd) || !is_s390_elf (obfd))
     return TRUE;
 
   if (!is_s390_elf (ibfd) || !is_s390_elf (obfd))
     return TRUE;
 
-  if (!elf_s390_merge_obj_attributes (ibfd, obfd))
+  if (!elf_s390_merge_obj_attributes (ibfd, info))
     return FALSE;
 
   elf_elfheader (obfd)->e_flags |= elf_elfheader (ibfd)->e_flags;
     return FALSE;
 
   elf_elfheader (obfd)->e_flags |= elf_elfheader (ibfd)->e_flags;
@@ -4054,6 +4035,7 @@ elf32_s390_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
 #define elf_backend_got_header_size    12
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
 #define elf_backend_got_header_size    12
+#define elf_backend_want_dynrelro      1
 #define elf_backend_rela_normal                1
 
 #define elf_info_to_howto                    elf_s390_info_to_howto
 #define elf_backend_rela_normal                1
 
 #define elf_info_to_howto                    elf_s390_info_to_howto
@@ -4068,21 +4050,23 @@ elf32_s390_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 #define elf_backend_adjust_dynamic_symbol     elf_s390_adjust_dynamic_symbol
 #define elf_backend_check_relocs             elf_s390_check_relocs
 #define elf_backend_copy_indirect_symbol      elf_s390_copy_indirect_symbol
 #define elf_backend_adjust_dynamic_symbol     elf_s390_adjust_dynamic_symbol
 #define elf_backend_check_relocs             elf_s390_check_relocs
 #define elf_backend_copy_indirect_symbol      elf_s390_copy_indirect_symbol
-#define elf_backend_create_dynamic_sections   elf_s390_create_dynamic_sections
+#define elf_backend_create_dynamic_sections   _bfd_elf_create_dynamic_sections
 #define elf_backend_finish_dynamic_sections   elf_s390_finish_dynamic_sections
 #define elf_backend_finish_dynamic_symbol     elf_s390_finish_dynamic_symbol
 #define elf_backend_gc_mark_hook             elf_s390_gc_mark_hook
 #define elf_backend_finish_dynamic_sections   elf_s390_finish_dynamic_sections
 #define elf_backend_finish_dynamic_symbol     elf_s390_finish_dynamic_symbol
 #define elf_backend_gc_mark_hook             elf_s390_gc_mark_hook
-#define elf_backend_gc_sweep_hook            elf_s390_gc_sweep_hook
 #define elf_backend_reloc_type_class         elf_s390_reloc_type_class
 #define elf_backend_relocate_section         elf_s390_relocate_section
 #define elf_backend_size_dynamic_sections     elf_s390_size_dynamic_sections
 #define elf_backend_init_index_section       _bfd_elf_init_1_index_section
 #define elf_backend_grok_prstatus            elf_s390_grok_prstatus
 #define elf_backend_reloc_type_class         elf_s390_reloc_type_class
 #define elf_backend_relocate_section         elf_s390_relocate_section
 #define elf_backend_size_dynamic_sections     elf_s390_size_dynamic_sections
 #define elf_backend_init_index_section       _bfd_elf_init_1_index_section
 #define elf_backend_grok_prstatus            elf_s390_grok_prstatus
+#define elf_backend_grok_psinfo                      elf_s390_grok_psinfo
+#define elf_backend_write_core_note          elf_s390_write_core_note
 #define elf_backend_plt_sym_val                      elf_s390_plt_sym_val
 #define elf_backend_plt_sym_val                      elf_s390_plt_sym_val
-#define elf_backend_add_symbol_hook           elf_s390_add_symbol_hook
-#define elf_backend_sort_relocs_p             elf_s390_elf_sort_relocs_p
+#define elf_backend_sort_relocs_p            elf_s390_elf_sort_relocs_p
 
 #define bfd_elf32_mkobject             elf_s390_mkobject
 #define elf_backend_object_p           elf_s390_object_p
 
 
 #define bfd_elf32_mkobject             elf_s390_mkobject
 #define elf_backend_object_p           elf_s390_object_p
 
+#define elf_backend_linux_prpsinfo32_ugid16    TRUE
+
 #include "elf32-target.h"
 #include "elf32-target.h"
This page took 0.050492 seconds and 4 git commands to generate.