Can weak symbol be resolved among libraries during linking?

佐手、 提交于 2019-12-24 04:35:52

问题


My scenario is about cross-compiling to a Arduino Due (ARM target), but I guess it's a generic C weak symbol problem.

I want to break my firmware into 3 parts: 1. The hardware library (CMSIS, Middleware) -> libHardware.a 2. Realtime OS library -> libOS.a 3. Application code -> Output.elf linked to above.

the referenced CMSIS implementation has declared the followings:

void SysTick_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
// ...and a few dozen IRQ handler hook skipped for brevity

The idea of the CMSIS design is to have the Application Code implementing and handling some of IRQ selectively.

nm reports for libHardware.a

startup_sam3xa.o:
00000000 W SysTick_Handler
...

And in my scenario, I would like to implement theses IRQ handlers in the libOS.a.

I implement void SysTick_Handler(void), nm reports:

cortex_handlers.o:
00000000 T SysTick_Handler
....

Then I link them together, which basically boils down to

g++ -o app.elf -Wl,--start-group app.o libHardware.a libOS.a -Wl,--end-group

(Grouping is necessary because OS depends on the low level Hardware function. And Hardware need to calls the IRQ/main() function provdided by the OS)

nm reports:

...
00080124 W SysTick_Handler
...

It's still weak! I expect it to be using the strong symbol defined in the libOS.a. At the end, SysTick isn't handled, which of course leads to catastrophic failure.

On the other hand, if I don't declare them as weak in libHardware/startup_sam3xa.c, everything works fine. If I choose to implement SysTick_Handler in the app/app.c, it's strongly linked too.

So my question is: how could libOS.a implements the weak handler defined in libHardware.a? Or what would be the best practice in these firmware development scenarios?


回答1:


When you define the SysTick_Handler in cortex_handlers.c it defines the normal entry point. But it will overwrite the weak symbol only when the linker gets a request to link the specific object file (from libOS.a).

The libHardware.a usually defines the Interrupt vector table where the SysTick_Handler is referenced. This is the only pointer this actual name comes in the game. (For the ARM it's just an entry in the vector table.) The same library already provides a weak symbol. Therefore the linker doesn't search for that symbols anymore. When you want to overwrite the symbol in cortex_handlers.c you need to reference any symbol in that file causing the linker to use cortex_handlers.o. That will kick off the weak symbol.

// cortex_handlers.c

void SysTick_Handler()
{
}

int link_my_cortex_handlers_file;

Just reference somewhere the symbol link_my_cortex_handlers_file.




回答2:


Thanks to the above answer by harper, I was able to discover that Arduino solved this problem on the Due by moving all the weak definitions from startup_sam3xa.c to their cortex_handlers.c file so that the weak defs belonged to the "OS" instead of the hardware (using the language of the OP).




回答3:


Another solution is to keep the source for your handler (or whatever) separate, but #include it into a source file that must always be referenced when using the library (if your library has such a thing and is not all optional.) Using different words than another answer, the linker when examining a library .a works in units of object files .o : if an object file has any symbol that resolves an unresolved symbol when the linker is making a pass over the .o units in the archive (and the linker can make many passes), the linker puts all the symbols from the object file into the linked binary, resolving unresolved symbols and overriding weak definitions. Order of libraries in the link command is important and you may need a library to appear twice in the link command. The linker flag whole-archive also can solve the problem. My answer is succinct, but could be wrong.



来源:https://stackoverflow.com/questions/15984535/can-weak-symbol-be-resolved-among-libraries-during-linking

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!