I’m writing a linker script for LD to collect all .init_array sections
in order to call the constructor of all global objects declared in my firmware.
Everything works fine unless I have a global object, not referenced, in a static
library. In this case, despite the fact that I use the KEEP macro as follow, the object not explicitly referenced, it get discarded in the final binary. (no matter if I use -gc-sections or not).
If the very same not referenced object is placed outside the static library, thus being
caught by the generic line of the linker script, it does get included.
.init_array :
{
_init_array_start = .;
KEEP (*core*:*(SORT(.init_array*)))
KEEP (*core*:*(.init_array))
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (_init_array_end = .);
} > flash
The library is called libcore.a. Other objects explicitly referenced in the libcore.a do get included.
Any help on how to fix this would be really appreciated.
Thanks in advance
Static libraries are actually an
ararchive containing multiple.ofiles and an index. The index is used to determine which.ofiles to link based on what symbols were referenced by the main program. As such, if no symbols from a.ofile are referenced, the linker won’t even load the.ofile in question, so the linker script never gets its hands on it.Assuming you’re using GNU LD, you could use
ld‘s-rflag to combine multiple.ofiles into a singlelibcore.ofile, and use that as the only.ofile in the archive. The downside of this is that you’ll potentially be pulling in unnecessary code that would otherwise be elided by skipping.ofiles. Alternately, you could also add dummy references from all other.ofiles in the archive to the.ofile with your static constructor.