[英]How I can make alias on external defined function in C?
在编译此 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)
要别名外部函数,您可以使用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
的纳米页面,它会说, 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
指定了部分,在冒号之后是值,然后是global
我通过传递错误类型和objcopy
失败并告诉我有效类型的列表,我从中选择了global
。
尝试在myimp2_augmented.o
上运行nm
,您会看到我们添加了符号。
现在您应该能够链接myimp2_augmented.o
而不是myimp.o
并且您的程序可以调用coolguy
而不会出现链接错误。
这里 NMI_Handler 有一个弱定义属性意味着如果 NMI_Handler 没有定义,那么 Default_Handler 的定义将用于 NMI_Handler。 通常有强大的定义可用于 NMI_Handler 或 Default_Handler 等中断。您可能需要在编译中添加这些文件以删除错误。如果您想以自己的方式处理 NMI_Handler,那么您可以在某处定义它,并且该定义将被包含在内弱者之一。
对于本地 C 项目,尤其是在固件项目的情况下,员工弱和别名属性实现覆盖机制很受欢迎。
声明和定义都可以用__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:
#ifndef _BOARD_H_
#define _BOARD_H_
#define STARTUP_HANDLER startup_handler //to export symbol
#endif
希望我的代码可以帮助:)
您可以在MyGitHub上查看更多详细信息和程序屏幕截图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.