This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
GNU LD: Linker script generating incorrect address
- From: Jens Bauer <jens-lists at gpio dot dk>
- To: binutils at sourceware dot org
- Date: Tue, 21 May 2013 06:26:02 +0200
- Subject: GNU LD: Linker script generating incorrect address
Hi.
This is probably not a bug (perhaps except from in my own linker-script).
Anyway, it does smell interesting, I think.
I have several sections in my linker-script.
Today I just added a new section, which isn't a real section, but a way of 'ensuring' that there's at least 8 bytes available on the heap.
I have a stack, which is fixed at 0x10008000, the end of my normal SRAM.
I have a section, which purpose it is to reserve some space on this stack (I call this section .ustack; not really relevant).
The length of this stack is _eustack - _sustack. For this example, I've reserved 256 bytes (0x100) for the stack.
The heap is located after all other sections, but before the .ustack section.
Here's some data from my .map file:
.heap 0x10005b00 0x8
0x10005b00 . = ALIGN (0x4)
0x10005b00 _end = .
0x10005b00 PROVIDE (end, .)
0x10005b00 . = ALIGN (0x4)
0x10005b00 _sheap = .
*(.heap .heap.*)
0x10005b07 . = (. + 0x7)
*fill* 0x10005b00 0x7
0x10005b07 . = (. | 0x1)
0x10005b08 . = ALIGN (0x4)
*fill* 0x10005b07 0x1
.ustack 0x00005b64 0x100
0x00005b64 . = ALIGN (0x4)
0x00005b64 _sustack = .
*(.ustack .ustack.*)
.ustack 0x00005b64 0x100 src/LWOS/Variables.o
0x00005c64 . = ALIGN (0x4)
0x00005c64 _eustack = .
0x00000100 _lustack = (_eustack - _sustack)
0x10008000 _stack = (ORIGIN (sram) + 0x8000)
0x1000239c _eheap = (_stack - _lustack)
Now, wait a minute... GNU LD, you just told me that you know that the stack is located at 0x10008000; you also told me that you found out that _lustack is 0x100.
How come, you get the result _eheap = 0x1000239c when subtracting 0x100 from 0x10008000 then ? -Shouldn't this be approximately 0x10007f00 ?
Here's the most interesting part of my linker-script...
.heap _estack (NOLOAD) : /* a heap pseudo-section that defines the minimum required heap size */
{
. = ALIGN(4); /* make sure end is on an even address */
_end = .; /* Define a global symbol marking the end of application RAM */
PROVIDE(end = .); /* end is before the heap */
. = ALIGN(4); /* make sure heap starts on an even address */
_sheap = .; /* Define a global symbol marking the start of the heap. */
*(.heap .heap.*) /* all .heap sections */
. = . + 7; /* make sure we always have room for 2 longwords */
. = . | 1; /* force align to *always* do something, which means always include the heap section! */
. = ALIGN(4); /* make sure heap ends on an even address */
} >sram
.ustack (NOLOAD) : /* a user stack pseudo-section that only defines the user stack length */
{
. = ALIGN(4);
_sustack = .;
*(.ustack .ustack.*)
. = ALIGN(4);
_eustack = .;
_lustack = _eustack - _sustack;
}
_stack = ORIGIN(sram) + LENGTH(sram); /* This is the best place for the stack; it grows downwards towards the BSS */
_eheap = _stack - _lustack; /* calculate the length of the heap */
...Never mind the _estack; .heap is "daisy-chained" onto another section called '.stackarea', a left-over from before I started modifying the script.
I know that it might be silly to do what I'm doing to force the heap to be 8 bytes. Ahem.. I'm actually abusing a LD behaviour (it's only temporary, though).
Also, I made sure I understand the relevant parts in the linker-script docs, before making any changes.
Am I doing something completely wrong anywhere ?
Love
Jens