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.
This commit is contained in:
Andrew Burgess 2015-01-07 10:51:35 +00:00
parent 43d66c95c8
commit c05b575a8d
11 changed files with 95 additions and 2 deletions

View File

@ -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.

View 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

View File

@ -1,3 +1,15 @@
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.

View File

@ -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\)
#...

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,6 @@
#...
Linker script and memory map
#...
0x0+10 foo = 0x10
\[!provide\] PROVIDE \(foo, bar\)
#...

View File

@ -0,0 +1,6 @@
#source: provide-5.s
#ld: -T provide-5.t
#PROG: nm
#map: provide-5-map.d
#...
0+10 A foo

View File

@ -0,0 +1,4 @@
.data
.global baz
baz:
.word 0

View File

@ -0,0 +1,10 @@
SECTIONS
{
foo = 0x10;
PROVIDE (foo = bar);
.data 0x1000 :
{
*(.data)
}
}

View 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"