如何制作一个不能被dead_stripped的目标文件?

时间:2012-10-19 17:37:50

标签: ios linker mach-o dead-code

生成一个的Mach-O目标文件的最简单方法是设置SUBSECTIONS_VIA_SYMBOLS标志,这样链接器(-dead_strip)就不会后来尝试将文本部分切成碎片并猜测使用了哪些碎片?

我可以使用llvm / gcc(4.2.1)的命令行选项来防止它首先发出.subsections_via_symbols,或者使用命令行工具来删除标记现有的目标文件。

(根据Mach-O规范自己编写这样的工具是一种选择,但如果可能的话,我宁愿不再重新发明轮子。)

平台: iOS,使用XCode 4.5从OSX进行交叉编译。


背景:我们正在提供其他公司构建到应用中的静态库。当我们的库遇到问题时,会产生一个崩溃报告,其中包含堆栈跟踪和某些其他关键信息(如果我们很幸运),我们稍后会进行分析。通常,部署的应用程序已被剥离调试信息,因此解释堆栈跟踪是一个问题。如果我们自己制作应用程序,我们只需在剥离之前保存DWARF调试数据,并使用它来解码传入崩溃报告中的地址。但我们不能依赖应用程序制造商从他们的链接步骤向我们提供这些数据。

我们正在做的是让崩溃报告包含所选功能的运行时地址;从中我们可以推断我们的链接器映射中的地址与崩溃报告中的地址之间的偏移量。在将它们填入.a之前,我们将整个库逐步链接到单个.o中;因为它只做了一件很重要的事情,当应用程序最终被链接时,从它中删除未使用的功能将节省很多。遗憾的是,库中有一些 small 代码,有时不使用(主要功能的替代API入口点,用于解释错误代码的小助手函数等),以及应用程序开发人员与-dead_strip链接,它扰乱了崩溃报告的地址重建,最终应用程序中的相对偏移量与我们的增量链接操作中的链接器映射不同。

我们无法真实地要求所有应用程序开发人员在其构建过程中禁用死代码剥离,因此如果我们将.o标记为“不死可剥”并且最终应用程序链接,那么这似乎是更好的方法尊重。

1 个答案:

答案 0 :(得分:1)

我解决了。

如果 all 输入对象已设置,则增量链接操作的输出仅设置MH_SUBSECTIONS_VIA_SYMBOLS。如果有一个显式指令集,那么从汇编程序输入生成的目标文件只会设置它。因此,可以通过链接 empty 汇编程序输入来删除该标志:

echo > empty.s
$(CC) $(CFLAGS) input.o empty.s -nostdlib -Wl,r -o output.o