|
|
@@ -1,276 +0,0 @@
|
|
|
-From 3d9c8f6b3f033a6092425b7344647fb51dbed5c6 Mon Sep 17 00:00:00 2001
|
|
|
-From: Alan Modra <[email protected]>
|
|
|
-Date: Sun, 26 Aug 2018 14:23:38 +0930
|
|
|
-Subject: [PATCH] Delay evaluation of alignment expressions in output sections
|
|
|
-
|
|
|
-git commit 702d16713 broke expressions using CONSTANT(COMMONPAGESIZE)
|
|
|
-in ALIGN or SUBALIGN of output section statements, because these
|
|
|
-optional fields were evaluated at script parse time and the patch in
|
|
|
-question delayed setting of config.commonpagesize. The right thing to
|
|
|
-do is keep the tree representation of those fields for later
|
|
|
-evaluation.
|
|
|
-
|
|
|
- PR 23571
|
|
|
- * ldlang.h (section_alignment): Make it an expression tree.
|
|
|
- (subsection_alignment): Likewise.
|
|
|
- * ldlang.c (topower): Delete.
|
|
|
- (output_section_statement_newfunc): Adjust initialization.
|
|
|
- (init_os): Evaluate section_alignment.
|
|
|
- (lang_size_sections_1): Likewise.
|
|
|
- (size_input_section): Evaluate subsection_alignment.
|
|
|
- (lang_enter_output_section_statement): Don't evaluate here.
|
|
|
- (lang_new_phdr): Use exp_get_vma rather than exp_get_value_int.
|
|
|
- * ldexp.h (exp_get_value_int): Delete.
|
|
|
- (exp_get_power): Declare.
|
|
|
- * ldexp.c (exp_get_value_int): Delete.
|
|
|
- (exp_get_power): New function.
|
|
|
- * emultempl/pe.em (place_orphan): Build expression for section
|
|
|
- alignment.
|
|
|
- * emultempl/pep.em (place_orphan): Likewise.
|
|
|
- * testsuite/ld-scripts/pr23571.d,
|
|
|
- * testsuite/ld-scripts/pr23571.t: New test.
|
|
|
- * testsuite/ld-scripts/align.exp: Run it.
|
|
|
----
|
|
|
- ld/ChangeLog | 23 +++++++++++++++++++
|
|
|
- ld/emultempl/pe.em | 2 +-
|
|
|
- ld/emultempl/pep.em | 2 +-
|
|
|
- ld/ldexp.c | 20 ++++++++++++++--
|
|
|
- ld/ldexp.h | 4 ++--
|
|
|
- ld/ldlang.c | 48 +++++++++++++--------------------------
|
|
|
- ld/ldlang.h | 4 ++--
|
|
|
- ld/testsuite/ld-scripts/align.exp | 4 ++++
|
|
|
- ld/testsuite/ld-scripts/pr23571.d | 10 ++++++++
|
|
|
- ld/testsuite/ld-scripts/pr23571.t | 11 +++++++++
|
|
|
- 10 files changed, 88 insertions(+), 40 deletions(-)
|
|
|
- create mode 100644 ld/testsuite/ld-scripts/pr23571.d
|
|
|
- create mode 100644 ld/testsuite/ld-scripts/pr23571.t
|
|
|
-
|
|
|
---- a/ld/emultempl/pe.em
|
|
|
-+++ b/ld/emultempl/pe.em
|
|
|
-@@ -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;
|
|
|
- }
|
|
|
- }
|
|
|
---- a/ld/emultempl/pep.em
|
|
|
-+++ b/ld/emultempl/pep.em
|
|
|
-@@ -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;
|
|
|
- }
|
|
|
- }
|
|
|
---- a/ld/ldexp.c
|
|
|
-+++ b/ld/ldexp.c
|
|
|
-@@ -1522,10 +1522,26 @@ exp_get_vma (etree_type *tree, bfd_vma d
|
|
|
- return def;
|
|
|
- }
|
|
|
-
|
|
|
-+/* 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. */
|
|
|
-+
|
|
|
- int
|
|
|
--exp_get_value_int (etree_type *tree, int def, char *name)
|
|
|
-+exp_get_power (etree_type *tree, char *name)
|
|
|
- {
|
|
|
-- return exp_get_vma (tree, def, 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 *
|
|
|
---- a/ld/ldexp.h
|
|
|
-+++ b/ld/ldexp.h
|
|
|
-@@ -229,8 +229,8 @@ void exp_print_tree
|
|
|
- (etree_type *);
|
|
|
- bfd_vma exp_get_vma
|
|
|
- (etree_type *, bfd_vma, char *);
|
|
|
--int exp_get_value_int
|
|
|
-- (etree_type *, int, char *);
|
|
|
-+int exp_get_power
|
|
|
-+ (etree_type *, char *);
|
|
|
- fill_type *exp_get_fill
|
|
|
- (etree_type *, fill_type *, char *);
|
|
|
- bfd_vma exp_get_abs_int
|
|
|
---- a/ld/ldlang.c
|
|
|
-+++ b/ld/ldlang.c
|
|
|
-@@ -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;
|
|
|
---- a/ld/ldlang.h
|
|
|
-+++ b/ld/ldlang.h
|
|
|
-@@ -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;
|
|
|
---- a/ld/testsuite/ld-scripts/align.exp
|
|
|
-+++ b/ld/testsuite/ld-scripts/align.exp
|
|
|
-@@ -53,3 +53,7 @@ if ![is_aout_format] {
|
|
|
- }
|
|
|
- run_dump_test align2c
|
|
|
- set LDFLAGS "$saved_LDFLAGS"
|
|
|
-+
|
|
|
-+if { [is_elf_format] && ![is_generic_elf] } {
|
|
|
-+ run_dump_test pr23571
|
|
|
-+}
|
|
|
---- /dev/null
|
|
|
-+++ b/ld/testsuite/ld-scripts/pr23571.d
|
|
|
-@@ -0,0 +1,10 @@
|
|
|
-+#source: align2a.s
|
|
|
-+#ld: -T pr23571.t -z common-page-size=0x1000
|
|
|
-+#objdump: -h -w
|
|
|
-+
|
|
|
-+.*: +file format .*
|
|
|
-+
|
|
|
-+Sections:
|
|
|
-+Idx Name +Size +VMA +LMA +File off +Algn +Flags
|
|
|
-+ +0 \.text +[0-9a-f]* +0+1000 +0+1000 .*
|
|
|
-+ +1 \.data +[0-9a-f]* +0+2000 +0+2000 +[0-9a-f]* +2\*\*12 .*
|
|
|
---- /dev/null
|
|
|
-+++ b/ld/testsuite/ld-scripts/pr23571.t
|
|
|
-@@ -0,0 +1,11 @@
|
|
|
-+SECTIONS
|
|
|
-+{
|
|
|
-+ .text CONSTANT(COMMONPAGESIZE) : {
|
|
|
-+ *(.text)
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ .data : ALIGN(CONSTANT(COMMONPAGESIZE)) {
|
|
|
-+ *(.data)
|
|
|
-+ }
|
|
|
-+ /DISCARD/ : {*(*)}
|
|
|
-+}
|