This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH 2/2] ld: Don't evaluate unneeded PROVIDE expressions.
- From: Andrew Burgess <andrew dot burgess at embecosm dot com>
- To: binutils at sourceware dot org
- Cc: Alan Modra <amodra at gmail dot com>, Hans-Peter Nilsson <hp at bitrange dot com>
- Date: Tue, 20 Jan 2015 10:21:48 +0000
- Subject: Re: [PATCH 2/2] ld: Don't evaluate unneeded PROVIDE expressions.
- Authentication-results: sourceware.org; auth=none
- References: <cover dot 1420631791 dot git dot andrew dot burgess at embecosm dot com> <3d30f0e7bfaf420b6a4d64a818db85700c4fc083 dot 1420631791 dot git dot andrew dot burgess at embecosm dot com> <alpine dot BSF dot 2 dot 02 dot 1501072022030 dot 57687 at arjuna dot pair dot com> <20150108101756 dot GG3103 at embecosm dot com> <alpine dot BSF dot 2 dot 02 dot 1501080607080 dot 20143 at arjuna dot pair dot com> <20150108200304 dot GM3103 at embecosm dot com> <20150112003853 dot GD23768 at bubble dot grove dot modra dot org> <20150119110620 dot GB2143 at embecosm dot com>
* Andrew Burgess <andrew.burgess@embecosm.com> [2015-01-19 11:06:20 +0000]:
>
> Revised patch is below, the only change is to the testsuite directory.
>
Just before pushing the change I realised that there was a bug in my
code. I now have a revised version of my code, which is actually
simpler, I had previously failed to realise that an expression could
have class etree_provide (unused PROVIDE), or etree_provided (used
PROVIDE), the difference between these two tells me everything I need
to know.
I checked this against the same 110 targets as before and all pass.
Given how similar this version is to the previous, approved, version,
I'm just going to push this.
Thanks,
Andrew
---
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.
---
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(-)
create mode 100644 ld/testsuite/ld-scripts/provide-4-map.d
create mode 100644 ld/testsuite/ld-scripts/provide-4.d
create mode 100644 ld/testsuite/ld-scripts/provide-4.t
create mode 100644 ld/testsuite/ld-scripts/provide-5-map.d
create mode 100644 ld/testsuite/ld-scripts/provide-5.d
create mode 100644 ld/testsuite/ld-scripts/provide-5.s
create mode 100644 ld/testsuite/ld-scripts/provide-5.t
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"
--
1.9.3