diff options
Diffstat (limited to 'ld/scripttempl/elf.sc')
-rw-r--r-- | ld/scripttempl/elf.sc | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index 7994b5f..5796b0a 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. */ |