符号表

520 阅读2分钟

编译命令

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