From: Andrew Burgess Date: Wed, 7 Jan 2015 10:51:35 +0000 (+0000) Subject: ld: Don't evaluate unneeded PROVIDE expressions. X-Git-Tag: binutils-2_25_1~227 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9320edc3f859dbe66c7786058ab89833b0fce346;p=thirdparty%2Fbinutils-gdb.git 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 --git a/ld/ChangeLog b/ld/ChangeLog index 594fc280a9c..1f34f5e253b 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,6 +1,12 @@ 2015-02-11 Alan Modra Apply from master. + 2015-01-20 Andrew Burgess + * 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 PR 17165 * ldlang.c (lang_process): Run lang_common before lang_gc_sections. diff --git a/ld/ldlang.c b/ld/ldlang.c index dc787b00898..2433acfb3b2 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 d7dfad8dcc4..0b97c822166 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,6 +1,17 @@ 2015-02-11 Alan Modra Apply from master. + 2015-01-20 Andrew Burgess + * 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 * 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 index 00000000000..d8e4a2815b9 --- /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 00000000000..a7d37e3c347 --- /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 00000000000..424c238e43e --- /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 00000000000..2271dfd1b78 --- /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 00000000000..1b14fa6a2fe --- /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 00000000000..1d05efd858a --- /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 00000000000..eda741e05c8 --- /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 a6d3514e74f..83b5c0ff6a3 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"