链接器会将哪些类型的符号放入可执行的 ELF 中?
Posted
技术标签:
【中文标题】链接器会将哪些类型的符号放入可执行的 ELF 中?【英文标题】:What kinds of symbols will the linker put into an executable ELF? 【发布时间】:2012-12-27 21:49:55 【问题描述】:考虑以下命令:
g++ -Wl,--start-group main.o liba.a -Wl,--end-group -o a.out
是否有可能在 a.out 中有一些在 liba.a 中定义但 main.o 没有使用的符号?如果是,在什么情况下?在编写源代码或调用编译器或链接器时是否有一些技巧来实现这一点?据我所知,这不应该发生,但我最近确实遇到了这样的情况。
【问题讨论】:
这是学校作业还是面试问题? 你说你遇到了一个案子。什么情况? 我自己编译了chromium,在最终的可执行ELF文件中发现了很多未使用的符号。 【参考方案1】:我能想到至少三种可能发生这种情况的情况:
-Wl,--whole-archive
可用于强制将liba.a
包含在其整个中,而不仅仅是所需的目标文件。
liba.a
可能包含 C 运行时使用的符号,绕过 main.o
的内容。此类符号的最常见原因是具有构造函数的 C++ 全局或文件范围对象。
默认情况下,链接器会在单个目标文件的规模上修剪未使用的代码;如果一个目标文件定义了一堆符号,只有其中一些被使用,那么无论如何它们都将出现。您可以通过使用-ffunction-sections -fdata-sections
编译进入 liba.a
的所有内容,然后在链接时提供-Wl,--gc-sections
来解决此问题。对于最近的 GCC(我不会在 4.7 之前的版本上尝试此操作),使用 -flto
编译 everything 然后使用 -fwhole-program
链接也可能会有所帮助。
【讨论】:
如果我们忽略 flto,我不同意。如果您直接与liba.a
链接,那么无论您是否需要,整个库都会被拉入。 -la
不会把它全部拉进去。
@mats 我现在无法检查,但我 99% 确定你错了:-la
…-la
和 liba.a
据我所知对链接器的含义完全相同。以上是关于链接器会将哪些类型的符号放入可执行的 ELF 中?的主要内容,如果未能解决你的问题,请参考以下文章