Reputation: 1653
I'm using a modular build system for software than runs on an ARM embedded target as well as on a normal X86 (linux) machine. I'm compiling with a GNU toolchain, thus linking using ld
.
One of the modules makes use of a linkerscript trick to assemble an array of 'registered' objects. The objects are created with a macro like this:
#define RegObject(name, arg1, arg2, etc) \
static TRegObject name \
__attribute__((section ("regobj_table"), used)) = \
{ arg1, arg2, etc }
The module also adds an implicit linker script to the link step, which looks like this:
SECTIONS
{
.data : ALIGN(4)
{
regobj_table_start = .;
KEEP(*(regobj_table))
regobj_table_end = .;
}
}
The regobj_table_start
and regobj_table_end
symbols are used by the code to find the registered objects. This solution works just fine for native (Linux) compiled targets.
This doesn't work for the ARM target however. The reason is that I have a custom default linker script for the target (it's a tiny microcontroller, running without an OS), which defines a load memory address for the .data
section. This is because the section is stored in Flash memory, but once the microcontroller boots it's copied to RAM. The relevant part of the linker script looks like this:
MEMORY
{
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 512k
RAM (rwx) : ORIGIN = 0x40000000, LENGTH = 32k
}
SECTIONS
{
/* ... other stuff ... */
.data :
{
_data = .;
*(.data)
*(.data.*)
} >RAM AT>ROM
/* ... even more stuff ... */
}
This sets the VMA of the .data
section to somewhere in the 0x4000000 range, and the LMA in the 0x00000000 range.
The problem is that when the implicit linker script is added to the command-line of ld
, it just forgets about the LMA and it becomes equal to the VMA again. I'm desperately looking for a method to tell ld
to not touch the LMA when loading the implicit linker script.
Upvotes: 3
Views: 1649
Reputation: 1
Try using INSERT AFTER ... as the last line. This will insert your script into the default one.
Upvotes: 0