This is an archive of the discontinued LLVM Phabricator instance.

[LLD][ELD] - Do not reject INFO output section type when used with a start address.
ClosedPublic

Authored by grimar on Aug 21 2018, 12:53 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

grimar created this revision.Aug 21 2018, 12:53 AM
ruiu added a comment.Aug 21 2018, 1:06 AM

This function seems a bit too complicated compared to what it should do. Can you simplify if you add peek2() function that returns Tokens[Pos+2] from the lexer?

grimar updated this revision to Diff 161675.Aug 21 2018, 2:38 AM
  • Addressed review comments.
ruiu added inline comments.Aug 21 2018, 2:45 AM
ELF/ScriptLexer.cpp
248–252 ↗(On Diff #161675)

This is perhaps fine, but why don't you just return Tokens[Pos+2]?

ELF/ScriptParser.cpp
735 ↗(On Diff #161675)

I don't think you need a helper function. Can you do something like this?

unless the following two tokens are "(" and ("LOAD", "INFO" or ...)
  read expression
if the next token is "("
  read "LOAD", "INFO", ...

Hi George. Do we actually want this behaviour?

The GNU linker docs states that these output section description type attributes are: " supported for backward compatibility, and are rarely used" which to me reads like deprecated.

We could instead emit an error that these are deprecated and possibly mention which input sections would be affected.

Hi George. Do we actually want this behaviour?

The GNU linker docs states that these output section description type attributes are: " supported for backward compatibility, and are rarely used" which to me reads like deprecated.

We could instead emit an error that these are deprecated and possibly mention which input sections would be affected.

Hi Ben,

We already had a support of "INFO" (I believe we had a user request for that previously). This patch fixes https://bugs.llvm.org/show_bug.cgi?id=38625
and does not bring anything very new, but just teaches parser about one more possible case.

Also, note that we already support the following:

.stack address_expression (NOLOAD) :
{

but not the

.stack address_expression (INFO) :
{

yet. So I think it is worth to implement both for consistency and few users we have.

Also, note that we already support the following:

.stack address_expression (NOLOAD) :
{

but not the

.stack address_expression (INFO) :
{

yet. So I think it is worth to implement both for consistency and few users we have.

The difference is that NOLOAD is not a deprecated feature, and has an effect that would otherwise be difficult to achieve. INFO, OVERLAY etc.. are deprecated, and the user just needs to set section flags correctly to achieve the same effect.

grimar added a subscriber: psmith.Aug 21 2018, 6:44 AM

+Peter.
A little discussion about why "COPY"/"INFO"/"OVERLAY" was implemented is here: D43071.

I'm not sure it is possible to do exactly what the author is doing with https://bugs.llvm.org/show_bug.cgi?id=38625 with a section without SHF_ALLOC. The entire contents of the output section are defined by .= stack_start. As stack_start is calculated by the linker I don't think it would have been possible to do this with a section.

My preference would be to support the INFO, COPY, OVERLAY with an address for embedded users. Many people start by porting examples from GNU ld and aren't experts in linker scripts or startup code. I think it would be useful to be as compatible as possible. I also think we can't imply deprecation from "supported for backwards compatibility" as deprecation often implies removal at a future point.

PROVIDE(_stack_start = ORIGIN(RAM) + LENGTH(RAM));
.stack _edata (INFO) :
{
  _estack = .;
  . = _stack_start;
  _sstack = .;
} > RAM

In the arm-none-eabi gcc toolchain the sample linker scripts using COPY have a .heap and .stack section to provide the size that are already not SHF_ALLOC (so the COPY isn't strictly necessary):

	.heap (COPY):
	{
		__end__ = .;
		PROVIDE(end = .);
		*(.heap*)
		__HeapLimit = .;
	} > RAM

	/* .stack_dummy section doesn't contains any symbols. It is only
	 * used for linker to calculate size of stack sections, and assign
	 * values to stack symbols later */
	.stack_dummy (COPY):
	{
		*(.stack*)
	} > RAM

With the .heap and .stack sections being defined in the startup code for a particular device with something like:

	.section .stack
	.align	3
#ifdef __STACK_SIZE
	.equ	Stack_Size, __STACK_SIZE
#else
	.equ	Stack_Size, 0xc00
#endif
	.globl	__StackTop
	.globl	__StackLimit
__StackLimit:
	.space	Stack_Size
	.size	__StackLimit, . - __StackLimit
__StackTop:
	.size	__StackTop, . - __StackTop

Thanks for the detailed reply Peter!

I am certainly convinced that these features are not deprecated if they feature in examples in your documentation. Also, as you point out, how can you otherwise control the output section properties for entirely artificial output sections (well apart from either binary editing after linking, or creating an empty section with the correct properties in the inputs and assigning it to the output section).

Do you have a better source of documentation for these linker script features than the gnu docs. I find the gnu docs difficult, for example the gnu docs state for NOLOAD that: "the section should be marked as not loadable, so that it will not be loaded into memory when the program is run". Which I find difficult to interpret in in terms of ELF and leaves me required to read the source code to understand what NOLOAD does!

Do you have a better source of documentation for these linker script features than the gnu docs. I find the gnu docs difficult, for example the gnu docs state for NOLOAD that: "the section should be marked as not loadable, so that it will not be loaded into memory when the program is run". Which I find difficult to interpret in in terms of ELF and leaves me required to read the source code to understand what NOLOAD does!

I really wish I did; most of the time it is having to go to the source code, binutils mailing list posts or commit logs, to work out what is supposed to happen.

grimar updated this revision to Diff 161911.Aug 22 2018, 2:40 AM
grimar marked an inline comment as done.

Thanks, Peter!

  • Addressed Rui's comments.
ELF/ScriptLexer.cpp
248–252 ↗(On Diff #161675)

Tried to be consistent with peek() implementation. Fixed.

ELF/ScriptParser.cpp
735 ↗(On Diff #161675)

Done.

ruiu accepted this revision.Aug 27 2018, 3:52 AM

LGTM

This revision is now accepted and ready to land.Aug 27 2018, 3:52 AM
This revision was automatically updated to reflect the committed changes.
This revision was automatically updated to reflect the committed changes.