aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ChangeLog13
-rw-r--r--ld/ldexp.c88
-rw-r--r--ld/ldlang.c1
-rw-r--r--ld/testsuite/ld-scripts/provide-6.d9
-rw-r--r--ld/testsuite/ld-scripts/provide-6.t11
-rw-r--r--ld/testsuite/ld-scripts/provide-7.d8
-rw-r--r--ld/testsuite/ld-scripts/provide-7.t11
-rw-r--r--ld/testsuite/ld-scripts/provide-8.d8
-rw-r--r--ld/testsuite/ld-scripts/provide-8.t14
9 files changed, 121 insertions, 42 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index f96517e..956a856 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,18 @@
2018-01-11 Andrew Burgess <andrew.burgess@embecosm.com>
+ * ldexp.c (exp_fold_tree_1): Rework condition underwhich provide
+ nodes are ignored in the tree walk, and move the location at which
+ we change provide nodes into provided nodes.
+ (exp_init_os): Add etree_provided.
+ * testsuite/ld-scripts/provide-6.d: New file.
+ * testsuite/ld-scripts/provide-6.t: New file.
+ * testsuite/ld-scripts/provide-7.d: New file.
+ * testsuite/ld-scripts/provide-7.t: New file.
+ * testsuite/ld-scripts/provide-8.d: New file.
+ * testsuite/ld-scripts/provide-8.t: New file.
+
+2018-01-11 Andrew Burgess <andrew.burgess@embecosm.com>
+
* testsuite/ld-scripts/provide-3.d: Add xfail directive.
* testsuite/ld-scripts/provide-4.d: Use new map file name.
* testsuite/ld-scripts/provide-5.d: Use new map file name.
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 800c7f8..6398a2d 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -1153,13 +1153,12 @@ exp_fold_tree_1 (etree_type *tree)
2) Section relative symbol values cannot be correctly
converted to absolute values, as is required by many
expressions, until final section sizing is complete. */
- if ((expld.result.valid_p
- && (expld.phase == lang_final_phase_enum
- || expld.assign_name != NULL))
- || (expld.phase <= lang_mark_phase_enum
- && tree->type.node_class == etree_assign
- && tree->assign.defsym))
+ if (expld.phase == lang_final_phase_enum
+ || expld.assign_name != NULL)
{
+ if (tree->type.node_class == etree_provide)
+ tree->type.node_class = etree_provided;
+
if (h == NULL)
{
h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
@@ -1169,44 +1168,49 @@ exp_fold_tree_1 (etree_type *tree)
tree->assign.dst);
}
- if (expld.result.section == NULL)
- expld.result.section = expld.section;
- if (!update_definedness (tree->assign.dst, h) && 0)
+ /* If the expression is not valid then fake a zero value. In
+ the final phase any errors will already have been raised,
+ in earlier phases we want to create this definition so
+ that it can be seen by other expressions. */
+ if (!expld.result.valid_p
+ && h->type == bfd_link_hash_new)
+ {
+ expld.result.value = 0;
+ expld.result.section = NULL;
+ expld.result.valid_p = TRUE;
+ }
+
+ if (expld.result.valid_p)
{
- /* Symbol was already defined. For now this error
- is disabled because it causes failures in the ld
- testsuite: ld-elf/var1, ld-scripts/defined5, and
- ld-scripts/pr14962. Some of these no doubt
- reflect scripts used in the wild. */
- (*link_info.callbacks->multiple_definition)
- (&link_info, h, link_info.output_bfd,
- expld.result.section, expld.result.value);
+ if (expld.result.section == NULL)
+ expld.result.section = expld.section;
+ if (!update_definedness (tree->assign.dst, h) && 0)
+ {
+ /* Symbol was already defined. For now this error
+ is disabled because it causes failures in the ld
+ testsuite: ld-elf/var1, ld-scripts/defined5, and
+ ld-scripts/pr14962. Some of these no doubt
+ reflect scripts used in the wild. */
+ (*link_info.callbacks->multiple_definition)
+ (&link_info, h, link_info.output_bfd,
+ expld.result.section, expld.result.value);
+ }
+ h->type = bfd_link_hash_defined;
+ h->u.def.value = expld.result.value;
+ h->u.def.section = expld.result.section;
+ h->linker_def = ! tree->assign.type.lineno;
+ h->ldscript_def = 1;
+
+ /* Copy the symbol type if this is an expression only
+ referencing a single symbol. (If the expression
+ contains ternary conditions, ignoring symbols on
+ false branches.) */
+ if (expld.assign_src != NULL
+ && (expld.assign_src
+ != (struct bfd_link_hash_entry *) 0 - 1))
+ bfd_copy_link_hash_symbol_type (link_info.output_bfd, h,
+ expld.assign_src);
}
- h->type = bfd_link_hash_defined;
- h->u.def.value = expld.result.value;
- h->u.def.section = expld.result.section;
- h->linker_def = ! tree->assign.type.lineno;
- h->ldscript_def = 1;
- if (tree->type.node_class == etree_provide)
- tree->type.node_class = etree_provided;
-
- /* Copy the symbol type if this is an expression only
- referencing a single symbol. (If the expression
- contains ternary conditions, ignoring symbols on
- false branches.) */
- if (expld.result.valid_p
- && expld.assign_src != NULL
- && expld.assign_src != (struct bfd_link_hash_entry *) 0 - 1)
- bfd_copy_link_hash_symbol_type (link_info.output_bfd, h,
- expld.assign_src);
- }
- else if (expld.phase == lang_final_phase_enum)
- {
- h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
- FALSE, FALSE, TRUE);
- if (h != NULL
- && h->type == bfd_link_hash_new)
- h->type = bfd_link_hash_undefined;
}
expld.assign_name = NULL;
}
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 294e632..1526d7b 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -2207,6 +2207,7 @@ exp_init_os (etree_type *exp)
{
case etree_assign:
case etree_provide:
+ case etree_provided:
exp_init_os (exp->assign.src);
break;
diff --git a/ld/testsuite/ld-scripts/provide-6.d b/ld/testsuite/ld-scripts/provide-6.d
new file mode 100644
index 0000000..dd40515
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-6.d
@@ -0,0 +1,9 @@
+#source: provide-5.s
+#ld: -T provide-6.t
+#PROG: nm
+#xfail: x86_64-*-cygwin
+
+#...
+0+1000 D foo
+0+1000 D foo_2
+#...
diff --git a/ld/testsuite/ld-scripts/provide-6.t b/ld/testsuite/ld-scripts/provide-6.t
new file mode 100644
index 0000000..6b5d11c
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-6.t
@@ -0,0 +1,11 @@
+SECTIONS
+{
+ .data 0x1000 :
+ {
+ *(.data)
+ }
+
+ foo = ADDR (.data);
+ foo_2 = foo;
+ PROVIDE (foo = 0x20);
+}
diff --git a/ld/testsuite/ld-scripts/provide-7.d b/ld/testsuite/ld-scripts/provide-7.d
new file mode 100644
index 0000000..c524fe4
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-7.d
@@ -0,0 +1,8 @@
+#source: provide-5.s
+#ld: -T provide-7.t
+#PROG: nm
+
+#...
+0+10 A foo
+0+10 A foo_2
+#...
diff --git a/ld/testsuite/ld-scripts/provide-7.t b/ld/testsuite/ld-scripts/provide-7.t
new file mode 100644
index 0000000..882883e
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-7.t
@@ -0,0 +1,11 @@
+SECTIONS
+{
+ .data 0x1000 :
+ {
+ *(.data)
+ }
+
+ foo = 0x10;
+ foo_2 = foo;
+ PROVIDE (foo = 0x20);
+}
diff --git a/ld/testsuite/ld-scripts/provide-8.d b/ld/testsuite/ld-scripts/provide-8.d
new file mode 100644
index 0000000..a402937
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-8.d
@@ -0,0 +1,8 @@
+#source: provide-5.s
+#ld: -T provide-8.t
+#PROG: nm
+#xfail: x86_64-*-cygwin mmix-*-* sh-*-pe spu-*-*
+
+#...
+0+4000 D __FOO
+#...
diff --git a/ld/testsuite/ld-scripts/provide-8.t b/ld/testsuite/ld-scripts/provide-8.t
new file mode 100644
index 0000000..ffc3467
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-8.t
@@ -0,0 +1,14 @@
+SECTIONS
+{
+ .data 0x1000 :
+ {
+ *(.data)
+ QUAD (__FOO);
+ }
+
+ .foo 0x4000 :
+ {
+ PROVIDE (__FOO = .);
+ *(.foo)
+ }
+}