aldarel
aldarel

Reputation: 456

IRQ symbol defined in static library does not override weak IRQ definition from ARM/GCC startup

I have built a static library (*.a for gcc, *.lib for keil). One of its source file, compiled into library, contains definition of RADIO_IRQHandler. An excerpt from this source file, called "ral_irq_handlers.c", is below:

...
void ral_symbol_import(void) //dummy function
{
    return;
}
...
void RADIO_IRQHandler(void)
{
    ...
}
...

This IRQ symbol definition should override the weak definition which is declared in startup file. The startup file is not compiled into any static library and is just a regular file inside the project.

An excerpt of arm_startup_xxx.s file (keil toolchain) is below:

Default_Handler PROC
                ...
                EXPORT   RADIO_IRQHandler [WEAK]
                ...
...
RADIO_IRQHandler
...
                B .
                ENDP
                ALIGN

An excerpt of similar gcc_startup_xxx.s file (gcc toolchain) is below:

.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  RADIO_IRQHandler
    ...
    .end

Then I observed a strange behaviour. When I use any API function from "ral_irq_handlers.c" source file (compiled into library) inside one of the project source files, the linking is done correctly. Example:

...
int main(void)
{
    ral_symbol_import();
    ...
}
...

However, if I don't use any API function of "ral_irq_handlers.c" source file, the linker cannot find the RADIO_IRQHandler symbol defined in my library. Can I somehow do this without this ugly hack (calling the dummy function to force correct linking)?

I would like to modify only the library code without touching the startup files.

Upvotes: 3

Views: 802

Answers (1)

Freddie Chopin
Freddie Chopin

Reputation: 8860

As far as I know you cannot do that easily, as linker will only search your library if it cannot find the symbol for the handler. As it can find it (weak definition in the startup) it doesn't look any further.

However you may solve it by linking your library like that:

... -Wl,--whole-archive -l:path/to/our/library.a -Wl,--no-whole-archive ...

Also you don't actually have to call the dummy function to cause the linking of module. All you need is telling the linker you need it, for example like that:

void ral_symbol_import(void);
void (* const variable)() = &ral_symbol_import;

Upvotes: 1

Related Questions