Man Page(man otool)
在terminal中输入man otool
会指向llvm-otool。下面会说明llvm-tool和otool的关系。
名字:
otool - 打印目标文件相关信息的工具。llvm-otool是otool到objdump的一个临时转换工具。
概要:
otool [相关选项] [相应文件]
描述:
otool
otool命令可以用于指定需要展示目标文件或者库的某部分。如果不使用-m
选项,那么对应的文件参数可以是libx.a(foo.o),仅仅展示库文件(libx.a)中的某一个目标文件(foo.o)。otool能够正确地辨认Mach-O文件和通用文件格式。otool可以使用原始数字形式(不使用-v
)展示指定的信息,或者使用常量宏的对应的符号形式(使用-v
或-V
),具体的操作可以看下文,有很多选项和-v,-V结合使用。
llvm-otool
llvm-otool拥有otool所有的选项,并执行等效的objdump命令。它存在的目的是减轻即将废弃otool工具在使用上带来的痛苦,基于开源objdump提供对应相似的功能。意思就是说llvm-otool是基于objdump实现otool所有的功能。它作为一个临时命令会在otool被移除之后移除掉。
- -show-objdump-command:展示llvm-tool将会执行的命令;
otool参数选项
至少以下参数中至少有一个需要指定:
-a: 展示archive头部,如果该文件是archvie文件;
-S: 展示__.SYMDEF文件的内容,如果该文件是archive文件;
-f: 展示通用头部;
-h: 展示Mach-O头部;
-l: 展示load commands(这在文件中存在对应的内容);
-L: 展示目标文件使用到的共享库信息,这些信息包含了名称和版本号。如果是共享库的话还可以展示共享库的ID;
-D: 仅仅展示共享库的名称,更多的信息见install_name_tool(1)。
-s segname sectname:展示指定section(segname,sectname)的内容。如果指定了-v,则展示该section的类型,除非类型为0(section的头部标记)。当指定了-v, __OBJC,__protocol __OBJC,__string_object __OBJC,__runtime_setup部分也会被展示出来。
-t: 展示__TEXT, __text区域的内容,也就是代码区的内容。加上-v标记便可以反汇编这些文本。加上-V标记,还可以反汇编操作数。
-d: 展示__DATA, __data数据区域的内容。
-o: 展示Objective-C运行时系统中__OBJC段的内容;
-r: 展示重定位项(relocation);
-c: 展示核心文件中的参数字符串(argv[], envp[]);
-I: 展示间接符号表(Indirect);
-T: 展示动态链接共享库的内容表(Table);
-R: 展示动态链接共享库的索引(Reference);
-M: 展示动态链接共享库的组件表(Module);
-H: 展示二级命名空间提示表(Hints);
-G: 展示代码表中的数据;
-C: 展示链接器的优化项(也可以添加-v);
-P: 以字符串的方式打印infoplist部分(__TEXT, __info_plist);
下面的选项同样也可以添加(大多是跟反汇编有关的选项):
- -p name:使用-t,-v或者-V选项从符号名称开始地方一直到(__TEXT, __text)末尾进行反汇编;
otool -p _main -tV a.o/// _main函数开始进行反汇编
-v:在可能的情况下,以详细的方式(符号化)展示;
-V:使用符号化的方式反汇编操作数。这在使用-t选项的时候非常有用。既然是使用了符号化的方式那就意味着包含了-v选项;
-X:在反汇编的时候不打印主地址或者头部信息;
-q:在执行反汇编的时候,使用llvm的反汇编器。这在x86和arm架构下都是可用的。并且这是一个默认值;
-mcpu=arg:在使用llvm反汇编器执行反汇编操作时指定的cpu参数;
-function_offsets:在反汇编时打印上一个标签的16进制偏移的大小;
-j:在反汇编时打印指令操作符字节大小(When doing disassembly print the print the opcode bytes of the instructions.);
在反汇编时,otool反汇编器对应的选项:
-arch arch_type:指定架构(比如x86,arm),当文件作为一个通用文件(即文件有多种架构)时archotool进行操作(在arch(3)中查看arch_types)。arch_type可以是"all",该文件作用于所有的架构。默认情况是根据主机的架构来进行展示,但是该文件得包含该架构才行;否则,该文件的所有架构将会展示出来。
-m:目标文件名称不会存入对应语法中,使用该选项可以插入文件名;
--version: 打印otool的版本信息;
如果只是需要知道怎么使用otool的话,后面完全没有必要继续看了,后面主要讲了otool到objdump的过渡。
llvm-otool
在各个参数中,主要是添加了对应objdump的选项,有助于由otool平滑过渡到objdump。
特殊选项
- -l:也总意味着-h选项,在objdump中使用
-private-headers
来打印所有的mach头和load command; - -r:打印重定位信息和objdump的格式不同;
- -S:为了打印__.SYMDEF的内容,使用llvm-nm配合
-print-armap
选项;
一般注意事项
大部分陈旧的otool选项已经过时,不再使用之后,仅打印目标文件的一部分。当使用llvm-otool时会打印出来说明该功能已经过时。如果没有已给出otool选项功能等同的选择时,objdump会在执行时打印这部分信息。
不支持libx.a(foo.o)类似的参数。就像是总是在使用-m选项一样(因为如果要支持打印共享库中某一部分的内容,我们不要添加-m选项)。
当执行反汇编时,即使是32位的ARM,默认情况也是不会打印操作码的字节数的。需要打印ARM的操作码字节数时,可以使用otool搭配-j
选项。
在一些情况下otool和objdump在打印空格时候稍有不同。就是说即使在objdump和otool功能相似的情况其输出都会出现不同。
选项的特殊转换
以下是otool选项的一个列表,以及给出使用objdump选项打印相似信息的选项。当使用objdump的选项时,-macho
选项是必须要加上的。打印详细信息的情况下,-v选项也是默认使用的。在objdump中使用-non-verbose
选项来打印非详细信息。
-a:objdump使用
-archive-headers
会打印archive头部信息,前提条件是该文件是归档的。在otool中使用-aV选项来获取archive头部的偏移量,objdump使用-archive-member-offsets
达到相同的效果;-S:objdump无法打印__.SYMDEF文件内容,如果要打印对应的内容可以使用llvm-nm配上
-print-armap
参数;-f:objdump使用
-uni-versal-headers
打印通用头部信息;-h:objdump使用
-private-header
来打印Mach的头部信息;-l:objdump使用
-private-headers
展示load command信息,同时也会打印Mach头部数据;-L:objdump打印共享库相关信息,使用
-dylibs-used
选项;-D:objdump打印共享库名称使用
-dylib-id
选项;-s segname sectname:objdump展示section的选项是
-section [segname,]sectname
,其中方括号内的内容是可选的,也就是segname是可选。它会搜索所有匹配sectname的segements。-t objdump为了展示__TEXT,__text部分的内容提供了
_section __TEXT,__text
选项。如果想要在反汇编的时候想使用类似otool里面-tV选项的功能,在objdump中使用-disassemble
选项。通常情况下objdump是默认会在反汇编的时候符号化对应的操作数,就像是otool -tV一样,如果不想这么做可以加上objdump -no-symbolic-operands
。(关于操作数operands,它是汇编语言中对数据寻址时,使用立即数、寄存器或者内存方式来存储对应数据,并对数据寻址的表现形式)-d objdump对应的命令:
-section __DATA, __data
;-o objdump对应的命令:
-objc-meta-data
;-r objdump使用相同的
-r
选项来展示重定位内容;-I objdump对应的命令:
-indirect-symbols
;-G objdump对应的命令:
-data-in-code
;-C objdump对应的命令:
-link-opt-hints
;-P objdump对应的命令:
-info-plist
;-p name objdump对应的命令:
-dis-symname
;-v objdump对应的命令:
-non-verbose
;-V 默认情况下objdump是开启了对应功能;
-X objdump对应的命令:
-no-leading-addr
;-mcpu=arg objdump对应的命令:
-mcpu=arg
;-arch arch-type objdump对应的命令:
-arch arch-type
;-j objdump默认情况下是打印对应的操作码的,如果要取消这个默认情况使用
-no-show-raw-insn
选项;--version objdump使用
-version
来打印版本信息;
已过时的选项
-c-T-R-M-H-i-q-Q-function_offsets-m
更多内容可查看原文。