假设我们要找到var2的偏移量:
int var1 = 1;
int var2 = 2;
int main(){}
构建后,nm 给出:
nm -a a.out | grep var
0000000100001000 D _var1
0000000100001004 D _var2
使用gobjdump (port install binutils) 我们可以读取程序头:
gobjdump -x a.out
a.out: file format mach-o-x86-64
a.out
architecture: i386:x86-64, flags 0x00000012:
EXEC_P, HAS_SYMS
start address 0x0000000100000f90
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000000b 0000000100000f90 0000000100000f90 00000f90 2**4
CONTENTS, ALLOC, LOAD, CODE
1 __TEXT.__unwind_info 00000048 0000000100000f9c 0000000100000f9c 00000f9c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .eh_frame 00000018 0000000100000fe8 0000000100000fe8 00000fe8 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .data 00000008 0000000100001000 0000000100001000 00001000 2**2
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
0000000100000000 g 0f SECT 01 0010 [.text] __mh_execute_header
0000000100000f90 g 0f SECT 01 0000 [.text] _main
0000000100001000 g 0f SECT 04 0000 [.data] _var1
0000000100001004 g 0f SECT 04 0000 [.data] _var2
0000000000000000 g 01 UND 00 0100 dyld_stub_binder
因此nm返回的var2的地址在.data段中,它在虚拟内存地址100001000处加载,文件偏移为1000。可以得到var2as100001004 - 100001000 + 1000 = 1004的文件偏移量。
这可以用十六进制编辑器验证:
256 0000ff0: 017a 5200 0178 1001 100c 0708 9001 0000 .zR..x..........
257 0001000: 0100 0000 0200 0000 0000 0000 0000 0000 ................
258 0001010: 0000 0000 0000 0000 0000 0000 0000 0000 ................