aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog16
-rw-r--r--ld/ldlang.c61
-rw-r--r--ld/testsuite/ld-scripts/provide-10.d3
-rw-r--r--ld/testsuite/ld-scripts/provide-10.map6
-rw-r--r--ld/testsuite/ld-scripts/provide-11.d3
-rw-r--r--ld/testsuite/ld-scripts/provide-11.map6
-rw-r--r--ld/testsuite/ld-scripts/provide-12.d3
-rw-r--r--ld/testsuite/ld-scripts/provide-12.map6
-rw-r--r--ld/testsuite/ld-scripts/provide-9.d3
-rw-r--r--ld/testsuite/ld-scripts/provide-9.map6
-rw-r--r--ld/testsuite/ld-scripts/provide-9.t25
11 files changed, 118 insertions, 20 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 74e5b4f..a7869c7 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,21 @@
2020-10-16 Andrew Burgess <andrew.burgess@embecosm.com>
+ * ldlang.c (lang_process): Add extra call to
+ lang_do_memory_regions, and pass parameter.
+ (lang_do_memory_regions): Add parameter, only define origin and
+ length when requested. Reindent.
+ * testsuite/ld-scripts/provide-10.d: New file.
+ * testsuite/ld-scripts/provide-10.map: New file.
+ * testsuite/ld-scripts/provide-11.d: New file.
+ * testsuite/ld-scripts/provide-11.map: New file.
+ * testsuite/ld-scripts/provide-12.d: New file.
+ * testsuite/ld-scripts/provide-12.map: New file.
+ * testsuite/ld-scripts/provide-9.d: New file.
+ * testsuite/ld-scripts/provide-9.map: New file.
+ * testsuite/ld-scripts/provide-9.t: New file.
+
+2020-10-16 Andrew Burgess <andrew.burgess@embecosm.com>
+
* ld.texi (Options): Extend the description of --defsym.
2020-10-16 Nick Clifton <nickc@redhat.com>
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 4249b3a..2073ac0 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -98,7 +98,7 @@ static void lang_record_phdrs (void);
static void lang_do_version_exports_section (void);
static void lang_finalize_version_expr_head
(struct bfd_elf_version_expr_head *);
-static void lang_do_memory_regions (void);
+static void lang_do_memory_regions (bfd_boolean);
/* Exported variables. */
const char *output_target;
@@ -7909,13 +7909,22 @@ lang_process (void)
if (!bfd_section_already_linked_table_init ())
einfo (_("%F%P: can not create hash table: %E\n"));
+ /* A first pass through the memory regions ensures that if any region
+ references a symbol for its origin or length then this symbol will be
+ added to the symbol table. Having these symbols in the symbol table
+ means that when we call open_input_bfds PROVIDE statements will
+ trigger to provide any needed symbols. The regions origins and
+ lengths are not assigned as a result of this call. */
+ lang_do_memory_regions (FALSE);
+
/* Create a bfd for each input file. */
current_target = default_target;
lang_statement_iteration++;
open_input_bfds (statement_list.head, OPEN_BFD_NORMAL);
- /* open_input_bfds also handles assignments, so we can give values
- to symbolic origin/length now. */
- lang_do_memory_regions ();
+
+ /* Now that open_input_bfds has processed assignments and provide
+ statements we can give values to symbolic origin/length now. */
+ lang_do_memory_regions (TRUE);
#if BFD_SUPPORTS_PLUGINS
if (link_info.lto_plugin_active)
@@ -9373,10 +9382,16 @@ lang_do_version_exports_section (void)
lang_new_vers_node (greg, lreg), NULL);
}
-/* Evaluate LENGTH and ORIGIN parts of MEMORY spec */
+/* Evaluate LENGTH and ORIGIN parts of MEMORY spec. This is initially
+ called with UPDATE_REGIONS_P set to FALSE, in this case no errors are
+ thrown, however, references to symbols in the origin and length fields
+ will be pushed into the symbol table, this allows PROVIDE statements to
+ then provide these symbols. This function is called a second time with
+ UPDATE_REGIONS_P set to TRUE, this time the we update the actual region
+ data structures, and throw errors if missing symbols are encountered. */
static void
-lang_do_memory_regions (void)
+lang_do_memory_regions (bfd_boolean update_regions_p)
{
lang_memory_region_type *r = lang_memory_region_list;
@@ -9385,24 +9400,30 @@ lang_do_memory_regions (void)
if (r->origin_exp)
{
exp_fold_tree_no_dot (r->origin_exp);
- if (expld.result.valid_p)
- {
- r->origin = expld.result.value;
- r->current = r->origin;
- }
- else
- einfo (_("%F%P: invalid origin for memory region %s\n"),
- r->name_list.name);
+ if (update_regions_p)
+ {
+ if (expld.result.valid_p)
+ {
+ r->origin = expld.result.value;
+ r->current = r->origin;
+ }
+ else
+ einfo (_("%P: invalid origin for memory region %s\n"),
+ r->name_list.name);
+ }
}
if (r->length_exp)
{
exp_fold_tree_no_dot (r->length_exp);
- if (expld.result.valid_p)
- r->length = expld.result.value;
- else
- einfo (_("%F%P: invalid length for memory region %s\n"),
- r->name_list.name);
- }
+ if (update_regions_p)
+ {
+ if (expld.result.valid_p)
+ r->length = expld.result.value;
+ else
+ einfo (_("%P: invalid length for memory region %s\n"),
+ r->name_list.name);
+ }
+ }
}
}
diff --git a/ld/testsuite/ld-scripts/provide-10.d b/ld/testsuite/ld-scripts/provide-10.d
new file mode 100644
index 0000000..7481a92
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-10.d
@@ -0,0 +1,3 @@
+#source: provide-5.s
+#ld: --defsym=mem_origin=0x300 --defsym=mem_length=0x400 -T provide-9.t
+#map: provide-10.map
diff --git a/ld/testsuite/ld-scripts/provide-10.map b/ld/testsuite/ld-scripts/provide-10.map
new file mode 100644
index 0000000..022b962
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-10.map
@@ -0,0 +1,6 @@
+#...
+Memory Configuration
+
+Name Origin Length Attributes
+FOO 0x[0-9a-f]+300 +0x[0-9a-f]+400
+#pass
diff --git a/ld/testsuite/ld-scripts/provide-11.d b/ld/testsuite/ld-scripts/provide-11.d
new file mode 100644
index 0000000..79bcfa6
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-11.d
@@ -0,0 +1,3 @@
+#source: provide-5.s
+#ld: --defsym=mem_length=0x400 -T provide-9.t
+#map: provide-11.map
diff --git a/ld/testsuite/ld-scripts/provide-11.map b/ld/testsuite/ld-scripts/provide-11.map
new file mode 100644
index 0000000..7176312
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-11.map
@@ -0,0 +1,6 @@
+#...
+Memory Configuration
+
+Name Origin Length Attributes
+FOO 0x[0-9a-f]+100 +0x[0-9a-f]+400
+#pass
diff --git a/ld/testsuite/ld-scripts/provide-12.d b/ld/testsuite/ld-scripts/provide-12.d
new file mode 100644
index 0000000..41d9590
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-12.d
@@ -0,0 +1,3 @@
+#source: provide-5.s
+#ld: --defsym=mem_origin=0x300 -T provide-9.t
+#map: provide-12.map
diff --git a/ld/testsuite/ld-scripts/provide-12.map b/ld/testsuite/ld-scripts/provide-12.map
new file mode 100644
index 0000000..e76654b
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-12.map
@@ -0,0 +1,6 @@
+#...
+Memory Configuration
+
+Name Origin Length Attributes
+FOO 0x[0-9a-f]+300 +0x[0-9a-f]+200
+#pass
diff --git a/ld/testsuite/ld-scripts/provide-9.d b/ld/testsuite/ld-scripts/provide-9.d
new file mode 100644
index 0000000..94dc029
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-9.d
@@ -0,0 +1,3 @@
+#source: provide-5.s
+#ld: -T provide-9.t
+#map: provide-9.map
diff --git a/ld/testsuite/ld-scripts/provide-9.map b/ld/testsuite/ld-scripts/provide-9.map
new file mode 100644
index 0000000..e35e3e2
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-9.map
@@ -0,0 +1,6 @@
+#...
+Memory Configuration
+
+Name Origin Length Attributes
+FOO 0x[0-9a-f]+100 +0x[0-9a-f]+200
+#pass
diff --git a/ld/testsuite/ld-scripts/provide-9.t b/ld/testsuite/ld-scripts/provide-9.t
new file mode 100644
index 0000000..00d906a
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-9.t
@@ -0,0 +1,25 @@
+PROVIDE (mem_origin = 0x100);
+PROVIDE (mem_length = 0x200);
+
+MEMORY
+{
+ FOO : ORIGIN = mem_origin, LENGTH = mem_length
+}
+
+SECTIONS
+{
+ .data : {
+ *(.data .data.*)
+ } >FOO
+
+ .text : {
+ *(.text .text.*)
+ } >FOO
+
+ .bss : {
+ *(.bss .bss.*)
+ } >FOO
+
+ /DISCARD/ : { *(.*) }
+}
+