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

index f3282d82785fde9f262dfab2b88663a4039f16be..6e503811b77d99a101aeaf550b2c6a13cebe15e8 100644 (file)
@@ -653,6 +653,8 @@ struct elf_s390_link_hash_table
   asection *srelbss;
   asection *irelifunc;
 
+  bfd_boolean split_got;
+
   union {
     bfd_signed_vma refcount;
     bfd_vma offset;
@@ -736,6 +738,8 @@ 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;
@@ -749,6 +753,28 @@ create_got_section (bfd *dynobj,
   htab->elf.srelgot = bfd_get_linker_section (dynobj, ".rela.got");
   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;
 }
 
@@ -3814,6 +3840,14 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
        ->this_hdr.sh_entsize = 8;
     }
 
+  if (htab->elf.sgot && htab->split_got)
+    {
+      bfd_put_64 (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)
     {
@@ -3923,6 +3957,8 @@ const struct elf_size_info s390_elf64_size_info =
 #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    24
 #define elf_backend_rela_normal                1
 
index 98db3d3bc61b2cb00cc4fa66848d9912fa060127..9d58a3b4240ae315382d0e2e833151581f7525de 100644 (file)
@@ -11,8 +11,11 @@ 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) >= 24 ? 24 : 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.