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