]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ld: Don't evaluate unneeded PROVIDE expressions.
authorAndrew Burgess <andrew.burgess@embecosm.com>
Wed, 7 Jan 2015 10:51:35 +0000 (10:51 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 11 Feb 2015 12:36:43 +0000 (23:06 +1030)
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
ld/ldlang.c
ld/testsuite/ChangeLog
ld/testsuite/ld-scripts/provide-4-map.d [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-4.d [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-4.t [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-5-map.d [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-5.d [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-5.s [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-5.t [new file with mode: 0644]
ld/testsuite/ld-scripts/provide.exp

index 594fc280a9cb39072e487a57cd74b9c1d55524cb..1f34f5e253bce75a20319ed9200141d482bd67a7 100644 (file)
@@ -1,6 +1,12 @@
 2015-02-11  Alan Modra  <amodra@gmail.com>
 
        Apply from master.
+       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-19  Alan Modra  <amodra@gmail.com>
        PR 17165
        * ldlang.c (lang_process): Run lang_common before lang_gc_sections.
index dc787b008988d78eca1c3f645af8e503c66d8ff2..2433acfb3b2fcff2b7fe59637b242da810cacd0d 100644 (file)
@@ -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
index d7dfad8dcc4f9f138bf137c9b0dce85e8f4228e6..0b97c822166f5e272ae2fb374f120b7c21a77e57 100644 (file)
@@ -1,6 +1,17 @@
 2015-02-11  Alan Modra  <amodra@gmail.com>
 
        Apply from master.
+       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.
diff --git a/ld/testsuite/ld-scripts/provide-4-map.d b/ld/testsuite/ld-scripts/provide-4-map.d
new file mode 100644 (file)
index 0000000..d8e4a28
--- /dev/null
@@ -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 (file)
index 0000000..a7d37e3
--- /dev/null
@@ -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 (file)
index 0000000..424c238
--- /dev/null
@@ -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 (file)
index 0000000..2271dfd
--- /dev/null
@@ -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 (file)
index 0000000..1b14fa6
--- /dev/null
@@ -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 (file)
index 0000000..1d05efd
--- /dev/null
@@ -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 (file)
index 0000000..eda741e
--- /dev/null
@@ -0,0 +1,10 @@
+SECTIONS
+{
+  foo = 0x10;
+  PROVIDE (foo = bar);
+
+  .data 0x1000 :
+  {
+    *(.data)
+  }
+}
index a6d3514e74f4c9302bf2bb28e6b7d67ad5bc4bad..83b5c0ff6a3a623cd03a31c99dc6769dd359f895 100644 (file)
@@ -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"