Compare commits

...

4 Commits

Author SHA1 Message Date
H.J. Lu
53902422e4 x86-64: Add tests for -z separate-code -z max-page-size=0x1000
PR ld/22393
	* testsuite/ld-x86-64/pr22393-3a.c: New file.
	* testsuite/ld-x86-64/pr22393-3a.rd: Likewise.
	* testsuite/ld-x86-64/pr22393-3b.c: Likewise.
	* testsuite/ld-x86-64/pr22393-3b.rd: Likewise.
	* testsuite/ld-x86-64/x86-64.exp: Run tests for -z separate-code
	-z max-page-size=0x1000.
2018-01-11 05:29:06 -08:00
H.J. Lu
57b3b752a9 ld: Add tests for -z separate-code and -z noseparate-code
Verify that -z separate-code works and -z noseparate-code doesn't disable
-z relro.

	PR ld/22393
	* testsuite/ld-elf/pr16322.d: Add -z noseparate-code.
	* testsuite/ld-elf/pr22393-1.s: New file.
	* testsuite/ld-elf/pr22393-1a.d: Likewise.
	* testsuite/ld-elf/pr22393-1b.d: Likewise.
	* testsuite/ld-elf/pr22393-1c.d: Likewise.
	* testsuite/ld-elf/pr22393-1d.d: Likewise.
	* testsuite/ld-elf/pr22393-1e.d: Likewise.
	* testsuite/ld-elf/pr22393-1f.d: Likewise.
	* testsuite/ld-elf/pr22393-2a.c: Likewise.
	* testsuite/ld-elf/pr22393-2a.rd: Likewise.
	* testsuite/ld-elf/pr22393-2b.c: Likewise.
	* testsuite/ld-elf/pr22393-2b.rd: Likewise.
	* testsuite/ld-elf/shared.exp: Run tests for -z separate-code.
2018-01-11 05:29:05 -08:00
H.J. Lu
007a829fe1 ld: Create a new LOAD segment for separate code segment
When generating separate code LOAD segment, create a new LOAD segment
if the previous section contains text and the current section doesn't
or vice versa:

Elf file type is DYN (Shared object file)
Entry point 0x200020
There are 7 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x00200 0x00200 R   0x200000
  LOAD           0x200000 0x00200000 0x00200000 0x00036 0x00036 R E 0x200000
  LOAD           0x400000 0x00400000 0x00400000 0x00064 0x00064 R   0x200000
  LOAD           0x400f80 0x00600f80 0x00600f80 0x000a0 0x000a0 RW  0x200000
  DYNAMIC        0x400f80 0x00600f80 0x00600f80 0x00080 0x00080 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x400f80 0x00600f80 0x00600f80 0x00080 0x00080 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .hash .gnu.hash .dynsym .dynstr .rela.plt
   01     .plt .text
   02     .rodata .eh_frame
   03     .dynamic .got.plt
   04     .dynamic
   05
   06     .dynamic

to prevent fetching or executing data in code pages as instructions.

Also don't put a writable section in a read-only segment if there is a
RELRO segment.

Since code segment is aligned and padded to the maximum page size on
disk, the minimum file size is bigger than the maximum page size which
is 2MB (0x200000):

-rwxr-xr-x 1 hjl hjl 4201932 Jan 10 10:41 libfoo.so

"-z max-page-size=0x1000" can be used to reduce the maximum page size to
4KB (0x1000):

-rwxr-xr-x 1 hjl hjl   15820 Jan 10 10:44 libfoo.so

	PR ld/22393
	* elf.c (_bfd_elf_map_sections_to_segments): When generating
	separate code and read-only data LOAD segments, create a new
	LOAD segment if the previous section contains text and the
	current section doesn't or vice versa.  Don't put a writable
	section in a read-only segment if there is a RELRO segment.
2018-01-11 05:29:05 -08:00
H.J. Lu
c11c786f0b 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}.
2018-01-11 05:29:05 -08:00
26 changed files with 501 additions and 28 deletions

View File

@@ -4566,6 +4566,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
asection **hdrpp;
bfd_boolean phdr_in_segment = TRUE;
bfd_boolean writable;
bfd_boolean executable;
int tls_count = 0;
asection *first_tls = NULL;
asection *first_mbind = NULL;
@@ -4654,6 +4655,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
if (maxpagesize == 0)
maxpagesize = 1;
writable = FALSE;
executable = FALSE;
dynsec = bfd_get_section_by_name (abfd, ".dynamic");
if (dynsec != NULL
&& (dynsec->flags & SEC_LOAD) == 0)
@@ -4756,18 +4758,27 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
file, then there is no other reason for a new segment. */
new_segment = FALSE;
}
else if (info != NULL
&& info->separate_code
&& executable != ((hdr->flags & SEC_CODE) != 0))
{
new_segment = TRUE;
}
else if (! writable
&& (hdr->flags & SEC_READONLY) == 0
&& (((last_hdr->lma + last_size - 1) & -maxpagesize)
!= (hdr->lma & -maxpagesize)))
&& ((info != NULL
&& info->relro_end > info->relro_start)
|| (((last_hdr->lma + last_size - 1) & -maxpagesize)
!= (hdr->lma & -maxpagesize))))
{
/* We don't want to put a writable section in a read only
segment, unless they are on the same page in memory
anyhow. We already know that the last section does not
bring us past the current section on the page, so the
only case in which the new section is not on the same
page as the previous section is when the previous section
ends precisely on a page boundary. */
anyhow and there is no RELRO segment. We already
know that the last section does not bring us past the
current section on the page, so the only case in which
the new section is not on the same page as the previous
section is when the previous section ends precisely on
a page boundary. */
new_segment = TRUE;
}
else
@@ -4789,6 +4800,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
{
if ((hdr->flags & SEC_READONLY) == 0)
writable = TRUE;
if ((hdr->flags & SEC_CODE) != 0)
executable = TRUE;
last_hdr = hdr;
/* .tbss sections effectively have zero size. */
if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
@@ -4814,6 +4827,11 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
else
writable = FALSE;
if ((hdr->flags & SEC_CODE) == 0)
executable = FALSE;
else
executable = TRUE;
last_hdr = hdr;
/* .tbss sections effectively have zero size. */
if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)

View File

@@ -386,6 +386,9 @@ struct bfd_link_info
/* 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;

View File

@@ -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.

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -1787,6 +1787,10 @@ elf_shlib_list_options (FILE *file)
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, _("\

View File

@@ -316,6 +316,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
@@ -478,6 +489,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}}
@@ -508,9 +521,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"
@@ -532,8 +546,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

View File

@@ -1,4 +1,4 @@
#ld: -shared -z relro
#ld: -shared -z relro -z noseparate-code
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*

View File

@@ -0,0 +1,21 @@
.section .rodata,"a",%progbits
.globl fx1
.type fx1, %object
fx1:
.zero 20
.section .data.rel.ro,"aw",%progbits
.globl px1
.type px1, %object
px1:
.dc.a fx1
.text
.global start /* Used by SH targets. */
start:
.global _start
_start:
.global __start
__start:
.global main /* Used by HPPA targets. */
main:
.dc.a 0

View File

@@ -0,0 +1,9 @@
#source: pr22393-1.s
#ld: -shared -z separate-code -z relro
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
#failif
#...
+[0-9]+ +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
#...

View File

@@ -0,0 +1,9 @@
#source: pr22393-1.s
#ld: -shared -z relro -z separate-code
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
#failif
#...
+[0-9]+ +.*.text.*(.eh_frame|\.rodata).*
#...

View File

@@ -0,0 +1,9 @@
#source: pr22393-1.s
#ld: -pie -z separate-code
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
#failif
#...
+[0-9]+ +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
#...

View File

@@ -0,0 +1,9 @@
#source: pr22393-1.s
#ld: -pie -z separate-code
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
#failif
#...
+[0-9]+ +.*.text.*(.eh_frame|\.rodata).*
#...

View File

@@ -0,0 +1,9 @@
#source: pr22393-1.s
#ld: -z separate-code
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
#failif
#...
+[0-9]+ +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
#...

View File

@@ -0,0 +1,9 @@
#source: pr22393-1.s
#ld: -z separate-code
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
#failif
#...
+[0-9]+ +.*.text.*(.eh_frame|\.rodata).*
#...

View File

@@ -0,0 +1,7 @@
#include <stdio.h>
void
test()
{
printf ("PASS\n");
}

View File

@@ -0,0 +1,9 @@
#source: pr22393-1.s
#ld: -shared -z textonly
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
#failif
#...
+[0-9]+ +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
#...

View File

@@ -0,0 +1,7 @@
void test(void);
int main()
{
test();
return 0;
}

View File

@@ -0,0 +1,9 @@
#source: pr22393-1.s
#ld: -shared -z textonly
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
#failif
#...
+[0-9]+ +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
#...

View File

@@ -819,6 +819,51 @@ if { [istarget *-*-linux*]
{} \
"libpr19579.so" \
] \
[list \
"Build pr22393-2a.so" \
"-shared -Wl,-z,separate-code" \
"-fPIC" \
{pr22393-2a.c} \
{{readelf -lW pr22393-2a.rd} \
{readelf -lW pr22393-2b.rd}} \
"pr22393-2a.so" \
] \
[list \
"Build pr22393-2a-now.so" \
"-shared -Wl,-z,separate-code,-z,now" \
"-fPIC" \
{pr22393-2a.c} \
{{readelf -lW pr22393-2a.rd} \
{readelf -lW pr22393-2b.rd}} \
"pr22393-2a-now.so" \
] \
[list \
"Build pr22393-2" \
"$NOPIE_LDFLAGS -Wl,-z,separate-code,--no-as-needed tmpdir/pr22393-2a.so" \
"$NOPIE_CFLAGS" \
{pr22393-2b.c} \
{{readelf -lW pr22393-2a.rd} \
{readelf -lW pr22393-2b.rd}} \
"pr22393-2" \
] \
[list \
"Build pr22393-2 (PIE)" \
"-pie -Wl,-z,separate-code,--no-as-needed tmpdir/pr22393-2a-now.so" \
"-fPIE" \
{pr22393-2b.c} \
{{readelf -lW pr22393-2a.rd} \
{readelf -lW pr22393-2b.rd}} \
"pr22393-2-pie" \
] \
[list \
"Build pr22393-2 (static)" \
"-static -Wl,-z,separate-code" \
"" \
{pr22393-2a.c pr22393-2b.c} \
{{readelf -lW pr22393-2a.rd} \
{readelf -lW pr22393-2b.rd}} \
"pr22393-2-static" \
] \
]
run_ld_link_exec_tests [list \
[list \
@@ -956,6 +1001,32 @@ if { [istarget *-*-linux*]
"pass.out" \
"-fPIE" \
] \
[list \
"Run pr22393-2" \
"$NOPIE_LDFLAGS -Wl,-z,separate-code,--no-as-needed tmpdir/pr22393-2a.so" \
"" \
{pr22393-2b.c} \
"pr22393-2" \
"pass.out" \
"$NOPIE_CFLAGS" \
] \
[list \
"Run pr22393-2 (PIE)" \
"-pie -Wl,-z,separate-code,--no-as-needed tmpdir/pr22393-2a-now.so" \
"" \
{pr22393-2b.c} \
"pr22393-2-pie" \
"pass.out" \
"-fPIE" \
] \
[list \
"Run pr22393-2 (static)" \
"-static -Wl,-z,separate-code" \
"" \
{pr22393-2a.c pr22393-2b.c} \
"pr22393-2-static" \
"pass.out" \
] \
]
}

View File

@@ -0,0 +1,7 @@
#include <stdio.h>
void
test()
{
printf ("PASS\n");
}

View File

@@ -0,0 +1,9 @@
#source: pr22393-1.s
#ld: -shared -z textonly
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
#failif
#...
+[0-9]+ +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
#...

View File

@@ -0,0 +1,7 @@
void test(void);
int main()
{
test();
return 0;
}

View File

@@ -0,0 +1,9 @@
#source: pr22393-1.s
#ld: -shared -z textonly
#readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
#failif
#...
+[0-9]+ +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
#...

View File

@@ -1105,6 +1105,51 @@ if { [isnative] && [which $CC] != 0 } {
{} \
"pr22064.so" \
] \
[list \
"Build pr22393-3a.so" \
"-shared -Wl,-z,separate-code,-z,max-page-size=0x1000" \
"-fPIC" \
{pr22393-3a.c} \
{{readelf -lW pr22393-3a.rd} \
{readelf -lW pr22393-3b.rd}} \
"pr22393-3a.so" \
] \
[list \
"Build pr22393-3a-now.so" \
"-shared -Wl,-z,separate-code,-z,now,-z,max-page-size=0x1000" \
"-fPIC" \
{pr22393-3a.c} \
{{readelf -lW pr22393-3a.rd} \
{readelf -lW pr22393-3b.rd}} \
"pr22393-3a-now.so" \
] \
[list \
"Build pr22393-3" \
"$NOPIE_LDFLAGS -Wl,-z,separate-code,-z,max-page-size=0x1000,--no-as-needed tmpdir/pr22393-2a.so" \
"$NOPIE_CFLAGS" \
{pr22393-3b.c} \
{{readelf -lW pr22393-3a.rd} \
{readelf -lW pr22393-3b.rd}} \
"pr22393-3" \
] \
[list \
"Build pr22393-3 (PIE)" \
"-pie -Wl,-z,separate-code,-z,max-page-size=0x1000,--no-as-needed tmpdir/pr22393-2a-now.so" \
"-fPIE" \
{pr22393-3b.c} \
{{readelf -lW pr22393-3a.rd} \
{readelf -lW pr22393-3b.rd}} \
"pr22393-3-pie" \
] \
[list \
"Build pr22393-3 (static)" \
"-static -Wl,-z,separate-code,-z,max-page-size=0x1000" \
"" \
{pr22393-3a.c pr22393-3b.c} \
{{readelf -lW pr22393-3a.rd} \
{readelf -lW pr22393-3b.rd}} \
"pr22393-3-static" \
] \
]
if {[istarget "x86_64-*-linux*-gnux32"]} {
@@ -1404,6 +1449,32 @@ if { [isnative] && [which $CC] != 0 } {
"pass.out" \
"-fPIE" \
] \
[list \
"Run pr22393-3" \
"$NOPIE_LDFLAGS -Wl,-z,separate-code,-z,max-page-size=0x1000,--no-as-needed tmpdir/pr22393-3a.so" \
"" \
{pr22393-3b.c} \
"pr22393-3" \
"pass.out" \
"$NOPIE_CFLAGS" \
] \
[list \
"Run pr22393-3 (PIE)" \
"-pie -Wl,-z,separate-code,-z,max-page-size=0x1000,--no-as-needed tmpdir/pr22393-3a-now.so" \
"" \
{pr22393-3b.c} \
"pr22393-3-pie" \
"pass.out" \
"-fPIE" \
] \
[list \
"Run pr22393-3 (static)" \
"-static -Wl,-z,separate-code,-z,max-page-size=0x1000" \
"" \
{pr22393-3a.c pr22393-3b.c} \
"pr22393-3-static" \
"pass.out" \
] \
]
# Run-time tests which require working ifunc attribute support.