This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/2] ld: Don't evaluate unneeded PROVIDE expressions.


This is the patch that solves the issue with PROVIDE referencing an
undefined symbol.

The only thing I'm not sure about is my choice of text for when a
PROVIDE statement is not going to provide anything, right now I use
'[!provide]' the style of which was inspired by the '[unresolved]' a
few lines above.  I wanted to keep the length of the string inline
with the '*undef* ' string in the same block.  Any suggestions for
better formatting will be appreciated.

Otherwise, OK to apply?

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.exp: Run the provide-4.d test.
---
 ld/ChangeLog                            |  7 +++++++
 ld/ldlang.c                             | 14 ++++++++++++--
 ld/testsuite/ChangeLog                  |  7 +++++++
 ld/testsuite/ld-scripts/provide-4-map.d | 26 ++++++++++++++++++++++++++
 ld/testsuite/ld-scripts/provide-4.d     | 10 ++++++++++
 ld/testsuite/ld-scripts/provide-4.t     | 16 ++++++++++++++++
 ld/testsuite/ld-scripts/provide.exp     |  1 +
 7 files changed, 79 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

diff --git a/ld/ChangeLog b/ld/ChangeLog
index be4617f..fab597e 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,10 @@
+2015-01-07  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-01  Alan Modra  <amodra@gmail.com>
 
 	* ldver.c (ldversion): Just print current year.
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 9f3d209..a99febe 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3983,7 +3983,14 @@ 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
+      || bfd_link_hash_lookup (link_info.hash,
+                               assignment->exp->assign.dst,
+                               FALSE, FALSE, TRUE) != NULL)
+    exp_fold_tree (tree, osec, &print_dot);
+  else
+    expld.result.valid_p = FALSE;
   if (expld.result.valid_p)
     {
       bfd_vma value;
@@ -4021,7 +4028,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 266e996..521c819 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,5 +1,12 @@
 2015-01-07  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.exp: Run the provide-4.d test.
+
+2015-01-07  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..ec95715
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-4-map.d
@@ -0,0 +1,26 @@
+#...
+Linker script and memory map
+
+                0x0000000000000001                PROVIDE \(foo, 0x1\)
+                \[!provide\]                        PROVIDE \(bar, 0x2\)
+                0x0000000000000003                PROVIDE \(baz, 0x3\)
+
+\.text           0x0000000000000000        0x0
+ \.text          0x0000000000000000        0x0 tmpdir/dump0\.o
+
+\.iplt           0x0000000000000000        0x0
+ \.iplt          0x0000000000000000        0x0 tmpdir/dump0\.o
+
+\.rela\.dyn       0x0000000000000000        0x0
+ \.rela\.iplt     0x0000000000000000        0x0 tmpdir/dump0\.o
+ \.rela\.data     0x0000000000000000        0x0 tmpdir/dump0\.o
+
+\.data           0x0000000000002000       0x10
+ \*\(\.data\)
+ \.data          0x0000000000002000       0x10 tmpdir/dump0\.o
+                0x0000000000002000                foo
+                \[!provide\]                        PROVIDE \(loc1, ALIGN \(\., 0x10\)\)
+                0x0000000000002010                PROVIDE \(loc2, ALIGN \(\., 0x10\)\)
+                \[!provide\]                        PROVIDE \(loc3, \(loc1 \+ 0x20\)\)
+                0x0000000000002030                loc4 = \(loc2 \+ 0x20\)
+#...
\ No newline at end of file
diff --git a/ld/testsuite/ld-scripts/provide-4.d b/ld/testsuite/ld-scripts/provide-4.d
new file mode 100644
index 0000000..78482ea
--- /dev/null
+++ b/ld/testsuite/ld-scripts/provide-4.d
@@ -0,0 +1,10 @@
+#source: provide-2.s
+#ld: -T provide-4.t
+#PROG: nm
+#map: provide-4-map.d
+
+0000000000000003 A baz
+0000000000002000 D foo
+0000000000002010 D loc2
+0000000000002030 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.exp b/ld/testsuite/ld-scripts/provide.exp
index 7f45e58..baba0a4 100644
--- a/ld/testsuite/ld-scripts/provide.exp
+++ b/ld/testsuite/ld-scripts/provide.exp
@@ -40,5 +40,6 @@ run_dump_test provide-1
 run_dump_test provide-2
 setup_xfail *-*-*
 run_dump_test provide-3
+run_dump_test provide-4
 
 set LDFLAGS "$saved_LDFLAGS"
-- 
1.9.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]