如何防止链接器丢弃函数? [英] how to prevent linker from discarding a function?
问题描述
我的 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:
main1.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.
但是在这个程序中:
main2.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:
main3.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
:
main4.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屋!