gpt4 book ai didi

c - 静态库中定义的 IRQ 符号不会覆盖 ARM/GCC 启动时的弱 IRQ 定义

转载 作者:太空宇宙 更新时间:2023-11-03 23:42:09 26 4
gpt4 key购买 nike

我已经构建了一个静态库(*.a 用于 gcc,*.lib 用于 keil)。它的源文件之一,编译成库,包含 RADIO_IRQHandler 的定义。下面是这个名为“ral_irq_handlers.c”的源文件的摘录:

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

这个 IRQ 符号定义应该覆盖启动文件中声明的弱定义。启动文件没有编译成任何静态库,只是项目内部的一个普通文件。

arm_startup_xxx.s 文件(keil 工具链)的摘录如下:

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

类似的 gcc_startup_xxx.s 文件(gcc 工具链)的摘录如下:

.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

然后我观察到一个奇怪的行为。当我在其中一个项目源文件中使用“ral_irq_handlers.c”源文件(编译到库中)中的任何 API 函数时,链接已正确完成。示例:

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

但是,如果我不使用“ral_irq_handlers.c”源文件的任何 API 函数,链接器无法找到我的库中定义的 RADIO_IRQHandler 符号。如果没有这个丑陋的 hack(调用虚拟函数来强制正确链接),我能以某种方式做到这一点吗?

我只想修改库代码而不修改启动文件。

最佳答案

据我所知,您无法轻松做到这一点,因为链接器只会在找不到处理程序的符号时搜索您的库。因为它可以找到它(启动时的定义较弱)所以它不会再看下去。

但是你可以通过像这样链接你的库来解决它:

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

此外,您实际上不必调用虚拟函数来导致模块链接。您所需要的只是告诉链接器您需要它,例如:

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

关于c - 静态库中定义的 IRQ 符号不会覆盖 ARM/GCC 启动时的弱 IRQ 定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42269765/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com