From 889b6e259681b33254505cea96edebf1477d44eb Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 19 Jul 2018 13:24:40 +0100 Subject: [PATCH] Improve partial relro support for the s/390. --- binutils-s390-partial-relro.patch | 872 ++++++++++++++++++++++++++++++ binutils.spec | 10 +- 2 files changed, 881 insertions(+), 1 deletion(-) create mode 100644 binutils-s390-partial-relro.patch diff --git a/binutils-s390-partial-relro.patch b/binutils-s390-partial-relro.patch new file mode 100644 index 0000000..83fd98a --- /dev/null +++ b/binutils-s390-partial-relro.patch @@ -0,0 +1,872 @@ +diff -rup binutils.orig/bfd/elf64-s390.c binutils-2.31.1/bfd/elf64-s390.c +--- binutils.orig/bfd/elf64-s390.c 2018-07-19 12:37:28.107030007 +0100 ++++ binutils-2.31.1/bfd/elf64-s390.c 2018-07-19 12:38:11.235548717 +0100 +@@ -481,7 +481,7 @@ elf_s390_is_local_label_name (bfd *abfd, + + #define RELA_ENTRY_SIZE sizeof (Elf64_External_Rela) + +-/* The first three entries in a procedure linkage table are reserved, ++/* The first three entries in a global offset table are reserved, + and the initial contents are unimportant (we zero them out). + Subsequent entries look like this. See the SVR4 ABI 386 + supplement to see how this works. */ +@@ -511,8 +511,8 @@ elf_s390_is_local_label_name (bfd *abfd, + LG 1,0(1) # 6 bytes Load address from GOT in r1 + BCR 15,1 # 2 bytes Jump to address + RET1: BASR 1,0 # 2 bytes Return from GOT 1st time +- LGF 1,12(1) # 6 bytes Load offset in symbl table in r1 +- BRCL 15,-x # 6 bytes Jump to start of PLT ++ LGF 1,12(1) # 6 bytes Load rela.plt offset into r1 ++ BRCL 15,-x # 6 bytes Jump to first PLT entry + .long ? # 4 bytes offset into .rela.plt + + Total = 32 bytes per PLT entry +@@ -1605,8 +1605,7 @@ allocate_dynrelocs (struct elf_link_hash + /* Make room for this entry. */ + s->size += PLT_ENTRY_SIZE; + +- /* We also need to make an entry in the .got.plt section, which +- will be placed in the .got section by the linker script. */ ++ /* We also need to make an entry in the .got.plt section. */ + htab->elf.sgotplt->size += GOT_ENTRY_SIZE; + + /* We also need to make an entry in the .rela.plt section. */ +@@ -1831,6 +1830,20 @@ elf_s390_size_dynamic_sections (bfd *out + } + } + ++ if (htab->elf.sgot && s390_gotplt_after_got_p (info)) ++ { ++ /* _bfd_elf_create_got_section adds the got header size always ++ to .got.plt but we need it in .got if this section comes ++ first. */ ++ htab->elf.sgot->size += 3 * GOT_ENTRY_SIZE; ++ htab->elf.sgotplt->size -= 3 * GOT_ENTRY_SIZE; ++ ++ /* Make the _GLOBAL_OFFSET_TABLE_ symbol point to the .got ++ instead of .got.plt. */ ++ htab->elf.hgot->root.u.def.section = htab->elf.sgot; ++ htab->elf.hgot->root.u.def.value = 0; ++ } ++ + /* Set up .got offsets for local syms, and space for local dynamic + relocs. */ + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) +@@ -2131,7 +2144,6 @@ elf_s390_relocate_section (bfd *output_b + bfd_boolean unresolved_reloc; + bfd_reloc_status_type r; + int tls_type; +- asection *base_got = htab->elf.sgot; + bfd_boolean resolved_to_zero; + + r_type = ELF64_R_TYPE (rel->r_info); +@@ -2172,7 +2184,7 @@ elf_s390_relocate_section (bfd *output_b + case R_390_PLTOFF16: + case R_390_PLTOFF32: + case R_390_PLTOFF64: +- relocation -= htab->elf.sgot->output_section->vma; ++ relocation -= s390_got_pointer (info); + break; + case R_390_GOTPLT12: + case R_390_GOTPLT16: +@@ -2192,10 +2204,10 @@ elf_s390_relocate_section (bfd *output_b + htab->elf.sgot->contents + + local_got_offsets[r_symndx]); + relocation = (local_got_offsets[r_symndx] + +- htab->elf.sgot->output_offset); ++ s390_got_offset (info)); + + if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT) +- relocation += htab->elf.sgot->output_section->vma; ++ relocation += s390_got_pointer (info); + break; + } + default: +@@ -2254,25 +2266,23 @@ elf_s390_relocate_section (bfd *output_b + + if (s390_is_ifunc_symbol_p (h)) + { ++ /* Entry indices of .iplt and .igot.plt match ++ 1:1. No magic PLT first entry here. */ + plt_index = h->plt.offset / PLT_ENTRY_SIZE; +- relocation = (plt_index * GOT_ENTRY_SIZE + +- htab->elf.igotplt->output_offset); +- if (r_type == R_390_GOTPLTENT) +- relocation += htab->elf.igotplt->output_section->vma; ++ relocation = (plt_index * GOT_ENTRY_SIZE ++ + s390_gotplt_offset (info) ++ + htab->elf.igotplt->output_offset); + } + else + { +- /* Calc. index no. +- Current offset - size first entry / entry size. */ +- plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / +- PLT_ENTRY_SIZE; +- +- /* Offset in GOT is PLT index plus GOT headers(3) +- times 8, addr & GOT addr. */ +- relocation = (plt_index + 3) * GOT_ENTRY_SIZE; +- if (r_type == R_390_GOTPLTENT) +- relocation += htab->elf.sgot->output_section->vma; ++ plt_index = ((h->plt.offset - PLT_FIRST_ENTRY_SIZE) ++ / PLT_ENTRY_SIZE); ++ ++ relocation = (plt_index * GOT_ENTRY_SIZE ++ + s390_gotplt_offset (info)); + } ++ if (r_type == R_390_GOTPLTENT) ++ relocation += s390_got_pointer (info); + unresolved_reloc = FALSE; + break; + } +@@ -2286,7 +2296,7 @@ elf_s390_relocate_section (bfd *output_b + case R_390_GOTENT: + /* Relocation is to the entry for this symbol in the global + offset table. */ +- if (base_got == NULL) ++ if (htab->elf.sgot == NULL) + abort (); + + if (h != NULL) +@@ -2303,8 +2313,19 @@ elf_s390_relocate_section (bfd *output_b + { + /* No explicit GOT usage so redirect to the + got.iplt slot. */ +- base_got = htab->elf.igotplt; +- off = h->plt.offset / PLT_ENTRY_SIZE * GOT_ENTRY_SIZE; ++ relocation = (s390_gotplt_offset (info) ++ + htab->elf.igotplt->output_offset ++ + (h->plt.offset / PLT_ENTRY_SIZE ++ * GOT_ENTRY_SIZE)); ++ ++ /* For @GOTENT the relocation is against the offset between ++ the instruction and the symbols entry in the GOT and not ++ between the start of the GOT and the symbols entry. We ++ add the vma of the GOT to get the correct value. */ ++ if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT) ++ relocation += s390_got_pointer (info); ++ ++ break; + } + else + { +@@ -2337,7 +2358,7 @@ elf_s390_relocate_section (bfd *output_b + else + { + bfd_put_64 (output_bfd, relocation, +- base_got->contents + off); ++ htab->elf.sgot->contents + off); + h->got.offset |= 1; + } + +@@ -2419,7 +2440,7 @@ elf_s390_relocate_section (bfd *output_b + if (off >= (bfd_vma) -2) + abort (); + +- relocation = base_got->output_offset + off; ++ relocation = s390_got_offset (info) + off; + + /* For @GOTENT the relocation is against the offset between + the instruction and the symbols entry in the GOT and not +@@ -2427,7 +2448,7 @@ elf_s390_relocate_section (bfd *output_b + add the vma of the GOT to get the correct value. */ + if ( r_type == R_390_GOTENT + || r_type == R_390_GOTPLTENT) +- relocation += base_got->output_section->vma; ++ relocation += s390_got_pointer (info); + + break; + +@@ -2445,22 +2466,17 @@ elf_s390_relocate_section (bfd *output_b + relocation = (htab->elf.iplt->output_section->vma + + htab->elf.iplt->output_offset + + h->plt.offset +- - htab->elf.sgot->output_section->vma); ++ - s390_got_pointer (info)); + goto do_relocation; + } + +- /* Note that sgot->output_offset is not involved in this +- calculation. We always want the start of .got. If we +- defined _GLOBAL_OFFSET_TABLE in a different way, as is +- permitted by the ABI, we might have to change this +- calculation. */ +- relocation -= htab->elf.sgot->output_section->vma; ++ relocation -= s390_got_pointer (info); + break; + + case R_390_GOTPC: + case R_390_GOTPCDBL: + /* Use global offset table as symbol value. */ +- relocation = htab->elf.sgot->output_section->vma; ++ relocation = s390_got_pointer (info); + unresolved_reloc = FALSE; + break; + +@@ -2509,7 +2525,7 @@ elf_s390_relocate_section (bfd *output_b + || h->plt.offset == (bfd_vma) -1 + || (htab->elf.splt == NULL && !s390_is_ifunc_symbol_p (h))) + { +- relocation -= htab->elf.sgot->output_section->vma; ++ relocation -= s390_got_pointer (info); + break; + } + +@@ -2517,12 +2533,12 @@ elf_s390_relocate_section (bfd *output_b + relocation = (htab->elf.iplt->output_section->vma + + htab->elf.iplt->output_offset + + h->plt.offset +- - htab->elf.sgot->output_section->vma); ++ - s390_got_pointer (info)); + else + relocation = (htab->elf.splt->output_section->vma + + htab->elf.splt->output_offset + + h->plt.offset +- - htab->elf.sgot->output_section->vma); ++ - s390_got_pointer (info)); + unresolved_reloc = FALSE; + break; + +@@ -3296,7 +3312,7 @@ elf_s390_finish_dynamic_symbol (bfd *out + if (h->plt.offset != (bfd_vma) -1) + { + bfd_vma plt_index; +- bfd_vma got_offset; ++ bfd_vma gotplt_offset; + Elf_Internal_Rela rela; + bfd_byte *loc; + +@@ -3325,18 +3341,25 @@ elf_s390_finish_dynamic_symbol (bfd *out + Current offset - size first entry / entry size. */ + plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE; + +- /* Offset in GOT is PLT index plus GOT headers(3) times 8, +- addr & GOT addr. */ +- got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; ++ /* The slots in the .got.plt correspond to the PLT slots in ++ the same order. */ ++ gotplt_offset = plt_index * GOT_ENTRY_SIZE; ++ ++ /* If .got.plt comes first it needs to contain the 3 header ++ entries. */ ++ if (!s390_gotplt_after_got_p (info)) ++ gotplt_offset += 3 * GOT_ENTRY_SIZE; + + /* Fill in the blueprint of a PLT. */ + memcpy (htab->elf.splt->contents + h->plt.offset, elf_s390x_plt_entry, + PLT_ENTRY_SIZE); + +- /* Fixup the relative address to the GOT entry */ ++ /* The first instruction in the PLT entry is a LARL loading ++ the address of the GOT slot. We write the 4 byte ++ immediate operand of the LARL instruction here. */ + bfd_put_32 (output_bfd, + (htab->elf.sgotplt->output_section->vma + +- htab->elf.sgotplt->output_offset + got_offset ++ htab->elf.sgotplt->output_offset + gotplt_offset + - (htab->elf.splt->output_section->vma + + htab->elf.splt->output_offset + + h->plt.offset))/2, +@@ -3356,12 +3379,12 @@ elf_s390_finish_dynamic_symbol (bfd *out + + htab->elf.splt->output_offset + + h->plt.offset + + 14), +- htab->elf.sgotplt->contents + got_offset); ++ htab->elf.sgotplt->contents + gotplt_offset); + + /* Fill in the entry in the .rela.plt section. */ + rela.r_offset = (htab->elf.sgotplt->output_section->vma + + htab->elf.sgotplt->output_offset +- + got_offset); ++ + gotplt_offset); + rela.r_info = ELF64_R_INFO (h->dynindx, R_390_JMP_SLOT); + rela.r_addend = 0; + loc = htab->elf.srelplt->contents + plt_index * +@@ -3568,8 +3591,8 @@ elf_s390_finish_dynamic_sections (bfd *o + continue; + + case DT_PLTGOT: +- s = htab->elf.sgotplt; +- dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; ++ /* DT_PLTGOT matches _GLOBAL_OFFSET_TABLE_ */ ++ dyn.d_un.d_ptr = s390_got_pointer (info); + break; + + case DT_JMPREL: +@@ -3606,10 +3629,11 @@ elf_s390_finish_dynamic_sections (bfd *o + /* fill in blueprint for plt 0 entry */ + memcpy (htab->elf.splt->contents, elf_s390x_first_plt_entry, + PLT_FIRST_ENTRY_SIZE); +- /* Fixup relative address to start of GOT */ ++ /* The second instruction in the first PLT entry is a LARL ++ loading the GOT pointer. Fill in the LARL immediate ++ address. */ + bfd_put_32 (output_bfd, +- (htab->elf.sgotplt->output_section->vma +- + htab->elf.sgotplt->output_offset ++ (s390_got_pointer (info) + - htab->elf.splt->output_section->vma + - htab->elf.splt->output_offset - 6)/2, + htab->elf.splt->contents + 8); +@@ -3619,21 +3643,22 @@ elf_s390_finish_dynamic_sections (bfd *o + = PLT_ENTRY_SIZE; + } + +- if (htab->elf.sgotplt) ++ if (htab->elf.hgot && htab->elf.hgot->root.u.def.section) + { + /* Fill in the first three entries in the global offset table. */ +- if (htab->elf.sgotplt->size > 0) ++ if (htab->elf.hgot->root.u.def.section->size > 0) + { + bfd_put_64 (output_bfd, + (sdyn == NULL ? (bfd_vma) 0 + : sdyn->output_section->vma + sdyn->output_offset), +- htab->elf.sgotplt->contents); ++ htab->elf.hgot->root.u.def.section->contents); + /* One entry for shared object struct ptr. */ +- bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 8); ++ bfd_put_64 (output_bfd, (bfd_vma) 0, ++ htab->elf.hgot->root.u.def.section->contents + 8); + /* One entry for _dl_runtime_resolve. */ +- bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 16); ++ bfd_put_64 (output_bfd, (bfd_vma) 0, ++ htab->elf.hgot->root.u.def.section->contents + 16); + } +- + elf_section_data (htab->elf.sgot->output_section) + ->this_hdr.sh_entsize = 8; + } +diff -rup binutils.orig/bfd/elf-s390-common.c binutils-2.31.1/bfd/elf-s390-common.c +--- binutils.orig/bfd/elf-s390-common.c 2018-07-19 12:37:28.113029940 +0100 ++++ binutils-2.31.1/bfd/elf-s390-common.c 2018-07-19 12:38:11.235548717 +0100 +@@ -30,6 +30,87 @@ s390_is_ifunc_symbol_p (struct elf_link_ + return h->type == STT_GNU_IFUNC || eh->ifunc_resolver_address != 0; + } + ++/* Return true if .got.plt is supposed to be emitted after .got. */ ++ ++static inline bfd_boolean ++s390_gotplt_after_got_p (struct bfd_link_info *info) ++{ ++ struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info); ++ ++ if (!htab->elf.sgot || !htab->elf.sgotplt) ++ return TRUE; ++ ++ if (htab->elf.sgot->output_section == htab->elf.sgotplt->output_section) ++ { ++ if (htab->elf.sgot->output_offset < htab->elf.sgotplt->output_offset) ++ return TRUE; ++ } ++ else ++ { ++ if (htab->elf.sgot->output_section->vma ++ <= htab->elf.sgotplt->output_section->vma) ++ return TRUE; ++ } ++ return FALSE; ++} ++ ++/* Return the value of the _GLOBAL_OFFSET_TABLE_ symbol. */ ++ ++static inline bfd_vma ++s390_got_pointer (struct bfd_link_info *info) ++{ ++ struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info); ++ bfd_vma got_pointer; ++ ++ BFD_ASSERT (htab && htab->elf.hgot); ++ ++ got_pointer = (htab->elf.hgot->root.u.def.section->output_section->vma ++ + htab->elf.hgot->root.u.def.section->output_offset); ++ /* Our ABI requires the GOT pointer to point at the very beginning ++ of the global offset table. */ ++ BFD_ASSERT (got_pointer ++ <= (htab->elf.sgot->output_section->vma ++ + htab->elf.sgot->output_offset)); ++ BFD_ASSERT (got_pointer ++ <= (htab->elf.sgotplt->output_section->vma ++ + htab->elf.sgotplt->output_offset)); ++ ++ return got_pointer; ++} ++ ++ ++/* Return the offset of the .got versus _GLOBAL_OFFSET_TABLE_. */ ++ ++static inline bfd_vma ++s390_got_offset (struct bfd_link_info *info) ++{ ++ struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info); ++ ++ /* The absolute address of the .got in the target image. */ ++ bfd_vma got_address = (htab->elf.sgot->output_section->vma ++ + htab->elf.sgot->output_offset); ++ ++ /* GOT offset must not be negative. */ ++ BFD_ASSERT (s390_got_pointer (info) <= got_address); ++ return got_address - s390_got_pointer (info); ++} ++ ++/* Return the offset of the .got.plt versus _GLOBAL_OFFSET_TABLE_. */ ++ ++static inline bfd_vma ++s390_gotplt_offset (struct bfd_link_info *info) ++{ ++ struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info); ++ ++ /* The absolute address of the .got.plt in the target image. */ ++ bfd_vma gotplt_address = (htab->elf.sgotplt->output_section->vma ++ + htab->elf.sgotplt->output_offset); ++ ++ /* GOT offset must not be negative. */ ++ BFD_ASSERT (s390_got_pointer (info) <= gotplt_address); ++ return gotplt_address - s390_got_pointer (info); ++} ++ + /* Create sections needed by STT_GNU_IFUNC symbol. */ + + static bfd_boolean +diff -rup binutils.orig/ld/emulparams/elf64_s390.sh binutils-2.31.1/ld/emulparams/elf64_s390.sh +--- binutils.orig/ld/emulparams/elf64_s390.sh 2018-07-19 12:37:28.544025130 +0100 ++++ binutils-2.31.1/ld/emulparams/elf64_s390.sh 2018-07-19 12:38:11.235548717 +0100 +@@ -11,9 +11,12 @@ NOP=0x07070707 + TEMPLATE_NAME=elf32 + GENERATE_SHLIB_SCRIPT=yes + GENERATE_PIE_SCRIPT=yes ++GENERATE_RELRO_SCRIPT=yes + NO_SMALL_DATA=yes + EXTRA_EM_FILE=s390 + IREL_IN_PLT= ++SEPARATE_GOTPLT=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. +diff -rup binutils.orig/ld/emultempl/elf32.em binutils-2.31.1/ld/emultempl/elf32.em +--- binutils.orig/ld/emultempl/elf32.em 2018-07-19 12:37:28.549025074 +0100 ++++ binutils-2.31.1/ld/emultempl/elf32.em 2018-07-19 12:37:39.041907980 +0100 +@@ -2376,17 +2376,41 @@ echo ' && link_info.combrelo + echo ' && link_info.relro' >> e${EMULATION_NAME}.c + echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xdw >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c ++echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c ++echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xdceo >> e${EMULATION_NAME}.c ++fi + echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c + echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c + echo ' && link_info.combreloc) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xdce >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c ++echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xdco >> e${EMULATION_NAME}.c ++fi + echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c + echo ' && link_info.combreloc) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xdc >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c ++echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xdeo >> e${EMULATION_NAME}.c ++fi + fi + echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c + echo ' && link_info.separate_code) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xde >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xdo >> e${EMULATION_NAME}.c ++fi + echo ' ; else if (bfd_link_pie (&link_info)) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xd >> e${EMULATION_NAME}.c + fi +@@ -2402,17 +2426,41 @@ echo ' && link_info.combrelo + echo ' && link_info.relro' >> e${EMULATION_NAME}.c + echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xsw >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c ++echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c ++echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xsceo >> e${EMULATION_NAME}.c ++fi + echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c + echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c + echo ' && link_info.separate_code) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xsce >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c ++echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xsco >> e${EMULATION_NAME}.c ++fi + echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c + echo ' && link_info.combreloc) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c ++echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xseo >> e${EMULATION_NAME}.c ++fi + fi + echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c + echo ' && link_info.separate_code) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xse >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xso >> e${EMULATION_NAME}.c ++fi + echo ' ; else if (bfd_link_dll (&link_info)) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c + fi +@@ -2425,14 +2473,34 @@ echo ' ; else if (link_info.combreloc' + echo ' && link_info.relro' >> e${EMULATION_NAME}.c + echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xw >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c ++echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xceo >> e${EMULATION_NAME}.c ++fi + echo ' ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c + echo ' && link_info.separate_code) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xce >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xco >> e${EMULATION_NAME}.c ++fi + echo ' ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c + fi +-echo ' ; else if (link_info.separate_code) return' >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (link_info.separate_code' >> e${EMULATION_NAME}.c ++echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xeo >> e${EMULATION_NAME}.c ++fi ++echo ' ; else if (link_info.separate_code) return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.xe >> e${EMULATION_NAME}.c ++if test -n "$GENERATE_RELRO_SCRIPT" ; then ++echo ' ; else if (link_info.relro) return' >> e${EMULATION_NAME}.c ++sed $sc ldscripts/${EMULATION_NAME}.xo >> e${EMULATION_NAME}.c ++fi + echo ' ; else return' >> e${EMULATION_NAME}.c + sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c + echo '; }' >> e${EMULATION_NAME}.c +@@ -2471,6 +2539,21 @@ fragment < ldscripts/${EMULATION_NAME}.xe + ++if test -n "$GENERATE_RELRO_SCRIPT"; then ++ LD_FLAG= ++ RELRO=" " ++ ( echo "/* Script for -z relo: generate normal executables with separate code segment */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xo ++ LD_FLAG=textonly ++ ( echo "/* Script for -z separate-code -z relo: generate normal executables with separate code segment */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xeo ++ unset RELRO ++fi + LD_FLAG=n + DATA_ALIGNMENT=${DATA_ALIGNMENT_n} + ( echo "/* Script for -n: mix text and data on same page */" +@@ -353,6 +367,25 @@ if test -n "$GENERATE_COMBRELOC_SCRIPT"; + rm -f ${COMBRELOC} + COMBRELOC= + unset RELRO_NOW ++ if test -n "$GENERATE_RELRO_SCRIPT"; then ++ LD_FLAG=c ++ RELRO=" " ++ COMBRELOC=ldscripts/${EMULATION_NAME}.xco.tmp ++ ( echo "/* Script for -z combreloc -z relro: combine and sort reloc sections */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xco ++ rm -f ${COMBRELOC} ++ LD_FLAG=ctextonly ++ COMBRELOC=ldscripts/${EMULATION_NAME}.xceo.tmp ++ ( echo "/* Script for -z combreloc -z separate-code -z relro: combine and sort reloc sections */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xceo ++ rm -f ${COMBRELOC} ++ COMBRELOC= ++ unset RELRO ++ fi + fi + + if test -n "$GENERATE_SHLIB_SCRIPT"; then +@@ -370,6 +403,23 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; the + . ${CUSTOMIZER_SCRIPT} + . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc + ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xse ++ ++ if test -n "$GENERATE_RELRO_SCRIPT"; then ++ RELRO=" " ++ LD_FLAG=shared ++ ( ++ echo "/* Script for ld --shared -z relro: link shared library */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xso ++ LD_FLAG=sharedtextonly ++ ( ++ echo "/* Script for ld --shared -z relro -z separate-code: link shared library with separate code segment */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xseo ++ unset RELRO ++ fi + if test -n "$GENERATE_COMBRELOC_SCRIPT"; then + DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}} + LD_FLAG=cshared +@@ -401,8 +451,27 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; the + . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc + ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xswe + rm -f ${COMBRELOC} +- COMBRELOC= + unset RELRO_NOW ++ ++ if test -n "$GENERATE_RELRO_SCRIPT"; then ++ LD_FLAG=wshared ++ RELRO=" " ++ COMBRELOC=ldscripts/${EMULATION_NAME}.xsco.tmp ++ ( echo "/* Script for --shared -z combreloc -z relro: shared library, combine & sort relocs with separate code segment */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xsco ++ rm -f ${COMBRELOC} ++ LD_FLAG=wsharedtextonly ++ COMBRELOC=ldscripts/${EMULATION_NAME}.xsceo.tmp ++ ( echo "/* Script for --shared -z combreloc -z relro -z separate-code: shared library, combine & sort relocs with separate code segment */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xsceo ++ rm -f ${COMBRELOC} ++ unset RELRO ++ fi ++ COMBRELOC= + fi + unset CREATE_SHLIB + fi +@@ -422,6 +491,22 @@ if test -n "$GENERATE_PIE_SCRIPT"; then + . ${CUSTOMIZER_SCRIPT} + . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc + ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xde ++ if test -n "$GENERATE_RELRO_SCRIPT"; then ++ RELRO=" " ++ LD_FLAG=pie ++ ( ++ echo "/* Script for ld -pie -z relro: link position independent executable */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdo ++ LD_FLAG=pietextonly ++ ( ++ echo "/* Script for ld -pie -z relro -z separate-code: link position independent executable with separate code segment */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdeo ++ unset RELRO ++ fi + if test -n "$GENERATE_COMBRELOC_SCRIPT"; then + DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}} + COMBRELOC=ldscripts/${EMULATION_NAME}.xdc.tmp +@@ -453,8 +538,28 @@ if test -n "$GENERATE_PIE_SCRIPT"; then + . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc + ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdwe + rm -f ${COMBRELOC} +- COMBRELOC= + unset RELRO_NOW ++ ++ if test -n "$GENERATE_RELRO_SCRIPT"; then ++ LD_FLAG=wpie ++ RELRO=" " ++ COMBRELOC=ldscripts/${EMULATION_NAME}.xdco.tmp ++ ( echo "/* Script for -pie -z combreloc -z relro: position independent executable, combine & sort relocs with separate code segment */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdco ++ rm -f ${COMBRELOC} ++ LD_FLAG=wpietextonly ++ COMBRELOC=ldscripts/${EMULATION_NAME}.xdceo.tmp ++ ( echo "/* Script for -pie -z combreloc -z relro -z separate-code: position independent executable, combine & sort relocs with separate code segment */" ++ . ${CUSTOMIZER_SCRIPT} ++ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ++ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdceo ++ rm -f ${COMBRELOC} ++ ++ unset RELRO ++ fi ++ COMBRELOC= + fi + unset CREATE_PIE + fi +Only in binutils.orig/ld/testsuite/ld-s390: gotreloc_64-1.dd +Only in binutils-2.31.1/ld/testsuite/ld-s390: gotreloc_64-norelro-1.dd +Only in binutils-2.31.1/ld/testsuite/ld-s390: gotreloc_64-relro-1.dd +diff -rup binutils.orig/ld/testsuite/ld-s390/s390.exp binutils-2.31.1/ld/testsuite/ld-s390/s390.exp +--- binutils.orig/ld/testsuite/ld-s390/s390.exp 2018-07-19 12:37:28.498025644 +0100 ++++ binutils-2.31.1/ld/testsuite/ld-s390/s390.exp 2018-07-19 12:38:11.236548705 +0100 +@@ -70,10 +70,15 @@ set s390xtests { + {{readelf -WSsrl tlsbin_64.rd} {objdump -dzrj.text tlsbin_64.dd} + {objdump -sj.got tlsbin_64.sd} {objdump -sj.tdata tlsbin_64.td}} + "tlsbin_64"} +- {"GOT: symbol address load from got to larl" +- "-shared -melf64_s390 --hash-style=sysv --version-script=gotreloc-1.ver" "" ++ {"GOT: norelro symbol address load from got to larl" ++ "-shared -melf64_s390 -z norelro --hash-style=sysv --version-script=gotreloc-1.ver" "" + "-m64" {gotreloc-1.s} +- {{objdump -dzrj.text gotreloc_64-1.dd}} ++ {{objdump -dzrj.text gotreloc_64-norelro-1.dd}} ++ "gotreloc_64-1"} ++ {"GOT: relro symbol address load from got to larl" ++ "-shared -melf64_s390 -z relro --hash-style=sysv --version-script=gotreloc-1.ver" "" ++ "-m64" {gotreloc-1.s} ++ {{objdump -dzrj.text gotreloc_64-relro-1.dd}} + "gotreloc_64-1"} + {"PLT: offset test" + "-shared -m elf64_s390 -dT pltoffset-1.ld" "" diff --git a/binutils.spec b/binutils.spec index 4eab4a8..985ca73 100644 --- a/binutils.spec +++ b/binutils.spec @@ -69,7 +69,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.31.1 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ URL: https://sourceware.org/binutils @@ -163,6 +163,10 @@ Patch11: binutils-do-not-provide-shared-section-symbols.patch # Lifetime: Fixed in 2.32 (maybe) Patch12: binutils-gold-ignore-discarded-note-relocs.patch +# Purpose: Improve partial relro support for 64-bit s/390. +# Lifetime: Fixed in 2.32 +Patch13: binutils-s390-partial-relro.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -299,6 +303,7 @@ using libelf instead of BFD. %patch10 -p1 %patch11 -p1 %patch12 -p1 +%patch13 -p1 # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -706,6 +711,9 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Thu Jul 19 2018 Fedora Release Engineering - 2.31.2-1 +- Improve partial relro support for the s/390. + * Thu Jul 19 2018 Fedora Release Engineering - 2.31.1-1 - Rebase to official 2.31.1 GNU Binutils release. - Retire: binutils-2.22.52.0.1-export-demangle.h.patch