889b6e2
diff -rup binutils.orig/bfd/elf64-s390.c binutils-2.31.1/bfd/elf64-s390.c
889b6e2
--- binutils.orig/bfd/elf64-s390.c	2018-07-19 12:37:28.107030007 +0100
889b6e2
+++ binutils-2.31.1/bfd/elf64-s390.c	2018-07-19 12:38:11.235548717 +0100
889b6e2
@@ -481,7 +481,7 @@ elf_s390_is_local_label_name (bfd *abfd,
889b6e2
 
889b6e2
 #define RELA_ENTRY_SIZE sizeof (Elf64_External_Rela)
889b6e2
 
889b6e2
-/* The first three entries in a procedure linkage table are reserved,
889b6e2
+/* The first three entries in a global offset table are reserved,
889b6e2
    and the initial contents are unimportant (we zero them out).
889b6e2
    Subsequent entries look like this.  See the SVR4 ABI 386
889b6e2
    supplement to see how this works.  */
889b6e2
@@ -511,8 +511,8 @@ elf_s390_is_local_label_name (bfd *abfd,
889b6e2
 	 LG   1,0(1)	  # 6 bytes  Load address from GOT in r1
889b6e2
 	 BCR  15,1	  # 2 bytes  Jump to address
889b6e2
    RET1: BASR 1,0	  # 2 bytes  Return from GOT 1st time
889b6e2
-	 LGF  1,12(1)	  # 6 bytes  Load offset in symbl table in r1
889b6e2
-	 BRCL 15,-x	  # 6 bytes  Jump to start of PLT
889b6e2
+	 LGF  1,12(1)	  # 6 bytes  Load rela.plt offset into r1
889b6e2
+	 BRCL 15,-x	  # 6 bytes  Jump to first PLT entry
889b6e2
 	 .long ?	  # 4 bytes  offset into .rela.plt
889b6e2
 
889b6e2
    Total = 32 bytes per PLT entry
889b6e2
@@ -1605,8 +1605,7 @@ allocate_dynrelocs (struct elf_link_hash
889b6e2
 	  /* Make room for this entry.  */
889b6e2
 	  s->size += PLT_ENTRY_SIZE;
889b6e2
 
889b6e2
-	  /* We also need to make an entry in the .got.plt section, which
889b6e2
-	     will be placed in the .got section by the linker script.  */
889b6e2
+	  /* We also need to make an entry in the .got.plt section.  */
889b6e2
 	  htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
889b6e2
 
889b6e2
 	  /* We also need to make an entry in the .rela.plt section.  */
889b6e2
@@ -1831,6 +1830,20 @@ elf_s390_size_dynamic_sections (bfd *out
889b6e2
 	}
889b6e2
     }
889b6e2
 
889b6e2
+  if (htab->elf.sgot && s390_gotplt_after_got_p (info))
889b6e2
+    {
889b6e2
+      /* _bfd_elf_create_got_section adds the got header size always
889b6e2
+	 to .got.plt but we need it in .got if this section comes
889b6e2
+	 first.  */
889b6e2
+      htab->elf.sgot->size += 3 * GOT_ENTRY_SIZE;
889b6e2
+      htab->elf.sgotplt->size -= 3 * GOT_ENTRY_SIZE;
889b6e2
+
889b6e2
+      /* Make the _GLOBAL_OFFSET_TABLE_ symbol point to the .got
889b6e2
+	 instead of .got.plt.  */
889b6e2
+      htab->elf.hgot->root.u.def.section = htab->elf.sgot;
889b6e2
+      htab->elf.hgot->root.u.def.value = 0;
889b6e2
+    }
889b6e2
+
889b6e2
   /* Set up .got offsets for local syms, and space for local dynamic
889b6e2
      relocs.  */
889b6e2
   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
889b6e2
@@ -2131,7 +2144,6 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
       bfd_boolean unresolved_reloc;
889b6e2
       bfd_reloc_status_type r;
889b6e2
       int tls_type;
889b6e2
-      asection *base_got = htab->elf.sgot;
889b6e2
       bfd_boolean resolved_to_zero;
889b6e2
 
889b6e2
       r_type = ELF64_R_TYPE (rel->r_info);
889b6e2
@@ -2172,7 +2184,7 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 		case R_390_PLTOFF16:
889b6e2
 		case R_390_PLTOFF32:
889b6e2
 		case R_390_PLTOFF64:
889b6e2
-		  relocation -= htab->elf.sgot->output_section->vma;
889b6e2
+		  relocation -= s390_got_pointer (info);
889b6e2
 		  break;
889b6e2
 		case R_390_GOTPLT12:
889b6e2
 		case R_390_GOTPLT16:
889b6e2
@@ -2192,10 +2204,10 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 				htab->elf.sgot->contents +
889b6e2
 				local_got_offsets[r_symndx]);
889b6e2
 		    relocation = (local_got_offsets[r_symndx] +
889b6e2
-				  htab->elf.sgot->output_offset);
889b6e2
+				  s390_got_offset (info));
889b6e2
 
889b6e2
 		    if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT)
889b6e2
-		      relocation += htab->elf.sgot->output_section->vma;
889b6e2
+		      relocation += s390_got_pointer (info);
889b6e2
 		    break;
889b6e2
 		  }
889b6e2
 		default:
889b6e2
@@ -2254,25 +2266,23 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 
889b6e2
 	      if (s390_is_ifunc_symbol_p (h))
889b6e2
 		{
889b6e2
+		  /* Entry indices of .iplt and .igot.plt match
889b6e2
+		     1:1. No magic PLT first entry here.  */
889b6e2
 		  plt_index = h->plt.offset / PLT_ENTRY_SIZE;
889b6e2
-		  relocation = (plt_index * GOT_ENTRY_SIZE +
889b6e2
-				htab->elf.igotplt->output_offset);
889b6e2
-		  if (r_type == R_390_GOTPLTENT)
889b6e2
-		    relocation += htab->elf.igotplt->output_section->vma;
889b6e2
+		  relocation = (plt_index * GOT_ENTRY_SIZE
889b6e2
+				+ s390_gotplt_offset (info)
889b6e2
+				+ htab->elf.igotplt->output_offset);
889b6e2
 		}
889b6e2
 	      else
889b6e2
 		{
889b6e2
-		  /* Calc. index no.
889b6e2
-		     Current offset - size first entry / entry size.  */
889b6e2
-		  plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) /
889b6e2
-		    PLT_ENTRY_SIZE;
889b6e2
-
889b6e2
-		  /* Offset in GOT is PLT index plus GOT headers(3)
889b6e2
-		     times 8, addr & GOT addr.  */
889b6e2
-		  relocation = (plt_index + 3) * GOT_ENTRY_SIZE;
889b6e2
-		  if (r_type == R_390_GOTPLTENT)
889b6e2
-		    relocation += htab->elf.sgot->output_section->vma;
889b6e2
+		  plt_index = ((h->plt.offset - PLT_FIRST_ENTRY_SIZE)
889b6e2
+			       / PLT_ENTRY_SIZE);
889b6e2
+
889b6e2
+		  relocation = (plt_index * GOT_ENTRY_SIZE
889b6e2
+				+ s390_gotplt_offset (info));
889b6e2
 		}
889b6e2
+	      if (r_type == R_390_GOTPLTENT)
889b6e2
+		relocation += s390_got_pointer (info);
889b6e2
 	      unresolved_reloc = FALSE;
889b6e2
 	      break;
889b6e2
 	    }
889b6e2
@@ -2286,7 +2296,7 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 	case R_390_GOTENT:
889b6e2
 	  /* Relocation is to the entry for this symbol in the global
889b6e2
 	     offset table.  */
889b6e2
-	  if (base_got == NULL)
889b6e2
+	  if (htab->elf.sgot == NULL)
889b6e2
 	    abort ();
889b6e2
 
889b6e2
 	  if (h != NULL)
889b6e2
@@ -2303,8 +2313,19 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 		    {
889b6e2
 		      /* No explicit GOT usage so redirect to the
889b6e2
 			 got.iplt slot.  */
889b6e2
-		      base_got = htab->elf.igotplt;
889b6e2
-		      off = h->plt.offset / PLT_ENTRY_SIZE * GOT_ENTRY_SIZE;
889b6e2
+		      relocation = (s390_gotplt_offset (info)
889b6e2
+				    + htab->elf.igotplt->output_offset
889b6e2
+				    + (h->plt.offset / PLT_ENTRY_SIZE
889b6e2
+				       * GOT_ENTRY_SIZE));
889b6e2
+
889b6e2
+		      /* For @GOTENT the relocation is against the offset between
889b6e2
+			 the instruction and the symbols entry in the GOT and not
889b6e2
+			 between the start of the GOT and the symbols entry. We
889b6e2
+			 add the vma of the GOT to get the correct value.  */
889b6e2
+		      if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT)
889b6e2
+			relocation += s390_got_pointer (info);
889b6e2
+
889b6e2
+		      break;
889b6e2
 		    }
889b6e2
 		  else
889b6e2
 		    {
889b6e2
@@ -2337,7 +2358,7 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 		  else
889b6e2
 		    {
889b6e2
 		      bfd_put_64 (output_bfd, relocation,
889b6e2
-				  base_got->contents + off);
889b6e2
+				  htab->elf.sgot->contents + off);
889b6e2
 		      h->got.offset |= 1;
889b6e2
 		    }
889b6e2
 
889b6e2
@@ -2419,7 +2440,7 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 	  if (off >= (bfd_vma) -2)
889b6e2
 	    abort ();
889b6e2
 
889b6e2
-	  relocation = base_got->output_offset + off;
889b6e2
+	  relocation = s390_got_offset (info) + off;
889b6e2
 
889b6e2
 	  /* For @GOTENT the relocation is against the offset between
889b6e2
 	     the instruction and the symbols entry in the GOT and not
889b6e2
@@ -2427,7 +2448,7 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 	     add the vma of the GOT to get the correct value.  */
889b6e2
 	  if (   r_type == R_390_GOTENT
889b6e2
 	      || r_type == R_390_GOTPLTENT)
889b6e2
-	    relocation += base_got->output_section->vma;
889b6e2
+	    relocation += s390_got_pointer (info);
889b6e2
 
889b6e2
 	  break;
889b6e2
 
889b6e2
@@ -2445,22 +2466,17 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 	      relocation = (htab->elf.iplt->output_section->vma
889b6e2
 			    + htab->elf.iplt->output_offset
889b6e2
 			    + h->plt.offset
889b6e2
-			    - htab->elf.sgot->output_section->vma);
889b6e2
+			    - s390_got_pointer (info));
889b6e2
 	      goto do_relocation;
889b6e2
 	    }
889b6e2
 
889b6e2
-	  /* Note that sgot->output_offset is not involved in this
889b6e2
-	     calculation.  We always want the start of .got.  If we
889b6e2
-	     defined _GLOBAL_OFFSET_TABLE in a different way, as is
889b6e2
-	     permitted by the ABI, we might have to change this
889b6e2
-	     calculation.  */
889b6e2
-	  relocation -= htab->elf.sgot->output_section->vma;
889b6e2
+	  relocation -= s390_got_pointer (info);
889b6e2
 	  break;
889b6e2
 
889b6e2
 	case R_390_GOTPC:
889b6e2
 	case R_390_GOTPCDBL:
889b6e2
 	  /* Use global offset table as symbol value.  */
889b6e2
-	  relocation = htab->elf.sgot->output_section->vma;
889b6e2
+	  relocation = s390_got_pointer (info);
889b6e2
 	  unresolved_reloc = FALSE;
889b6e2
 	  break;
889b6e2
 
889b6e2
@@ -2509,7 +2525,7 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 	      || h->plt.offset == (bfd_vma) -1
889b6e2
 	      || (htab->elf.splt == NULL && !s390_is_ifunc_symbol_p (h)))
889b6e2
 	    {
889b6e2
-	      relocation -= htab->elf.sgot->output_section->vma;
889b6e2
+	      relocation -= s390_got_pointer (info);
889b6e2
 	      break;
889b6e2
 	    }
889b6e2
 
889b6e2
@@ -2517,12 +2533,12 @@ elf_s390_relocate_section (bfd *output_b
889b6e2
 	    relocation = (htab->elf.iplt->output_section->vma
889b6e2
 			  + htab->elf.iplt->output_offset
889b6e2
 			  + h->plt.offset
889b6e2
-			  - htab->elf.sgot->output_section->vma);
889b6e2
+			  - s390_got_pointer (info));
889b6e2
 	  else
889b6e2
 	    relocation = (htab->elf.splt->output_section->vma
889b6e2
 			  + htab->elf.splt->output_offset
889b6e2
 			  + h->plt.offset
889b6e2
-			  - htab->elf.sgot->output_section->vma);
889b6e2
+			  - s390_got_pointer (info));
889b6e2
 	  unresolved_reloc = FALSE;
889b6e2
 	  break;
889b6e2
 
889b6e2
@@ -3296,7 +3312,7 @@ elf_s390_finish_dynamic_symbol (bfd *out
889b6e2
   if (h->plt.offset != (bfd_vma) -1)
889b6e2
     {
889b6e2
       bfd_vma plt_index;
889b6e2
-      bfd_vma got_offset;
889b6e2
+      bfd_vma gotplt_offset;
889b6e2
       Elf_Internal_Rela rela;
889b6e2
       bfd_byte *loc;
889b6e2
 
889b6e2
@@ -3325,18 +3341,25 @@ elf_s390_finish_dynamic_symbol (bfd *out
889b6e2
 	     Current offset - size first entry / entry size.  */
889b6e2
 	  plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE;
889b6e2
 
889b6e2
-	  /* Offset in GOT is PLT index plus GOT headers(3) times 8,
889b6e2
-	     addr & GOT addr.  */
889b6e2
-	  got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
889b6e2
+	  /* The slots in the .got.plt correspond to the PLT slots in
889b6e2
+	     the same order.  */
889b6e2
+	  gotplt_offset = plt_index * GOT_ENTRY_SIZE;
889b6e2
+
889b6e2
+	  /* If .got.plt comes first it needs to contain the 3 header
889b6e2
+	     entries.  */
889b6e2
+	  if (!s390_gotplt_after_got_p (info))
889b6e2
+	    gotplt_offset += 3 * GOT_ENTRY_SIZE;
889b6e2
 
889b6e2
 	  /* Fill in the blueprint of a PLT.  */
889b6e2
 	  memcpy (htab->elf.splt->contents + h->plt.offset, elf_s390x_plt_entry,
889b6e2
 		  PLT_ENTRY_SIZE);
889b6e2
 
889b6e2
-	  /* Fixup the relative address to the GOT entry */
889b6e2
+	  /* The first instruction in the PLT entry is a LARL loading
889b6e2
+	     the address of the GOT slot.  We write the 4 byte
889b6e2
+	     immediate operand of the LARL instruction here.  */
889b6e2
 	  bfd_put_32 (output_bfd,
889b6e2
 		      (htab->elf.sgotplt->output_section->vma +
889b6e2
-		       htab->elf.sgotplt->output_offset + got_offset
889b6e2
+		       htab->elf.sgotplt->output_offset + gotplt_offset
889b6e2
 		       - (htab->elf.splt->output_section->vma +
889b6e2
 			  htab->elf.splt->output_offset +
889b6e2
 			  h->plt.offset))/2,
889b6e2
@@ -3356,12 +3379,12 @@ elf_s390_finish_dynamic_symbol (bfd *out
889b6e2
 		       + htab->elf.splt->output_offset
889b6e2
 		       + h->plt.offset
889b6e2
 		       + 14),
889b6e2
-		      htab->elf.sgotplt->contents + got_offset);
889b6e2
+		      htab->elf.sgotplt->contents + gotplt_offset);
889b6e2
 
889b6e2
 	  /* Fill in the entry in the .rela.plt section.  */
889b6e2
 	  rela.r_offset = (htab->elf.sgotplt->output_section->vma
889b6e2
 			   + htab->elf.sgotplt->output_offset
889b6e2
-			   + got_offset);
889b6e2
+			   + gotplt_offset);
889b6e2
 	  rela.r_info = ELF64_R_INFO (h->dynindx, R_390_JMP_SLOT);
889b6e2
 	  rela.r_addend = 0;
889b6e2
 	  loc = htab->elf.srelplt->contents + plt_index *
889b6e2
@@ -3568,8 +3591,8 @@ elf_s390_finish_dynamic_sections (bfd *o
889b6e2
 	      continue;
889b6e2
 
889b6e2
 	    case DT_PLTGOT:
889b6e2
-	      s = htab->elf.sgotplt;
889b6e2
-	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
889b6e2
+	      /* DT_PLTGOT matches _GLOBAL_OFFSET_TABLE_ */
889b6e2
+	      dyn.d_un.d_ptr = s390_got_pointer (info);
889b6e2
 	      break;
889b6e2
 
889b6e2
 	    case DT_JMPREL:
889b6e2
@@ -3606,10 +3629,11 @@ elf_s390_finish_dynamic_sections (bfd *o
889b6e2
 	  /* fill in blueprint for plt 0 entry */
889b6e2
 	  memcpy (htab->elf.splt->contents, elf_s390x_first_plt_entry,
889b6e2
 		  PLT_FIRST_ENTRY_SIZE);
889b6e2
-	  /* Fixup relative address to start of GOT */
889b6e2
+	  /* The second instruction in the first PLT entry is a LARL
889b6e2
+	     loading the GOT pointer.  Fill in the LARL immediate
889b6e2
+	     address.  */
889b6e2
 	  bfd_put_32 (output_bfd,
889b6e2
-		      (htab->elf.sgotplt->output_section->vma
889b6e2
-		       + htab->elf.sgotplt->output_offset
889b6e2
+		      (s390_got_pointer (info)
889b6e2
 		       - htab->elf.splt->output_section->vma
889b6e2
 		       - htab->elf.splt->output_offset - 6)/2,
889b6e2
 		      htab->elf.splt->contents + 8);
889b6e2
@@ -3619,21 +3643,22 @@ elf_s390_finish_dynamic_sections (bfd *o
889b6e2
 	  = PLT_ENTRY_SIZE;
889b6e2
     }
889b6e2
 
889b6e2
-  if (htab->elf.sgotplt)
889b6e2
+  if (htab->elf.hgot && htab->elf.hgot->root.u.def.section)
889b6e2
     {
889b6e2
       /* Fill in the first three entries in the global offset table.  */
889b6e2
-      if (htab->elf.sgotplt->size > 0)
889b6e2
+      if (htab->elf.hgot->root.u.def.section->size > 0)
889b6e2
 	{
889b6e2
 	  bfd_put_64 (output_bfd,
889b6e2
 		      (sdyn == NULL ? (bfd_vma) 0
889b6e2
 		       : sdyn->output_section->vma + sdyn->output_offset),
889b6e2
-		      htab->elf.sgotplt->contents);
889b6e2
+		      htab->elf.hgot->root.u.def.section->contents);
889b6e2
 	  /* One entry for shared object struct ptr.  */
889b6e2
-	  bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 8);
889b6e2
+	  bfd_put_64 (output_bfd, (bfd_vma) 0,
889b6e2
+		      htab->elf.hgot->root.u.def.section->contents + 8);
889b6e2
 	  /* One entry for _dl_runtime_resolve.  */
889b6e2
-	  bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 16);
889b6e2
+	  bfd_put_64 (output_bfd, (bfd_vma) 0,
889b6e2
+		      htab->elf.hgot->root.u.def.section->contents + 16);
889b6e2
 	}
889b6e2
-
889b6e2
       elf_section_data (htab->elf.sgot->output_section)
889b6e2
 	->this_hdr.sh_entsize = 8;
889b6e2
     }
889b6e2
diff -rup binutils.orig/bfd/elf-s390-common.c binutils-2.31.1/bfd/elf-s390-common.c
889b6e2
--- binutils.orig/bfd/elf-s390-common.c	2018-07-19 12:37:28.113029940 +0100
889b6e2
+++ binutils-2.31.1/bfd/elf-s390-common.c	2018-07-19 12:38:11.235548717 +0100
889b6e2
@@ -30,6 +30,87 @@ s390_is_ifunc_symbol_p (struct elf_link_
889b6e2
   return h->type == STT_GNU_IFUNC || eh->ifunc_resolver_address != 0;
889b6e2
 }
889b6e2
 
889b6e2
+/* Return true if .got.plt is supposed to be emitted after .got.  */
889b6e2
+
889b6e2
+static inline bfd_boolean
889b6e2
+s390_gotplt_after_got_p (struct bfd_link_info *info)
889b6e2
+{
889b6e2
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
889b6e2
+
889b6e2
+  if (!htab->elf.sgot || !htab->elf.sgotplt)
889b6e2
+    return TRUE;
889b6e2
+
889b6e2
+  if (htab->elf.sgot->output_section == htab->elf.sgotplt->output_section)
889b6e2
+    {
889b6e2
+      if (htab->elf.sgot->output_offset < htab->elf.sgotplt->output_offset)
889b6e2
+	return TRUE;
889b6e2
+    }
889b6e2
+  else
889b6e2
+    {
889b6e2
+      if (htab->elf.sgot->output_section->vma
889b6e2
+	  <= htab->elf.sgotplt->output_section->vma)
889b6e2
+	return TRUE;
889b6e2
+    }
889b6e2
+  return FALSE;
889b6e2
+}
889b6e2
+
889b6e2
+/* Return the value of the _GLOBAL_OFFSET_TABLE_ symbol.  */
889b6e2
+
889b6e2
+static inline bfd_vma
889b6e2
+s390_got_pointer (struct bfd_link_info *info)
889b6e2
+{
889b6e2
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
889b6e2
+  bfd_vma got_pointer;
889b6e2
+
889b6e2
+  BFD_ASSERT (htab && htab->elf.hgot);
889b6e2
+
889b6e2
+  got_pointer = (htab->elf.hgot->root.u.def.section->output_section->vma
889b6e2
+		 + htab->elf.hgot->root.u.def.section->output_offset);
889b6e2
+  /* Our ABI requires the GOT pointer to point at the very beginning
889b6e2
+     of the global offset table.  */
889b6e2
+  BFD_ASSERT (got_pointer
889b6e2
+	      <= (htab->elf.sgot->output_section->vma
889b6e2
+		  + htab->elf.sgot->output_offset));
889b6e2
+  BFD_ASSERT (got_pointer
889b6e2
+	      <= (htab->elf.sgotplt->output_section->vma
889b6e2
+		  + htab->elf.sgotplt->output_offset));
889b6e2
+
889b6e2
+  return got_pointer;
889b6e2
+}
889b6e2
+
889b6e2
+
889b6e2
+/* Return the offset of the .got versus _GLOBAL_OFFSET_TABLE_.  */
889b6e2
+
889b6e2
+static inline bfd_vma
889b6e2
+s390_got_offset (struct bfd_link_info *info)
889b6e2
+{
889b6e2
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
889b6e2
+
889b6e2
+  /* The absolute address of the .got in the target image.  */
889b6e2
+  bfd_vma got_address = (htab->elf.sgot->output_section->vma
889b6e2
+			 + htab->elf.sgot->output_offset);
889b6e2
+
889b6e2
+  /* GOT offset must not be negative.  */
889b6e2
+  BFD_ASSERT (s390_got_pointer (info) <= got_address);
889b6e2
+  return got_address - s390_got_pointer (info);
889b6e2
+}
889b6e2
+
889b6e2
+/* Return the offset of the .got.plt versus _GLOBAL_OFFSET_TABLE_.  */
889b6e2
+
889b6e2
+static inline bfd_vma
889b6e2
+s390_gotplt_offset (struct bfd_link_info *info)
889b6e2
+{
889b6e2
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
889b6e2
+
889b6e2
+  /* The absolute address of the .got.plt in the target image.  */
889b6e2
+  bfd_vma gotplt_address = (htab->elf.sgotplt->output_section->vma
889b6e2
+			    + htab->elf.sgotplt->output_offset);
889b6e2
+
889b6e2
+  /* GOT offset must not be negative.  */
889b6e2
+  BFD_ASSERT (s390_got_pointer (info) <= gotplt_address);
889b6e2
+  return gotplt_address - s390_got_pointer (info);
889b6e2
+}
889b6e2
+
889b6e2
 /* Create sections needed by STT_GNU_IFUNC symbol.  */
889b6e2
 
889b6e2
 static bfd_boolean
889b6e2
diff -rup binutils.orig/ld/emulparams/elf64_s390.sh binutils-2.31.1/ld/emulparams/elf64_s390.sh
889b6e2
--- binutils.orig/ld/emulparams/elf64_s390.sh	2018-07-19 12:37:28.544025130 +0100
889b6e2
+++ binutils-2.31.1/ld/emulparams/elf64_s390.sh	2018-07-19 12:38:11.235548717 +0100
889b6e2
@@ -11,9 +11,12 @@ NOP=0x07070707
889b6e2
 TEMPLATE_NAME=elf32
889b6e2
 GENERATE_SHLIB_SCRIPT=yes
889b6e2
 GENERATE_PIE_SCRIPT=yes
889b6e2
+GENERATE_RELRO_SCRIPT=yes
889b6e2
 NO_SMALL_DATA=yes
889b6e2
 EXTRA_EM_FILE=s390
889b6e2
 IREL_IN_PLT=
889b6e2
+SEPARATE_GOTPLT=0
889b6e2
+test -z "$RELRO" && unset SEPARATE_GOTPLT
889b6e2
 
889b6e2
 # Treat a host that matches the target with the possible exception of "x"
889b6e2
 # in the name as if it were native.
889b6e2
diff -rup binutils.orig/ld/emultempl/elf32.em binutils-2.31.1/ld/emultempl/elf32.em
889b6e2
--- binutils.orig/ld/emultempl/elf32.em	2018-07-19 12:37:28.549025074 +0100
889b6e2
+++ binutils-2.31.1/ld/emultempl/elf32.em	2018-07-19 12:37:39.041907980 +0100
889b6e2
@@ -2376,17 +2376,41 @@ echo '             && link_info.combrelo
889b6e2
 echo '             && link_info.relro'			>> e${EMULATION_NAME}.c
889b6e2
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xdw			>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xdceo              >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 echo '  ; else if (bfd_link_pie (&link_info)'		>> e${EMULATION_NAME}.c
889b6e2
 echo '             && link_info.separate_code'		>> e${EMULATION_NAME}.c
889b6e2
 echo '             && link_info.combreloc) return'	>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xdce		>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xdco               >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 echo '  ; else if (bfd_link_pie (&link_info)'		>> e${EMULATION_NAME}.c
889b6e2
 echo '             && link_info.combreloc) return'	>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xdc			>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xdeo               >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 fi
889b6e2
 echo '  ; else if (bfd_link_pie (&link_info)'		>> e${EMULATION_NAME}.c
889b6e2
 echo '             && link_info.separate_code) return'	>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xde			>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xdo                >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 echo '  ; else if (bfd_link_pie (&link_info)) return'	>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xd			>> e${EMULATION_NAME}.c
889b6e2
 fi
889b6e2
@@ -2402,17 +2426,41 @@ echo '             && link_info.combrelo
889b6e2
 echo '             && link_info.relro'			>> e${EMULATION_NAME}.c
889b6e2
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xsw			>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xsceo              >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 echo '  ; else if (bfd_link_dll (&link_info)'		>> e${EMULATION_NAME}.c
889b6e2
 echo '             && link_info.combreloc'		>> e${EMULATION_NAME}.c
889b6e2
 echo '             && link_info.separate_code) return'	>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xsce			>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xsco               >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 echo '  ; else if (bfd_link_dll (&link_info)'		>> e${EMULATION_NAME}.c
889b6e2
 echo '             && link_info.combreloc) return'	>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xsc			>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xseo               >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 fi
889b6e2
 echo '  ; else if (bfd_link_dll (&link_info)'		>> e${EMULATION_NAME}.c
889b6e2
 echo '             && link_info.separate_code) return'	>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xse			>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xso               >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 echo '  ; else if (bfd_link_dll (&link_info)) return'	>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xs			>> e${EMULATION_NAME}.c
889b6e2
 fi
889b6e2
@@ -2425,14 +2473,34 @@ echo '  ; else if (link_info.combreloc'
889b6e2
 echo '             && link_info.relro'			>> e${EMULATION_NAME}.c
889b6e2
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xw			>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (link_info.combreloc'                 >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.separate_code'		>> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'          >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xceo                >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 echo '  ; else if (link_info.combreloc'			>> e${EMULATION_NAME}.c
889b6e2
 echo '             && link_info.separate_code) return'	>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xce			>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (link_info.combreloc'                 >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'          >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xco                 >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 echo '  ; else if (link_info.combreloc) return'		>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xc			>> e${EMULATION_NAME}.c
889b6e2
 fi
889b6e2
-echo '  ; else if (link_info.separate_code) return'		>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (link_info.separate_code'             >> e${EMULATION_NAME}.c
889b6e2
+echo '             && link_info.relro) return'          >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xeo                 >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
+echo '  ; else if (link_info.separate_code) return'     >> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.xe			>> e${EMULATION_NAME}.c
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+echo '  ; else if (link_info.relro) return'             >> e${EMULATION_NAME}.c
889b6e2
+sed $sc ldscripts/${EMULATION_NAME}.xo                  >> e${EMULATION_NAME}.c
889b6e2
+fi
889b6e2
 echo '  ; else return'					>> e${EMULATION_NAME}.c
889b6e2
 sed $sc ldscripts/${EMULATION_NAME}.x			>> e${EMULATION_NAME}.c
889b6e2
 echo '; }'						>> e${EMULATION_NAME}.c
889b6e2
@@ -2471,6 +2539,21 @@ fragment <
889b6e2
       else
889b6e2
 	return "ldscripts/${EMULATION_NAME}.xdw";
889b6e2
     }
889b6e2
+EOF
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+fragment <
889b6e2
+  else if (bfd_link_pie (&link_info)
889b6e2
+	   && link_info.combreloc
889b6e2
+	   && link_info.relro)
889b6e2
+    {
889b6e2
+      if (link_info.separate_code)
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xdceo";
889b6e2
+      else
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xdco";
889b6e2
+    }
889b6e2
+EOF
889b6e2
+fi
889b6e2
+fragment <
889b6e2
   else if (bfd_link_pie (&link_info)
889b6e2
 	   && link_info.combreloc)
889b6e2
     {
889b6e2
@@ -2481,6 +2564,18 @@ fragment <
889b6e2
     }
889b6e2
 EOF
889b6e2
 fi
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+fragment <
889b6e2
+  else if (bfd_link_pie (&link_info)
889b6e2
+	   && link_info.relro)
889b6e2
+    {
889b6e2
+      if (link_info.separate_code)
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xdeo";
889b6e2
+      else
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xdo";
889b6e2
+    }
889b6e2
+EOF
889b6e2
+fi
889b6e2
 fragment <
889b6e2
   else if (bfd_link_pie (&link_info))
889b6e2
     {
889b6e2
@@ -2502,6 +2597,21 @@ fragment <
889b6e2
       else
889b6e2
 	return "ldscripts/${EMULATION_NAME}.xsw";
889b6e2
     }
889b6e2
+EOF
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+fragment <
889b6e2
+  else if (bfd_link_dll (&link_info)
889b6e2
+	   && link_info.combreloc
889b6e2
+	   && link_info.relro)
889b6e2
+    {
889b6e2
+      if (link_info.separate_code)
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xsceo";
889b6e2
+      else
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xsco";
889b6e2
+    }
889b6e2
+EOF
889b6e2
+fi
889b6e2
+fragment <
889b6e2
   else if (bfd_link_dll (&link_info) && link_info.combreloc)
889b6e2
     {
889b6e2
       if (link_info.separate_code)
889b6e2
@@ -2511,6 +2621,18 @@ fragment <
889b6e2
     }
889b6e2
 EOF
889b6e2
 fi
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+fragment <
889b6e2
+  else if (bfd_link_dll (&link_info)
889b6e2
+	   && link_info.relro)
889b6e2
+    {
889b6e2
+      if (link_info.separate_code)
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xseo";
889b6e2
+      else
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xso";
889b6e2
+    }
889b6e2
+EOF
889b6e2
+fi
889b6e2
 fragment <
889b6e2
   else if (bfd_link_dll (&link_info))
889b6e2
     {
889b6e2
@@ -2531,6 +2653,20 @@ fragment <
889b6e2
       else
889b6e2
 	return "ldscripts/${EMULATION_NAME}.xw";
889b6e2
     }
889b6e2
+EOF
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+fragment <
889b6e2
+  else if (link_info.combreloc
889b6e2
+	   && link_info.relro)
889b6e2
+    {
889b6e2
+      if (link_info.separate_code)
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xceo";
889b6e2
+      else
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xco";
889b6e2
+    }
889b6e2
+EOF
889b6e2
+fi
889b6e2
+fragment <
889b6e2
   else if (link_info.combreloc)
889b6e2
     {
889b6e2
       if (link_info.separate_code)
889b6e2
@@ -2540,6 +2676,17 @@ fragment <
889b6e2
     }
889b6e2
 EOF
889b6e2
 fi
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
889b6e2
+fragment <
889b6e2
+  else if (link_info.relro)
889b6e2
+    {
889b6e2
+      if (link_info.separate_code)
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xeo";
889b6e2
+      else
889b6e2
+	return "ldscripts/${EMULATION_NAME}.xo";
889b6e2
+    }
889b6e2
+EOF
889b6e2
+fi
889b6e2
 fragment <
889b6e2
   else
889b6e2
     {
889b6e2
diff -rup binutils.orig/ld/genscripts.sh binutils-2.31.1/ld/genscripts.sh
889b6e2
--- binutils.orig/ld/genscripts.sh	2018-07-19 12:37:28.540025175 +0100
889b6e2
+++ binutils-2.31.1/ld/genscripts.sh	2018-07-19 12:37:39.041907980 +0100
889b6e2
@@ -306,6 +306,20 @@ LD_FLAG=textonly
889b6e2
   . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
 ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xe
889b6e2
 
889b6e2
+if test -n "$GENERATE_RELRO_SCRIPT"; then
889b6e2
+    LD_FLAG=
889b6e2
+    RELRO=" "
889b6e2
+    ( echo "/* Script for -z relo: generate normal executables with separate code segment */"
889b6e2
+      . ${CUSTOMIZER_SCRIPT}
889b6e2
+      . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+    ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xo
889b6e2
+    LD_FLAG=textonly
889b6e2
+    ( echo "/* Script for -z separate-code -z relo: generate normal executables with separate code segment */"
889b6e2
+      . ${CUSTOMIZER_SCRIPT}
889b6e2
+      . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+    ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xeo
889b6e2
+    unset RELRO
889b6e2
+fi
889b6e2
 LD_FLAG=n
889b6e2
 DATA_ALIGNMENT=${DATA_ALIGNMENT_n}
889b6e2
 ( echo "/* Script for -n: mix text and data on same page */"
889b6e2
@@ -353,6 +367,25 @@ if test -n "$GENERATE_COMBRELOC_SCRIPT";
889b6e2
   rm -f ${COMBRELOC}
889b6e2
   COMBRELOC=
889b6e2
   unset RELRO_NOW
889b6e2
+  if test -n "$GENERATE_RELRO_SCRIPT"; then
889b6e2
+      LD_FLAG=c
889b6e2
+      RELRO=" "
889b6e2
+      COMBRELOC=ldscripts/${EMULATION_NAME}.xco.tmp
889b6e2
+      ( echo "/* Script for -z combreloc -z relro: combine and sort reloc sections */"
889b6e2
+	. ${CUSTOMIZER_SCRIPT}
889b6e2
+	. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+      ) | sed -e '/^ *$/d;s/[    ]*$//' > ldscripts/${EMULATION_NAME}.xco
889b6e2
+      rm -f ${COMBRELOC}
889b6e2
+      LD_FLAG=ctextonly
889b6e2
+      COMBRELOC=ldscripts/${EMULATION_NAME}.xceo.tmp
889b6e2
+      ( echo "/* Script for -z combreloc -z separate-code -z relro: combine and sort reloc sections */"
889b6e2
+	. ${CUSTOMIZER_SCRIPT}
889b6e2
+	. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+      ) | sed -e '/^ *$/d;s/[    ]*$//' > ldscripts/${EMULATION_NAME}.xceo
889b6e2
+      rm -f ${COMBRELOC}
889b6e2
+      COMBRELOC=
889b6e2
+      unset RELRO
889b6e2
+  fi
889b6e2
 fi
889b6e2
 
889b6e2
 if test -n "$GENERATE_SHLIB_SCRIPT"; then
889b6e2
@@ -370,6 +403,23 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; the
889b6e2
     . ${CUSTOMIZER_SCRIPT}
889b6e2
     . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
   ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xse
889b6e2
+
889b6e2
+  if test -n "$GENERATE_RELRO_SCRIPT"; then
889b6e2
+      RELRO=" "
889b6e2
+      LD_FLAG=shared
889b6e2
+      (
889b6e2
+	  echo "/* Script for ld --shared -z relro: link shared library */"
889b6e2
+	  . ${CUSTOMIZER_SCRIPT}
889b6e2
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+      ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xso
889b6e2
+      LD_FLAG=sharedtextonly
889b6e2
+      (
889b6e2
+	  echo "/* Script for ld --shared -z relro -z separate-code: link shared library with separate code segment */"
889b6e2
+	  . ${CUSTOMIZER_SCRIPT}
889b6e2
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+      ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xseo
889b6e2
+      unset RELRO
889b6e2
+  fi
889b6e2
   if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
889b6e2
     DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}}
889b6e2
     LD_FLAG=cshared
889b6e2
@@ -401,8 +451,27 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; the
889b6e2
       . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
     ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xswe
889b6e2
     rm -f ${COMBRELOC}
889b6e2
-    COMBRELOC=
889b6e2
     unset RELRO_NOW
889b6e2
+
889b6e2
+    if test -n "$GENERATE_RELRO_SCRIPT"; then
889b6e2
+	LD_FLAG=wshared
889b6e2
+	RELRO=" "
889b6e2
+	COMBRELOC=ldscripts/${EMULATION_NAME}.xsco.tmp
889b6e2
+	( echo "/* Script for --shared -z combreloc -z relro: shared library, combine & sort relocs with separate code segment */"
889b6e2
+	  . ${CUSTOMIZER_SCRIPT}
889b6e2
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+	) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xsco
889b6e2
+	rm -f ${COMBRELOC}
889b6e2
+	LD_FLAG=wsharedtextonly
889b6e2
+	COMBRELOC=ldscripts/${EMULATION_NAME}.xsceo.tmp
889b6e2
+	( echo "/* Script for --shared -z combreloc -z relro -z separate-code: shared library, combine & sort relocs with separate code segment */"
889b6e2
+	  . ${CUSTOMIZER_SCRIPT}
889b6e2
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+	) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xsceo
889b6e2
+	rm -f ${COMBRELOC}
889b6e2
+	unset RELRO
889b6e2
+    fi
889b6e2
+    COMBRELOC=
889b6e2
   fi
889b6e2
   unset CREATE_SHLIB
889b6e2
 fi
889b6e2
@@ -422,6 +491,22 @@ if test -n "$GENERATE_PIE_SCRIPT"; then
889b6e2
     . ${CUSTOMIZER_SCRIPT}
889b6e2
     . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
   ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xde
889b6e2
+  if test -n "$GENERATE_RELRO_SCRIPT"; then
889b6e2
+      RELRO=" "
889b6e2
+      LD_FLAG=pie
889b6e2
+      (
889b6e2
+	  echo "/* Script for ld -pie -z relro: link position independent executable */"
889b6e2
+	  . ${CUSTOMIZER_SCRIPT}
889b6e2
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+      ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xdo
889b6e2
+      LD_FLAG=pietextonly
889b6e2
+      (
889b6e2
+	  echo "/* Script for ld -pie -z relro -z separate-code: link position independent executable with separate code segment */"
889b6e2
+	  . ${CUSTOMIZER_SCRIPT}
889b6e2
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+      ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xdeo
889b6e2
+      unset RELRO
889b6e2
+  fi
889b6e2
   if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
889b6e2
     DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}}
889b6e2
     COMBRELOC=ldscripts/${EMULATION_NAME}.xdc.tmp
889b6e2
@@ -453,8 +538,28 @@ if test -n "$GENERATE_PIE_SCRIPT"; then
889b6e2
       . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
     ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xdwe
889b6e2
     rm -f ${COMBRELOC}
889b6e2
-    COMBRELOC=
889b6e2
     unset RELRO_NOW
889b6e2
+
889b6e2
+    if test -n "$GENERATE_RELRO_SCRIPT"; then
889b6e2
+	LD_FLAG=wpie
889b6e2
+	RELRO=" "
889b6e2
+	COMBRELOC=ldscripts/${EMULATION_NAME}.xdco.tmp
889b6e2
+	( echo "/* Script for -pie -z combreloc -z relro: position independent executable, combine & sort relocs with separate code segment */"
889b6e2
+	  . ${CUSTOMIZER_SCRIPT}
889b6e2
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+	) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xdco
889b6e2
+	rm -f ${COMBRELOC}
889b6e2
+	LD_FLAG=wpietextonly
889b6e2
+	COMBRELOC=ldscripts/${EMULATION_NAME}.xdceo.tmp
889b6e2
+	( echo "/* Script for -pie -z combreloc -z relro -z separate-code: position independent executable, combine & sort relocs with separate code segment */"
889b6e2
+	  . ${CUSTOMIZER_SCRIPT}
889b6e2
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
889b6e2
+	) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xdceo
889b6e2
+	rm -f ${COMBRELOC}
889b6e2
+
889b6e2
+	unset RELRO
889b6e2
+    fi
889b6e2
+    COMBRELOC=
889b6e2
   fi
889b6e2
   unset CREATE_PIE
889b6e2
 fi
889b6e2
Only in binutils.orig/ld/testsuite/ld-s390: gotreloc_64-1.dd
889b6e2
Only in binutils-2.31.1/ld/testsuite/ld-s390: gotreloc_64-norelro-1.dd
889b6e2
Only in binutils-2.31.1/ld/testsuite/ld-s390: gotreloc_64-relro-1.dd
889b6e2
diff -rup binutils.orig/ld/testsuite/ld-s390/s390.exp binutils-2.31.1/ld/testsuite/ld-s390/s390.exp
889b6e2
--- binutils.orig/ld/testsuite/ld-s390/s390.exp	2018-07-19 12:37:28.498025644 +0100
889b6e2
+++ binutils-2.31.1/ld/testsuite/ld-s390/s390.exp	2018-07-19 12:38:11.236548705 +0100
889b6e2
@@ -70,10 +70,15 @@ set s390xtests {
889b6e2
      {{readelf -WSsrl tlsbin_64.rd} {objdump -dzrj.text tlsbin_64.dd}
889b6e2
       {objdump -sj.got tlsbin_64.sd} {objdump -sj.tdata tlsbin_64.td}}
889b6e2
      "tlsbin_64"}
889b6e2
-    {"GOT: symbol address load from got to larl"
889b6e2
-     "-shared -melf64_s390 --hash-style=sysv --version-script=gotreloc-1.ver" ""
889b6e2
+    {"GOT: norelro symbol address load from got to larl"
889b6e2
+     "-shared -melf64_s390 -z norelro --hash-style=sysv --version-script=gotreloc-1.ver" ""
889b6e2
      "-m64" {gotreloc-1.s}
889b6e2
-     {{objdump -dzrj.text gotreloc_64-1.dd}}
889b6e2
+     {{objdump -dzrj.text gotreloc_64-norelro-1.dd}}
889b6e2
+     "gotreloc_64-1"}
889b6e2
+    {"GOT: relro symbol address load from got to larl"
889b6e2
+     "-shared -melf64_s390 -z relro --hash-style=sysv --version-script=gotreloc-1.ver" ""
889b6e2
+     "-m64" {gotreloc-1.s}
889b6e2
+     {{objdump -dzrj.text gotreloc_64-relro-1.dd}}
889b6e2
      "gotreloc_64-1"}
889b6e2
     {"PLT: offset test"
889b6e2
      "-shared -m elf64_s390 -dT pltoffset-1.ld" ""