Compare commits

...

6 Commits

Author SHA1 Message Date
H.J. Lu
391c2c35ce 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-09 09:32:58 -08:00
H.J. Lu
37c28ba4dc 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-09 09:28:59 -08:00
H.J. Lu
75f88a3cce ld/ppc/spu: Also set expld.textseg.phase to exp_seg_none
* emultempl/ppc32elf.em (ppc_before_allocation): Also set
	expld.textseg.phase to exp_seg_none.
	* emultempl/ppc64elf.em (prelim_size_sections): Likewise.
	* emultempl/spuelf.em (spu_before_allocation): Likewise.
2018-01-09 09:22:16 -08:00
H.J. Lu
756d9f918f ld: Create a new LOAD segment for separate code-only LOAD segment
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:

Elf file type is DYN (Shared object file)
Entry point 0x200ff0
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           0x000fd0 0x00200fd0 0x00200fd0 0x0002b 0x0002b R E 0x200000
  LOAD           0x001000 0x00201000 0x00201000 0x00058 0x00058 R   0x200000
  LOAD           0x200f80 0x00400f80 0x00400f80 0x000a0 0x000a0 RW  0x200000
  DYNAMIC        0x200f80 0x00400f80 0x00400f80 0x00080 0x00080 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x200f80 0x00400f80 0x00400f80 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

This is to prevent executing data in read-only sections as instructions.

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

Since there are more than 2 LOAD segments, the minimum file size is
bigger than the maximum page size which is 2MB (0x200000):

-rwxr-xr-x 1 hjl hjl 2104892 Nov 12 11:53 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 11836 Nov 12 13:22 libfoo.so

Elf file type is DYN (Shared object file)
Entry point 0x1ff0
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   0x1000
  LOAD           0x000fd0 0x00001fd0 0x00001fd0 0x0002b 0x0002b R E 0x1000
  LOAD           0x001000 0x00002000 0x00002000 0x00058 0x00058 R   0x1000
  LOAD           0x001f80 0x00002f80 0x00002f80 0x000a0 0x000a0 RW  0x1000
  DYNAMIC        0x001f80 0x00002f80 0x00002f80 0x00080 0x00080 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x001f80 0x00002f80 0x00002f80 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

	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-09 09:18:24 -08:00
H.J. Lu
c91ad020c2 ld: Add TEXT_SEGMENT_ALIGN/TEXT_SEGMENT_{RELRO_}END
Text-only LOAD segment has the same requirement for segment alignment
and page sizes as GNU_RELRO segment.  But for GNU_RELRO segment, the
segment may not end at the same address of the end of data segment.  But
text-only LOAD segment is exactly the same as text LOAD segment.

This patch adds TEXT_SEGMENT_ALIGN, TEXT_SEGMENT_RELRO_END and
TEXT_SEGMENT_END, which mimic DATA_SEGMENT_ALIGN, DATA_SEGMENT_RELRO_END
and DATA_SEGMENT_END.  They work on text segment, instead of data
segment.  TEXT_SEGMENT_ALIGN is placed at the start of text sections.
Both TEXT_SEGMENT_RELRO_END and TEXT_SEGMENT_END are placed at the end
of text sections.  TEXT_SEGMENT_ALIGN is created from DATA_SEGMENT_ALIGN
by replacing DATA_SEGMENT_ALIGN with TEXT_SEGMENT_ALIGN.  It simply sets
text_start and text_end from TEXT_SEGMENT_ALIGN, TEXT_SEGMENT_RELRO_END
and TEXT_SEGMENT_END the same way as relro_start and relro_end are set
from DATA_SEGMENT_ALIGN, DATA_SEGMENT_RELRO_END and DATA_SEGMENT_END.

include/

	PR ld/22393
	* bfdlink.h (bfd_link_info): Add text_start and text_end.

ld/

	PR ld/22393
	* ldexp.c (exp_print_token): Add TEXT_SEGMENT_ALIGN,
	TEXT_SEGMENT_RELRO_END and TEXT_SEGMENT_END.
	(fold_unary): Handle TEXT_SEGMENT_END.
	(fold_binary): Handle TEXT_SEGMENT_RELRO_END and
	TEXT_SEGMENT_END.
	(exp_unop): Also check TEXT_SEGMENT_END.
	* ldexp.h (ldexp_control): Add textseg.
	* ldgram.y: Handle TEXT_SEGMENT_ALIGN, TEXT_SEGMENT_RELRO_END
	and TEXT_SEGMENT_END.
	* ldlang.c (strip_excluded_output_sections): Also set
	expld.textseg.phase to exp_seg_none.
	(lang_size_sections_1): Also call ldlang_check_relro_region with
	&expld.textseg.
	(lang_size_relro_segment): Also handle expld.textseg.
	(lang_size_sections): Also handle expld.textseg.  Set
	link_info.text_start and link_info.text_end for -z textonly.
	(lang_find_relro_sections): Also check expld.textseg.
	* ldlex.l: Add TEXT_SEGMENT_ALIGN, TEXT_SEGMENT_RELRO_END and
	TEXT_SEGMENT_END.
	* scripttempl/elf.sc (TEXT_SEGMENT_ALIGN): New.
	(TEXT_SEGMENT_RELRO_END): Likewise.
	(TEXT_SEGMENT_END): Likewise.
	Add ${TEXT_SEGMENT_ALIGN} before text sections and add
	${TEXT_SEGMENT_RELRO_END}/${TEXT_SEGMENT_END} after text
	sections for non-relocatable link.
2018-01-09 09:14:32 -08:00
H.J. Lu
972d6cb518 ld: Add "-z separate-code" option to ELF linker
Code-only LOAD segment has the same requirement for segment alignment
and page sizes as GNU_RELRO segment.  But for GNU_RELRO segment, the
segment may not end at the same address of the end of data segment.  But
for code-only LOAD segment, it is exactly the same as code LOAD segment.

The new "-z separate-code" option will turn on both separate code read-only
data LOAD segments and GNU_RELRO segment.  The new "-z noseparate-code"
option will turn off only separate code and read-only data LOAD segments.
"-z relro" is updated not to turn off separate code and read-only data
LOAD segments.  "-z norelro" is updated to turn off both GNU_RELRO segment
as well as separate code and read-only data LOAD segments.

include/

	PR ld/22393
	* bfdlink.h (bfd_link_info): Change the relro field to 2 bits.

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): Set the first bit of
	link_info.relro for "-z relro".  Clear link_info.relro for
	"-z norelro".  Set link_info.relro to 2 for "-z separate-code".
	Keep only the first bit of link_info.relro for "notextonly".
	* genscripts.sh: Generate linker scripts for "-z separate-code".
	(LD_FLAG): Set to *textonly for "-z separate-code".
	* lexsup.c (elf_shlib_list_options): Update linker help messsages
	for "-z relro" and "-z norelro".  Add linker help messsages for
	"-z separate-code" and "-z noseparate-code".
	* ld.texinfo: Update "-z norelro".  Document "-z separate-code".
2018-01-09 09:05:25 -08:00
34 changed files with 633 additions and 61 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->text_end > info->text_start
&& 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

@@ -383,8 +383,11 @@ struct bfd_link_info
executable. */
unsigned int emitrelocations: 1;
/* TRUE if PT_GNU_RELRO segment should be created. */
unsigned int relro: 1;
/* Non-zero if PT_GNU_RELRO as well as separate code and read-only data
PT_LOAD segments should be created. 1 for PT_GNU_RELRO segment only,
> 1 for PT_GNU_RELRO segment as well as separate code and read-only
data PT_LOAD segments. */
unsigned int relro: 2;
/* Nonzero if .eh_frame_hdr section and PT_GNU_EH_FRAME ELF segment
should be created. 1 for DWARF2 tables, 2 for compact tables. */
@@ -624,6 +627,9 @@ struct bfd_link_info
/* May be used to set DT_FLAGS_1 for ELF. */
bfd_vma flags_1;
/* Start and end of text-only region. */
bfd_vma text_start, text_end;
/* Start and end of RELRO region. */
bfd_vma relro_start, relro_end;

View File

@@ -1,4 +1,7 @@
-*- text -*-
* Add -z separate-code to generate separate code and read-only data
PT_LOAD segments.
* 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.relro > 1' >> 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.relro > 1' >> 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.relro > 1) 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.relro > 1' >> 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.relro > 1) 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.relro > 1) 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.relro > 1' >> 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.relro > 1) 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.relro > 1) 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.relro > 1)
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.relro > 1)
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.relro > 1)
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.relro > 1)
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.relro > 1)
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.relro > 1)
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.relro > 1)
return "ldscripts/${EMULATION_NAME}.xwe";
else
return "ldscripts/${EMULATION_NAME}.xw";
}
else if (link_info.combreloc)
return "ldscripts/${EMULATION_NAME}.xc";
{
if (link_info.relro > 1)
return "ldscripts/${EMULATION_NAME}.xce";
else
return "ldscripts/${EMULATION_NAME}.xc";
}
EOF
fi
fragment <<EOF
else
return "ldscripts/${EMULATION_NAME}.x";
{
if (link_info.relro > 1)
return "ldscripts/${EMULATION_NAME}.xe";
else
return "ldscripts/${EMULATION_NAME}.x";
}
}
EOF
@@ -2735,9 +2813,13 @@ fragment <<EOF
else if (strcmp (optarg, "nocopyreloc") == 0)
link_info.nocopyreloc = TRUE;
else if (strcmp (optarg, "relro") == 0)
link_info.relro = TRUE;
link_info.relro |= 1;
else if (strcmp (optarg, "norelro") == 0)
link_info.relro = FALSE;
link_info.relro = 0;
else if (strcmp (optarg, "separate-code") == 0)
link_info.relro = 2;
else if (strcmp (optarg, "noseparate-code") == 0)
link_info.relro &= 1;
else if (strcmp (optarg, "common") == 0)
link_info.elf_stt_common = elf_stt_common;
else if (strcmp (optarg, "nocommon") == 0)

View File

@@ -149,6 +149,7 @@ ppc_before_allocation (void)
if (expld.phase != lang_mark_phase_enum)
{
expld.phase = lang_mark_phase_enum;
expld.textseg.phase = exp_seg_none;
expld.dataseg.phase = exp_seg_none;
one_lang_size_sections_pass (NULL, FALSE);
lang_reset_memory_regions ();

View File

@@ -266,6 +266,7 @@ prelim_size_sections (void)
if (expld.phase != lang_mark_phase_enum)
{
expld.phase = lang_mark_phase_enum;
expld.textseg.phase = exp_seg_none;
expld.dataseg.phase = exp_seg_none;
one_lang_size_sections_pass (NULL, FALSE);
/* We must not cache anything from the preliminary sizing. */

View File

@@ -272,6 +272,7 @@ spu_before_allocation (void)
/* Size the sections. This is premature, but we need to know the
rough layout so that overlays can be found. */
expld.phase = lang_mark_phase_enum;
expld.textseg.phase = exp_seg_none;
expld.dataseg.phase = exp_seg_none;
one_lang_size_sections_pass (NULL, TRUE);

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 and read-only data segments */"
. ${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 and read-only data segments */"
. ${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 and read-only data segments */"
. ${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 and read-only data segments */"
. ${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 and read-only data segments */"
. ${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 and read-only data segments */"
. ${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 and read-only data segments */"
. ${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 and read-only data segments */"
. ${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 and read-only data segments */"
. ${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

@@ -1262,7 +1262,16 @@ Create an ELF @code{PT_GNU_RELRO} segment header in the object. This
specifies a memory segment that should be made read-only after
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}.
Don't create an ELF @code{PT_GNU_RELRO} segment if @samp{norelro} is
used, which also implies @option{-z noseparate-code}.
@item separate-code
@itemx noseparate-code
Create separate code and read-only data @code{PT_LOAD} segment headers
in the object. This specifies a memory segment that should contain
only instructions. This option also implies @option{-z relro}. Don't
create separate code and read-only data @code{PT_LOAD} segments if
@samp{noseparate-code} is used.
@item shstk
Generate GNU_PROPERTY_X86_FEATURE_1_SHSTK in .note.gnu.property section

View File

@@ -131,6 +131,9 @@ exp_print_token (token_code_type code, int infix_p)
{ DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
{ DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
{ DATA_SEGMENT_END, "DATA_SEGMENT_END" },
{ TEXT_SEGMENT_ALIGN, "TEXT_SEGMENT_ALIGN" },
{ TEXT_SEGMENT_RELRO_END, "TEXT_SEGMENT_RELRO_END" },
{ TEXT_SEGMENT_END, "TEXT_SEGMENT_END" },
{ ORIGIN, "ORIGIN" },
{ LENGTH, "LENGTH" },
{ SEGMENT_START, "SEGMENT_START" }
@@ -411,6 +414,10 @@ fold_unary (etree_type *tree)
fold_segment_end (&expld.dataseg);
break;
case TEXT_SEGMENT_END:
fold_segment_end (&expld.textseg);
break;
default:
FAIL ();
break;
@@ -659,6 +666,14 @@ fold_binary (etree_type *tree)
fold_segment_relro_end (&expld.dataseg, &lhs);
break;
case TEXT_SEGMENT_ALIGN:
fold_segment_align (&expld.textseg, &lhs);
break;
case TEXT_SEGMENT_RELRO_END:
fold_segment_relro_end (&expld.textseg, &lhs);
break;
default:
FAIL ();
}
@@ -1311,7 +1326,8 @@ exp_unop (int code, etree_type *child)
&& code != ALIGN_K
&& code != ABSOLUTE
&& code != NEXT
&& code != DATA_SEGMENT_END)
&& code != DATA_SEGMENT_END
&& code != TEXT_SEGMENT_END)
exp_value_fold (new_e);
return new_e;
}

View File

@@ -178,6 +178,9 @@ struct ldexp_control {
/* State machine and results for DATASEG. */
seg_align_type dataseg;
/* State machine and results for TEXTSEG. */
seg_align_type textseg;
};
extern struct ldexp_control expld;

View File

@@ -127,6 +127,7 @@ static int error_index;
%token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
%token SECTIONS PHDRS INSERT_K AFTER BEFORE
%token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
%token TEXT_SEGMENT_ALIGN TEXT_SEGMENT_RELRO_END TEXT_SEGMENT_END
%token SORT_BY_NAME SORT_BY_ALIGNMENT SORT_NONE
%token SORT_BY_INIT_PRIORITY
%token '{' '}'
@@ -993,6 +994,12 @@ exp :
{ $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); }
| DATA_SEGMENT_END '(' exp ')'
{ $$ = exp_unop (DATA_SEGMENT_END, $3); }
| TEXT_SEGMENT_ALIGN '(' exp ',' exp ')'
{ $$ = exp_binop (TEXT_SEGMENT_ALIGN, $3, $5); }
| TEXT_SEGMENT_RELRO_END '(' exp ',' exp ')'
{ $$ = exp_binop (TEXT_SEGMENT_RELRO_END, $5, $3); }
| TEXT_SEGMENT_END '(' exp ')'
{ $$ = exp_unop (TEXT_SEGMENT_END, $3); }
| SEGMENT_START '(' NAME ',' exp ')'
{ /* The operands to the expression node are
placed in the opposite order from the way

View File

@@ -3889,6 +3889,7 @@ strip_excluded_output_sections (void)
{
expld.phase = lang_mark_phase_enum;
expld.dataseg.phase = exp_seg_none;
expld.textseg.phase = exp_seg_none;
one_lang_size_sections_pass (NULL, FALSE);
lang_reset_memory_regions ();
}
@@ -5448,14 +5449,17 @@ lang_size_sections_1
bfd_vma newdot = dot;
etree_type *tree = s->assignment_statement.exp;
expld.textseg.relro = exp_seg_relro_none;
expld.dataseg.relro = exp_seg_relro_none;
exp_fold_tree (tree,
output_section_statement->bfd_section,
&newdot);
ldlang_check_relro_region (s, &expld.textseg);
ldlang_check_relro_region (s, &expld.dataseg);
expld.textseg.relro = exp_seg_relro_none;
expld.dataseg.relro = exp_seg_relro_none;
/* This symbol may be relative to this section. */
@@ -5662,35 +5666,56 @@ static bfd_boolean
lang_size_relro_segment (bfd_boolean *relax, bfd_boolean check_regions)
{
bfd_boolean do_reset = FALSE;
bfd_boolean do_data_relro;
bfd_vma data_initial_base, data_relro_end;
bfd_boolean do_text_relro = FALSE;
bfd_boolean do_data_relro = FALSE;
if (link_info.relro && expld.dataseg.relro_end)
if (link_info.relro)
{
do_data_relro = TRUE;
data_initial_base = expld.dataseg.base;
data_relro_end = lang_size_relro_segment_1 (&expld.dataseg);
}
else
{
do_data_relro = FALSE;
data_initial_base = data_relro_end = 0;
}
bfd_vma text_initial_base, text_relro_end;
bfd_vma data_initial_base, data_relro_end;
if (do_data_relro)
{
lang_reset_memory_regions ();
one_lang_size_sections_pass (relax, check_regions);
/* Assignments to dot, or to output section address in a user
script have increased padding over the original. Revert. */
if (do_data_relro && expld.dataseg.relro_end > data_relro_end)
if (link_info.relro > 1 && expld.textseg.relro_end)
{
expld.dataseg.base = data_initial_base;;
do_reset = TRUE;
do_text_relro = TRUE;
text_initial_base = expld.textseg.base;
text_relro_end = lang_size_relro_segment_1 (&expld.textseg);
}
else
text_initial_base = text_relro_end = 0;
if (expld.dataseg.relro_end)
{
do_data_relro = TRUE;
data_initial_base = expld.dataseg.base;
data_relro_end = lang_size_relro_segment_1 (&expld.dataseg);
}
else
data_initial_base = data_relro_end = 0;
if (do_text_relro || do_data_relro)
{
lang_reset_memory_regions ();
one_lang_size_sections_pass (relax, check_regions);
/* Assignments to dot, or to output section address in a user
script have increased padding over the original. Revert. */
if (do_text_relro && expld.textseg.relro_end > text_relro_end)
{
expld.textseg.base = text_initial_base;
do_reset = TRUE;
}
if (do_data_relro && expld.dataseg.relro_end > data_relro_end)
{
expld.dataseg.base = data_initial_base;;
do_reset = TRUE;
}
}
}
if (!do_text_relro && lang_size_segment (&expld.textseg))
do_reset = TRUE;
if (!do_data_relro && lang_size_segment (&expld.dataseg))
do_reset = TRUE;
@@ -5702,13 +5727,17 @@ lang_size_sections (bfd_boolean *relax, bfd_boolean check_regions)
{
expld.phase = lang_allocating_phase_enum;
expld.dataseg.phase = exp_seg_none;
expld.textseg.phase = exp_seg_none;
one_lang_size_sections_pass (relax, check_regions);
if (expld.textseg.phase != exp_seg_end_seen)
expld.textseg.phase = exp_seg_done;
if (expld.dataseg.phase != exp_seg_end_seen)
expld.dataseg.phase = exp_seg_done;
if (expld.dataseg.phase == exp_seg_end_seen)
if (expld.textseg.phase == exp_seg_end_seen
|| expld.dataseg.phase == exp_seg_end_seen)
{
bfd_boolean do_reset
= lang_size_relro_segment (relax, check_regions);
@@ -5719,6 +5748,12 @@ lang_size_sections (bfd_boolean *relax, bfd_boolean check_regions)
one_lang_size_sections_pass (relax, check_regions);
}
if (link_info.relro > 1 && expld.textseg.relro_end)
{
link_info.text_start = expld.textseg.base;
link_info.text_end = expld.textseg.relro_end;
}
if (link_info.relro && expld.dataseg.relro_end)
{
link_info.relro_start = expld.dataseg.base;
@@ -6904,15 +6939,33 @@ lang_find_relro_sections_1 (lang_statement_union_type *s,
static void
lang_find_relro_sections (void)
{
bfd_boolean has_relro_section = FALSE;
/* Check all sections in the link script. */
if (link_info.relro)
{
bfd_boolean has_relro_section;
lang_find_relro_sections_1 (expld.dataseg.relro_start_stat,
&expld.dataseg, &has_relro_section);
if (link_info.relro > 1)
{
has_relro_section = FALSE;
lang_find_relro_sections_1 (expld.textseg.relro_start_stat,
&expld.textseg,
&has_relro_section);
if (!has_relro_section)
link_info.relro = 1;
}
if (!has_relro_section)
link_info.relro = FALSE;
/* We can't turn off RELRO if we need to generate read-only
PT_LOAD segment. */
if (link_info.relro == 1)
{
has_relro_section = FALSE;
lang_find_relro_sections_1 (expld.dataseg.relro_start_stat,
&expld.dataseg,
&has_relro_section);
if (!has_relro_section)
link_info.relro = 0;
}
}
}
/* Relax all sections until bfd_relax_section gives up. */

View File

@@ -250,6 +250,9 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN);}
<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END);}
<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_END" { RTOKEN(DATA_SEGMENT_END);}
<EXPRESSION,BOTH,SCRIPT>"TEXT_SEGMENT_ALIGN" { RTOKEN(TEXT_SEGMENT_ALIGN);}
<EXPRESSION,BOTH,SCRIPT>"TEXT_SEGMENT_RELRO_END" { RTOKEN(TEXT_SEGMENT_RELRO_END);}
<EXPRESSION,BOTH,SCRIPT>"TEXT_SEGMENT_END" { RTOKEN(TEXT_SEGMENT_END);}
<EXPRESSION,BOTH,SCRIPT>"ADDR" { RTOKEN(ADDR);}
<EXPRESSION,BOTH,SCRIPT>"LOADADDR" { RTOKEN(LOADADDR);}
<EXPRESSION,BOTH,SCRIPT>"ALIGNOF" { RTOKEN(ALIGNOF); }

View File

@@ -1785,9 +1785,16 @@ elf_shlib_list_options (FILE *file)
fprintf (file, _("\
-z relro Create RELRO program header\n"));
fprintf (file, _("\
-z norelro Don't create RELRO program header (default)\n"));
-z norelro Don't create RELRO nor separate code and read-only\n\
data program headers (default)\n"));
#endif
fprintf (file, _("\
-z separate-code Create separate code and read-only data program\n\
headers\n"));
fprintf (file, _("\
-z noseparate-code Don't create separate code and read-only data\n\
program headers (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"));

View File

@@ -139,6 +139,23 @@ if test -z "$DATA_SEGMENT_ALIGN"; then
DATA_SEGMENT_RELRO_END=". = DATA_SEGMENT_RELRO_END (${SEPARATE_GOTPLT-0}, .);"
fi
fi
# Don't bother with text-only segment when there are data sections between
# .plt and .text.
if test -n "$TINY_READONLY_SECTION"; then
TEXT_SEGMENT_ALIGN=" "
TEXT_SEGMENT_RELRO_END=" "
TEXT_SEGMENT_END=" "
fi
if test -z "$TEXT_SEGMENT_ALIGN" && test -n "$DATA_SEGMENT_ALIGN"; then
case "$LD_FLAG" in
*textonly*)
TEXT_SEGMENT_ALIGN=`echo $DATA_SEGMENT_ALIGN | sed -e "s/DATA/TEXT/g"`
TEXT_SEGMENT_ALIGN=". = $TEXT_SEGMENT_ALIGN;"
TEXT_SEGMENT_RELRO_END=". = TEXT_SEGMENT_RELRO_END (0, .);"
TEXT_SEGMENT_END=". = TEXT_SEGMENT_END (.);"
;;
esac
fi
if test -z "${INITIAL_READONLY_SECTIONS}${CREATE_SHLIB}"; then
INITIAL_READONLY_SECTIONS=".interp ${RELOCATING-0} : { *(.interp) }"
fi
@@ -478,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}}
@@ -508,6 +527,8 @@ cat <<EOF
${RELOCATING+PROVIDE (__${ETEXT_NAME} = .);}
${RELOCATING+PROVIDE (_${ETEXT_NAME} = .);}
${RELOCATING+PROVIDE (${ETEXT_NAME} = .);}
${RELOCATING+${TEXT_SEGMENT_RELRO_END}}
${RELOCATING+${TEXT_SEGMENT_END}}
EOF
if test -n "${SEPARATE_CODE}"; then

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.