summaryrefslogtreecommitdiff
path: root/ld/scripttempl/elf.sc
diff options
context:
space:
mode:
Diffstat (limited to 'ld/scripttempl/elf.sc')
-rw-r--r--ld/scripttempl/elf.sc69
1 files changed, 46 insertions, 23 deletions
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index 7994b5f11e..5796b0a2e3 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -40,7 +40,7 @@
# NO_RELA_RELOCS - Don't include .rela.* sections in script
# NON_ALLOC_DYN - Place dynamic sections after data segment.
# TEXT_DYNAMIC - .dynamic in text segment, not data segment.
-# EMBEDDED - whether this is for an embedded system.
+# EMBEDDED - whether this is for an embedded system.
# SHLIB_TEXT_START_ADDR - if set, add to SIZEOF_HEADERS to set
# start address of shared library.
# INPUT_FILES - INPUT command of files to always include
@@ -53,6 +53,9 @@
# OTHER_SYMBOLS - symbols to place right at the end of the script.
# ETEXT_NAME - name of a symbol for the end of the text section,
# normally etext.
+# SEPARATE_CODE - if set, .text and similar sections containing
+# actual machine instructions must be in wholly disjoint
+# pages from any other data, including headers
# SEPARATE_GOTPLT - if set, .got.plt should be separate output section,
# so that .got can be in the RELRO area. It should be set to
# the number of bytes in the beginning of .got.plt which can be
@@ -170,7 +173,7 @@ if test -z "${NO_SMALL_DATA}"; then
SDATA="/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
- .${SDATA_NAME} ${RELOCATING-0} :
+ .${SDATA_NAME} ${RELOCATING-0} :
{
${RELOCATING+${SDATA_START_SYMBOLS}}
${CREATE_SHLIB+*(.${SDATA_NAME}2 .${SDATA_NAME}2.* .gnu.linkonce.s2.*)}
@@ -255,7 +258,7 @@ FINI_ARRAY=".fini_array ${RELOCATING-0} :
${DTORS_IN_FINI_ARRAY}
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_end = .);}}
}"
-CTOR=".ctors ${CONSTRUCTING-0} :
+CTOR=".ctors ${CONSTRUCTING-0} :
{
${CONSTRUCTING+${CTOR_START}}
/* gcc uses crtbegin.o to find the start of
@@ -300,9 +303,15 @@ 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})"
+if [ -z "$SEPARATE_CODE" ]; then
+ SIZEOF_HEADERS_CODE=" + SIZEOF_HEADERS"
+else
+ SIZEOF_HEADERS_CODE=
+fi
+
# if this is for an embedded system, don't add SIZEOF_HEADERS.
if [ -z "$EMBEDDED" ]; then
- test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR} + SIZEOF_HEADERS"
+ test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR}${SIZEOF_HEADERS_CODE}"
else
test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR}"
fi
@@ -325,11 +334,19 @@ SECTIONS
{
/* Read-only sections, merged into text segment: */
${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+PROVIDE (__executable_start = ${TEXT_START_ADDR}); . = ${TEXT_BASE_ADDRESS};}}}
- ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR} + SIZEOF_HEADERS;}}
- ${CREATE_PIE+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR} + SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR}${SIZEOF_HEADERS_CODE};}}
+ ${CREATE_PIE+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR}${SIZEOF_HEADERS_CODE};}}
+EOF
+
+emit_early_ro()
+{
+ cat <<EOF
${INITIAL_READONLY_SECTIONS}
.note.gnu.build-id : { *(.note.gnu.build-id) }
EOF
+}
+
+test -n "${SEPARATE_CODE}" || emit_early_ro
test -n "${RELOCATING+0}" || unset NON_ALLOC_DYN
test -z "${NON_ALLOC_DYN}" || TEXT_DYNAMIC=
@@ -424,7 +441,8 @@ cat >> ldscripts/dyntmp.$$ <<EOF
${OTHER_PLT_RELOC_SECTIONS}
EOF
-if test -z "${NON_ALLOC_DYN}"; then
+emit_dyn()
+{
if test -z "${NO_REL_RELOCS}${NO_RELA_RELOCS}"; then
cat ldscripts/dyntmp.$$
else
@@ -436,11 +454,13 @@ if test -z "${NON_ALLOC_DYN}"; then
fi
fi
rm -f ldscripts/dyntmp.$$
-fi
+}
+
+test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
cat <<EOF
- .init ${RELOCATING-0} :
- {
+ .init ${RELOCATING-0} :
+ {
${RELOCATING+${INIT_START}}
KEEP (*(.init))
${RELOCATING+${INIT_END}}
@@ -469,6 +489,21 @@ cat <<EOF
${RELOCATING+PROVIDE (__${ETEXT_NAME} = .);}
${RELOCATING+PROVIDE (_${ETEXT_NAME} = .);}
${RELOCATING+PROVIDE (${ETEXT_NAME} = .);}
+EOF
+
+if test -n "${SEPARATE_CODE}"; then
+ cat <<EOF
+ /* Adjust the address for the rodata segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. = ${RODATA_ADDR-ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))};}}}
+ ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_RODATA_ADDR-ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))};}}
+ ${CREATE_PIE+${RELOCATING+. = ${SHLIB_RODATA_ADDR-ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))};}}
+EOF
+ emit_early_ro
+ emit_dyn
+fi
+
+cat <<EOF
${WRITABLE_RODATA-${RODATA}}
.${RODATA_NAME}1 ${RELOCATING-0} : { *(.${RODATA_NAME}1) }
${CREATE_SHLIB-${SDATA2}}
@@ -565,19 +600,7 @@ cat <<EOF
${RELOCATING+${DATA_SEGMENT_END}}
EOF
-if test -n "${NON_ALLOC_DYN}"; then
- if test -z "${NO_REL_RELOCS}${NO_RELA_RELOCS}"; then
- cat ldscripts/dyntmp.$$
- else
- if test -z "${NO_REL_RELOCS}"; then
- sed -e '/^[ ]*\.rela\.[^}]*$/,/}/d' -e '/^[ ]*\.rela\./d' ldscripts/dyntmp.$$
- fi
- if test -z "${NO_RELA_RELOCS}"; then
- sed -e '/^[ ]*\.rel\.[^}]*$/,/}/d' -e '/^[ ]*\.rel\./d' ldscripts/dyntmp.$$
- fi
- fi
- rm -f ldscripts/dyntmp.$$
-fi
+test -z "${NON_ALLOC_DYN}" || emit_dyn
cat <<EOF
/* Stabs debugging sections. */