]> 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>
Wed, 8 Jun 2016 12:07:29 +0000 (14:07 +0200)
bfd/elf64-s390.c
ld/emulparams/elf64_s390.sh

index f3282d82785fde9f262dfab2b88663a4039f16be..5c12c6c676b4acf55ec514c4b66ad6795e840dfe 100644 (file)
@@ -736,6 +736,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 +751,24 @@ 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;
+    }
+  else
+    got_section = htab->elf.sgotplt;
+
+  /* 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 +3834,16 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
        ->this_hdr.sh_entsize = 8;
     }
 
+  /* The condition here has to match the one in create_got_section.  */
+  if (htab->elf.sgot && info->combreloc && info->relro &&
+      !(info->flags & DF_BIND_NOW))
+    {
+      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 +3953,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.