上篇简单的介绍了一下Mach-O文件,这篇将继续介绍源码定义在Header和Load Commands的一些字段含义
1.胖二进制文件
源码位置在mach-o/fat.h.

image.png
magic:特征字段,定义为FAT_MAGIC常量,加载器通过该字段判断文件的类型
nfat_arch:指当前的胖二进制文件包含了多少个不同架构的Mach-O文件.
在fat_header后会紧跟fat_arch结构,有多少个不同架构的Mach-O文件就会有多少个fat_arch,用来描述对应的Mach-O文件的具体信息.

image.png
cputype:标识CPU架构,如ARM、X86_64
cpusubtype:标识具体的CPU类型,区分不同版本的处理器
offset:指定该CPU架构数据相对于文件开头的偏移量
size:CPU架构数据的大小
align:指定数据的内存对齐边界,必须为2的N次方
2.Mach-O头部
头部保存了CPU架构、大小端序、文件类型、加载命令数量等基本信息.
源码位置在mach-o/loader

image.png
magic:特征字段,标识当前设备是大端还是小端
cputype、cpusubtype:与fat_header定义的一致
filetype:Mach-O文件的类型
ncmds:加载命令的数量
sizeofcmds:加载命令占用的总字节大小
flags:文件的一些标志信息.比如启用ASLR(只有filetype为MH_EXECUTE类型中使用)技术增加程序安全性.取值为0x200000
reserved:保留字段(64位架构存在)
3.Load Commands
加载命令是紧跟在Mach-O头部之后,用于明确告诉加载器如何处理二进制数据.

image.png
cmd:表示当前加载命令的类型
cmdsize:表示当前加载命令的大小
4.段加载命令(LC_SEGMENT)
每个段都定义了一个虚拟内存区域,动态链接器负责把这个区域映射到进程地址空间.用结构体segment_command表示如下

image.png
cmd:加载命令的类型
cmdsize:表示当前加载命令的大小
segname:段名称,占用16字节
vmaddr:段的虚拟内存地址
vmasize:段的虚拟内存大小
fileoff:段在文件中的偏移量
filesize:段的文件中大小
maxprot:段页面的最高内存保护(读,写,执行)
nsects:段中包含节的数量.
flags:段的标志信息
如何加载段:系统从fileoff处加载大小为filesize的内容到虚拟内存vmaaddr处,大小为vmsize,段页面的权限由initprot初始化,权限可以被修改,但是不能超过maxprot.
5.动态库加载命令(LC_LOAD_DYLIB)
定义结构如下:

image.png

image.png
*name:动态库完整路径
*timestamp:动态库构建时的时间戳
*current_version:当前版本号
*compatibility_version:兼容版本号
注意:该结构对应的命令还可能是LC_LOAD_WEAK_DYLIB.都表示加载动态库.只不过带有WEAK声明的是可选的,代表缺少这些库也没有什么影响.而LC_LOAD_DYLIB不同,若依赖库没有找到,会结束该进程
好了时间不早了,下次有时间在继续补充