如何在C中为外部定义的函数创建别名?

时间:2018-02-07 09:29:16

标签: c gcc alias weak

在编译此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)

4 个答案:

答案 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)

按照建议的here,将以下内容添加到链接器命令文件中:

PROVIDE(NMI_Handler = Default_Handler);

(并从C代码中删除弱别名声明。)

答案 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 上查看更多详细信息和程序屏幕截图。