Here is some ARM assembly code compiled with GCC.
Snippet from startup.s:
.globl Default_Handler
.type Default_Handler, %function
Default_Handler:
B .
.size Default_Handler, . - Default_Handler
.macro IRQ handler
.weak \handler
.set \handler, Default_Handler
.endm
IRQ POWER_CLOCK_IRQHandler
In file1.c
void POWER_CLOCK_IRQHandler(void)
{
//Do some things...
}
In this code, POWER_CLOCK_IRQHandler is a weak symbol. When the code runs, code from file1 is executed.
Now I define Default_Handler in another file and I comment out its definition in startup.s.
.globl Default_Handler
.type Default_Handler, %function
//Default_Handler:
// B .
.size Default_Handler, . - Default_Handler
.macro IRQ handler
.weak \handler
.set \handler, Default_Handler
.endm
IRQ POWER_CLOCK_IRQHandler
In file 3:
void Default_Handler(void)
{
//Do some other things
}
If I write the definition of Default_Handler in another file or I declare Default_Handler as weak, POWER_CLOCK_IRQHandler will be linked against Default_Handler. The linker misses the weak attribute and does not link it against POWER_CLOCK_IRQHandler in file1.c, it just tried to resolve the expression given in .set.
Can someone explain what occurs precisely?
What is the proper solution to keep weak attribute effective on POWER_CLOCK_IRQHandler when the Default_Handler implementation is in another file than startup.s?