From: Andreas Krebbel Date: Mon, 11 Jun 2018 11:23:00 +0000 (+0200) Subject: ld: Enable using separate linker script for -z relro X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a38137289e91fd548fc27fb6566a439233b94d65;p=binutils-gdb.git ld: Enable using separate linker script for -z relro With this patch dedicated linker scripts can be generated for partial relro triggered by defining GENERATE_RELRO_SCRIPT in the target specific scripts. This is necessary for e.g. S/390 where usually the .got.plt comes first and prevents the relro segment from being extended across the non-plt GOT entries. The patch started with the work from Marcin taken from the mwk user branches. However, the patch needed substantial changes due to the 'separate code' feature which got committed in the meantime. ld/ChangeLog: 2018-07-18 Andreas Krebbel Marcin Koƛcielnicki * emultempl/elf32.em: Add code to pick dedicated linker scripts for partial relro. * genscripts.sh: Generate dedicated linker scripts for partial relro. --- diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 1ad9d6b6fa8..5160e2449b9 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -2376,17 +2376,41 @@ echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c 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.combreloc' >> e${EMULATION_NAME}.c 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' >> e${EMULATION_NAME}.c 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 +398,25 @@ if test -n "$GENERATE_COMBRELOC_SCRIPT"; then 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 +434,23 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; then . ${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 +482,27 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; then . ${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 +522,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 +569,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