咱们在前面学习了,编译最终会生成mach-o文件,那么mach-o结构是怎么的呢?linux
Mach-O实际上是Mach Object文件格式的缩写,是mac以及iOS上可执行文件的格式, 相似于windows上的PE格式 (Portable Executable ), linux上的elf格式 (Executable and Linking Format)小程序
记录编译后的可执行文件,对象代码,共享库,动态加载代码和内存转储的文件格式。不一样于 xml 这样的文件,它只是二进制字节流,里面有不一样的包含元信息的数据块,好比字节顺序,cpu 类型,块大小等。文件内容是不能够修改的,由于在 .app 目录中有个 _CodeSignature 的目录,里面包含了程序代码的签名,这个签名的做用就是保证签名后 .app 里的文件,包括资源文件,Mach-O 文件都不可以更改。windows
咱们打开machOView bash
Load commands是一张包含不少内容的表。 内容包括区域的位置、符号表、动态符号表等。 微信
符号 | 含义 |
---|---|
LC_SEGMENT_64 | 将文件中(32位或64位)的段映射到进程地址空间中 |
LC_DYLD_INFO_ONLY | 动态连接相关信息 |
LC_SYMTAB | 符号地址 |
LC_DYSYMTAB | 动态符号表地址 |
LC_LOAD_DYLINKER | 使用谁加载,咱们使用dyld |
LC_UUID | 文件的UUID |
LC_VERSION_MIN_MACOSX | 支持最低的操做系统版本 |
LC_SOURCE_VERSION | 源代码版本 |
LC_MAIN | 设置程序主线程的入口地址和栈大小 |
LC_LOAD_DYLIB | 依赖库的路径,包含三方库 |
LC_FUNCTION_STARTS | 函数起始地址表 |
LC_CODE_SIGNATURE | 代码签名 |
其中LC_LOAD_DYLINKER和LC_LOAD_DYLIBapp
Data 一般是对象文件中最大的部分,包含Segement的具体数据,如静态C字符串,带参数/不带参数的OC方法,带参数/不带参数的C函数。函数
使用命令xcrun size -x -l -m main查看segment中的内容学习
显示为测试
Mac-mini-2:测试mac jxq$ xcrun size -x -l -m main
Segment __PAGEZERO: 0x100000000 (vmaddr 0x0 fileoff 0)
Segment __TEXT: 0x1000 (vmaddr 0x100000000 fileoff 0)
Section __text: 0x52 (addr 0x100000ef0 offset 3824)
Section __stubs: 0x18 (addr 0x100000f42 offset 3906)
Section __stub_helper: 0x38 (addr 0x100000f5c offset 3932)
Section __cstring: 0x1b (addr 0x100000f94 offset 3988)
Section __unwind_info: 0x48 (addr 0x100000fb0 offset 4016)
total 0x105
Segment __DATA: 0x1000 (vmaddr 0x100001000 fileoff 4096)
Section __nl_symbol_ptr: 0x8 (addr 0x100001000 offset 4096)
Section __got: 0x8 (addr 0x100001008 offset 4104)
Section __la_symbol_ptr: 0x20 (addr 0x100001010 offset 4112)
Section __cfstring: 0x20 (addr 0x100001030 offset 4144)
Section __objc_imageinfo: 0x8 (addr 0x100001050 offset 4176)
total 0x58
Segment __LINKEDIT: 0x1000 (vmaddr 0x100002000 fileoff 8192)
total 0x100003000
复制代码
这里咱们大概了解了mach-o文件的内容,那么mach-o是如何执行的呢? 咱们将在下一篇文章,动态连接学习。spa