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.
This commit is contained in:
Andreas Krebbel 2018-06-11 13:23:00 +02:00 committed by Andreas Krebbel
parent 0984c34e76
commit a38137289e
2 changed files with 291 additions and 8 deletions

View File

@ -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
{

View File

@ -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