如何验证死代码是否已从二进制文件中删除?

noa*_*mtm 5 unix linux macos xcode

我的 c/obj-c 代码(使用 clang 构建的 iOS 应用程序)有一些被#ifdefs. 我想确保从这些函数调用的代码,而不是从其他函数(死代码)调用的代码在链接时被删除(消除)。我试过:

  1. 在应该消除的函数中添加本地文字 char[];strings在可执行文件上运行时该字符串仍然可见。
  2. 添加一个应该被消除的功能;运行字符串时函数名称仍然可见。

在你问之前,我正在构建发布,并且所有剥离设置(显然包括死代码剥离)都已启用。

这个问题并不是 xcode/apple/iOS 特有的;我认为在任何 POSIX 开发平台上答案都应该几乎相同。

pet*_*rph 2

(编辑)

在 binutils 中,ld有一个--gc-sections选项可以对对象级别的部分执行您想要的操作。您有多种选择:

  • 使用gcc的标志-ffunction-sections并将-fdata-sections每个符号隔离到其自己的部分中,然后使用--gc-sections;

  • 所有要删除的候选放入一个单独的文件中,链接器将能够删除整个部分;

  • 反汇编生成的二进制文件,删除无效代码,然后再次汇编;

  • strip与适当的选项一起使用-N,从符号表中丢弃有问题的符号 - 这会将代码和数据保留在那里,但不会显示在符号表中。

  • 我不熟悉这个选项,但我刚刚读到它,我认为它不会达到OP想要的效果。它似乎只是为了删除整个未使用的部分(如“.text”、“.bss”等),但在这种情况下,我们希望消除某些函数(主要在“.text”中),同时保留其他函数(其中也主要在`.text`中)。 (2认同)