This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Linker script values as absolute / relative / number confusion


I trying to take a linker script that used to work on older linkers and get it running on a more recent (2.22) linker.

I'm running into confusion relating to changes in how symbols in the linker script are treated as absolute, relative, or just numbers, and converted from one type to another.

I have a simple example,

> cat obj.s
        .text
        .4byte 0x0
> as -o obj.o obj.s
> ld -T memmap1.ld -Map link1.map -o obj.x obj.o
> cat memmap1.ld
SECTIONS
{
  . = 0x100;

  .text :
  {
    *(.text*)
  }

_pad_to = 0x200;

  .padding :
  {
    BYTE(0); . = ALIGN(8);
    . += (. < _pad_to) ? (_pad_to - .) : 0;
  }

  .end :
  {
    BYTE(0);
  }

  /DISCARD/ : { *(*) }
}
> grep "\.end" link1.map

## END ##

Ok, so, you'll notice a grep at the end, that's how I'm judging success / failure. There's probably lots wrong with the script, so here's what I'm trying to do,

The ".padding" section should fill enough space so that the section /after/ it starts at the address in _pad_to. The address of ".end" then should be 0x200, and the output from the grep, would I hope look like this:
.end 0x0000000000000200 0x1


[ I know there are "correct" ways to force the start address of ".end" to the right place, lets pretend there's a /really/ good reason why I want to do things this way for now. ]

On ld 2.19 I do get the behaviour I'd like. On current HEAD I don't, instead I get:
.end 0x0000000000000304 0x1


The problem it turns out is the line:
  . += (. < _pad_to) ? (_pad_to - .) : 0;

So, I read up in the documentation, and in this page:

http://sourceware.org/binutils/docs-2.22/ld/Expression-Section.html#Expression-Section

If I look at the line in bits, first ". < _pad_to", whether "." is treated as relative or absolute it will be less than "_pad_to", so it's the "_pad_to - ." that's causing the problem.

The docs say that absolute symbols in output sections are treated as plain numbers, so I have "<plain-number: 0x200> - <relative-addr: 0x8>". The docs further suggest that the result of this will be 0x1fc, leading to my change in behaviour.

Ok, so I apply the following patch to "fix" my linker script, the line in question now becomes:
. += (ABSOLUTE(.) < _pad_to) ? (_pad_to - ABSOLUTE(.)) : 0;


Now I rerun the test, and grep for my output line .... and nothing has changed.

So docs again, and indeed, binary operations involving an absolute address and a plain-number convert the number to an absolute. Gah.

Ok, so I throw a few more ABSOLUTEs at the thing, and I get:
. += (ABSOLUTE(.) < ABSOLUTE(_pad_to)) ? (ABSOLUTE(_pad_to) - ABSOLUTE(.)) : 0;


Now I rerun the test and joy, things work again.

So, finally, my questions,

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

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



So, last bit of info is to figure out where all the changes came from. I'm using the git mirror (git://sourceware.org/git/binutils.git), the commit that actually changed the behaviour was dc027516e99b4795b1fba7179de6fe00606910, which was added as a result of bug, http://sourceware.org/bugzilla/show_bug.cgi?id=12066, which was raised as a result of commit 557189b0dd1f3dec6b00b91b9b0c5459ece72a52.


The mailing list thread for commit 557189b0 is:
  http://sourceware.org/ml/binutils/2010-08/msg00118.html

Thanks for your time,

Andrew













Question 1:







Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]