diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2018-06-11 13:23:00 +0200 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.ibm.com> | 2018-07-18 13:20:06 +0200 |
commit | a38137289e91fd548fc27fb6566a439233b94d65 (patch) | |
tree | 6cfffbd27fb55feb22dc50b2c935cc047d0687a0 /ld | |
parent | 0984c34e7683e1e987eaf4f9e057b678cb67efa6 (diff) | |
download | binutils-a38137289e91fd548fc27fb6566a439233b94d65.zip binutils-a38137289e91fd548fc27fb6566a439233b94d65.tar.gz binutils-a38137289e91fd548fc27fb6566a439233b94d65.tar.bz2 |
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 <krebbel@linux.ibm.com>
Marcin KoĆcielnicki <koriakin@0x04.net>
* emultempl/elf32.em: Add code to pick dedicated linker scripts
for partial relro.
* genscripts.sh: Generate dedicated linker scripts for partial relro.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/emultempl/elf32.em | 149 | ||||
-rwxr-xr-x | ld/genscripts.sh | 150 |
2 files changed, 291 insertions, 8 deletions
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 1ad9d6b..5160e24 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 <<EOF else return "ldscripts/${EMULATION_NAME}.xdw"; } +EOF +if test -n "$GENERATE_RELRO_SCRIPT" ; then +fragment <<EOF + else if (bfd_link_pie (&link_info) + && link_info.combreloc + && link_info.relro) + { + if (link_info.separate_code) + return "ldscripts/${EMULATION_NAME}.xdceo"; + else + return "ldscripts/${EMULATION_NAME}.xdco"; + } +EOF +fi +fragment <<EOF else if (bfd_link_pie (&link_info) && link_info.combreloc) { @@ -2481,6 +2564,18 @@ fragment <<EOF } EOF fi +if test -n "$GENERATE_RELRO_SCRIPT" ; then +fragment <<EOF + else if (bfd_link_pie (&link_info) + && link_info.relro) + { + if (link_info.separate_code) + return "ldscripts/${EMULATION_NAME}.xdeo"; + else + return "ldscripts/${EMULATION_NAME}.xdo"; + } +EOF +fi fragment <<EOF else if (bfd_link_pie (&link_info)) { @@ -2502,6 +2597,21 @@ fragment <<EOF else return "ldscripts/${EMULATION_NAME}.xsw"; } +EOF +if test -n "$GENERATE_RELRO_SCRIPT" ; then +fragment <<EOF + else if (bfd_link_dll (&link_info) + && link_info.combreloc + && link_info.relro) + { + if (link_info.separate_code) + return "ldscripts/${EMULATION_NAME}.xsceo"; + else + return "ldscripts/${EMULATION_NAME}.xsco"; + } +EOF +fi +fragment <<EOF else if (bfd_link_dll (&link_info) && link_info.combreloc) { if (link_info.separate_code) @@ -2511,6 +2621,18 @@ fragment <<EOF } EOF fi +if test -n "$GENERATE_RELRO_SCRIPT" ; then +fragment <<EOF + else if (bfd_link_dll (&link_info) + && link_info.relro) + { + if (link_info.separate_code) + return "ldscripts/${EMULATION_NAME}.xseo"; + else + return "ldscripts/${EMULATION_NAME}.xso"; + } +EOF +fi fragment <<EOF else if (bfd_link_dll (&link_info)) { @@ -2531,6 +2653,20 @@ fragment <<EOF else return "ldscripts/${EMULATION_NAME}.xw"; } +EOF +if test -n "$GENERATE_RELRO_SCRIPT" ; then +fragment <<EOF + else if (link_info.combreloc + && link_info.relro) + { + if (link_info.separate_code) + return "ldscripts/${EMULATION_NAME}.xceo"; + else + return "ldscripts/${EMULATION_NAME}.xco"; + } +EOF +fi +fragment <<EOF else if (link_info.combreloc) { if (link_info.separate_code) @@ -2540,6 +2676,17 @@ fragment <<EOF } EOF fi +if test -n "$GENERATE_RELRO_SCRIPT" ; then +fragment <<EOF + else if (link_info.relro) + { + if (link_info.separate_code) + return "ldscripts/${EMULATION_NAME}.xeo"; + else + return "ldscripts/${EMULATION_NAME}.xo"; + } +EOF +fi fragment <<EOF else { diff --git a/ld/genscripts.sh b/ld/genscripts.sh index 370b222..6300a6a 100755 --- a/ld/genscripts.sh +++ b/ld/genscripts.sh @@ -59,11 +59,42 @@ # sun3.xn [used when the linker is invoked with "-n"] # sun3.xr [used when the linker is invoked with "-r"] # sun3.xu [used when the linker is invoked with "-Ur"] -# and maybe: -# sun3.xc [used when the linker is invoked with "-z combreloc"] -# sun3.xsc [used when the linker is invoked with "--shared"] -# sun3.xdc [used when the linker is invoked with "-pie"] -# sun3.xa [used when the linker is invoked with "--enable-auto-import"] +# +# depending on platform specific settings linker scripts with the +# following suffixes might be generated as well: +# +# xdwe: -pie -z combreloc -z separate-code -z now +# xdw: -pie -z combreloc -z relro -z now +# xdceo: -pie -z combreloc -z separate-code -z relro +# xdce: -pie -z combreloc -z separate-code +# xdco: -pie -z combreloc -z relro +# xdc: -pie -z combreloc +# xdeo: -pie -z separate-code -z relro +# xde: -pie -z separate-code +# xdo: -pie -z relro +# xd: -pie +# +# xswe: -shared -z combreloc -z separate-code -z now +# xsw: -shared -z combreloc -z relro -z now +# xsceo: -shared -z combreloc -z separate-code -z relro +# xsce: -shared -z combreloc -z separate-code +# xsco: -shared -z combreloc -z relro +# xsc: -shared -z combreloc +# xseo: -shared -z separate-code -z relro +# xse: -shared -z separate-code +# xso: -shared -z relro +# xs: -shared +# +# xwe: -z combreloc -z separate-code -z now +# xw: -z combreloc -z relro -z now +# xceo: -z combreloc -z separate-code -z relro +# xce: -z combreloc -z separate-code +# xco: -z combreloc -z relro +# xc: -z combreloc +# xeo: -z separate-code -z relro +# xe: -z separate-code +# xo: -z relro +# # # It also produced the C source file: # @@ -306,6 +337,20 @@ LD_FLAG=textonly . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc ) | sed -e '/^ *$/d;s/[ ]*$//' > 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 |