Hi everybody, Until now my interrupt vector was in my main project (the one generating the binary). It's stored in the section .vector, and I use the KEEP(.vector) in my linker script to be sure that it doesn't get discarded. I recently decided to put the interrupt vector it in a static library. Unfortunately it is now discarded by LD. LD is still keeping the .vector section, but it is empty and I don't understand why. I found an ugly workaround: referencing the interrupt vector in a source file in my main project (the one generating the binary), but I'm sure there is a better solution. Thanks in advance for your help.
By default, the linker only includes symbols from libraries if they are referenced from earlier code in the link process. To circumvent that for your vector, you could either add a "-u <symbol>" to your linker command line or add a "EXTERN(<symbol>)" to your linker script.
Thank you very much Markus, The EXTERN(...) command was exactly what I needed. Now I have a second problem: When I said "I recently decided to put the interrupt vector it in a static library." it's not exactly true: I'm trying to link a binary from another binary. basically I need 2 versions of my binary with different offsets to take into consideration a bootloader or not. So I'm building: - A first binary "bin1.elf" with offset zero (loaded without bootloader) it vector: 0x0000, start: 0x0080 - A second binary "bin2.elf" with offset 0x1000 (loaded with bootloader). it vector: 0x1000, start: 0x1080 My approach was to link the second binary with the first one as an input. LD doesn't seem to complain, but there is a problem with the interrupt vector: It has been properly relocated to the adress 0x1000, but it's content is not updated and the addresses are wrong. (first entry which is the start address remains 0x0080 instead of 0x1080). The mapping of bin2.elf is correct, it vector is located at 0x1000, start is located at 0x1080. It's like if the content of the interrupt vector has been directly copied from bin1.elf instead of being resolved by the linker as I expected. Is my solution possible ? if yes, how to resolve the content of my interrupt vector for bin2.elf Or is there a better solution ? Thank you all. EDIT: If I link bin1.elf as a static library instead of native executable (libbin1.a), I have no problem.
: Edited by User
What you want to do sounds like a bootloader? Like first part to initialize hardware from ROM, second one copied to RAM then and executed there? Then you should probably read up the linker scripts "AT" directive.
: Edited by User
No, I'm generating a software that can be loaded either without any bootloader (for instance in an emulator) or with a bootloader (for instance in the actual device). I don't want to detail it too much, but basically my binary interrupt vector is not located at the same place. LMA & VMA are the same: in ROM. I took the addresses as an exemple, but the code executed in ROM, not in RAM, sorry for the missunderstanding. I don't think the "AT" directive would help me.
For now I slightly changed my process: my first project will generate libbin1.a & bin1.elf, which solve my problem. I thougth it would be practical to link a .elf as a static lib, but I'm not sure it's the correct solution. Thanks for the help, if you have any better idea please share it.
Still not entirely sure if I completely understood what you want to do, but did you consider the -r (relocatable output) to ld for the "first" link? It should allow you to use the first object file as input to the second link stage and -r should ensure that the binary is properly relocated.
This looks good, but once I activate this option, I got the error: "gc-sections requires either an entry or an undefined symbol" I guess, --gc-sections & -r are not compatible, which sounds logical since -r will probably try to keep all the sections in the elf file. But my project won't compile as well with --no-gc-sections Edit: Yes, they are not compatible, it's written in the manual.
: Edited by User