在编译此C代码
时extern void Default_Handler(void);
void NMI_Handler(void) __attribute__ ((weak, alias ("Default_Handler")));
我已经receve
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)
为别名一个外部功能,您可以使用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
,即0000000000000000,与myadd
相同。如果您在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
查看objcopy
man
页面中--add-symbol
上的文档。基本上.text
指定了该部分,在结肠后值之后,然后通过传递不良类型和objcopy
发现global
失败,并告诉我有效类型的列表,我从中选择了global
。
尝试在myimp2_augmented.o
上运行nm
,您会看到我们添加了符号。
现在,您应该能够与myimp2_augmented.o
而不是myimp.o
链接,并且您的程序可以致电coolguy
而无需链接错误。
如下所示,将以下内容添加到您的链接命令文件:
PROVIDE(NMI_Handler = Default_Handler);
(并从C代码中删除弱的别名声明。(
这里的nmi_handler具有弱定义属性,意味着,如果未定义nmi_handler,则将用于nmi_handler的default_handler的定义。通常,有很强的定义可用于中断,例如nmi_handler或default_handler。一个弱的。
员工弱和别名属性很受欢迎,可以为本机C项目实施覆盖机制,尤其是在固件项目的情况下。
声明和定义都可以通过__attribute__((weak))
注意,其链接优先规则与Head File中存在任何声明有关。
仅编码和编译它是一个很好的策略。然后查看链接时会发生什么是寻找其定义。我通常通过-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:
#ifndef _BOARD_H_
#define _BOARD_H_
#define STARTUP_HANDLER startup_handler //to export symbol
#endif
希望我的代码能有所帮助:(
您可以在mygithub上查看更多详细信息和程序屏幕截图。