如何防止链接器丢弃函数? [英] how to prevent linker from discarding a function?

查看:30
本文介绍了如何防止链接器丢弃函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 C 代码中有一个函数被隐式调用,并被链接器转储.我怎样才能防止这种现象?

I have a function in my C code that is being called implicitly, and getting dumped by the linker. how can I prevent this phenomena?

我正在使用 gcc 和链接器标志 -gc-sections 进行编译,我不想从标志中排除整个文件.我尝试使用属性:used"和externally_visible",但都没有奏效.

I'm compiling using gcc and the linker flag -gc-sections, and I don't want to exclude the whole file from the flag. I tried using attributes: "used" and "externally_visible" and neither has worked.

void __attribute__((section(".mySec"), nomicromips, used)) func(){
...
}

在地图文件上,我可以看到该函数已编译但未链接.我用错了吗?还有其他方法吗?

on map file I can see that the function has compiled but didn't linked. am I using it wrong? is there any other way to do it?

推荐答案

你误解了used 属性

You are misunderstanding the used attribute

二手

附加到函数的这个属性意味着必须为函数发出代码,即使看起来函数没有被引用...

This attribute, attached to a function, means that code must be emitted for the function even if it appears that the function is not referenced...

编译器必须发出函数定义,即使函数出现不被引用.编译器永远不会断定一个函数是未引用的如果它有外部链接.所以在这个程序中:

i.e the compiler must emit the function definition even the function appears to be unreferenced. The compiler will never conclude that a function is unreferenced if it has external linkage. So in this program:

ma​​in1.c

static void foo(void){}

int main(void)
{
    return 0;
}

编译:

$ gcc -c -O1 main1.c

根本没有发出 foo 的定义:

No definition of foo is emitted at all:

$ nm main1.o
0000000000000000 T main

因为 foo 在翻译单元中没有被引用,不是外部的,所以可能会被优化出来.

because foo is not referenced in the translation unit, is not external, and so may be optimised out.

但是在这个程序中:

ma​​in2.c

static void __attribute__((used)) foo(void){}

int main(void)
{
    return 0;
}

__attribute__((used)) 强制编译器发出本地定义:

__attribute__((used)) compels the compiler to emit the local definition:

$ gcc -c -O1 main2.c
$ nm main2.o
0000000000000000 t foo
0000000000000001 T main

但这并不能阻止 链接器 丢弃一个部分其中定义了 foo,在存在 -gc-sections 的情况下,即使 foo 是外部的,如果该部分未使用:

But this does nothing to inhibit the linker from discarding a section in which foo is defined, in the presence of -gc-sections, even if foo is external, if that section is unused:

ma​​in3.c

void foo(void){}

int main(void)
{
    return 0;
}

使用功能部分编译:

$ gcc -c -ffunction-sections -O1 main3.c

foo的全局定义在目标文件中:

The global definition of foo is in the object file:

$ nm main3.o
0000000000000000 T foo
0000000000000000 T main

但链接后:

$ gcc -Wl,-gc-sections,-Map=mapfile main3.o

foo 没有在程序中定义:

$ nm a.out | grep foo; echo Done
Done

并且定义 foo 的函数部分被丢弃:

And the function-section defining foo was discarded:

地图文件

...
...
Discarded input sections
 ...
 ...
 .text.foo      0x0000000000000000        0x1 main3.o
 ...
 ...

根据 Eric Postpischil 的评论,强制 链接器 保留一个明显未使用的功能部分,您必须告诉它假设该程序使用链接器选项引用未使用的函数 {-u|--undefined} foo:

As per Eric Postpischil's comment, to force the linker to retain an apparently unused function-section you must tell it to assume that the program references the unused function, with linker option {-u|--undefined} foo:

ma​​in4.c

void __attribute__((section(".mySec"))) foo(void){}

int main(void)
{
    return 0;
}

如果你不告诉它:

$ gcc -c main4.c
$ gcc -Wl,-gc-sections main4.o
$ nm a.out | grep foo; echo Done
Done

foo 未在程序中定义.如果你告诉它:

foo is not defined in the program. If you do tell it that:

$ gcc -c main4.c
$ gcc -Wl,-gc-sections,--undefined=foo main4.o
$ nm a.out | grep foo; echo Done
0000000000001191 T foo
Done

它被定义了.used 属性没有用处.

it is defined. There's no use for attribute used.

这篇关于如何防止链接器丢弃函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆