I am trying to link Cortex-M4 firmware with clang + lld. The gcc build works fine. I am using the stock CMSIS linker script with only RAM & ROM size adjusted (bases are the same). Beginning of the script (without comments):
__ROM_BASE = 0x00000000;
__ROM_SIZE = 0x00040000; /* 256 KB */
__RAM_BASE = 0x20000000;
__RAM_SIZE = 0x00010000; /* 64 KB */
__STACK_SIZE = 0x00000400;
__HEAP_SIZE = 0x00000C00;
MEMORY
{
FLASH (rx) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
RAM (rwx) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
}
Linking fails on the assert ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
at the very end of the script. If I remove the assert the binary links fine, but stack is at a wrong address. It ends up in flash (heap is also in the wrong place). Output from nm
:
200018a8 B __bss_end__
200000d8 B __bss_start__
00004568 R __copy_table_end__
0000455c R __copy_table_start__
200000d4 D __data_end__
20000000 D __data_start__
00000000 ? __end__
00004570 A __etext
0000455c R __exidx_end
0000454c T __exidx_start
00000c00 A __HEAP_SIZE
00000c00 ? __HeapLimit
200000d4 d __init_array_end
200000d0 d __init_array_start
w __libc_fini_array
00000445 T __libc_init_array
200000d0 d __preinit_array_end
200000d0 d __preinit_array_start
20000000 A __RAM_BASE
00010000 A __RAM_SIZE
00000000 A __ROM_BASE
00040000 A __ROM_SIZE
00000400 ? __stack
00000400 A __STACK_SIZE
00000000 ? __StackLimit
00000400 ? __StackTop
The code of course crashes when trying to run on the Cortex-M. I found this ticket. If I change my .stack
section to:
.stack (COPY) :
{
. = ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE;
__StackLimit = .;
. = . + __STACK_SIZE;
. = ALIGN(8);
__StackTop = .;
} > RAM
PROVIDE(__stack = __StackTop);
then I am getting overflow errors:
ld.lld: error: section '.stack' will not fit in region 'RAM': overflowed by 536879272 bytes
That huge number is 0x200020A8 so the lld
probably gets the end address correctly, but not the origin.
How can I fix the linker script to place the stack correctly at top of RAM? Thanks for help
I fixed it by removing COPY
and adding NOLOAD
to the stack section. It builds and runs fine both with gcc and clang.
.stack (ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE) (NOLOAD) :
{
. = ALIGN(8);
__StackLimit = .;
. = . + __STACK_SIZE;
. = ALIGN(8);
__StackTop = .;
} > RAM
PROVIDE(__stack = __StackTop);