Blame SOURCES/binutils-s390x-partial-relro.patch

cf4a45
diff -rup binutils.orig/bfd/elf64-s390.c binutils-2.30/bfd/elf64-s390.c
cf4a45
--- binutils.orig/bfd/elf64-s390.c	2019-03-11 14:41:06.432547033 +0000
cf4a45
+++ binutils-2.30/bfd/elf64-s390.c	2019-03-11 14:45:42.066369572 +0000
cf4a45
@@ -475,7 +475,7 @@ elf_s390_is_local_label_name (bfd *abfd,
cf4a45
 
cf4a45
 #define RELA_ENTRY_SIZE sizeof (Elf64_External_Rela)
cf4a45
 
cf4a45
-/* The first three entries in a procedure linkage table are reserved,
cf4a45
+/* The first three entries in a global offset table are reserved,
cf4a45
    and the initial contents are unimportant (we zero them out).
cf4a45
    Subsequent entries look like this.  See the SVR4 ABI 386
cf4a45
    supplement to see how this works.  */
cf4a45
@@ -505,8 +505,8 @@ elf_s390_is_local_label_name (bfd *abfd,
cf4a45
 	 LG   1,0(1)	  # 6 bytes  Load address from GOT in r1
cf4a45
 	 BCR  15,1	  # 2 bytes  Jump to address
cf4a45
    RET1: BASR 1,0	  # 2 bytes  Return from GOT 1st time
cf4a45
-	 LGF  1,12(1)	  # 6 bytes  Load offset in symbl table in r1
cf4a45
-	 BRCL 15,-x	  # 6 bytes  Jump to start of PLT
cf4a45
+	 LGF  1,12(1)	  # 6 bytes  Load rela.plt offset into r1
cf4a45
+	 BRCL 15,-x	  # 6 bytes  Jump to first PLT entry
cf4a45
 	 .long ?	  # 4 bytes  offset into .rela.plt
cf4a45
 
cf4a45
    Total = 32 bytes per PLT entry
cf4a45
@@ -1599,8 +1599,7 @@ allocate_dynrelocs (struct elf_link_hash
cf4a45
 	  /* Make room for this entry.  */
cf4a45
 	  s->size += PLT_ENTRY_SIZE;
cf4a45
 
cf4a45
-	  /* We also need to make an entry in the .got.plt section, which
cf4a45
-	     will be placed in the .got section by the linker script.  */
cf4a45
+	  /* We also need to make an entry in the .got.plt section.  */
cf4a45
 	  htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
cf4a45
 
cf4a45
 	  /* We also need to make an entry in the .rela.plt section.  */
cf4a45
@@ -1825,6 +1824,20 @@ elf_s390_size_dynamic_sections (bfd *out
cf4a45
 	}
cf4a45
     }
cf4a45
 
cf4a45
+  if (htab->elf.sgot && s390_gotplt_after_got_p (info))
cf4a45
+    {
cf4a45
+      /* _bfd_elf_create_got_section adds the got header size always
cf4a45
+	 to .got.plt but we need it in .got if this section comes
cf4a45
+	 first.  */
cf4a45
+      htab->elf.sgot->size += 3 * GOT_ENTRY_SIZE;
cf4a45
+      htab->elf.sgotplt->size -= 3 * GOT_ENTRY_SIZE;
cf4a45
+
cf4a45
+      /* Make the _GLOBAL_OFFSET_TABLE_ symbol point to the .got
cf4a45
+	 instead of .got.plt.  */
cf4a45
+      htab->elf.hgot->root.u.def.section = htab->elf.sgot;
cf4a45
+      htab->elf.hgot->root.u.def.value = 0;
cf4a45
+    }
cf4a45
+
cf4a45
   /* Set up .got offsets for local syms, and space for local dynamic
cf4a45
      relocs.  */
cf4a45
   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
cf4a45
@@ -2125,7 +2138,6 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
       bfd_boolean unresolved_reloc;
cf4a45
       bfd_reloc_status_type r;
cf4a45
       int tls_type;
cf4a45
-      asection *base_got = htab->elf.sgot;
cf4a45
       bfd_boolean resolved_to_zero;
cf4a45
 
cf4a45
       r_type = ELF64_R_TYPE (rel->r_info);
cf4a45
@@ -2166,7 +2178,7 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 		case R_390_PLTOFF16:
cf4a45
 		case R_390_PLTOFF32:
cf4a45
 		case R_390_PLTOFF64:
cf4a45
-		  relocation -= htab->elf.sgot->output_section->vma;
cf4a45
+		  relocation -= s390_got_pointer (info);
cf4a45
 		  break;
cf4a45
 		case R_390_GOTPLT12:
cf4a45
 		case R_390_GOTPLT16:
cf4a45
@@ -2186,10 +2198,10 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 				htab->elf.sgot->contents +
cf4a45
 				local_got_offsets[r_symndx]);
cf4a45
 		    relocation = (local_got_offsets[r_symndx] +
cf4a45
-				  htab->elf.sgot->output_offset);
cf4a45
+				  s390_got_offset (info));
cf4a45
 
cf4a45
 		    if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT)
cf4a45
-		      relocation += htab->elf.sgot->output_section->vma;
cf4a45
+		      relocation += s390_got_pointer (info);
cf4a45
 		    break;
cf4a45
 		  }
cf4a45
 		default:
cf4a45
@@ -2248,25 +2260,23 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 
cf4a45
 	      if (s390_is_ifunc_symbol_p (h))
cf4a45
 		{
cf4a45
+		  /* Entry indices of .iplt and .igot.plt match
cf4a45
+		     1:1. No magic PLT first entry here.  */
cf4a45
 		  plt_index = h->plt.offset / PLT_ENTRY_SIZE;
cf4a45
-		  relocation = (plt_index * GOT_ENTRY_SIZE +
cf4a45
-				htab->elf.igotplt->output_offset);
cf4a45
-		  if (r_type == R_390_GOTPLTENT)
cf4a45
-		    relocation += htab->elf.igotplt->output_section->vma;
cf4a45
+		  relocation = (plt_index * GOT_ENTRY_SIZE
cf4a45
+				+ s390_gotplt_offset (info)
cf4a45
+				+ htab->elf.igotplt->output_offset);
cf4a45
 		}
cf4a45
 	      else
cf4a45
 		{
cf4a45
-		  /* Calc. index no.
cf4a45
-		     Current offset - size first entry / entry size.  */
cf4a45
-		  plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) /
cf4a45
-		    PLT_ENTRY_SIZE;
cf4a45
-
cf4a45
-		  /* Offset in GOT is PLT index plus GOT headers(3)
cf4a45
-		     times 8, addr & GOT addr.  */
cf4a45
-		  relocation = (plt_index + 3) * GOT_ENTRY_SIZE;
cf4a45
-		  if (r_type == R_390_GOTPLTENT)
cf4a45
-		    relocation += htab->elf.sgot->output_section->vma;
cf4a45
+		  plt_index = ((h->plt.offset - PLT_FIRST_ENTRY_SIZE)
cf4a45
+			       / PLT_ENTRY_SIZE);
cf4a45
+
cf4a45
+		  relocation = (plt_index * GOT_ENTRY_SIZE
cf4a45
+				+ s390_gotplt_offset (info));
cf4a45
 		}
cf4a45
+	      if (r_type == R_390_GOTPLTENT)
cf4a45
+		relocation += s390_got_pointer (info);
cf4a45
 	      unresolved_reloc = FALSE;
cf4a45
 	      break;
cf4a45
 	    }
cf4a45
@@ -2280,7 +2290,7 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 	case R_390_GOTENT:
cf4a45
 	  /* Relocation is to the entry for this symbol in the global
cf4a45
 	     offset table.  */
cf4a45
-	  if (base_got == NULL)
cf4a45
+	  if (htab->elf.sgot == NULL)
cf4a45
 	    abort ();
cf4a45
 
cf4a45
 	  if (h != NULL)
cf4a45
@@ -2297,8 +2307,19 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 		    {
cf4a45
 		      /* No explicit GOT usage so redirect to the
cf4a45
 			 got.iplt slot.  */
cf4a45
-		      base_got = htab->elf.igotplt;
cf4a45
-		      off = h->plt.offset / PLT_ENTRY_SIZE * GOT_ENTRY_SIZE;
cf4a45
+		      relocation = (s390_gotplt_offset (info)
cf4a45
+				    + htab->elf.igotplt->output_offset
cf4a45
+				    + (h->plt.offset / PLT_ENTRY_SIZE
cf4a45
+				       * GOT_ENTRY_SIZE));
cf4a45
+
cf4a45
+		      /* For @GOTENT the relocation is against the offset between
cf4a45
+			 the instruction and the symbols entry in the GOT and not
cf4a45
+			 between the start of the GOT and the symbols entry. We
cf4a45
+			 add the vma of the GOT to get the correct value.  */
cf4a45
+		      if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT)
cf4a45
+			relocation += s390_got_pointer (info);
cf4a45
+
cf4a45
+		      break;
cf4a45
 		    }
cf4a45
 		  else
cf4a45
 		    {
cf4a45
@@ -2331,7 +2352,7 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 		  else
cf4a45
 		    {
cf4a45
 		      bfd_put_64 (output_bfd, relocation,
cf4a45
-				  base_got->contents + off);
cf4a45
+				  htab->elf.sgot->contents + off);
cf4a45
 		      h->got.offset |= 1;
cf4a45
 		    }
cf4a45
 
cf4a45
@@ -2413,7 +2434,7 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 	  if (off >= (bfd_vma) -2)
cf4a45
 	    abort ();
cf4a45
 
cf4a45
-	  relocation = base_got->output_offset + off;
cf4a45
+	  relocation = s390_got_offset (info) + off;
cf4a45
 
cf4a45
 	  /* For @GOTENT the relocation is against the offset between
cf4a45
 	     the instruction and the symbols entry in the GOT and not
cf4a45
@@ -2421,7 +2442,7 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 	     add the vma of the GOT to get the correct value.  */
cf4a45
 	  if (   r_type == R_390_GOTENT
cf4a45
 	      || r_type == R_390_GOTPLTENT)
cf4a45
-	    relocation += base_got->output_section->vma;
cf4a45
+	    relocation += s390_got_pointer (info);
cf4a45
 
cf4a45
 	  break;
cf4a45
 
cf4a45
@@ -2439,22 +2460,17 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 	      relocation = (htab->elf.iplt->output_section->vma
cf4a45
 			    + htab->elf.iplt->output_offset
cf4a45
 			    + h->plt.offset
cf4a45
-			    - htab->elf.sgot->output_section->vma);
cf4a45
+			    - s390_got_pointer (info));
cf4a45
 	      goto do_relocation;
cf4a45
 	    }
cf4a45
 
cf4a45
-	  /* Note that sgot->output_offset is not involved in this
cf4a45
-	     calculation.  We always want the start of .got.  If we
cf4a45
-	     defined _GLOBAL_OFFSET_TABLE in a different way, as is
cf4a45
-	     permitted by the ABI, we might have to change this
cf4a45
-	     calculation.  */
cf4a45
-	  relocation -= htab->elf.sgot->output_section->vma;
cf4a45
+	  relocation -= s390_got_pointer (info);
cf4a45
 	  break;
cf4a45
 
cf4a45
 	case R_390_GOTPC:
cf4a45
 	case R_390_GOTPCDBL:
cf4a45
 	  /* Use global offset table as symbol value.  */
cf4a45
-	  relocation = htab->elf.sgot->output_section->vma;
cf4a45
+	  relocation = s390_got_pointer (info);
cf4a45
 	  unresolved_reloc = FALSE;
cf4a45
 	  break;
cf4a45
 
cf4a45
@@ -2503,7 +2519,7 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 	      || h->plt.offset == (bfd_vma) -1
cf4a45
 	      || (htab->elf.splt == NULL && !s390_is_ifunc_symbol_p (h)))
cf4a45
 	    {
cf4a45
-	      relocation -= htab->elf.sgot->output_section->vma;
cf4a45
+	      relocation -= s390_got_pointer (info);
cf4a45
 	      break;
cf4a45
 	    }
cf4a45
 
cf4a45
@@ -2511,12 +2527,12 @@ elf_s390_relocate_section (bfd *output_b
cf4a45
 	    relocation = (htab->elf.iplt->output_section->vma
cf4a45
 			  + htab->elf.iplt->output_offset
cf4a45
 			  + h->plt.offset
cf4a45
-			  - htab->elf.sgot->output_section->vma);
cf4a45
+			  - s390_got_pointer (info));
cf4a45
 	  else
cf4a45
 	    relocation = (htab->elf.splt->output_section->vma
cf4a45
 			  + htab->elf.splt->output_offset
cf4a45
 			  + h->plt.offset
cf4a45
-			  - htab->elf.sgot->output_section->vma);
cf4a45
+			  - s390_got_pointer (info));
cf4a45
 	  unresolved_reloc = FALSE;
cf4a45
 	  break;
cf4a45
 
cf4a45
@@ -3289,7 +3305,7 @@ elf_s390_finish_dynamic_symbol (bfd *out
cf4a45
   if (h->plt.offset != (bfd_vma) -1)
cf4a45
     {
cf4a45
       bfd_vma plt_index;
cf4a45
-      bfd_vma got_offset;
cf4a45
+      bfd_vma gotplt_offset;
cf4a45
       Elf_Internal_Rela rela;
cf4a45
       bfd_byte *loc;
cf4a45
 
cf4a45
@@ -3318,18 +3334,25 @@ elf_s390_finish_dynamic_symbol (bfd *out
cf4a45
 	     Current offset - size first entry / entry size.  */
cf4a45
 	  plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE;
cf4a45
 
cf4a45
-	  /* Offset in GOT is PLT index plus GOT headers(3) times 8,
cf4a45
-	     addr & GOT addr.  */
cf4a45
-	  got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
cf4a45
+	  /* The slots in the .got.plt correspond to the PLT slots in
cf4a45
+	     the same order.  */
cf4a45
+	  gotplt_offset = plt_index * GOT_ENTRY_SIZE;
cf4a45
+
cf4a45
+	  /* If .got.plt comes first it needs to contain the 3 header
cf4a45
+	     entries.  */
cf4a45
+	  if (!s390_gotplt_after_got_p (info))
cf4a45
+	    gotplt_offset += 3 * GOT_ENTRY_SIZE;
cf4a45
 
cf4a45
 	  /* Fill in the blueprint of a PLT.  */
cf4a45
 	  memcpy (htab->elf.splt->contents + h->plt.offset, elf_s390x_plt_entry,
cf4a45
 		  PLT_ENTRY_SIZE);
cf4a45
 
cf4a45
-	  /* Fixup the relative address to the GOT entry */
cf4a45
+	  /* The first instruction in the PLT entry is a LARL loading
cf4a45
+	     the address of the GOT slot.  We write the 4 byte
cf4a45
+	     immediate operand of the LARL instruction here.  */
cf4a45
 	  bfd_put_32 (output_bfd,
cf4a45
 		      (htab->elf.sgotplt->output_section->vma +
cf4a45
-		       htab->elf.sgotplt->output_offset + got_offset
cf4a45
+		       htab->elf.sgotplt->output_offset + gotplt_offset
cf4a45
 		       - (htab->elf.splt->output_section->vma +
cf4a45
 			  htab->elf.splt->output_offset +
cf4a45
 			  h->plt.offset))/2,
cf4a45
@@ -3349,12 +3372,12 @@ elf_s390_finish_dynamic_symbol (bfd *out
cf4a45
 		       + htab->elf.splt->output_offset
cf4a45
 		       + h->plt.offset
cf4a45
 		       + 14),
cf4a45
-		      htab->elf.sgotplt->contents + got_offset);
cf4a45
+		      htab->elf.sgotplt->contents + gotplt_offset);
cf4a45
 
cf4a45
 	  /* Fill in the entry in the .rela.plt section.  */
cf4a45
 	  rela.r_offset = (htab->elf.sgotplt->output_section->vma
cf4a45
 			   + htab->elf.sgotplt->output_offset
cf4a45
-			   + got_offset);
cf4a45
+			   + gotplt_offset);
cf4a45
 	  rela.r_info = ELF64_R_INFO (h->dynindx, R_390_JMP_SLOT);
cf4a45
 	  rela.r_addend = 0;
cf4a45
 	  loc = htab->elf.srelplt->contents + plt_index *
cf4a45
@@ -3561,8 +3584,8 @@ elf_s390_finish_dynamic_sections (bfd *o
cf4a45
 	      continue;
cf4a45
 
cf4a45
 	    case DT_PLTGOT:
cf4a45
-	      s = htab->elf.sgotplt;
cf4a45
-	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
cf4a45
+	      /* DT_PLTGOT matches _GLOBAL_OFFSET_TABLE_ */
cf4a45
+	      dyn.d_un.d_ptr = s390_got_pointer (info);
cf4a45
 	      break;
cf4a45
 
cf4a45
 	    case DT_JMPREL:
cf4a45
@@ -3599,10 +3622,11 @@ elf_s390_finish_dynamic_sections (bfd *o
cf4a45
 	  /* fill in blueprint for plt 0 entry */
cf4a45
 	  memcpy (htab->elf.splt->contents, elf_s390x_first_plt_entry,
cf4a45
 		  PLT_FIRST_ENTRY_SIZE);
cf4a45
-	  /* Fixup relative address to start of GOT */
cf4a45
+	  /* The second instruction in the first PLT entry is a LARL
cf4a45
+	     loading the GOT pointer.  Fill in the LARL immediate
cf4a45
+	     address.  */
cf4a45
 	  bfd_put_32 (output_bfd,
cf4a45
-		      (htab->elf.sgotplt->output_section->vma
cf4a45
-		       + htab->elf.sgotplt->output_offset
cf4a45
+		      (s390_got_pointer (info)
cf4a45
 		       - htab->elf.splt->output_section->vma
cf4a45
 		       - htab->elf.splt->output_offset - 6)/2,
cf4a45
 		      htab->elf.splt->contents + 8);
cf4a45
@@ -3612,21 +3636,22 @@ elf_s390_finish_dynamic_sections (bfd *o
cf4a45
 	  = PLT_ENTRY_SIZE;
cf4a45
     }
cf4a45
 
cf4a45
-  if (htab->elf.sgotplt)
cf4a45
+  if (htab->elf.hgot && htab->elf.hgot->root.u.def.section)
cf4a45
     {
cf4a45
       /* Fill in the first three entries in the global offset table.  */
cf4a45
-      if (htab->elf.sgotplt->size > 0)
cf4a45
+      if (htab->elf.hgot->root.u.def.section->size > 0)
cf4a45
 	{
cf4a45
 	  bfd_put_64 (output_bfd,
cf4a45
 		      (sdyn == NULL ? (bfd_vma) 0
cf4a45
 		       : sdyn->output_section->vma + sdyn->output_offset),
cf4a45
-		      htab->elf.sgotplt->contents);
cf4a45
+		      htab->elf.hgot->root.u.def.section->contents);
cf4a45
 	  /* One entry for shared object struct ptr.  */
cf4a45
-	  bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 8);
cf4a45
+	  bfd_put_64 (output_bfd, (bfd_vma) 0,
cf4a45
+		      htab->elf.hgot->root.u.def.section->contents + 8);
cf4a45
 	  /* One entry for _dl_runtime_resolve.  */
cf4a45
-	  bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 16);
cf4a45
+	  bfd_put_64 (output_bfd, (bfd_vma) 0,
cf4a45
+		      htab->elf.hgot->root.u.def.section->contents + 16);
cf4a45
 	}
cf4a45
-
cf4a45
       elf_section_data (htab->elf.sgot->output_section)
cf4a45
 	->this_hdr.sh_entsize = 8;
cf4a45
     }
cf4a45
diff -rup binutils.orig/bfd/elf-s390-common.c binutils-2.30/bfd/elf-s390-common.c
cf4a45
--- binutils.orig/bfd/elf-s390-common.c	2019-03-11 14:41:06.444546938 +0000
cf4a45
+++ binutils-2.30/bfd/elf-s390-common.c	2019-03-11 14:45:42.065369580 +0000
cf4a45
@@ -30,6 +30,87 @@ s390_is_ifunc_symbol_p (struct elf_link_
cf4a45
   return h->type == STT_GNU_IFUNC || eh->ifunc_resolver_address != 0;
cf4a45
 }
cf4a45
 
cf4a45
+/* Return true if .got.plt is supposed to be emitted after .got.  */
cf4a45
+
cf4a45
+static inline bfd_boolean
cf4a45
+s390_gotplt_after_got_p (struct bfd_link_info *info)
cf4a45
+{
cf4a45
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
cf4a45
+
cf4a45
+  if (!htab->elf.sgot || !htab->elf.sgotplt)
cf4a45
+    return TRUE;
cf4a45
+
cf4a45
+  if (htab->elf.sgot->output_section == htab->elf.sgotplt->output_section)
cf4a45
+    {
cf4a45
+      if (htab->elf.sgot->output_offset < htab->elf.sgotplt->output_offset)
cf4a45
+	return TRUE;
cf4a45
+    }
cf4a45
+  else
cf4a45
+    {
cf4a45
+      if (htab->elf.sgot->output_section->vma
cf4a45
+	  <= htab->elf.sgotplt->output_section->vma)
cf4a45
+	return TRUE;
cf4a45
+    }
cf4a45
+  return FALSE;
cf4a45
+}
cf4a45
+
cf4a45
+/* Return the value of the _GLOBAL_OFFSET_TABLE_ symbol.  */
cf4a45
+
cf4a45
+static inline bfd_vma
cf4a45
+s390_got_pointer (struct bfd_link_info *info)
cf4a45
+{
cf4a45
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
cf4a45
+  bfd_vma got_pointer;
cf4a45
+
cf4a45
+  BFD_ASSERT (htab && htab->elf.hgot);
cf4a45
+
cf4a45
+  got_pointer = (htab->elf.hgot->root.u.def.section->output_section->vma
cf4a45
+		 + htab->elf.hgot->root.u.def.section->output_offset);
cf4a45
+  /* Our ABI requires the GOT pointer to point at the very beginning
cf4a45
+     of the global offset table.  */
cf4a45
+  BFD_ASSERT (got_pointer
cf4a45
+	      <= (htab->elf.sgot->output_section->vma
cf4a45
+		  + htab->elf.sgot->output_offset));
cf4a45
+  BFD_ASSERT (got_pointer
cf4a45
+	      <= (htab->elf.sgotplt->output_section->vma
cf4a45
+		  + htab->elf.sgotplt->output_offset));
cf4a45
+
cf4a45
+  return got_pointer;
cf4a45
+}
cf4a45
+
cf4a45
+
cf4a45
+/* Return the offset of the .got versus _GLOBAL_OFFSET_TABLE_.  */
cf4a45
+
cf4a45
+static inline bfd_vma
cf4a45
+s390_got_offset (struct bfd_link_info *info)
cf4a45
+{
cf4a45
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
cf4a45
+
cf4a45
+  /* The absolute address of the .got in the target image.  */
cf4a45
+  bfd_vma got_address = (htab->elf.sgot->output_section->vma
cf4a45
+			 + htab->elf.sgot->output_offset);
cf4a45
+
cf4a45
+  /* GOT offset must not be negative.  */
cf4a45
+  BFD_ASSERT (s390_got_pointer (info) <= got_address);
cf4a45
+  return got_address - s390_got_pointer (info);
cf4a45
+}
cf4a45
+
cf4a45
+/* Return the offset of the .got.plt versus _GLOBAL_OFFSET_TABLE_.  */
cf4a45
+
cf4a45
+static inline bfd_vma
cf4a45
+s390_gotplt_offset (struct bfd_link_info *info)
cf4a45
+{
cf4a45
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
cf4a45
+
cf4a45
+  /* The absolute address of the .got.plt in the target image.  */
cf4a45
+  bfd_vma gotplt_address = (htab->elf.sgotplt->output_section->vma
cf4a45
+			    + htab->elf.sgotplt->output_offset);
cf4a45
+
cf4a45
+  /* GOT offset must not be negative.  */
cf4a45
+  BFD_ASSERT (s390_got_pointer (info) <= gotplt_address);
cf4a45
+  return gotplt_address - s390_got_pointer (info);
cf4a45
+}
cf4a45
+
cf4a45
 /* Create sections needed by STT_GNU_IFUNC symbol.  */
cf4a45
 
cf4a45
 static bfd_boolean
cf4a45
diff -rup binutils.orig/ld/emulparams/elf64_s390.sh binutils-2.30/ld/emulparams/elf64_s390.sh
cf4a45
--- binutils.orig/ld/emulparams/elf64_s390.sh	2019-03-11 14:41:05.978550619 +0000
cf4a45
+++ binutils-2.30/ld/emulparams/elf64_s390.sh	2019-03-11 14:45:42.066369572 +0000
cf4a45
@@ -11,9 +11,12 @@ NOP=0x07070707
cf4a45
 TEMPLATE_NAME=elf32
cf4a45
 GENERATE_SHLIB_SCRIPT=yes
cf4a45
 GENERATE_PIE_SCRIPT=yes
cf4a45
+GENERATE_RELRO_SCRIPT=yes
cf4a45
 NO_SMALL_DATA=yes
cf4a45
 EXTRA_EM_FILE=s390
cf4a45
 IREL_IN_PLT=
cf4a45
+SEPARATE_GOTPLT=0
cf4a45
+test -z "$RELRO" && unset SEPARATE_GOTPLT
cf4a45
 
cf4a45
 # Treat a host that matches the target with the possible exception of "x"
cf4a45
 # in the name as if it were native.
cf4a45
diff -rup binutils.orig/ld/emultempl/elf32.em binutils-2.30/ld/emultempl/elf32.em
cf4a45
--- binutils.orig/ld/emultempl/elf32.em	2019-03-11 14:41:05.971550675 +0000
cf4a45
+++ binutils-2.30/ld/emultempl/elf32.em	2019-03-11 14:45:42.064369587 +0000
cf4a45
@@ -2406,17 +2406,41 @@ echo '             && link_info.combrelo
cf4a45
 echo '             && link_info.relro'			>> e${EMULATION_NAME}.c
cf4a45
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xdw			>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xdceo              >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 echo '  ; else if (bfd_link_pie (&link_info)'		>> e${EMULATION_NAME}.c
cf4a45
 echo '             && link_info.separate_code'		>> e${EMULATION_NAME}.c
cf4a45
 echo '             && link_info.combreloc) return'	>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xdce		>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xdco               >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 echo '  ; else if (bfd_link_pie (&link_info)'		>> e${EMULATION_NAME}.c
cf4a45
 echo '             && link_info.combreloc) return'	>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xdc			>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xdeo               >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 fi
cf4a45
 echo '  ; else if (bfd_link_pie (&link_info)'		>> e${EMULATION_NAME}.c
cf4a45
 echo '             && link_info.separate_code) return'	>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xde			>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xdo                >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 echo '  ; else if (bfd_link_pie (&link_info)) return'	>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xd			>> e${EMULATION_NAME}.c
cf4a45
 fi
cf4a45
@@ -2432,17 +2456,41 @@ echo '             && link_info.combrelo
cf4a45
 echo '             && link_info.relro'			>> e${EMULATION_NAME}.c
cf4a45
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xsw			>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xsceo              >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 echo '  ; else if (bfd_link_dll (&link_info)'		>> e${EMULATION_NAME}.c
cf4a45
 echo '             && link_info.combreloc'		>> e${EMULATION_NAME}.c
cf4a45
 echo '             && link_info.separate_code) return'	>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xsce			>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xsco               >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 echo '  ; else if (bfd_link_dll (&link_info)'		>> e${EMULATION_NAME}.c
cf4a45
 echo '             && link_info.combreloc) return'	>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xsc			>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xseo               >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 fi
cf4a45
 echo '  ; else if (bfd_link_dll (&link_info)'		>> e${EMULATION_NAME}.c
cf4a45
 echo '             && link_info.separate_code) return'	>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xse			>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'         >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xso               >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 echo '  ; else if (bfd_link_dll (&link_info)) return'	>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xs			>> e${EMULATION_NAME}.c
cf4a45
 fi
cf4a45
@@ -2455,14 +2503,34 @@ echo '  ; else if (link_info.combreloc'
cf4a45
 echo '             && link_info.relro'			>> e${EMULATION_NAME}.c
cf4a45
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xw			>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (link_info.combreloc'                 >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.separate_code'		>> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'          >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xceo                >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 echo '  ; else if (link_info.combreloc'			>> e${EMULATION_NAME}.c
cf4a45
 echo '             && link_info.separate_code) return'	>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xce			>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (link_info.combreloc'                 >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'          >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xco                 >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 echo '  ; else if (link_info.combreloc) return'		>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xc			>> e${EMULATION_NAME}.c
cf4a45
 fi
cf4a45
-echo '  ; else if (link_info.separate_code) return'		>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (link_info.separate_code'             >> e${EMULATION_NAME}.c
cf4a45
+echo '             && link_info.relro) return'          >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xeo                 >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
+echo '  ; else if (link_info.separate_code) return'     >> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.xe			>> e${EMULATION_NAME}.c
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+echo '  ; else if (link_info.relro) return'             >> e${EMULATION_NAME}.c
cf4a45
+sed $sc ldscripts/${EMULATION_NAME}.xo                  >> e${EMULATION_NAME}.c
cf4a45
+fi
cf4a45
 echo '  ; else return'					>> e${EMULATION_NAME}.c
cf4a45
 sed $sc ldscripts/${EMULATION_NAME}.x			>> e${EMULATION_NAME}.c
cf4a45
 echo '; }'						>> e${EMULATION_NAME}.c
cf4a45
@@ -2501,6 +2569,21 @@ fragment <
cf4a45
       else
cf4a45
 	return "ldscripts/${EMULATION_NAME}.xdw";
cf4a45
     }
cf4a45
+EOF
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+fragment <
cf4a45
+  else if (bfd_link_pie (&link_info)
cf4a45
+	   && link_info.combreloc
cf4a45
+	   && link_info.relro)
cf4a45
+    {
cf4a45
+      if (link_info.separate_code)
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xdceo";
cf4a45
+      else
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xdco";
cf4a45
+    }
cf4a45
+EOF
cf4a45
+fi
cf4a45
+fragment <
cf4a45
   else if (bfd_link_pie (&link_info)
cf4a45
 	   && link_info.combreloc)
cf4a45
     {
cf4a45
@@ -2511,6 +2594,18 @@ fragment <
cf4a45
     }
cf4a45
 EOF
cf4a45
 fi
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+fragment <
cf4a45
+  else if (bfd_link_pie (&link_info)
cf4a45
+	   && link_info.relro)
cf4a45
+    {
cf4a45
+      if (link_info.separate_code)
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xdeo";
cf4a45
+      else
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xdo";
cf4a45
+    }
cf4a45
+EOF
cf4a45
+fi
cf4a45
 fragment <
cf4a45
   else if (bfd_link_pie (&link_info))
cf4a45
     {
cf4a45
@@ -2532,6 +2627,21 @@ fragment <
cf4a45
       else
cf4a45
 	return "ldscripts/${EMULATION_NAME}.xsw";
cf4a45
     }
cf4a45
+EOF
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+fragment <
cf4a45
+  else if (bfd_link_dll (&link_info)
cf4a45
+	   && link_info.combreloc
cf4a45
+	   && link_info.relro)
cf4a45
+    {
cf4a45
+      if (link_info.separate_code)
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xsceo";
cf4a45
+      else
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xsco";
cf4a45
+    }
cf4a45
+EOF
cf4a45
+fi
cf4a45
+fragment <
cf4a45
   else if (bfd_link_dll (&link_info) && link_info.combreloc)
cf4a45
     {
cf4a45
       if (link_info.separate_code)
cf4a45
@@ -2541,6 +2651,18 @@ fragment <
cf4a45
     }
cf4a45
 EOF
cf4a45
 fi
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+fragment <
cf4a45
+  else if (bfd_link_dll (&link_info)
cf4a45
+	   && link_info.relro)
cf4a45
+    {
cf4a45
+      if (link_info.separate_code)
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xseo";
cf4a45
+      else
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xso";
cf4a45
+    }
cf4a45
+EOF
cf4a45
+fi
cf4a45
 fragment <
cf4a45
   else if (bfd_link_dll (&link_info))
cf4a45
     {
cf4a45
@@ -2561,6 +2683,20 @@ fragment <
cf4a45
       else
cf4a45
 	return "ldscripts/${EMULATION_NAME}.xw";
cf4a45
     }
cf4a45
+EOF
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+fragment <
cf4a45
+  else if (link_info.combreloc
cf4a45
+	   && link_info.relro)
cf4a45
+    {
cf4a45
+      if (link_info.separate_code)
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xceo";
cf4a45
+      else
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xco";
cf4a45
+    }
cf4a45
+EOF
cf4a45
+fi
cf4a45
+fragment <
cf4a45
   else if (link_info.combreloc)
cf4a45
     {
cf4a45
       if (link_info.separate_code)
cf4a45
@@ -2570,6 +2706,17 @@ fragment <
cf4a45
     }
cf4a45
 EOF
cf4a45
 fi
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
cf4a45
+fragment <
cf4a45
+  else if (link_info.relro)
cf4a45
+    {
cf4a45
+      if (link_info.separate_code)
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xeo";
cf4a45
+      else
cf4a45
+	return "ldscripts/${EMULATION_NAME}.xo";
cf4a45
+    }
cf4a45
+EOF
cf4a45
+fi
cf4a45
 fragment <
cf4a45
   else
cf4a45
     {
cf4a45
diff -rup binutils.orig/ld/genscripts.sh binutils-2.30/ld/genscripts.sh
cf4a45
--- binutils.orig/ld/genscripts.sh	2019-03-11 14:41:05.983550579 +0000
cf4a45
+++ binutils-2.30/ld/genscripts.sh	2019-03-11 14:45:42.065369580 +0000
cf4a45
@@ -304,6 +304,20 @@ LD_FLAG=textonly
cf4a45
   . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
 ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xe
cf4a45
 
cf4a45
+if test -n "$GENERATE_RELRO_SCRIPT"; then
cf4a45
+    LD_FLAG=
cf4a45
+    RELRO=" "
cf4a45
+    ( echo "/* Script for -z relo: generate normal executables with separate code segment */"
cf4a45
+      . ${CUSTOMIZER_SCRIPT}
cf4a45
+      . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+    ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xo
cf4a45
+    LD_FLAG=textonly
cf4a45
+    ( echo "/* Script for -z separate-code -z relo: generate normal executables with separate code segment */"
cf4a45
+      . ${CUSTOMIZER_SCRIPT}
cf4a45
+      . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+    ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xeo
cf4a45
+    unset RELRO
cf4a45
+fi
cf4a45
 LD_FLAG=n
cf4a45
 DATA_ALIGNMENT=${DATA_ALIGNMENT_n}
cf4a45
 ( echo "/* Script for -n: mix text and data on same page */"
cf4a45
@@ -351,6 +365,25 @@ if test -n "$GENERATE_COMBRELOC_SCRIPT";
cf4a45
   rm -f ${COMBRELOC}
cf4a45
   COMBRELOC=
cf4a45
   unset RELRO_NOW
cf4a45
+  if test -n "$GENERATE_RELRO_SCRIPT"; then
cf4a45
+      LD_FLAG=c
cf4a45
+      RELRO=" "
cf4a45
+      COMBRELOC=ldscripts/${EMULATION_NAME}.xco.tmp
cf4a45
+      ( echo "/* Script for -z combreloc -z relro: combine and sort reloc sections */"
cf4a45
+	. ${CUSTOMIZER_SCRIPT}
cf4a45
+	. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+      ) | sed -e '/^ *$/d;s/[    ]*$//' > ldscripts/${EMULATION_NAME}.xco
cf4a45
+      rm -f ${COMBRELOC}
cf4a45
+      LD_FLAG=ctextonly
cf4a45
+      COMBRELOC=ldscripts/${EMULATION_NAME}.xceo.tmp
cf4a45
+      ( echo "/* Script for -z combreloc -z separate-code -z relro: combine and sort reloc sections */"
cf4a45
+	. ${CUSTOMIZER_SCRIPT}
cf4a45
+	. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+      ) | sed -e '/^ *$/d;s/[    ]*$//' > ldscripts/${EMULATION_NAME}.xceo
cf4a45
+      rm -f ${COMBRELOC}
cf4a45
+      COMBRELOC=
cf4a45
+      unset RELRO
cf4a45
+  fi
cf4a45
 fi
cf4a45
 
cf4a45
 if test -n "$GENERATE_SHLIB_SCRIPT"; then
cf4a45
@@ -368,6 +401,23 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; the
cf4a45
     . ${CUSTOMIZER_SCRIPT}
cf4a45
     . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
   ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xse
cf4a45
+
cf4a45
+  if test -n "$GENERATE_RELRO_SCRIPT"; then
cf4a45
+      RELRO=" "
cf4a45
+      LD_FLAG=shared
cf4a45
+      (
cf4a45
+	  echo "/* Script for ld --shared -z relro: link shared library */"
cf4a45
+	  . ${CUSTOMIZER_SCRIPT}
cf4a45
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+      ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xso
cf4a45
+      LD_FLAG=sharedtextonly
cf4a45
+      (
cf4a45
+	  echo "/* Script for ld --shared -z relro -z separate-code: link shared library with separate code segment */"
cf4a45
+	  . ${CUSTOMIZER_SCRIPT}
cf4a45
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+      ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xseo
cf4a45
+      unset RELRO
cf4a45
+  fi
cf4a45
   if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
cf4a45
     DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}}
cf4a45
     LD_FLAG=cshared
cf4a45
@@ -399,8 +449,27 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; the
cf4a45
       . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
     ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xswe
cf4a45
     rm -f ${COMBRELOC}
cf4a45
-    COMBRELOC=
cf4a45
     unset RELRO_NOW
cf4a45
+
cf4a45
+    if test -n "$GENERATE_RELRO_SCRIPT"; then
cf4a45
+	LD_FLAG=wshared
cf4a45
+	RELRO=" "
cf4a45
+	COMBRELOC=ldscripts/${EMULATION_NAME}.xsco.tmp
cf4a45
+	( echo "/* Script for --shared -z combreloc -z relro: shared library, combine & sort relocs with separate code segment */"
cf4a45
+	  . ${CUSTOMIZER_SCRIPT}
cf4a45
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+	) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xsco
cf4a45
+	rm -f ${COMBRELOC}
cf4a45
+	LD_FLAG=wsharedtextonly
cf4a45
+	COMBRELOC=ldscripts/${EMULATION_NAME}.xsceo.tmp
cf4a45
+	( echo "/* Script for --shared -z combreloc -z relro -z separate-code: shared library, combine & sort relocs with separate code segment */"
cf4a45
+	  . ${CUSTOMIZER_SCRIPT}
cf4a45
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+	) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xsceo
cf4a45
+	rm -f ${COMBRELOC}
cf4a45
+	unset RELRO
cf4a45
+    fi
cf4a45
+    COMBRELOC=
cf4a45
   fi
cf4a45
   unset CREATE_SHLIB
cf4a45
 fi
cf4a45
@@ -420,6 +489,22 @@ if test -n "$GENERATE_PIE_SCRIPT"; then
cf4a45
     . ${CUSTOMIZER_SCRIPT}
cf4a45
     . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
   ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xde
cf4a45
+  if test -n "$GENERATE_RELRO_SCRIPT"; then
cf4a45
+      RELRO=" "
cf4a45
+      LD_FLAG=pie
cf4a45
+      (
cf4a45
+	  echo "/* Script for ld -pie -z relro: link position independent executable */"
cf4a45
+	  . ${CUSTOMIZER_SCRIPT}
cf4a45
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+      ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xdo
cf4a45
+      LD_FLAG=pietextonly
cf4a45
+      (
cf4a45
+	  echo "/* Script for ld -pie -z relro -z separate-code: link position independent executable with separate code segment */"
cf4a45
+	  . ${CUSTOMIZER_SCRIPT}
cf4a45
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+      ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xdeo
cf4a45
+      unset RELRO
cf4a45
+  fi
cf4a45
   if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
cf4a45
     DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}}
cf4a45
     COMBRELOC=ldscripts/${EMULATION_NAME}.xdc.tmp
cf4a45
@@ -451,8 +536,28 @@ if test -n "$GENERATE_PIE_SCRIPT"; then
cf4a45
       . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
     ) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xdwe
cf4a45
     rm -f ${COMBRELOC}
cf4a45
-    COMBRELOC=
cf4a45
     unset RELRO_NOW
cf4a45
+
cf4a45
+    if test -n "$GENERATE_RELRO_SCRIPT"; then
cf4a45
+	LD_FLAG=wpie
cf4a45
+	RELRO=" "
cf4a45
+	COMBRELOC=ldscripts/${EMULATION_NAME}.xdco.tmp
cf4a45
+	( echo "/* Script for -pie -z combreloc -z relro: position independent executable, combine & sort relocs with separate code segment */"
cf4a45
+	  . ${CUSTOMIZER_SCRIPT}
cf4a45
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+	) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xdco
cf4a45
+	rm -f ${COMBRELOC}
cf4a45
+	LD_FLAG=wpietextonly
cf4a45
+	COMBRELOC=ldscripts/${EMULATION_NAME}.xdceo.tmp
cf4a45
+	( echo "/* Script for -pie -z combreloc -z relro -z separate-code: position independent executable, combine & sort relocs with separate code segment */"
cf4a45
+	  . ${CUSTOMIZER_SCRIPT}
cf4a45
+	  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
cf4a45
+	) | sed -e '/^ *$/d;s/[	 ]*$//' > ldscripts/${EMULATION_NAME}.xdceo
cf4a45
+	rm -f ${COMBRELOC}
cf4a45
+
cf4a45
+	unset RELRO
cf4a45
+    fi
cf4a45
+    COMBRELOC=
cf4a45
   fi
cf4a45
   unset CREATE_PIE
cf4a45
 fi
cf4a45
diff -rup binutils.orig/ld/testsuite/ld-s390/s390.exp binutils-2.30/ld/testsuite/ld-s390/s390.exp
cf4a45
--- binutils.orig/ld/testsuite/ld-s390/s390.exp	2019-03-11 14:41:06.029550216 +0000
cf4a45
+++ binutils-2.30/ld/testsuite/ld-s390/s390.exp	2019-03-11 14:45:42.066369572 +0000
cf4a45
@@ -70,10 +70,15 @@ set s390xtests {
cf4a45
      {{readelf -WSsrl tlsbin_64.rd} {objdump -dzrj.text tlsbin_64.dd}
cf4a45
       {objdump -sj.got tlsbin_64.sd} {objdump -sj.tdata tlsbin_64.td}}
cf4a45
      "tlsbin_64"}
cf4a45
-    {"GOT: symbol address load from got to larl"
cf4a45
-     "-shared -melf64_s390 --hash-style=sysv --version-script=gotreloc-1.ver" ""
cf4a45
+    {"GOT: norelro symbol address load from got to larl"
cf4a45
+     "-shared -melf64_s390 -z norelro --hash-style=sysv --version-script=gotreloc-1.ver" ""
cf4a45
      "-m64" {gotreloc-1.s}
cf4a45
-     {{objdump -dzrj.text gotreloc_64-1.dd}}
cf4a45
+     {{objdump -dzrj.text gotreloc_64-norelro-1.dd}}
cf4a45
+     "gotreloc_64-1"}
cf4a45
+    {"GOT: relro symbol address load from got to larl"
cf4a45
+     "-shared -melf64_s390 -z relro --hash-style=sysv --version-script=gotreloc-1.ver" ""
cf4a45
+     "-m64" {gotreloc-1.s}
cf4a45
+     {{objdump -dzrj.text gotreloc_64-relro-1.dd}}
cf4a45
      "gotreloc_64-1"}
cf4a45
     {"PLT: offset test"
cf4a45
      "-shared -m elf64_s390 -dT pltoffset-1.ld" ""
cf4a45
--- /dev/null	2019-03-11 08:49:22.227998809 +0000
cf4a45
+++ binutils-2.30/ld/testsuite/ld-s390/gotreloc_64-relro-1.dd	2019-03-11 14:53:27.144667759 +0000
cf4a45
@@ -0,0 +1,12 @@
cf4a45
+tmpdir/gotreloc_64-1:     file format elf64-s390
cf4a45
+
cf4a45
+Disassembly of section .text:
cf4a45
+
cf4a45
+.* <foo>:
cf4a45
+.*:	c0 10 00 00 00 0e [	 ]*larl	%r1,.* <bar>
cf4a45
+.*:	c0 10 00 00 00 0b [	 ]*larl	%r1,.* <bar>
cf4a45
+.*:	c4 1d 00 00 .. .. [	 ]*lrl	%r1,.* <_GLOBAL_OFFSET_TABLE_\+0x18>
cf4a45
+.*:	58 10 c0 18 [	 ]*l	%r1,24\(%r12\)
cf4a45
+.*:	e3 10 c0 18 00 58 [	 ]*ly	%r1,24\(%r12\)
cf4a45
+.* <bar>:
cf4a45
+.*:	00 00 01 23       	.long	0x00000123
cf4a45
--- /dev/null	2019-03-11 08:49:22.227998809 +0000
cf4a45
+++ binutils-2.30/ld/testsuite/ld-s390/gotreloc_64-norelro-1.dd	2019-03-11 14:45:42.066369572 +0000
cf4a45
@@ -0,0 +1,12 @@
cf4a45
+tmpdir/gotreloc_64-1:     file format elf64-s390
cf4a45
+
cf4a45
+Disassembly of section .text:
cf4a45
+
cf4a45
+.* <foo>:
cf4a45
+.*:	c0 10 00 00 00 0e [	 ]*larl	%r1,.* <bar>
cf4a45
+.*:	c0 10 00 00 00 0b [	 ]*larl	%r1,.* <bar>
cf4a45
+.*:	c4 1d 00 00 08 86 [	 ]*lrl	%r1,.* <_GLOBAL_OFFSET_TABLE_\+0x18>
cf4a45
+.*:	58 10 c0 18 [	 ]*l	%r1,24\(%r12\)
cf4a45
+.*:	e3 10 c0 18 00 58 [	 ]*ly	%r1,24\(%r12\)
cf4a45
+.* <bar>:
cf4a45
+.*:	00 00 01 23       	.long	0x00000123