diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2018-01-11 19:01:39 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2018-01-11 19:01:52 -0800 |
commit | 47acac12c83f173481debc64618626b50ecf7498 (patch) | |
tree | e48aae92826c2b354a47ca3721c85cfa93b4194e /ld | |
parent | 6181e9c2c5ba252ac016f51903dc35d7bfbbca71 (diff) | |
download | gdb-47acac12c83f173481debc64618626b50ecf7498.zip gdb-47acac12c83f173481debc64618626b50ecf7498.tar.gz gdb-47acac12c83f173481debc64618626b50ecf7498.tar.bz2 |
ld: Add "-z separate-code" option to ELF linker
The new "-z separate-code" option will generate separate code LOAD
segment which must be in wholly disjoint pages from any other data.
include/
PR ld/22393
* bfdlink.h (bfd_link_info): Add separate_code.
ld/
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}.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 19 | ||||
-rw-r--r-- | ld/NEWS | 2 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 100 | ||||
-rwxr-xr-x | ld/genscripts.sh | 76 | ||||
-rw-r--r-- | ld/ld.texinfo | 7 | ||||
-rw-r--r-- | ld/lexsup.c | 4 | ||||
-rw-r--r-- | ld/scripttempl/elf.sc | 22 |
7 files changed, 210 insertions, 20 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 977d779..28ce852 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,24 @@ 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 * testsuite/ld-elf/pr22649-1.s: New file. * testsuite/ld-elf/pr22649-2a.s: Likewise. @@ -1,4 +1,6 @@ -*- 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. diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index a12aefa..8ff19bf 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -2367,13 +2367,25 @@ if test -n "$GENERATE_PIE_SCRIPT" ; then 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 @@ -2381,24 +2393,45 @@ if test -n "$GENERATE_SHLIB_SCRIPT" ; then 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 @@ -2431,15 +2464,30 @@ fragment <<EOF && 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 @@ -2447,28 +2495,58 @@ if test -n "$GENERATE_COMBRELOC_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 @@ -2738,6 +2816,10 @@ fragment <<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) diff --git a/ld/genscripts.sh b/ld/genscripts.sh index 43ccf5e..8732422 100755 --- a/ld/genscripts.sh +++ b/ld/genscripts.sh @@ -290,14 +290,20 @@ CONSTRUCTING=" " . ${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 */" @@ -321,44 +327,78 @@ if test -n "$GENERATE_COMBRELOC_SCRIPT"; then . ${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 @@ -366,31 +406,51 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; then 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 diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 4fd12bb..8cd2bed 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -1264,6 +1264,13 @@ relocation, if supported. Specifying @samp{common-page-size} smaller 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 diff --git a/ld/lexsup.c b/ld/lexsup.c index 8ed7070..f219160 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -1788,6 +1788,10 @@ elf_shlib_list_options (FILE *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, _("\ -z nocommon Generate common symbols with STT_OBJECT type\n")); diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index 139773d..9787ab5 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -322,6 +322,17 @@ STACK=".stack ${RELOCATING-0}${RELOCATING+${STACK_ADDR}} : 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 @@ -484,6 +495,8 @@ emit_dyn() test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn cat <<EOF + ${RELOCATING+${TEXT_SEGMENT_ALIGN}} + .init ${RELOCATING-0}${RELOCATING+${INIT_ADDR}} : { ${RELOCATING+${INIT_START}} @@ -514,9 +527,10 @@ cat <<EOF ${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" @@ -538,8 +552,10 @@ SEGMENT_START(\"rodata-segment\", ${SHLIB_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 |