我如何在C中对外部定义函数制作别名



在编译此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_WANTnm 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上查看更多详细信息和程序屏幕截图。

相关内容

  • 没有找到相关文章

最新更新