gcc链接器获取未使用对象的列表

gcc linker get list of unused objects

本文关键字:对象 列表 未使用 获取 链接 gcc      更新时间:2023-10-16

我想在具有许多库的大型C应用程序中识别未使用的对象文件。随着时间的推移,这个项目已经发展了很多,现在我想搜索不再使用的库,这样我就可以从依赖文件中删除它们。使用gcc链接器是否可以识别任何未使用的对象?

例如,如果我用gcc编译一个应用程序,假设没有使用library2的任何符号/函数。有什么方法可以获得哪些对象没有链接的信息吗?

gcc library1.o library2.o main.o -o main.elf

我知道gcc有编译器和链接器标志来删除未使用的符号:

-fdata-sections -ffunction-sections -Wl,--gc-sections

然而,通过这种方式,我不知道gcc删除了哪些对象。如果gcc可以选择获取未链接到应用程序的对象列表,那将是完美的选择。

仅需提及:我需要基于对象文件而不是基于函数/符号的它!

有人知道gcc有这样的选择吗?

例如,如果我用gcc编译一个应用程序,假设没有使用library2的任何符号/函数。有什么方法可以获得哪些对象没有链接的信息吗?

gcc library1.o library2.o main.o -o main.elf

使用上面的命令,即使library2.o中的任何代码都没有使用,它也将链接进来。要了解原因,请阅读此或此。

的确,如果使用-ffunction-sections -fdata-sections编译library2.o中的代码,并使用-Wl,-gc-sections链接,那么library2.o中的所有代码和数据都将被GC输出,但这不是您给出的命令。

据推测,如果您将库用作库,您会对发生的事情更感兴趣:

gcc main.o -o main.elf -lrary1 -lrary2

在这种情况下,如果没有引用library2中的任何代码,链接器将不会将其拉入链接。

没有办法向链接器索取没有使用的对象列表,但(如果您使用的是GNU ld(有一种方法可以向链接器索要使用过的对象列表:-M-Map选项。一旦您知道使用了哪些对象,只需从链接时使用的所有对象中减去已使用的对象即可获得未使用的列表。

更新:

Gold链接器支持--print-symbol-counts FILENAME选项,这在这里也很有用。它打印定义的和使用的符号计数。对于library2.a,它应该打印$num_defined 00表示library2.a中没有任何对象被实际使用。

看看callcatcher

这会将程序编译为程序集,并从程序集输出中提取明显的引用。我想这正是你在寻找的。(注意,由于它分析汇编程序输出,它只能在x86平台上工作(

注意callcatcher忽略了虚拟函数(出于一些好的原因(,因此它将不允许您直接分析这些函数。