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.
(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".