Commit c935ff02 authored by H.J. Lu's avatar H.J. Lu
Browse files

Revert "Add "-z textonly" option to ELF linker"

This reverts commit e87d0965.

"-z separate-code" has been checked into master branch.
parent d6531146
From e7528d011919097b241c86a5e3adc776219dbec8 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 10 Nov 2017 13:53:20 -0800
Subject: [PATCH 2/6] 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.
---
include/bfdlink.h | 3 ++
ld/ldexp.c | 18 ++++++++-
ld/ldexp.h | 3 ++
ld/ldgram.y | 7 ++++
ld/ldlang.c | 109 +++++++++++++++++++++++++++++++++++++-------------
ld/ldlex.l | 3 ++
ld/scripttempl/elf.sc | 21 ++++++++++
7 files changed, 135 insertions(+), 29 deletions(-)
diff --git a/include/bfdlink.h b/include/bfdlink.h
index d283429fdb..2fdfb2ab71 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -626,6 +626,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;
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 83d9f8f2a7..71051ceb19 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -134,6 +134,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" }
@@ -416,6 +419,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;
@@ -664,6 +671,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 ();
}
@@ -1342,7 +1357,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;
}
diff --git a/ld/ldexp.h b/ld/ldexp.h
index 5ff0fa0a1f..d1429353e1 100644
--- a/ld/ldexp.h
+++ b/ld/ldexp.h
@@ -173,6 +173,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;
diff --git a/ld/ldgram.y b/ld/ldgram.y
index d701e076a2..53da2d062a 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -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
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 674004ee38..ea45bc5639 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3891,6 +3891,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 ();
}
@@ -5450,14 +5451,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. */
@@ -5664,35 +5668,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);
+ if (link_info.relro > 1 && expld.textseg.relro_end)
+ {
+ 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;
- /* 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 (expld.dataseg.relro_end)
{
- expld.dataseg.base = data_initial_base;;
- do_reset = TRUE;
+ 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;
@@ -5704,13 +5729,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);
@@ -5721,6 +5750,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;
@@ -6906,15 +6941,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. */
diff --git a/ld/ldlex.l b/ld/ldlex.l
index 207c97f323..538c372a0f 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -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); }
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index 9f291b359f..9eb024e809 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -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
--
2.13.6
From cc2bcf62719bc5cf63105843ced20d0952667142 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sun, 12 Nov 2017 11:34:03 -0800
Subject: [PATCH 3/6] ld: Create a new LOAD segment for text-only LOAD segment
When there is a text-only 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 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 there is a
text-only LOAD segment, 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.
---
bfd/elf.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/bfd/elf.c b/bfd/elf.c
index 694e43540f..9c5de9675c 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4555,6 +4555,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;
@@ -4643,6 +4644,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)
@@ -4745,18 +4747,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
@@ -4778,6 +4789,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))
@@ -4803,6 +4816,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)
--
2.13.6
From ab0d66f33a7b3ec2ba54057d3ab3e3b5b76f4975 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 13 Nov 2017 14:30:36 -0800
Subject: [PATCH 4/6] 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.
---
ld/emultempl/ppc32elf.em | 1 +
ld/emultempl/ppc64elf.em | 1 +
ld/emultempl/spuelf.em | 1 +
3 files changed, 3 insertions(+)
diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em
index f78a117222..5817fc99c0 100644
--- a/ld/emultempl/ppc32elf.em
+++ b/ld/emultempl/ppc32elf.em
@@ -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 ();
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index d6d5b0acf3..131bae7b54 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -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. */