链接器会将哪些类型的符号放入可执行的 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 -laliba.a 据我所知对链接器的含义完全相同。

以上是关于链接器会将哪些类型的符号放入可执行的 ELF 中?的主要内容,如果未能解决你的问题,请参考以下文章

《程序员自我修养》阅读笔记-静态链接

ELF文件格式分析

ELF格式解读- elf头部与节头

C温故补缺(十七):动态链接(ELF,PIC,GOT,PLT)

ELF格式解读- elf头部与节头

我可以从 ELF 文件的符号表中的符号信息中获取对象名称吗?