列出gcc或clang对象文件中的内部引用



给定一个公开符号的对象文件,如何确定该符号是否也在内部使用?

我的目标是检测死功能。我已经能够(通过readelf)从另一个对象文件中查找它是否被使用,但当它仅在内部使用时,这将失败。

如果重要的话,我正在使用C++

它实际上取决于编译器如何处理编译内单元调用,但有一些建议。

首先,如果您正在优化,编译器可能会内联您的函数,即使它们没有标记为inline。实际上,如果函数标记有always_inline属性,它将努力做到这一点。因此,即使函数f实际调用了函数g,也没有证据表明它调用了函数。请注意,如果g的目标代码(以及其他调用函数)中。

因此,避免优化并以某种方式抑制always_inline。您甚至可以显式指定-fno-inline来防止内联。

其次,您的目标体系结构可能具有相对的调用和分支指令。如果将fg放在它们共同的代码段中,编译器可能会利用这一点。它是非内联函数的默认值。在这种情况下,编译器在编译时知道调用位置和被调用方开头之间的偏移量,并可以生成相对调用或跳转指令;不需要进一步的重新定位。有些编译器可能会发出"无操作"重定位,但有些编译器不会。没有重新定位意味着符号没有被引用。

因此,使用-ffunction-sections(对于数据使用-fdata-sections)。然后,每个函数都被放在自己的部分中,编译器将别无选择,只能为链接器生成一个重新定位以进行修复(从而引用被调用方的符号)。

请注意,如果在调用ld时使用-ffunction-sections,然后指定--gc-sections,编译器将丢弃所有未引用的节。如果添加-M,您将获得最终的模块映射。丢弃的函数不会显示在映射中。

顺便说一句,请记住,在某些情况下,静态分析无法检测到函数永远无法调用。例如,在一个编写良好的C++程序中,__cxa_pure_virtual永远不会被调用,但在所有抽象类的虚拟函数表中都会有对它的引用。此外,普通虚拟函数的重写将通过虚拟函数表引用并链接,即使在整个程序中没有对该虚拟函数的单个调用。符号分析无法检测到这些情况。

相关内容

  • 没有找到相关文章

最新更新