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

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

例如,如果我使用gcc编译应用程序,并且假设没有使用library2的符号/函数。 有没有办法获取有关哪些对象未链接的信息?

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

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

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

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

仅举几个:我需要基于目标文件而不是基于function/符号!

有没有人知道gcc的这种选择?

例如,如果我使用gcc编译应用程序,并且假设没有使用library2的符号/函数。 有没有办法获取有关哪些对象未链接的信息?

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

使用上面的命令,即使没有使用过任何代码, library2.o 也会被链接。 要了解原因,请阅读本文或此内容 。

确实如果你使用-ffunction-sections -fdata-sectionslibrary2.o编译代码并使用library2.o-ffunction-sections -fdata-sections链接,那么来自library2.o所有代码和数据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 0表示实际上没有使用library2.a中的任何对象。

看看callcatcher

这会将您的程序编译为汇编并从汇编输出中提取明显的引用。 我猜这正是你要找的东西。 (注意,由于它分析汇编程序输出它只能在x86平台上运行)

注意callcatcher忽略虚函数(出于某些原因),因此它不会直接允许您分析它们。