commit
e8e10743f7b207b21a1efb0cc9e42487080db013
Author: Nick Clifton <nickc@redhat.com>
Date: Thu Jun 13 15:10:15 2024 +0100
Add --rosegment option to BFD linker to stop the '-z separate-code' from gen erating two read-only segments.
added --rosegment option to generate one read-only segment with
-z separate-code. But it puts the read-only data, which contains ELF
headers and .note.gnu.build-id section, in the executable segment:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x00000000 0x00000000 0x00185 0x00185 R E 0x1000
LOAD 0x001000 0x00001000 0x00001000 0x000d0 0x000d0 R 0x1000
LOAD 0x001f78 0x00002f78 0x00002f78 0x0008c 0x0008c RW 0x1000
DYNAMIC 0x001f78 0x00002f78 0x00002f78 0x00070 0x00070 RW 0x4
NOTE 0x000154 0x00000154 0x00000154 0x00024 0x00024 R 0x4
NOTE 0x00109c 0x0000109c 0x0000109c 0x00034 0x00034 R 0x4
GNU_PROPERTY 0x00109c 0x0000109c 0x0000109c 0x00034 0x00034 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
GNU_RELRO 0x001f78 0x00002f78 0x00002f78 0x00088 0x00088 R 0x1
Section to Segment mapping:
Segment Sections...
00 .note.gnu.build-id .text
01 .gnu.hash .dynsym .dynstr .rela.dyn .rodata .eh_frame .note.gnu.property
02 .dynamic .got.plt .data
03 .dynamic
04 .note.gnu.build-id
05 .note.gnu.property
06 .note.gnu.property
07
08 .dynamic .got.plt
which defeats the purpose of -z separate-code. Update --rosegment to
place code after read-only data:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x00000000 0x00000000 0x00248 0x00248 R 0x1000
LOAD 0x001000 0x00001000 0x00001000 0x00005 0x00005 R E 0x1000
LOAD 0x001f78 0x00002f78 0x00002f78 0x0008c 0x0008c RW 0x1000
DYNAMIC 0x001f78 0x00002f78 0x00002f78 0x00070 0x00070 RW 0x4
NOTE 0x000154 0x00000154 0x00000154 0x00024 0x00024 R 0x4
NOTE 0x000214 0x00000214 0x00000214 0x00034 0x00034 R 0x4
GNU_PROPERTY 0x000214 0x00000214 0x00000214 0x00034 0x00034 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
GNU_RELRO 0x001f78 0x00002f78 0x00002f78 0x00088 0x00088 R 0x1
Section to Segment mapping:
Segment Sections...
00 .note.gnu.build-id .gnu.hash .dynsym .dynstr .rela.dyn .rodata .eh_frame .note.gnu.property
01 .text
02 .dynamic .got.plt .data
03 .dynamic
04 .note.gnu.build-id
05 .note.gnu.property
06 .note.gnu.property
07
08 .dynamic .got.plt
PR ld/23704
PR ld/30907
PR ld/32191
PR ld/34003
* emulparams/elf32_x86_64.sh (ALL_TEXT_AFTER_RO): New.
* emulparams/elf_i386.sh (ALL_TEXT_AFTER_RO): Likewise.
* emulparams/elf_i386_be.sh (ALL_TEXT_AFTER_RO): Likewise.
* emulparams/elf_i386_vxworks.sh (ALL_TEXT_AFTER_RO): Likewise.
* emulparams/elf_iamcu.sh (ALL_TEXT_AFTER_RO): Likewise.
* emulparams/elf_x86_64.sh (ALL_TEXT_AFTER_RO): Likewise.
* scripttempl/elf.sc (ALL_TEXT_AFTER_RO): New. If set, place
code after read-only data for -z separate-code --rosegment.
* testsuite/ld-elf/pr30907-2.d: Skip x86 targets.
* testsuite/ld-elf/pr34003.d: New file.
* testsuite/ld-i386/pr32191.d: Updated.
* testsuite/ld-x86-64/pr32191-x32.d: Likewise.
* testsuite/ld-x86-64/pr32191.d: Likewise.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
"
OTHER_GOT_RELOC_SECTIONS="
.rela.tls ${RELOCATING-0} : { *(.rela.tls) }"
+ALL_TEXT_AFTER_RO=yes
if [ "x${host}" = "x${target}" ]; then
case " $EMULATION_LIBPATH " in
"
OTHER_GOT_RELOC_SECTIONS="
.rel.tls ${RELOCATING-0} : { *(.rel.tls) }"
+ALL_TEXT_AFTER_RO=yes
# Linux modify the default library search path to first include
# a 32-bit specific directory.
EXTRA_EM_FILE="elf-x86"
GENERATE_SHLIB_SCRIPT=yes
NO_SMALL_DATA=yes
+ALL_TEXT_AFTER_RO=yes
GENERATE_SHLIB_SCRIPT=yes
GENERATE_PIE_SCRIPT=yes
NO_SMALL_DATA=yes
+ALL_TEXT_AFTER_RO=yes
source_sh ${srcdir}/emulparams/vxworks.sh
source_sh ${srcdir}/emulparams/extern_protected_data.sh
source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
OTHER_PLT_SECTIONS="
.plt.got ${RELOCATING-0} : { *(.plt.got) }
"
+ALL_TEXT_AFTER_RO=yes
# Linux modify the default library search path to first include
# a 32-bit specific directory.
"
OTHER_GOT_RELOC_SECTIONS="
.rela.tls ${RELOCATING-0} : { *(.rela.tls) }"
+ALL_TEXT_AFTER_RO=yes
if [ "x${host}" = "x${target}" ]; then
case " $EMULATION_LIBPATH " in
# applied to every symbol definition
# ALL_TEXT_BEFORE_RO - put all code sections before read-only
# sections
+# ALL_TEXT_AFTER_RO - put all code sections after read-only
+# sections
#
# When adding sections, do note that the names of some sections are used
# when specifying the start address of the next.
if test -z "$TINY_READONLY_SECTION"; then
case "$LD_FLAG" in
*ro*textonly*)
- ALL_TEXT_BEFORE_RO=" "
+ if test -n "${ALL_TEXT_AFTER_RO}"; then
+ TEXT_AFTER_RO=" "
+ else
+ ALL_TEXT_BEFORE_RO=" "
+ fi
SEPARATE_TEXT=" "
TEXT_SEGMENT_ALIGN=". = ALIGN(${MAXPAGESIZE});"
;;
#------Early Read Only Data -----------------------------------------------
- if test -z "${ALL_TEXT_BEFORE_RO}"; then
+ if test -n "${TEXT_AFTER_RO}" || test -z "${ALL_TEXT_BEFORE_RO}"; then
# We are allowed to put R/O sections before code sections.
# Doing so either puts read only data into the code segment, if the data
# and code sections are contiguous, or creates a data segment followed by
test -n "${SEPARATE_CODE}" || emit_early_ro
test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
+ test -z "${TEXT_AFTER_RO}" || emit_rodata
# We only need the alignment if we have emitted some sections.
if test -z "${SEPARATE_CODE}"; then
align_text
- #------Read Only Data -----------------------------------------------------
+ if test -z "${TEXT_AFTER_RO}"; then
+ #------Read Only Data ------------------------------------------------
- align_rodata
+ align_rodata
- # If we have not already emitted the early read only data sections then do
- # so now. Also if the dynamic section has not already been emitted and we
- # can put it into the data segment, then do that here as well.
+ # If we have not already emitted the early read only data sections then do
+ # so now. Also if the dynamic section has not already been emitted and we
+ # can put it into the data segment, then do that here as well.
- if test -n "${ALL_TEXT_BEFORE_RO}"; then
- test -n "${SEPARATE_CODE}" || emit_early_ro
- test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
- fi
- test -z "${SEPARATE_CODE}" || emit_early_ro
- test -z "${SEPARATE_CODE}" || emit_dyn
+ if test -n "${ALL_TEXT_BEFORE_RO}"; then
+ test -n "${SEPARATE_CODE}" || emit_early_ro
+ test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
+ fi
+ test -z "${SEPARATE_CODE}" || emit_early_ro
+ test -z "${SEPARATE_CODE}" || emit_dyn
- # Now emit the rest of the read only data.
+ # Now emit the rest of the read only data.
- emit_rodata
+ emit_rodata
+ fi
#------Read Write Data ----------------------------------------------------
#source: pr22393-1.s
#ld: -shared -z separate-code -z relro --rosegment
#readelf: -l --wide
+#notarget: i?86-*-* x86_64-*-*
#target: *-*-linux-gnu *-*-gnu* arm*-*-uclinuxfdpiceabi
#xfail: ![check_shared_lib_support]
#xfail: ![check_relro_support]
--- /dev/null
+#name: --rosegment (has at least one R, one RX and one RW segments)
+#source: pr22393-1.s
+#ld: -shared -z separate-code -z relro --rosegment
+#readelf: -l --wide
+#target: i?86-*-* x86_64-*-*
+
+#...
+[ ]+LOAD[ ]+0x[0-9a-f x]+R[ ]+0x.*
+#...
+[ ]+LOAD[ ]+0x[0-9a-f x]+R E[ ]+0x.*
+#...
+[ ]+LOAD[ ]+0x[0-9a-f x]+RW[ ]+0x.*
+#...
#readelf: -lW
#...
- +[0-9]+ +\.note\.gnu\.build-id \.text
+ +[0-9]+ +\.note\.gnu\.build-id .*
+ +[0-9]+ +\.text
+#...
+[0-9]+ +\..* \.note\.gnu\.property .*
#pass
#readelf: -lW
#...
- +[0-9]+ +\.note\.gnu\.build-id \.text
+ +[0-9]+ +\.note\.gnu\.build-id .*
+ +[0-9]+ +\.text
+#...
+[0-9]+ +\..* \.note\.gnu\.property .*
#pass
#readelf: -lW
#...
- +[0-9]+ +\.note\.gnu\.build-id \.text
+ +[0-9]+ +\.note\.gnu\.build-id .*
+ +[0-9]+ +\.text
+#...
+[0-9]+ +\..* \.note\.gnu\.property .*
#pass