From ae9f9e49b769533d80ea0b90c8c3a4eb02233b8d Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 4 Sep 2018 12:02:54 +0100 Subject: [PATCH] Delay the evaluation of linker script constants until after the configuration options have been set. Resolves: #1624751 --- binutils-delay-ld-script-constant-eval.patch | 196 +++++++++++++++++++ binutils.spec | 11 +- 2 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 binutils-delay-ld-script-constant-eval.patch diff --git a/binutils-delay-ld-script-constant-eval.patch b/binutils-delay-ld-script-constant-eval.patch new file mode 100644 index 0000000..ff20b6a --- /dev/null +++ b/binutils-delay-ld-script-constant-eval.patch @@ -0,0 +1,196 @@ +diff -rup binutils.orig/ld/emultempl/pe.em binutils-2.31.1/ld/emultempl/pe.em +--- binutils.orig/ld/emultempl/pe.em 2018-09-04 11:00:05.546667021 +0100 ++++ binutils-2.31.1/ld/emultempl/pe.em 2018-09-04 11:00:58.427292612 +0100 +@@ -2165,7 +2165,7 @@ gld_${EMULATION_NAME}_place_orphan (asec + &add_child); + if (bfd_link_relocatable (&link_info)) + { +- os->section_alignment = s->alignment_power; ++ os->section_alignment = exp_intop (1U << s->alignment_power); + os->bfd_section->alignment_power = s->alignment_power; + } + } +diff -rup binutils.orig/ld/emultempl/pep.em binutils-2.31.1/ld/emultempl/pep.em +--- binutils.orig/ld/emultempl/pep.em 2018-09-04 11:00:05.545667029 +0100 ++++ binutils-2.31.1/ld/emultempl/pep.em 2018-09-04 11:01:29.340073740 +0100 +@@ -1962,7 +1962,7 @@ gld_${EMULATION_NAME}_place_orphan (asec + &add_child); + if (bfd_link_relocatable (&link_info)) + { +- os->section_alignment = s->alignment_power; ++ os->section_alignment = exp_intop (1U << s->alignment_power); + os->bfd_section->alignment_power = s->alignment_power; + } + } +diff -rup binutils.orig/ld/ldexp.c binutils-2.31.1/ld/ldexp.c +--- binutils.orig/ld/ldexp.c 2018-09-04 11:00:05.535667100 +0100 ++++ binutils-2.31.1/ld/ldexp.c 2018-09-04 11:03:29.179225246 +0100 +@@ -1528,6 +1528,28 @@ exp_get_value_int (etree_type *tree, int + return exp_get_vma (tree, def, name); + } + ++/* Return the smallest non-negative integer such that two raised to ++ that power is at least as large as the vma evaluated at TREE, if ++ TREE is a non-NULL expression that can be resolved. If TREE is ++ NULL or cannot be resolved, return -1. */ ++ ++signed int ++exp_get_power (etree_type *tree, char *name) ++{ ++ bfd_vma x = exp_get_vma (tree, -1, name); ++ bfd_vma p2; ++ int n; ++ ++ if (x == (bfd_vma) -1) ++ return -1; ++ ++ for (n = 0, p2 = 1; p2 < x; ++n, p2 <<= 1) ++ if (p2 == 0) ++ break; ++ ++ return n; ++} ++ + fill_type * + exp_get_fill (etree_type *tree, fill_type *def, char *name) + { +diff -rup binutils.orig/ld/ldexp.h binutils-2.31.1/ld/ldexp.h +--- binutils.orig/ld/ldexp.h 2018-09-04 11:00:05.536667092 +0100 ++++ binutils-2.31.1/ld/ldexp.h 2018-09-04 11:04:12.937915422 +0100 +@@ -231,6 +231,8 @@ bfd_vma exp_get_vma + (etree_type *, bfd_vma, char *); + int exp_get_value_int + (etree_type *, int, char *); ++signed int exp_get_power ++ (etree_type *, char *); + fill_type *exp_get_fill + (etree_type *, fill_type *, char *); + bfd_vma exp_get_abs_int +diff -rup binutils.orig/ld/ldlang.c binutils-2.31.1/ld/ldlang.c +--- binutils.orig/ld/ldlang.c 2018-09-04 11:00:05.536667092 +0100 ++++ binutils-2.31.1/ld/ldlang.c 2018-09-04 11:07:42.249433438 +0100 +@@ -1199,8 +1199,8 @@ output_section_statement_newfunc (struct + ret = (struct out_section_hash_entry *) entry; + memset (&ret->s, 0, sizeof (ret->s)); + ret->s.header.type = lang_output_section_statement_enum; +- ret->s.output_section_statement.subsection_alignment = -1; +- ret->s.output_section_statement.section_alignment = -1; ++ ret->s.output_section_statement.subsection_alignment = NULL; ++ ret->s.output_section_statement.section_alignment = NULL; + ret->s.output_section_statement.block_value = 1; + lang_list_init (&ret->s.output_section_statement.children); + lang_statement_append (stat_ptr, &ret->s, &ret->s.header.next); +@@ -2193,8 +2193,9 @@ init_os (lang_output_section_statement_t + exp_init_os (s->load_base); + + /* If supplied an alignment, set it. */ +- if (s->section_alignment != -1) +- s->bfd_section->alignment_power = s->section_alignment; ++ if (s->section_alignment != NULL) ++ s->bfd_section->alignment_power = exp_get_power (s->section_alignment, ++ "section alignment"); + } + + /* Make sure that all output sections mentioned in an expression are +@@ -4706,8 +4707,10 @@ size_input_section + is greater than any seen before, then record it too. Perform + the alignment by inserting a magic 'padding' statement. */ + +- if (output_section_statement->subsection_alignment != -1) +- i->alignment_power = output_section_statement->subsection_alignment; ++ if (output_section_statement->subsection_alignment != NULL) ++ i->alignment_power ++ = exp_get_power (output_section_statement->subsection_alignment, ++ "subsection alignment"); + + if (o->alignment_power < i->alignment_power) + o->alignment_power = i->alignment_power; +@@ -5147,7 +5150,8 @@ lang_size_sections_1 + section_alignment = os->bfd_section->alignment_power; + } + else +- section_alignment = os->section_alignment; ++ section_alignment = exp_get_power (os->section_alignment, ++ "section alignment"); + + /* Align to what the section needs. */ + if (section_alignment > 0) +@@ -5225,7 +5229,8 @@ lang_size_sections_1 + only align according to the value in the output + statement. */ + if (os->lma_region != os->region) +- section_alignment = os->section_alignment; ++ section_alignment = exp_get_power (os->section_alignment, ++ "section alignment"); + if (section_alignment > 0) + lma = align_power (lma, section_alignment); + } +@@ -6673,25 +6678,6 @@ lang_add_output (const char *name, int f + } + } + +-static int +-topower (int x) +-{ +- unsigned int i = 1; +- int l; +- +- if (x < 0) +- return -1; +- +- for (l = 0; l < 32; l++) +- { +- if (i >= (unsigned int) x) +- return l; +- i <<= 1; +- } +- +- return 0; +-} +- + lang_output_section_statement_type * + lang_enter_output_section_statement (const char *output_section_statement_name, + etree_type *address_exp, +@@ -6727,10 +6713,8 @@ lang_enter_output_section_statement (con + einfo (_("%F%P:%pS: error: align with input and explicit align specified\n"), + NULL); + +- os->subsection_alignment = +- topower (exp_get_value_int (subalign, -1, "subsection alignment")); +- os->section_alignment = +- topower (exp_get_value_int (align, -1, "section alignment")); ++ os->subsection_alignment = subalign; ++ os->section_alignment = align; + + os->load_base = ebase; + return os; +@@ -7748,7 +7732,7 @@ lang_new_phdr (const char *name, + n = (struct lang_phdr *) stat_alloc (sizeof (struct lang_phdr)); + n->next = NULL; + n->name = name; +- n->type = exp_get_value_int (type, 0, "program header type"); ++ n->type = exp_get_vma (type, 0, "program header type"); + n->filehdr = filehdr; + n->phdrs = phdrs; + n->at = at; +diff -rup binutils.orig/ld/ldlang.h binutils-2.31.1/ld/ldlang.h +--- binutils.orig/ld/ldlang.h 2018-09-04 11:00:05.533667114 +0100 ++++ binutils-2.31.1/ld/ldlang.h 2018-09-04 11:08:29.224100845 +0100 +@@ -143,6 +143,8 @@ typedef struct lang_output_section_state + fill_type *fill; + union etree_union *addr_tree; + union etree_union *load_base; ++ union etree_union *section_alignment; ++ union etree_union *subsection_alignment; + + /* If non-null, an expression to evaluate after setting the section's + size. The expression is evaluated inside REGION (above) with '.' +@@ -153,8 +155,6 @@ typedef struct lang_output_section_state + lang_output_section_phdr_list *phdrs; + + unsigned int block_value; +- int subsection_alignment; /* Alignment of components. */ +- int section_alignment; /* Alignment of start of section. */ + int constraint; + flagword flags; + enum section_type sectype; diff --git a/binutils.spec b/binutils.spec index 850ff06..a42b0b7 100644 --- a/binutils.spec +++ b/binutils.spec @@ -69,7 +69,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.31.1 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv3+ URL: https://sourceware.org/binutils @@ -181,6 +181,11 @@ Patch15: binutils-note-merge-improvements.patch # Lifetime: Fixed in 2.32 Patch16: binutils-detect-corrupt-sym-version-info.patch +# Purpose: Delay the evaluation of linker script constants until +# after the configuration options have been set. +# Lifetime: Fixed in 2.32 +Patch17: binutils-delay-ld-script-constant-eval.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -321,6 +326,7 @@ using libelf instead of BFD. %patch14 -p1 %patch15 -p1 %patch16 -p1 +%patch17 -p1 # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -728,6 +734,9 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Tue Sep 04 2018 Nick Clifton - 2.31.1-13 +- Delay the evaluation of linker script constants until after the configuration options have been set. (#1624751) + * Tue Aug 28 2018 Nick Clifton - 2.31.1-12 - Detect and report corrupt symbol version information. (#1599521)