在编译此C代码期间
extern void Default_Handler(void);
void NMI_Handler(void) __attribute__ ((weak, alias ("Default_Handler")));
我已经接受了这个
error: 'NMI_Handler' aliased to undefined symbol 'Default_Handler'
如何在外部定义的函数上创建别名?
编译器:
gcc version 7.2.1 20170904 (release) [ARM/embedded-7-branch revision 255204] (GNU Tools for Arm Embedded Processors 7-2017-q4-major)
答案 0 :(得分:0)
此处NMI_Handler具有弱定义属性意味着如果未定义NMI_Handler,则Default_Handler的定义将用于NMI_Handler。通常有强大的定义可用于NMI_Handler或Default_Handler之类的中断。你可能需要在编译中添加这些文件以删除错误。如果你想以自己的方式处理NMI_Handler,那么你可以在某处定义它,并且将包含该定义弱者之一。
答案 1 :(得分:0)
要为外部函数添加别名,可以使用objcopy
。这是一个示例:
说我有一个函数的定义,并且给它加上别名,就像下面的程序(称为myimp.c
)一样:
// myimp.c
int
myadd(int x, int y)
{
return x+y;
}
int
coolguy (int x, int y) __attribute__((alias("myadd")));
如果我们对此进行编译(但不链接),则会得到一个目标文件,并且可以检查其符号:
# compile
$ cc -c myimp.c
# look at the symbols
$ nm myimp.o
0000000000000000 T coolguy
0000000000000000 T myadd
因此,我们可以看到__attribute__((alias("myadd"))
只是添加了一个符号coolguy
,该符号的值与myadd
相同,为0000000000000000。如果您在man
页面中查找nm,它将表示T
表示它是.text
部分中的全局符号。这是有道理的,因为该函数不是static
,而是包含指令(与数据相反)。
因此,如果我们有目标文件,但没有源文件,并且想要添加函数别名,则可以使用objcopy --add-symbol
。
说我们有编译此源代码得到的目标文件:
// myimp2.c
int
myadd(int x, int y)
{
return x+y;
}
如上编译,我们将得到myimp2.o
,其符号表工具如下:
# look at the symbols
$ nm myimp2.o
0000000000000000 T myadd
因此,我们要添加coolguy
符号,如下所示
# objcopy --add-symbol coolguy=.text:0000000000000000,global myimp2.o myimp2_augmented.o
在--add-symbol
objcopy
页上的man
上查看文档。基本上.text
指定了该部分,在冒号后面指定了值,然后global
通过传递错误的类型而发现,objcopy
失败了,并告诉了我有效类型的列表,选择global
。
尝试在nm
上运行myimp2_augmented.o
,您会看到我们已经添加了符号。
现在,您应该可以与myimp2_augmented.o
链接而不是myimp.o
链接,并且程序可以调用coolguy
而不会链接错误。
答案 2 :(得分:0)
答案 3 :(得分:0)
员工弱和别名属性为原生 C 项目实现覆盖机制很流行,尤其是在固件项目的情况下。
声明和定义都可以用 Dependencies
表示,其链接优先级规则与头文件中是否存在声明有关。
仅仅编码和编译它是一个很好的策略。然后看看当链接是寻找它的定义时会发生什么。我通常通过 __attribute__((weak))
和 -Wl,-trace,-trace-symbol=ANY_FUNCTION_NAME_YOU_WANT
检查符号。
通常我只是创建一个弱属性函数定义并让其他对象覆盖它。 示例如下:
nm OBJECT_FILE_NAME
In C file:
//non-exported weak attribute definition
__attribute__((weak)) void startup_handler_dummy(void) {
printf("[%s][%s]Entry (NO OVERRIDE HANLDER COMES HERE)\n", __FILE__, __func__);
}
//weak and alias attribute declaration
void startup_handler_dummy_impl(void) __attribute__((weak, alias("startup_handler_dummy")));
//exported weak attribute definition
__attribute__((weak)) void startup_handler(void) {
startup_handler_dummy_impl();
}
In header file:
希望我的代码可以帮助:)
您可以在 MyGitHub 上查看更多详细信息和程序屏幕截图。