diff options
Diffstat (limited to 'patches/0002-ld-Add-TEXT_SEGMENT_ALIGN-TEXT_SEGMENT_-RELRO_-END.patch')
-rw-r--r-- | patches/0002-ld-Add-TEXT_SEGMENT_ALIGN-TEXT_SEGMENT_-RELRO_-END.patch | 410 |
1 files changed, 0 insertions, 410 deletions
diff --git a/patches/0002-ld-Add-TEXT_SEGMENT_ALIGN-TEXT_SEGMENT_-RELRO_-END.patch b/patches/0002-ld-Add-TEXT_SEGMENT_ALIGN-TEXT_SEGMENT_-RELRO_-END.patch deleted file mode 100644 index 459cf370d86..00000000000 --- a/patches/0002-ld-Add-TEXT_SEGMENT_ALIGN-TEXT_SEGMENT_-RELRO_-END.patch +++ /dev/null @@ -1,410 +0,0 @@ -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 - |