为什么 otool 会截断我的反汇编输出?

Why is otool truncating my disassembly output?

当我运行这个命令

otool -t binary

otool 将正确转储 binary 的文本部分。例如

0000000100002100   55 48 89 e5 41 56 53 48 8b 35 32 24 54 00 4c 8b 
:

但是当我运行这个命令时:

otool -tvV binary

otool 跳过正文部分的很大一部分:

00000001003a32ce pushq %rbp
:

前 3805646 个字节被简单地跳过,没有反汇编。如果我在 lldb 中打开二进制文件,我可以在跳过的地址反汇编代码。

有没有人有过类似的经历? otool 是否有内部大小限制并且 t运行 包含超出该限制的部分?是否有人发现了变通方法或知道可免费获得的类似工具?

我试图用 lldb:

反汇编整个二进制文件
lldb binary
(lldb) dis -s 0x100002100 -e ...

-e 设置为文本部分中最后一个字节的地址,但这也不起作用。实际上 lldb 在反汇编大约 5000 字节的文本部分后停止输出。

我以前见过这个,我相信 otool 是(烦人地)跳到第一个符号。如果你做nm -n binary,第一个定义的符号是在00000001003a32ce吗?

Xcode 附带另一个工具,称为 otool-classic,似乎可以分解整个文本段。据推测,它是 otool 重写或类似内容之前的旧版本。虽然它获取了整个文本段,但它可能在其他方面的功能较少(例如解码对选择器或字符串的引用)。要调用它,您可以使用 xcrun otool-classic <args>.

在我的测试中,您还可以使用 Xcode 早期版本附带的 otool 版本。来自 Xcode 7.3.1 和 Xcode 6.4 的没有这个问题。 (这些是我碰巧可以方便测试的。其他人可能也可以。)

根据 Ken Thomases 的回复和评论,我用旧 Xcode 版本的 otool 做了一些测试,发现 otool 在 Xcode 7.3.1效果更好,但也不会反汇编整个文本部分。我向 Apple 提交了错误报告,结果如下:

Engineering has determined that this issue behaves as intended based on the following information:

The implementation of otool(1) changed in Xcode 8 to be based on llvm-objdump(1) from the old otool-classic(1), which is still on the system.

For the llvm community, the current behavior of starting disassembly from the first known symbol is the behavior the llvm community desires.

确实,otool-classic 可以正常工作(xcrun otool-classic 可以正常工作),就像 Ken 在他的评论中已经指出的那样,但我对该答复不满意,所以我现在将提交LLVM 项目中的错误。