+2018-01-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/22393
+ * bfdlink.h (bfd_link_info): Add separate_code.
+
2018-01-04 Jim Wilson <jimw@sifive.com>
* opcode/riscv-opc.h (CSR_SBADADDR): Rename to CSR_STVAL. Rename
/* TRUE if PT_GNU_RELRO segment should be created. */
unsigned int relro: 1;
+ /* TRUE if separate code segment should be created. */
+ unsigned int separate_code: 1;
+
/* Nonzero if .eh_frame_hdr section and PT_GNU_EH_FRAME ELF segment
should be created. 1 for DWARF2 tables, 2 for compact tables. */
unsigned int eh_frame_hdr_type: 2;
+2018-01-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/22393
+ * NEWS: Mention "-z separate-code".
+ * emultempl/elf32.em (gld${EMULATION_NAME}_get_script): Get
+ builtin linker scripts and return linker scripts from disk for
+ "-z separate-code".
+ (gld${EMULATION_NAME}_handle_option): Handle "-z separate-code"
+ and "-z noseparate-code".
+ * genscripts.sh: Generate linker scripts for "-z separate-code".
+ (LD_FLAG): Set to *textonly for "-z separate-code".
+ * ld.texinfo: Document "-z separate-code".
+ * lexsup.c (elf_shlib_list_options): Add linker help messsages
+ for "-z separate-code" and "-z noseparate-code".
+ * scripttempl/elf.sc (SEPARATE_TEXT): New
+ (TEXT_SEGMENT_ALIGN): Likewise.
+ Use ${TEXT_SEGMENT_ALIGN} to align and pad text segment to
+ ${MAXPAGESIZE}.
+
2018-01-11 H.J. Lu <hongjiu.lu@intel.com>
PR ld/22649
-*- text -*-
+* Add -z separate-code to generate separate code PT_LOAD segment.
+
* Add -z globalaudit command line option to force audit libraries to be run
for every dynamic object loaded by an executable - provided that the loader
supports this functionality.
if test -n "$GENERATE_COMBRELOC_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.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdwe >> e${EMULATION_NAME}.c
+echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+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
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
+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
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
echo ' ; else if (bfd_link_pie (&link_info)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xd >> e${EMULATION_NAME}.c
fi
if test -n "$GENERATE_COMBRELOC_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.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xswe >> e${EMULATION_NAME}.c
+echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+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
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
+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
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
echo ' ; else if (bfd_link_dll (&link_info)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c
fi
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
echo ' ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xwe >> e${EMULATION_NAME}.c
+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
+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
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
+sed $sc ldscripts/${EMULATION_NAME}.xe >> e${EMULATION_NAME}.c
echo ' ; else return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
echo '; }' >> e${EMULATION_NAME}.c
&& link_info.combreloc
&& link_info.relro
&& (link_info.flags & DF_BIND_NOW))
- return "ldscripts/${EMULATION_NAME}.xdw";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xdwe";
+ else
+ return "ldscripts/${EMULATION_NAME}.xdw";
+ }
else if (bfd_link_pie (&link_info)
&& link_info.combreloc)
- return "ldscripts/${EMULATION_NAME}.xdc";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xdce";
+ else
+ return "ldscripts/${EMULATION_NAME}.xdc";
+ }
EOF
fi
fragment <<EOF
else if (bfd_link_pie (&link_info))
- return "ldscripts/${EMULATION_NAME}.xd";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xde";
+ else
+ return "ldscripts/${EMULATION_NAME}.xd";
+ }
EOF
fi
if test -n "$GENERATE_SHLIB_SCRIPT" ; then
fragment <<EOF
else if (bfd_link_dll (&link_info) && link_info.combreloc
&& link_info.relro && (link_info.flags & DF_BIND_NOW))
- return "ldscripts/${EMULATION_NAME}.xsw";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xswe";
+ else
+ return "ldscripts/${EMULATION_NAME}.xsw";
+ }
else if (bfd_link_dll (&link_info) && link_info.combreloc)
- return "ldscripts/${EMULATION_NAME}.xsc";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xsce";
+ else
+ return "ldscripts/${EMULATION_NAME}.xsc";
+ }
EOF
fi
fragment <<EOF
else if (bfd_link_dll (&link_info))
- return "ldscripts/${EMULATION_NAME}.xs";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xse";
+ else
+ return "ldscripts/${EMULATION_NAME}.xs";
+ }
EOF
fi
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
fragment <<EOF
else if (link_info.combreloc && link_info.relro
&& (link_info.flags & DF_BIND_NOW))
- return "ldscripts/${EMULATION_NAME}.xw";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xwe";
+ else
+ return "ldscripts/${EMULATION_NAME}.xw";
+ }
else if (link_info.combreloc)
- return "ldscripts/${EMULATION_NAME}.xc";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xce";
+ else
+ return "ldscripts/${EMULATION_NAME}.xc";
+ }
EOF
fi
fragment <<EOF
else
- return "ldscripts/${EMULATION_NAME}.x";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xe";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+ }
}
EOF
link_info.relro = TRUE;
else if (strcmp (optarg, "norelro") == 0)
link_info.relro = FALSE;
+ else if (strcmp (optarg, "separate-code") == 0)
+ link_info.separate_code = TRUE;
+ else if (strcmp (optarg, "noseparate-code") == 0)
+ link_info.separate_code = FALSE;
else if (strcmp (optarg, "common") == 0)
link_info.elf_stt_common = elf_stt_common;
else if (strcmp (optarg, "nocommon") == 0)
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xu
-LD_FLAG=
DATA_ALIGNMENT=${DATA_ALIGNMENT_}
RELOCATING=" "
+LD_FLAG=
( echo "/* Default linker script, for normal executables */"
. ${CUSTOMIZER_SCRIPT}
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.x
+LD_FLAG=textonly
+( echo "/* Script for -z separate-code: generate normal executables with separate code segment */"
+ . ${CUSTOMIZER_SCRIPT}
+ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xe
+
LD_FLAG=n
DATA_ALIGNMENT=${DATA_ALIGNMENT_n}
( echo "/* Script for -n: mix text and data on same page */"
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xc
rm -f ${COMBRELOC}
- LD_FLAG=w
+ LD_FLAG=ctextonly
+ COMBRELOC=ldscripts/${EMULATION_NAME}.xce.tmp
+ ( echo "/* Script for -z combreloc -z separate-code: combine and sort reloc sections with separate code segment */"
+ . ${CUSTOMIZER_SCRIPT}
+ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xce
+ rm -f ${COMBRELOC}
RELRO_NOW=" "
+ LD_FLAG=w
COMBRELOC=ldscripts/${EMULATION_NAME}.xw.tmp
( echo "/* Script for -z combreloc -z now -z relro: combine and sort reloc sections */"
. ${CUSTOMIZER_SCRIPT}
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xw
rm -f ${COMBRELOC}
+ LD_FLAG=wtextonly
+ COMBRELOC=ldscripts/${EMULATION_NAME}.xwe.tmp
+ ( echo "/* Script for -z combreloc -z now -z relro -z separate-code: combine and sort reloc sections with separate code segment */"
+ . ${CUSTOMIZER_SCRIPT}
+ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xwe
+ rm -f ${COMBRELOC}
COMBRELOC=
unset RELRO_NOW
fi
if test -n "$GENERATE_SHLIB_SCRIPT"; then
- LD_FLAG=shared
DATA_ALIGNMENT=${DATA_ALIGNMENT_s-${DATA_ALIGNMENT_}}
CREATE_SHLIB=" "
+ LD_FLAG=shared
(
echo "/* Script for ld --shared: link shared library */"
. ${CUSTOMIZER_SCRIPT}
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xs
+ LD_FLAG=sharedtextonly
+ (
+ echo "/* Script for ld --shared -z separate-code: link shared library with separate code segment */"
+ . ${CUSTOMIZER_SCRIPT}
+ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xse
if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
- LD_FLAG=cshared
DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}}
+ LD_FLAG=cshared
COMBRELOC=ldscripts/${EMULATION_NAME}.xsc.tmp
( echo "/* Script for --shared -z combreloc: shared library, combine & sort relocs */"
. ${CUSTOMIZER_SCRIPT}
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xsc
rm -f ${COMBRELOC}
- LD_FLAG=wshared
+ LD_FLAG=csharedtextonly
+ COMBRELOC=ldscripts/${EMULATION_NAME}.xsce.tmp
+ ( echo "/* Script for --shared -z combreloc -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}.xsce
+ rm -f ${COMBRELOC}
RELRO_NOW=" "
+ LD_FLAG=wshared
COMBRELOC=ldscripts/${EMULATION_NAME}.xsw.tmp
( echo "/* Script for --shared -z combreloc -z now -z relro: shared library, combine & sort relocs */"
. ${CUSTOMIZER_SCRIPT}
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xsw
rm -f ${COMBRELOC}
+ LD_FLAG=wsharedtextonly
+ COMBRELOC=ldscripts/${EMULATION_NAME}.xswe.tmp
+ ( echo "/* Script for --shared -z combreloc -z now -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}.xswe
+ rm -f ${COMBRELOC}
COMBRELOC=
unset RELRO_NOW
fi
fi
if test -n "$GENERATE_PIE_SCRIPT"; then
- LD_FLAG=pie
DATA_ALIGNMENT=${DATA_ALIGNMENT_s-${DATA_ALIGNMENT_}}
CREATE_PIE=" "
+ LD_FLAG=pie
(
echo "/* Script for ld -pie: link position independent executable */"
. ${CUSTOMIZER_SCRIPT}
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xd
+ LD_FLAG=pietextonly
+ (
+ echo "/* Script for ld -pie -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}.xde
if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
- LD_FLAG=cpie
DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}}
COMBRELOC=ldscripts/${EMULATION_NAME}.xdc.tmp
+ LD_FLAG=cpie
( echo "/* Script for -pie -z combreloc: position independent executable, combine & sort relocs */"
. ${CUSTOMIZER_SCRIPT}
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdc
rm -f ${COMBRELOC}
- LD_FLAG=wpie
+ LD_FLAG=cpietextonly
+ COMBRELOC=ldscripts/${EMULATION_NAME}.xdce.tmp
+ ( echo "/* Script for -pie -z combreloc -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}.xdce
+ rm -f ${COMBRELOC}
RELRO_NOW=" "
+ LD_FLAG=wpie
COMBRELOC=ldscripts/${EMULATION_NAME}.xdw.tmp
( echo "/* Script for -pie -z combreloc -z now -z relro: position independent executable, combine & sort relocs */"
. ${CUSTOMIZER_SCRIPT}
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdw
rm -f ${COMBRELOC}
+ LD_FLAG=wpietextonly
+ COMBRELOC=ldscripts/${EMULATION_NAME}.xdwe.tmp
+ ( echo "/* Script for -pie -z combreloc -z now -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}.xdwe
+ rm -f ${COMBRELOC}
COMBRELOC=
unset RELRO_NOW
fi
than the system page size will render this protection ineffective.
Don't create an ELF @code{PT_GNU_RELRO} segment if @samp{norelro}.
+@item separate-code
+@itemx noseparate-code
+Create separate code @code{PT_LOAD} segment header in the object. This
+specifies a memory segment that should contain only instructions and must
+be in wholly disjoint pages from any other data. Don't create separate
+code @code{PT_LOAD} segment if @samp{noseparate-code} is used.
+
@item shstk
Generate GNU_PROPERTY_X86_FEATURE_1_SHSTK in .note.gnu.property section
to indicate compatibility with Intel Shadow Stack. Supported for
fprintf (file, _("\
-z norelro Don't create RELRO program header (default)\n"));
#endif
+ fprintf (file, _("\
+ -z separate-code Create separate code program header\n"));
+ fprintf (file, _("\
+ -z noseparate-code Don't create separate code program header (default)\n"));
fprintf (file, _("\
-z common Generate common symbols with STT_COMMON type\n"));
fprintf (file, _("\
TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${TEXT_START_ADDR})"
SHLIB_TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${SHLIB_TEXT_START_ADDR:-0})"
+# Don't bother with separate code segment when there are data sections
+# between .plt and .text.
+if test -z "$TINY_READONLY_SECTION"; then
+ case "$LD_FLAG" in
+ *textonly*)
+ SEPARATE_TEXT=yes
+ TEXT_SEGMENT_ALIGN=". = ALIGN(${MAXPAGESIZE});"
+ ;;
+ esac
+fi
+
if [ -z "$SEPARATE_CODE" ]; then
SIZEOF_HEADERS_CODE=" + SIZEOF_HEADERS"
else
test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
cat <<EOF
+ ${RELOCATING+${TEXT_SEGMENT_ALIGN}}
+
.init ${RELOCATING-0}${RELOCATING+${INIT_ADDR}} :
{
${RELOCATING+${INIT_START}}
${RELOCATING+PROVIDE (__${ETEXT_NAME} = .);}
${RELOCATING+PROVIDE (_${ETEXT_NAME} = .);}
${RELOCATING+PROVIDE (${ETEXT_NAME} = .);}
+ ${RELOCATING+${TEXT_SEGMENT_ALIGN}}
EOF
-if test -n "${SEPARATE_CODE}"; then
+if test -n "${SEPARATE_CODE}${SEPARATE_TEXT}"; then
if test -n "${RODATA_ADDR}"; then
RODATA_ADDR="\
SEGMENT_START(\"rodata-segment\", ${RODATA_ADDR}) + SIZEOF_HEADERS"
${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_RODATA_ADDR};}}
${CREATE_PIE+${RELOCATING+. = ${SHLIB_RODATA_ADDR};}}
EOF
- emit_early_ro
- emit_dyn
+ if test -n "${SEPARATE_CODE}"; then
+ emit_early_ro
+ emit_dyn
+ fi
fi
cat <<EOF