ld: output section alignment and empty section.

Fangrui Song i@maskray.me
Thu Mar 12 02:55:26 GMT 2020
On 2020-03-10, Alan Modra wrote:
>On Thu, Mar 05, 2020 at 02:55:44PM +0100, KONRAD Frederic wrote:
>> Hi,
>>
>> I just figured out that the following linker script hunk:
>>
>>   . = ALIGN(0x4);
>>   .rodata :
>>   {
>>     . = ALIGN(0x4);
>>   }
>>
>> is creating an empty .rodata output section while I was expecting it not to be
>> emited.
>>
>> This is because we flag ". = ALIGN(xxx)" as SEC_KEEP in exp_fold_tree_1.
>>
>> Dropping that for ". = ALIGN(constant)" seems to fix the behavior:
>
>Yes it would, but you could also write the align inside .rodata using
>
>  . = ALIGN(. != 0 ? 4 : 1);
>
>That is one of the few forms of assigning to dot that ld recognises as
>*not* resulting in "keep this section".  This is documented under node
>"Output Section Discarding" in ld.info.
>
>I don't think there is a good reason to change this behaviour as there
>may even be scripts that rely on a simpler ALIGN to keep the section.
>
>> Is that because strip_excluded_output_sections happens before the relaxation?
>> Could that be a problem in the case of a constant alignment?
>
>Yes and yes.  It is possible to create a script that assigns an
>address (before the colon in an output section statement) or alignment
>(after the colon) to a section less than the constant alignment in
>some ". = ALIGN();" statement in that section, and the addresses of
>prior sections conspire to make the alignment do nothing before
>relaxation but to add padding when prior sections change.  The patches
>that were reverted with e0a3af227e ran into something like that when I
>tried to make the single operand ALIGN behave like the two operand
>form.
>
>> What do you think?
>
>Fix your script.  :-)

So the rule is:

SECTIONS {
   .not_created : { . = ALIGN(. != 0 ? 4 : 1); }
   .created : { . = ALIGN(4); }
}

I think it'd be nice to simply make the two output section descriptions create empty sections.

SECTIONS {
   .not_created : { PROVIDE(unreferenced = .); }

   .created0 : { . = ALIGN(. != 0 ? 4 : 1); }
   .created1 : { . = ALIGN(4); }
   .created2 : { PROVIDE(referenced = .); }
}



More information about the Binutils mailing list