iOS底层-Mach-O探索(一)

898 阅读3分钟

可执行文件

  什么是Mach-O呢?分析Mach-O对我们有什么帮助呢?
Mach-0其实是一种文件格式。Mach-O文件是Mach Object文件格式的缩写,它是用于可执行文件、动态库、目标代码的文件格式。作为a.out格式的替代,Mach-O格式提供了更强的扩展性,以及更快的符号表信息访问速度不同的操作系统,其可执行文件的格式也不同。系统内核将可执行文件读取到内存,然后根据可执行文件的头签名(magic魔术)判断二进制文件的格式,苹果系统可执行文件格式基本都是Mach-0文件。熟悉Mach-O文件格式,有助于更好的理解苹果底层的运行机制,更好的掌握dyld加载Mach-O的步骤。

通用二进制

  对于Apple而言不同CPU架构对应不同的指令集,如arm64x86_64,通用二进制格式就是将多种架构的Mach-O文件打包在一起,然后系统根据自己的CPU平台,选择合适的Mach-O,所以通用二进制格式也被称为胖二进制格式。例如我们在开发framework的时候,最后一步通常我们会将模拟器和真机的可执行文件合并在一起,生成一个通用二进制文件。
常用跟Mach-O相关指令:

  • 查看当前Mach-O的架构:lipo -info MachO文件
  • 合并Mach-Olipo -create MachO1 MachO2 -output 输出文件路径
  • 拆分Mach-Olipo MachO文件 –thin 架构 –output 输出文件路径   通过访问Apple开发者网站的opensource可以下载源码xnu,可以分析Mach-O的结构。依此访问 xnu -> EXTERNAL_HEADERS ->mach-o中找到该文件,通用二进制文件开始的Fat Headerfat_header结构体,而Fat Archs是表示通用二进制文件中有多少个Mach-O,单个Mach-O的描述是通过fat_arch结构体。两个结构体的定义如下
**struct** fat_header {

uint32_t magic; /* FAT_MAGIC */

    // 可以让系统内核读取该文件时知道是通用二进制文件

uint32_t nfat_arch; /* number of structs that follow */

    // 说明下面有多个fat_arch结构体,即通用二进制文件包含多少个Mach-O

};
\
// 描述Mach-O

**struct** fat_arch {

    // 说明Mach-O适用的平台

cpu_type_t cputype; /* cpu specifier (int) */

cpu_subtype_t cpusubtype; /* machine specifier (int) */

    // 描述了Mach-O二进制位于通用二进制文件的位置

    // 偏移

uint32_t offset; /* file offset to this object file */

    // 大小

uint32_t size; /* size of this object file */

    // 页对齐

uint32_t align; /* alignment as a power of 2 */

};

  小结:

  • 通用二进制文件是苹果公司提出的一种新的二进制文件的存储结构,可以同时存储多种架构的二进制指令,使CPU在读取该二进制文件时可以自动检测并选用合适的架构,以最理想的方式进行读取
  • 由于通用二进制文件会同时存储多种架构,所以比单一架构的二进制文件大很多,会占用大量的磁盘空间,但由于系统会自动选择最合适的,不相关的架构代码不会占用内存空间,且执行效率高

Mach-O文件的查看

  • 通过mac工具烂苹果(MachOView) 安装MachOView -> 打开Mach-O文件
  • 通过工具otool使用终端指令查看 otool -l Mach-O文件路径 下一期我们通过工具和源码分析一下Mach-O文件的内部结构。