2012-03-30 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>
Fri, 30 Mar 2012 13:36:22 +0000 (13:36 +0000)
committerAndreas Krebbel <Andreas.Krebbel@de.ibm.com>
Fri, 30 Mar 2012 13:36:22 +0000 (13:36 +0000)
* elf64-s390.c (elf_s390x_plt_entry, elf_s390x_first_plt_entry):
New definitions.
(PLT_PIC_ENTRY_WORD*, PLT_PIC12_ENTRY_WORD*): Remove.
(elf_s390_finish_dynamic_symbol): Use memcpy instead of bfd_put_32.
(elf_s390_finish_dynamic_sections): Likewise.
* elf32-s390.c (elf_s390_plt_entry, elf_s390_plt_pic_entry)
(elf_s390_plt_pic12_entry, elf_s390_plt_pic16_entry)
(elf_s390_plt_first_entry, elf_s390_plt_pic_first_entry): New definitions.
(PLT_PIC16_ENTRY_WORD*, PLT_ENTRY_WORD*)
(PLT_PIC_FIRST_ENTRY_WORD*, PLT_FIRST_ENTRY_WORD*): Remove.

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

index d1fa9b0..31f21d7 100644 (file)
@@ -1,5 +1,18 @@
 2012-03-30  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
+       * elf64-s390.c (elf_s390x_plt_entry, elf_s390x_first_plt_entry):
+       New definitions.
+       (PLT_PIC_ENTRY_WORD*, PLT_PIC12_ENTRY_WORD*): Remove.
+       (elf_s390_finish_dynamic_symbol): Use memcpy instead of bfd_put_32.
+       (elf_s390_finish_dynamic_sections): Likewise.
+       * elf32-s390.c (elf_s390_plt_entry, elf_s390_plt_pic_entry)
+       (elf_s390_plt_pic12_entry, elf_s390_plt_pic16_entry)
+       (elf_s390_plt_first_entry, elf_s390_plt_pic_first_entry): New definitions.
+       (PLT_PIC16_ENTRY_WORD*, PLT_ENTRY_WORD*)
+       (PLT_PIC_FIRST_ENTRY_WORD*, PLT_FIRST_ENTRY_WORD*): Remove.
+
+2012-03-30  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
        * elf32-s390.c (struct elf_s390_dyn_relocs): Remove.
        Rename all occurrences in the file to elf_dyn_relocs.
        * elf64-s390.c: Likewise.
index 9dc68e7..58048be 100644 (file)
@@ -569,29 +569,65 @@ RET1: BASR 1,0         # 2 bytes  Return from GOT 1st time
       .long ?          # 4 bytes  address of GOT entry
       .long ?          # 4 bytes  offset into symbol table  */
 
-#define PLT_PIC_ENTRY_WORD0 0x0d105810
-#define PLT_PIC_ENTRY_WORD1 0x10165811
-#define PLT_PIC_ENTRY_WORD2 0xc00007f1
-#define PLT_PIC_ENTRY_WORD3 0x0d105810
-#define PLT_PIC_ENTRY_WORD4 0x100ea7f4
-
-#define PLT_PIC12_ENTRY_WORD0 0x5810c000
-#define PLT_PIC12_ENTRY_WORD1 0x07f10000
-#define PLT_PIC12_ENTRY_WORD2 0x00000000
-#define PLT_PIC12_ENTRY_WORD3 0x0d105810
-#define PLT_PIC12_ENTRY_WORD4 0x100ea7f4
-
-#define PLT_PIC16_ENTRY_WORD0 0xa7180000
-#define PLT_PIC16_ENTRY_WORD1 0x5811c000
-#define PLT_PIC16_ENTRY_WORD2 0x07f10000
-#define PLT_PIC16_ENTRY_WORD3 0x0d105810
-#define PLT_PIC16_ENTRY_WORD4 0x100ea7f4
-
-#define PLT_ENTRY_WORD0     0x0d105810
-#define PLT_ENTRY_WORD1     0x10165810
-#define PLT_ENTRY_WORD2     0x100007f1
-#define PLT_ENTRY_WORD3     0x0d105810
-#define PLT_ENTRY_WORD4     0x100ea7f4
+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     */
+  };
+
+/* 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         */
+  };
+
+/* 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              */
+    0x00, 0x00,
+    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
+  };
+
+/* Optimized PLT pic entry for GOT offset < 32k.  xx will be replaced
+   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             */
+    0x00, 0x00,
+    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
+  };
 
 /* The first PLT entry pushes the offset into the symbol table
    from R1 onto the stack at 8(15) and the loader object info
@@ -618,18 +654,31 @@ PLT0:
    .word 0            # filler
    .long got          # address of GOT  */
 
-#define PLT_PIC_FIRST_ENTRY_WORD0 0x5010f01c
-#define PLT_PIC_FIRST_ENTRY_WORD1 0x5810c004
-#define PLT_PIC_FIRST_ENTRY_WORD2 0x5010f018
-#define PLT_PIC_FIRST_ENTRY_WORD3 0x5810c008
-#define PLT_PIC_FIRST_ENTRY_WORD4 0x07f10000
-
-#define PLT_FIRST_ENTRY_WORD0     0x5010f01c
-#define PLT_FIRST_ENTRY_WORD1     0x0d105810
-#define PLT_FIRST_ENTRY_WORD2     0x1012D203
-#define PLT_FIRST_ENTRY_WORD3     0xf0181004
-#define PLT_FIRST_ENTRY_WORD4     0x58101008
-#define PLT_FIRST_ENTRY_WORD5     0x07f10000
+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               */
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00
+  };
+
+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           */
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00
+  };
 
 
 /* s390 ELF linker hash entry.  */
@@ -3107,18 +3156,14 @@ elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym)
       /* Fill in the entry in the procedure linkage table.  */
       if (!info->shared)
        {
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD0,
-                     htab->splt->contents + h->plt.offset);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD1,
-                     htab->splt->contents + h->plt.offset + 4);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD2,
-                     htab->splt->contents + h->plt.offset + 8);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD3,
-                     htab->splt->contents + h->plt.offset + 12);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD4,
-                     htab->splt->contents + h->plt.offset + 16);
+         memcpy (htab->splt->contents + h->plt.offset, elf_s390_plt_entry,
+                 PLT_ENTRY_SIZE);
+
+         /* Adjust jump to the first plt entry.  */
          bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
                      htab->splt->contents + h->plt.offset + 20);
+
+         /* Push the GOT offset field.  */
          bfd_put_32 (output_bfd,
                      (htab->sgotplt->output_section->vma
                       + htab->sgotplt->output_offset
@@ -3127,52 +3172,50 @@ elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym)
        }
       else if (got_offset < 4096)
        {
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC12_ENTRY_WORD0 + got_offset,
-                     htab->splt->contents + h->plt.offset);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC12_ENTRY_WORD1,
-                     htab->splt->contents + h->plt.offset + 4);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC12_ENTRY_WORD2,
-                     htab->splt->contents + h->plt.offset + 8);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC12_ENTRY_WORD3,
-                     htab->splt->contents + h->plt.offset + 12);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC12_ENTRY_WORD4,
-                     htab->splt->contents + h->plt.offset + 16);
+         /* The GOT offset is small enough to be used directly as
+            displacement.  */
+         memcpy (htab->splt->contents + h->plt.offset,
+                 elf_s390_plt_pic12_entry,
+                 PLT_ENTRY_SIZE);
+
+         /* 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.  */
+         bfd_put_16 (output_bfd, (bfd_vma)0xc000 | got_offset,
+                     htab->splt->contents + h->plt.offset + 2);
+
+         /* Adjust the jump to the first plt entry.  */
          bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
                      htab->splt->contents + h->plt.offset + 20);
-         bfd_put_32 (output_bfd, (bfd_vma) 0,
-                     htab->splt->contents + h->plt.offset + 24);
        }
       else if (got_offset < 32768)
        {
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC16_ENTRY_WORD0 + got_offset,
-                     htab->splt->contents + h->plt.offset);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC16_ENTRY_WORD1,
-                     htab->splt->contents + h->plt.offset + 4);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC16_ENTRY_WORD2,
-                     htab->splt->contents + h->plt.offset + 8);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC16_ENTRY_WORD3,
-                     htab->splt->contents + h->plt.offset + 12);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC16_ENTRY_WORD4,
-                     htab->splt->contents + h->plt.offset + 16);
+         /* The GOT offset is too big for a displacement but small
+            enough to be a signed 16 bit immediate value as it can be
+            used in an lhi instruction.  */
+         memcpy (htab->splt->contents + h->plt.offset,
+                 elf_s390_plt_pic16_entry,
+                 PLT_ENTRY_SIZE);
+
+         /* Put in the GOT offset for the lhi instruction.  */
+         bfd_put_16 (output_bfd, (bfd_vma)got_offset,
+                     htab->splt->contents + h->plt.offset + 2);
+
+         /* Adjust the jump to the first plt entry.  */
          bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
                      htab->splt->contents + h->plt.offset + 20);
-         bfd_put_32 (output_bfd, (bfd_vma) 0,
-                     htab->splt->contents + h->plt.offset + 24);
        }
       else
        {
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD0,
-                     htab->splt->contents + h->plt.offset);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD1,
-                     htab->splt->contents + h->plt.offset + 4);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD2,
-                     htab->splt->contents + h->plt.offset + 8);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD3,
-                     htab->splt->contents + h->plt.offset + 12);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD4,
-                     htab->splt->contents + h->plt.offset + 16);
+         memcpy (htab->splt->contents + h->plt.offset,
+                 elf_s390_plt_pic_entry,
+                 PLT_ENTRY_SIZE);
+
+         /* Adjust the jump to the first plt entry.  */
          bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
                      htab->splt->contents + h->plt.offset + 20);
+
+         /* Push the GOT offset field.  */
          bfd_put_32 (output_bfd, got_offset,
                      htab->splt->contents + h->plt.offset + 24);
        }
@@ -3367,31 +3410,13 @@ elf_s390_finish_dynamic_sections (output_bfd, info)
          memset (htab->splt->contents, 0, PLT_FIRST_ENTRY_SIZE);
          if (info->shared)
            {
-             bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD0,
-                         htab->splt->contents );
-             bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD1,
-                         htab->splt->contents +4 );
-             bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD2,
-                         htab->splt->contents +8 );
-             bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD3,
-                         htab->splt->contents +12 );
-             bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD4,
-                         htab->splt->contents +16 );
-          }
+             memcpy (htab->splt->contents, elf_s390_plt_pic_first_entry,
+                     PLT_FIRST_ENTRY_SIZE);
+           }
          else
-          {
-             bfd_put_32 (output_bfd, (bfd_vma)PLT_FIRST_ENTRY_WORD0,
-                         htab->splt->contents );
-             bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD1,
-                         htab->splt->contents +4 );
-             bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD2,
-                         htab->splt->contents +8 );
-             bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD3,
-                         htab->splt->contents +12 );
-             bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD4,
-                         htab->splt->contents +16 );
-             bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD5,
-                         htab->splt->contents +20 );
+           {
+             memcpy (htab->splt->contents, elf_s390_plt_first_entry,
+                     PLT_FIRST_ENTRY_SIZE);
              bfd_put_32 (output_bfd,
                          htab->sgotplt->output_section->vma
                          + htab->sgotplt->output_offset,
index fc9b7a6..118b052 100644 (file)
@@ -553,14 +553,16 @@ elf_s390_is_local_label_name (abfd, name)
    the program that manages to have a symbol table of more than 2 GB with a
    total size of at max 4 GB.  */
 
-#define PLT_ENTRY_WORD0     (bfd_vma) 0xc0100000
-#define PLT_ENTRY_WORD1     (bfd_vma) 0x0000e310
-#define PLT_ENTRY_WORD2     (bfd_vma) 0x10000004
-#define PLT_ENTRY_WORD3     (bfd_vma) 0x07f10d10
-#define PLT_ENTRY_WORD4     (bfd_vma) 0xe310100c
-#define PLT_ENTRY_WORD5     (bfd_vma) 0x0014c0f4
-#define PLT_ENTRY_WORD6     (bfd_vma) 0x00000000
-#define PLT_ENTRY_WORD7     (bfd_vma) 0x00000000
+static const bfd_byte elf_s390x_plt_entry[PLT_ENTRY_SIZE] =
+  {
+    0xc0, 0x10, 0x00, 0x00, 0x00, 0x00,     /* larl    %r1,.       */
+    0xe3, 0x10, 0x10, 0x00, 0x00, 0x04,     /* lg      %r1,0(%r1)  */
+    0x07, 0xf1,                             /* br      %r1         */
+    0x0d, 0x10,                             /* basr    %r1,%r0     */
+    0xe3, 0x10, 0x10, 0x0c, 0x00, 0x14,     /* lgf     %r1,12(%r1) */
+    0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00,     /* jg      first plt   */
+    0x00, 0x00, 0x00, 0x00                  /* .long   0x00000000  */
+  };
 
 /* The first PLT entry pushes the offset into the symbol table
    from R1 onto the stack at 8(15) and the loader object info
@@ -577,14 +579,17 @@ elf_s390_is_local_label_name (abfd, name)
 
      Fixup at offset 8: relative address to start of GOT.  */
 
-#define PLT_FIRST_ENTRY_WORD0     (bfd_vma) 0xe310f038
-#define PLT_FIRST_ENTRY_WORD1     (bfd_vma) 0x0024c010
-#define PLT_FIRST_ENTRY_WORD2     (bfd_vma) 0x00000000
-#define PLT_FIRST_ENTRY_WORD3     (bfd_vma) 0xd207f030
-#define PLT_FIRST_ENTRY_WORD4     (bfd_vma) 0x1008e310
-#define PLT_FIRST_ENTRY_WORD5     (bfd_vma) 0x10100004
-#define PLT_FIRST_ENTRY_WORD6     (bfd_vma) 0x07f10700
-#define PLT_FIRST_ENTRY_WORD7     (bfd_vma) 0x07000700
+static const bfd_byte elf_s390x_first_plt_entry[PLT_FIRST_ENTRY_SIZE] =
+  {
+    0xe3, 0x10, 0xf0, 0x38, 0x00, 0x24,     /* stg     %r1,56(%r15)      */
+    0xc0, 0x10, 0x00, 0x00, 0x00, 0x00,     /* larl    %r1,.             */
+    0xd2, 0x07, 0xf0, 0x30, 0x10, 0x08,     /* mvc     48(8,%r15),8(%r1) */
+    0xe3, 0x10, 0x10, 0x10, 0x00, 0x04,     /* lg      %r1,16(%r1)       */
+    0x07, 0xf1,                             /* br      %r1               */
+    0x07, 0x00,                             /* nopr    %r0               */
+    0x07, 0x00,                             /* nopr    %r0               */
+    0x07, 0x00                              /* nopr    %r0               */
+  };
 
 
 /* s390 ELF linker hash entry.  */
@@ -3052,22 +3057,9 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
       got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
 
       /* Fill in the blueprint of a PLT.  */
-      bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD0,
-                 htab->splt->contents + h->plt.offset);
-      bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD1,
-                 htab->splt->contents + h->plt.offset + 4);
-      bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD2,
-                 htab->splt->contents + h->plt.offset + 8);
-      bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD3,
-                 htab->splt->contents + h->plt.offset + 12);
-      bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD4,
-                 htab->splt->contents + h->plt.offset + 16);
-      bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD5,
-                 htab->splt->contents + h->plt.offset + 20);
-      bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD6,
-                 htab->splt->contents + h->plt.offset + 24);
-      bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD7,
-                 htab->splt->contents + h->plt.offset + 28);
+      memcpy (htab->splt->contents + h->plt.offset, elf_s390x_plt_entry,
+             PLT_ENTRY_SIZE);
+
       /* Fixup the relative address to the GOT entry */
       bfd_put_32 (output_bfd,
                  (htab->sgotplt->output_section->vma +
@@ -3280,20 +3272,8 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
       if (htab->splt && htab->splt->size > 0)
        {
          /* fill in blueprint for plt 0 entry */
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD0,
-                     htab->splt->contents );
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD1,
-                     htab->splt->contents +4 );
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD3,
-                     htab->splt->contents +12 );
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD4,
-                     htab->splt->contents +16 );
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD5,
-                     htab->splt->contents +20 );
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD6,
-                     htab->splt->contents + 24);
-         bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD7,
-                     htab->splt->contents + 28 );
+         memcpy (htab->splt->contents, elf_s390x_first_plt_entry,
+                 PLT_FIRST_ENTRY_SIZE);
          /* Fixup relative address to start of GOT */
          bfd_put_32 (output_bfd,
                      (htab->sgotplt->output_section->vma +