]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
bfd/elf32-s390: Support partial got relro.
authorMarcin Kościelnicki <koriakin@0x04.net>
Fri, 3 Jun 2016 14:42:25 +0000 (16:42 +0200)
committerMarcin Kościelnicki <koriakin@0x04.net>
Mon, 4 Jul 2016 09:04:10 +0000 (11:04 +0200)
bfd/elf32-s390.c
ld/emulparams/elf_s390.sh

index e4ecff12967c5b3085e180e241e381fba88d5425..dc4b65af4426fd68ee103fc8ea269217cfecb0a0 100644 (file)
@@ -753,6 +753,8 @@ struct elf_s390_link_hash_table
   asection *srelbss;
   asection *irelifunc;
 
+  bfd_boolean split_got;
+
   union
   {
     bfd_signed_vma refcount;
@@ -836,6 +838,8 @@ static bfd_boolean
 create_got_section (bfd *dynobj, struct bfd_link_info *info)
 {
   struct elf_s390_link_hash_table *htab;
+  struct elf_link_hash_entry *h;
+  asection *got_section;
 
   if (! _bfd_elf_create_got_section (dynobj, info))
     return FALSE;
@@ -847,6 +851,27 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
   if (!htab->elf.sgot || !htab->elf.sgotplt || !htab->elf.srelgot)
     abort ();
 
+  /* The condition here has to match linker script selection.  */
+  if (info->combreloc && info->relro && !(info->flags & DF_BIND_NOW))
+    {
+      htab->elf.sgot->size += GOT_ENTRY_SIZE;
+      got_section = htab->elf.sgot;
+      htab->split_got = TRUE;
+    }
+  else
+    {
+      got_section = htab->elf.sgotplt;
+      htab->split_got = FALSE;
+    }
+
+  /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
+     or .got.plt section.  */
+  h = _bfd_elf_define_linkage_sym (dynobj, info, got_section,
+                                  "_GLOBAL_OFFSET_TABLE_");
+  elf_hash_table (info)->hgot = h;
+  if (h == NULL)
+       return FALSE;
+
   return TRUE;
 }
 
@@ -4054,6 +4079,15 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
       elf_section_data (htab->elf.sgotplt->output_section)
        ->this_hdr.sh_entsize = 4;
     }
+
+  if (htab->elf.sgot && htab->split_got)
+    {
+      bfd_put_32 (output_bfd,
+                 (sdyn == NULL ? (bfd_vma) 0
+                  : sdyn->output_section->vma + sdyn->output_offset),
+                 htab->elf.sgot->contents);
+    }
+
   /* Finish dynamic symbol for local IFUNC symbols.  */
   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
@@ -4156,6 +4190,8 @@ elf32_s390_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 #define elf_backend_want_got_plt       1
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
+/* We create got symbol ourselves, since it may not be in .got.plt */
+#define elf_backend_want_got_sym       0
 #define elf_backend_got_header_size    12
 #define elf_backend_rela_normal                1
 
index f2286ecc16048c6c19b00e06b7c8424a2decd2e0..cbf567233a2318c6d1871dd499211a8d15675a78 100644 (file)
@@ -10,5 +10,8 @@ NOP=0x07070707
 TEMPLATE_NAME=elf32
 GENERATE_SHLIB_SCRIPT=yes
 GENERATE_PIE_SCRIPT=yes
+GENERATE_RELRO_SCRIPT=yes
 NO_SMALL_DATA=yes
 IREL_IN_PLT=
+SEPARATE_GOTPLT="SIZEOF (.got.plt) >= 12 ? 12 : 0"
+test -z "$RELRO" && unset SEPARATE_GOTPLT