Linker script values as absolute / relative / number confusion

Andrew Burgess aburgess@broadcom.com
Wed Sep 19 14:01:00 GMT 2012


On 16/09/2012 11:19 PM, Alan Modra wrote:
> On Fri, Sep 14, 2012 at 05:20:58PM +0100, Andrew Burgess wrote:
>> (1) The thing I've ended up with doesn't feel great.  I create
>> _pad_to as an absolute symbol, but then need to wrap it in ABSOLUTE
>> in order to use it as an absolute symbol.  Is this /really/ the
>> intended behaviour.  I'm sure there's a really good reason for the
>> whole absolute addresses to numbers behaviour, but even after
>> reading the docs I don't understand why we'd want it this way, I'm
>> hoping someone can help me understand.
>
> If you've read the history then you know that ld script expression
> evaluation was such an ad-hoc mess that it couldn't be documented
> without pages of rules.  People wrote ld scripts without the benefit
> of much documentation and experimented until "it worked".  The changes
> I made probably didn't go far enough, but if I had rewritten
> expression evaluation to be completely sane that would have broken too
> many existing ld scripts.  Incidentally, a rewrite from scratch would
> have been a much easier task than trying to minimize incompatibility.

I did indeed get that impression.  I just wanted to ask anyway in case 
the answer had been "Oh no! What a terrible mistake, quick lets fix it." 
:)   Instead, I think the answer is more "Yeah it's not ideal, but 
that's now the expected behaviour", which is fair enough given where we 
started out.  I just wanted to be sure.

>
>> (2) In my second attempt, with the version of the line:
>>    . += (ABSOLUTE(.) < _pad_to) ? (_pad_to - ABSOLUTE(.)) : 0;
>> I see the size of "_pad_to - ABSOLUTE(.)" as "0x1fc", given that the
>> ".padding" section starts at 0x104, contains 1 byte then rounds up
>> to an 0x8 bounday, I think the value of ABSOLUTE(.) should be 0x108.
>
> Yes, it is.
>
>> Given that then after converting the number 0x200 to be an absolute
>> address ld comes up with the value "0x1fc + 0x108" = "0x304".  Given
>> that 0x200 (the original value of _pad_to) must be involved
>> somewhere, then all I can think is that ld believes the absolute
>> address for where this line is being executed is at 0x104, but this
>> seems wrong to me, should it not be 0x108?
>
> ld is doing ". = 0x200".  That results in the section ending at
> 0x104+0x200 = 0x304.  Neglecting the condition, your expression is
>
> . = . + (_pad_to - ABSOLUTE(.));
>
> So let's start with the innermost value of ".".
> This has value 4, in section ".padding".
> ABSOLUTE(.) then is 0x108, in the absolute section.
> _pad_to is 0x200, and the ld docs say "Expressions appearing inside an
> output section definition treat absolute symbols as numbers".  So this
> is just a number without any section.
> So, what is the result of the subtraction?  According to the ld docs,
> since one operand is absolute the other should first be made absolute.
> That doesn't happen here!  The ld docs are missing a rule.  Instead
> the number is used as is, and the result is 0xf8 absolute.  Now we add
> this to ".", which has value 4, section ".padding".  Given two
> different sections, ld converts both values to absolute, to get
> 0x108 + 0xf8.  So the net result is ". = 0x200".

Thanks for explaining that, I see where I went wrong now.

Cheers,

Andrew




More information about the Binutils mailing list