diff options
author | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-06-03 16:42:25 +0200 |
---|---|---|
committer | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-06-08 14:07:29 +0200 |
commit | d5879ef4f6557aa3cccba3c442b1c4e0ab640006 (patch) | |
tree | ba70f60e2c37b8ecb6b0369852bf2bfae820e11b | |
parent | 926671ce05da75d5c6b83fb887befa3e517fd3f6 (diff) | |
download | fsf-binutils-gdb-d5879ef4f6557aa3cccba3c442b1c4e0ab640006.zip fsf-binutils-gdb-d5879ef4f6557aa3cccba3c442b1c4e0ab640006.tar.gz fsf-binutils-gdb-d5879ef4f6557aa3cccba3c442b1c4e0ab640006.tar.bz2 |
bfd/elf32-s390: Support partial got relro.
-rw-r--r-- | bfd/elf32-s390.c | 32 | ||||
-rw-r--r-- | ld/emulparams/elf_s390.sh | 3 |
2 files changed, 35 insertions, 0 deletions
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index e4ecff1..ade0c08 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -836,6 +836,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 +849,23 @@ 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; + } + 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; } @@ -4054,6 +4073,17 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd, elf_section_data (htab->elf.sgotplt->output_section) ->this_hdr.sh_entsize = 4; } + + /* 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_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 +4186,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 diff --git a/ld/emulparams/elf_s390.sh b/ld/emulparams/elf_s390.sh index f2286ec..cbf5672 100644 --- a/ld/emulparams/elf_s390.sh +++ b/ld/emulparams/elf_s390.sh @@ -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 |