Commit Graph

1 Commits

Author SHA1 Message Date
Andrew Burgess
874ef0386f ld: Allow symbols from PROVIDE to be use in MEMORY regions
I wanted to write a linker script like this:

  PROVIDE(mem_origin = 0x1000);
  PROVIDE(mem_length = 0x1000);

  MEMORY
  {
    REGION : ORIGIN = mem_origin, LENGTH = mem_length
  }

  ....

Then when I link using this script I can optionally supply:

  --defsym=mem_origin=..... --defsym=mem_length=....

to override the defaults.

And though passing `--defsym' does work, if I remove the use of
`--defsym' and just rely on the defaults I get an error:

  ld-new: invalid origin for memory region REGION

Interestingly, if I make the above error non-fatal and dump a linker
map file I see that (a) REGION has origin 0x0, and length 0xffff...,
and (b) the symbol from the PROVIDE is provided.

An examination of ldlang.c:lang_process shows us what the issue is,
the origin and length of all memory regions are set as a result of a
single call to lang_do_memory_regions, this call is done after calling
open_input_bfds.

During the open_input_bfds call provide statements can be converted to
provided statements if we know that the assigned symbol is needed, but
for symbols that are only used in the memory regions we are unaware
that we need these symbols.

What I propose in this patch is to make two calls to
lang_do_memory_regions, in the first call we process the expressions
for the origin and length fields of each region, however, errors,
especially undefined symbols, will be ignored.  The origin and length
values are not updated.  However, by evaluating the expressions any
symbols we need will be added to the symbol table.

Now when we call open_input_bfds, when we process the provide
statements, we will see that the assigned symbol is needed add its new
value to the symbol table.

Finally we reach the original call to lang_do_memory_regions, in
this (now second) call we again process the expressions, and this time
update the origin and length values.  Any errors encountered now are
reported to the user.

ld/ChangeLog:

	* ldlang.c (lang_process): Add extra call to
	lang_do_memory_regions, and pass parameter.
	(lang_do_memory_regions): Add parameter, only define origin and
	length when requested.  Reindent.
	* testsuite/ld-scripts/provide-10.d: New file.
	* testsuite/ld-scripts/provide-10.map: New file.
	* testsuite/ld-scripts/provide-11.d: New file.
	* testsuite/ld-scripts/provide-11.map: New file.
	* testsuite/ld-scripts/provide-12.d: New file.
	* testsuite/ld-scripts/provide-12.map: New file.
	* testsuite/ld-scripts/provide-9.d: New file.
	* testsuite/ld-scripts/provide-9.map: New file.
	* testsuite/ld-scripts/provide-9.t: New file.
2020-10-16 13:43:49 +01:00