This is the mail archive of the
binutils-cvs@sourceware.org
mailing list for the binutils project.
[binutils-gdb] ld: Don't evaluate unneeded PROVIDE expressions.
- From: Andrew Burgess <aburgess at sourceware dot org>
- To: bfd-cvs at sourceware dot org
- Date: 20 Jan 2015 10:23:28 -0000
- Subject: [binutils-gdb] ld: Don't evaluate unneeded PROVIDE expressions.
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c05b575a8dfabab6af5d8586d1a5c0c67f819ac2
commit c05b575a8dfabab6af5d8586d1a5c0c67f819ac2
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date: Wed Jan 7 10:51:35 2015 +0000
ld: Don't evaluate unneeded PROVIDE expressions.
When creating a linker mapfile (using -Map=MAPFILE), we previously would
always try to evaluate the expression from a PROVIDE statement.
However, this is not always safe, consider:
PROVIDE (foo = 0x10);
PROVIDE (bar = foo);
In this example, if neither 'foo' or 'bar' is needed, then while
generating the linker mapfile evaluating the expression for 'foo' is
harmless (just the value 0x10). However, evaluating the expression for
'bar' requires the symbol 'foo', which is undefined. This used to cause
a fatal error.
This patch changes the behaviour, so that when the destination of the
PROVIDE is not defined (that is the PROVIDE is not going to provide
anything) the expression is not evaluated, and instead a special string
is displayed to indicate that the linker is discarding the PROVIDE
statement.
This change not only fixes the spurious undefined symbol error, but also
means that a user can now tell if a PROVIDE statement has provided
anything by inspecting the linker mapfile, something that could not be
done before.
ld/ChangeLog:
* ldlang.c (print_assignment): Only evaluate the expression for a
PROVIDE'd assignment when the destination is being defined.
Display a special message for PROVIDE'd symbols that are not being
provided.
ld/testsuite/ChangeLog:
* ld-scripts/provide-4.d: New file.
* ld-scripts/provide-4-map.d: New file.
* ld-scripts/provide-4.t: New file.
* ld-scripts/provide-5.d: New file.
* ld-scripts/provide-5.s: New file.
* ld-scripts/provide-5-map.d: New file.
* ld-scripts/provide-5.t: New file.
* ld-scripts/provide.exp: Run the provide-4.d and provide-5.d
tests.
Diff:
---
ld/ChangeLog | 7 +++++++
ld/ldlang.c | 12 ++++++++++--
ld/testsuite/ChangeLog | 12 ++++++++++++
ld/testsuite/ld-scripts/provide-4-map.d | 13 +++++++++++++
ld/testsuite/ld-scripts/provide-4.d | 9 +++++++++
ld/testsuite/ld-scripts/provide-4.t | 16 ++++++++++++++++
ld/testsuite/ld-scripts/provide-5-map.d | 6 ++++++
ld/testsuite/ld-scripts/provide-5.d | 6 ++++++
ld/testsuite/ld-scripts/provide-5.s | 4 ++++
ld/testsuite/ld-scripts/provide-5.t | 10 ++++++++++
ld/testsuite/ld-scripts/provide.exp | 2 ++
11 files changed, 95 insertions(+), 2 deletions(-)
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 1ca6fe3..4641ff0 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,10 @@
+2015-01-20 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * ldlang.c (print_assignment): Only evaluate the expression for a
+ PROVIDE'd assignment when the destination is being defined.
+ Display a special message for PROVIDE'd symbols that are not being
+ provided.
+
2015-01-20 Alan Modra <amodra@gmail.com>
* emulparams/elf64ppc.sh (BSS_PLT): Don't define.
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 0c72333..3ea22c2 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3983,7 +3983,12 @@ print_assignment (lang_assignment_statement_type *assignment,
osec = output_section->bfd_section;
if (osec == NULL)
osec = bfd_abs_section_ptr;
- exp_fold_tree (tree, osec, &print_dot);
+
+ if (assignment->exp->type.node_class != etree_provide)
+ exp_fold_tree (tree, osec, &print_dot);
+ else
+ expld.result.valid_p = FALSE;
+
if (expld.result.valid_p)
{
bfd_vma value;
@@ -4021,7 +4026,10 @@ print_assignment (lang_assignment_statement_type *assignment,
}
else
{
- minfo ("*undef* ");
+ if (assignment->exp->type.node_class == etree_provide)
+ minfo ("[!provide]");
+ else
+ minfo ("*undef* ");
#ifdef BFD64
minfo (" ");
#endif
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index b6e3481..0b47494 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,5 +1,17 @@
2015-01-20 Andrew Burgess <andrew.burgess@embecosm.com>
+ * ld-scripts/provide-4.d: New file.
+ * ld-scripts/provide-4-map.d: New file.
+ * ld-scripts/provide-4.t: New file.
+ * ld-scripts/provide-5.d: New file.
+ * ld-scripts/provide-5.s: New file.
+ * ld-scripts/provide-5-map.d: New file.
+ * ld-scripts/provide-5.t: New file.
+ * ld-scripts/provide.exp: Run the provide-4.d and provide-5.d
+ tests.
+
+2015-01-20 Andrew Burgess <andrew.burgess@embecosm.com>
+
* ld-scripts/overlay-size.d: Add 'map' option.
* ld-scripts/overlay-size.exp: Remove manual check of mapfile.
* lib/ld-lib.exp (run_dump_test): Add support for new 'map'
diff --git a/ld/testsuite/ld-scripts/provide-4-map.d b/ld/testsuite/ld-scripts/provide-4-map.d
new file mode 100644
index 0000000..d8e4a28
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-4-map.d
@@ -0,0 +1,13 @@
+#...
+Linker script and memory map
+#...
+ \[!provide\] PROVIDE \(foo, 0x1\)
+ \[!provide\] PROVIDE \(bar, 0x2\)
+ 0x0+3 PROVIDE \(baz, 0x3\)
+#...
+ 0x0+2000 foo
+ \[!provide\] PROVIDE \(loc1, ALIGN \(\., 0x10\)\)
+ 0x0+2010 PROVIDE \(loc2, ALIGN \(\., 0x10\)\)
+ \[!provide\] PROVIDE \(loc3, \(loc1 \+ 0x20\)\)
+ 0x0+2030 loc4 = \(loc2 \+ 0x20\)
+#...
diff --git a/ld/testsuite/ld-scripts/provide-4.d b/ld/testsuite/ld-scripts/provide-4.d
new file mode 100644
index 0000000..a7d37e3
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-4.d
@@ -0,0 +1,9 @@
+#source: provide-2.s
+#ld: -T provide-4.t
+#PROG: nm
+#map: provide-4-map.d
+#...
+0+3 A baz
+0+2000 D foo
+0+2010 D loc2
+0+2030 A loc4
diff --git a/ld/testsuite/ld-scripts/provide-4.t b/ld/testsuite/ld-scripts/provide-4.t
new file mode 100644
index 0000000..424c238
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-4.t
@@ -0,0 +1,16 @@
+SECTIONS
+{
+ PROVIDE (foo = 1);
+ PROVIDE (bar = 2);
+ PROVIDE (baz = 3);
+ .data 0x2000 :
+ {
+ *(.data)
+
+ PROVIDE (loc1 = ALIGN (., 0x10));
+ PROVIDE (loc2 = ALIGN (., 0x10));
+ }
+
+ PROVIDE (loc3 = loc1 + 0x20);
+ loc4 = loc2 + 0x20;
+}
diff --git a/ld/testsuite/ld-scripts/provide-5-map.d b/ld/testsuite/ld-scripts/provide-5-map.d
new file mode 100644
index 0000000..2271dfd
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-5-map.d
@@ -0,0 +1,6 @@
+#...
+Linker script and memory map
+#...
+ 0x0+10 foo = 0x10
+ \[!provide\] PROVIDE \(foo, bar\)
+#...
diff --git a/ld/testsuite/ld-scripts/provide-5.d b/ld/testsuite/ld-scripts/provide-5.d
new file mode 100644
index 0000000..1b14fa6
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-5.d
@@ -0,0 +1,6 @@
+#source: provide-5.s
+#ld: -T provide-5.t
+#PROG: nm
+#map: provide-5-map.d
+#...
+0+10 A foo
diff --git a/ld/testsuite/ld-scripts/provide-5.s b/ld/testsuite/ld-scripts/provide-5.s
new file mode 100644
index 0000000..1d05efd
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-5.s
@@ -0,0 +1,4 @@
+ .data
+ .global baz
+baz:
+ .word 0
diff --git a/ld/testsuite/ld-scripts/provide-5.t b/ld/testsuite/ld-scripts/provide-5.t
new file mode 100644
index 0000000..eda741e
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-5.t
@@ -0,0 +1,10 @@
+SECTIONS
+{
+ foo = 0x10;
+ PROVIDE (foo = bar);
+
+ .data 0x1000 :
+ {
+ *(.data)
+ }
+}
diff --git a/ld/testsuite/ld-scripts/provide.exp b/ld/testsuite/ld-scripts/provide.exp
index 7f45e58..3ddbb22 100644
--- a/ld/testsuite/ld-scripts/provide.exp
+++ b/ld/testsuite/ld-scripts/provide.exp
@@ -40,5 +40,7 @@ run_dump_test provide-1
run_dump_test provide-2
setup_xfail *-*-*
run_dump_test provide-3
+run_dump_test provide-4
+run_dump_test provide-5
set LDFLAGS "$saved_LDFLAGS"