编译命令
clang-xc-g-ca.c-oa.o
-x: 指定编译文件语言类型
-g: 生成调试信息
-c: 生成目标文件
-o: 输出文件
-I<directory> 在指定目录寻找头文件
-L <dir> 指定库文件路径 (.a\.dylib库文件)
-l<library_name> 指定链接的的库文件名称 (.a\.dylib库文件)
-F<directory> 在指定目录寻找framework头文件
-framework <framework_name> 指定链接的framework名称
目标文件
目标文件包含了机器指令代码、数据,链接时需要的信息,符号表、调试信息,字符串表。
//将源文件编译链接成可执行文件
clang test.m -o test
//将源文件编译成目标文件
clang -c test.m -o test.o
查看符号表
nm -pa a.o
-a: 显示符号表的所有内容
-g: 显示全局符号
-p: 不排序,显示符号原来的顺序
-r: 逆转顺序
-u: 显示未定义符号
查看文件内容
otool用来查看Mach-o文件内部结构
objdump用来查看文件的内部结构,包括 ELF 和 Mach-o
objdump -macho -d test //将所有包含指定段反汇编
(__TEXT,__text) section
_main:
100003fa0: 55 pushq %rbp
100003fa1: 48 89 e5 movq %rsp, %rbp
100003fa4: 31 c0 xorl %eax, %eax
100003fa6: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
100003fad: 5d popq %rbp
100003fae: c3 retq
objdump -macho -d test.o
(__TEXT,__text) section
_main:
0: 55 pushq %rbp
1: 48 89 e5 movq %rsp, %rbp
4: 31 c0 xorl %eax, %eax
6: c7 45 fc 00 00 00 00 movl $_main, -4(%rbp)//静地址相对位移调用指令
d: 5d popq %rbp
e: c3 retq
(__TEXT,__text) section
_test:
0: 55 pushq %rbp
1: 48 89 e5 movq %rsp, %rbp
4: 5d popq %rbp
5: c3 retq
6: 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:_test(%rax,%rax)
_test_1:
10: 55 pushq %rbp
11: 48 89 e5 movq %rsp, %rbp
14: 5d popq %rbp
15: c3 retq
16: 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:_test(%rax,%rax)
_main:
20: 55 pushq %rbp
21: 48 89 e5 movq %rsp, %rbp
24: 48 83 ec 10 subq $16, %rsp
28: c7 45 fc 00 00 00 00 movl $_test, -4(%rbp)
2f: c7 05 fc ff ff ff 15 00 00 00 movl $21, _global-4(%rip)
39: c7 05 fc ff ff ff 14 00 00 00 movl $20, _global-4(%rip)
43: e8 00 00 00 00 callq _test //位移量 + 下条指令地址 = 函数地址,链接时候会重定位
48: e8 00 00 00 00 callq _test_1
4d: 31 c0 xorl %eax, %eax
4f: 48 83 c4 10 addq $16, %rsp
53: 5d popq %rbp
54: c3 retq
objdump -macho -reloc test.o //重定位符号表
Relocation information (__TEXT,__text) 4 entries
address pcrel length extern type scattered symbolnum/value
00000049 True long True BRANCH False _test_1
00000044 True long True BRANCH False _test
0000003b True long True SIGNED4 False _global
00000031 True long True SIGNED4 False _global
Relocation information (__DWARF,__debug_info) 4 entries
address pcrel length extern type scattered symbolnum/value
00000056 False quad False UNSIGND False 1 (__TEXT,__text)
00000045 False quad False UNSIGND False 1 (__TEXT,__text)
00000034 False quad False UNSIGND False 1 (__TEXT,__text)
00000027 False quad False UNSIGND False 1 (__TEXT,__text)
Relocation information (__LD,__compact_unwind) 3 entries
address pcrel length extern type scattered symbolnum/value
00000040 False quad False UNSIGND False 1 (__TEXT,__text)
00000020 False quad False UNSIGND False 1 (__TEXT,__text)
00000000 False quad False UNSIGND False 1 (__TEXT,__text)
Relocation information (__DWARF,__debug_line) 1 entries
address pcrel length extern type scattered symbolnum/value
0000002b False quad False UNSIGND False 1 (__TEXT,__text)
objdump -macho -d test//真实的虚拟内存地址
(__TEXT,__text) section
_test:
100003f60: 55 pushq %rbp
100003f61: 48 89 e5 movq %rsp, %rbp
100003f64: 5d popq %rbp
100003f65: c3 retq
100003f66: 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:(%rax,%rax)
_test_1:
100003f70: 55 pushq %rbp
100003f71: 48 89 e5 movq %rsp, %rbp
100003f74: 5d popq %rbp
100003f75: c3 retq
100003f76: 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:(%rax,%rax)
_main:
100003f80: 55 pushq %rbp
100003f81: 48 89 e5 movq %rsp, %rbp
100003f84: 48 83 ec 10 subq $16, %rsp
100003f88: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
100003f8f: c7 05 67 40 00 00 15 00 00 00 movl $21, 16487(%rip)
100003f99: c7 05 5d 40 00 00 14 00 00 00 movl $20, 16477(%rip)
100003fa3: e8 b8 ff ff ff callq _test
100003fa8: e8 c3 ff ff ff callq _test_1
100003fad: 31 c0 xorl %eax, %eax
100003faf: 48 83 c4 10 addq $16, %rsp
100003fb3: 5d popq %rbp
100003fb4: c3 retq