File s390-relro.diff of Package cross-sparc-binutils

Implement fate#326356
This combines commits afca762f and a381372
to implement RELRO properly on s390.  Before that
the order of .got.plt vs. .got was such that the latter
couldn't be made read-only when lazy linking was enabled.

commit afca762f598d453c563f244cd3777715b1a0cb72
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date:   Thu Dec 21 13:12:03 2017 +0100

    S/390: Improve partial relro support for 64 bit
    
    Currently on S/390 the .got.plt always comes first which prevents the
    GNU_RELRO segment from being extended across the non-plt GOT entries.
    
    Just swapping both unfortunately is not that simple since our ABI
    requires the _GLOBAL_OFFSET_TABLE_ symbol to point to the very
    beginning of the entire GOT. Of the 3 magic GOT entries the first is
    accessed via got pointer while second and third are being accessed via
    DT_PLTGOT.  In order to keep them together we make DT_PLTGOT to point
    to the .got instead of .got.plt.  However, this violates an assumption
    in the dynamic linker prelink undo code about the GOTPLT entries
    starting at DT_PLTGOT + 3.  We got rid of this requirement with a
    Glibc patch already in version 2.24:
    https://sourceware.org/ml/libc-alpha/2016-06/msg01302.html
    
    So the S/390 relro GOT layout will look like this with this patch:
    
          +----------------------------------+
          |got[0]: DYNAMIC                   |   <--- _GLOBAL_OFFSET_TABLE_ == DT_PLTGOT .got
          |got[1]: link_map parm             |
          |got[2]: &_dl_runtime_resolve      |
          +----------------------------------+
          |                                  |   non-plt GOT entries
          |                                  |
          |                                  |
          +----------------------------------+
          |                                  |   <--- .gotplt, PLT GOT entries
          |                                  |
          |                                  |
          |                                  |
          +----------------------------------+
    
    The patch detects the current layout in size_dynamic_section in order
    to deal also with linker scripts not generated by this ld version.
    With partial relro enabled we pick a linker script where .got and
    .got.plt are swapped which then triggers the rest of the logic.
    
    ld/ChangeLog:
    
    2018-07-18  Andreas Krebbel  <krebbel@linux.ibm.com>
    
    	* emulparams/elf64_s390.sh: Define GENERATE_RELRO_SCRIPT and
    	SEPARATE_GOTPLT.
    	* testsuite/ld-s390/gotreloc_64-relro-1.dd: New test.
    	* testsuite/ld-s390/gotreloc_64-norelro-1.dd: Renamed from ...
    	* testsuite/ld-s390/gotreloc_64-1.dd: ... this.
    	* testsuite/ld-s390/s390.exp: Split the GOT testcase into two.
    
    bfd/ChangeLog:
    
    2018-07-18  Andreas Krebbel  <krebbel@linux.ibm.com>
    
    	* elf-s390-common.c (s390_gotplt_after_got_p): New function.
    	(s390_got_pointer): New function.
    	(s390_got_offset): New function.
    	(s390_gotplt_offset): New function.
    	* elf64-s390.c (allocate_dynrelocs): Adjust comment.
    	(elf_s390_size_dynamic_sections): Move space for magic GOT entries
    	from .got.plt to .got if necessary and pick the right location for
    	_GLOBAL_OFFSET_TABLE_.
    	(elf_s390_relocate_section): Use the wrapper functions from
    	elf-s390-common.c to deal with both possible layouts (either .got
    	or .got.plt first).
    	(elf_s390_finish_dynamic_sections): Likewise.
    	(elf_s390_finish_dynamic_symbol): Make the location of the GOT
    	magic entries conditional.

commit a38137289e91fd548fc27fb6566a439233b94d65
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date:   Mon Jun 11 13:23:00 2018 +0200

    ld: Enable using separate linker script for -z relro
    
    With this patch dedicated linker scripts can be generated for partial
    relro triggered by defining GENERATE_RELRO_SCRIPT in the target
    specific scripts.
    
    This is necessary for e.g. S/390 where usually the .got.plt comes
    first and prevents the relro segment from being extended across the
    non-plt GOT entries.
    
    The patch started with the work from Marcin taken from the mwk user
    branches.  However, the patch needed substantial changes due to the
    'separate code' feature which got committed in the meantime.
    
    ld/ChangeLog:
    
    2018-07-18  Andreas Krebbel  <krebbel@linux.ibm.com>
            Marcin Koƛcielnicki <koriakin@0x04.net>
    
        * emultempl/elf32.em: Add code to pick dedicated linker scripts
        for partial relro.
        * genscripts.sh: Generate dedicated linker scripts for partial relro.

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