Mach-O --- 基础

Mach-O为Mach Object文件格式的缩写,它是一种用于可执行文件,目标代码,动态库,内核转储的文件格式。作为a.out格式的替代,Mach-O提供了更强的扩展性,并提升了符号表中信息的访问速度。

Mach-O 文件结构如下图:


Mach-O --- 基础_第1张图片
Mach-O.png

另外可以下载MachOView工具查看Mach—O 文件结构。下面是UIKit 的截图

Mach-O --- 基础_第2张图片
Screen Shot 2017-04-16 at 2.51.56 PM.png

下面主要从以下角度学习Mach-O

  • 文件头 mach64 Header
  • 加载命令 Load Commands
  • Sections

Mach Header

/*
 * The 32-bit mach header appears at the very beginning of the object file for
 * 32-bit architectures.
 */
struct mach_header {
    uint32_t    magic;      /* mach magic number identifier */
    cpu_type_t  cputype;    /* cpu specifier */
    cpu_subtype_t   cpusubtype; /* machine specifier */
    uint32_t    filetype;   /* type of file */
    uint32_t    ncmds;      /* number of load commands */
    uint32_t    sizeofcmds; /* the size of all the load commands */
    uint32_t    flags;      /* flags */
};

/* Constant for the magic field of the mach_header (32-bit architectures) */
#define MH_MAGIC    0xfeedface  /* the mach magic number */
#define MH_CIGAM    0xcefaedfe  /* NXSwapInt(MH_MAGIC) */

/*
 * The 64-bit mach header appears at the very beginning of object files for
 * 64-bit architectures.
 */
struct mach_header_64 {
    uint32_t    magic;      /* mach magic number identifier */
    cpu_type_t  cputype;    /* cpu specifier */
    cpu_subtype_t   cpusubtype; /* machine specifier */
    uint32_t    filetype;   /* type of file */
    uint32_t    ncmds;      /* number of load commands */
    uint32_t    sizeofcmds; /* the size of all the load commands */
    uint32_t    flags;      /* flags */
    uint32_t    reserved;   /* reserved */
};

/* Constant for the magic field of the mach_header_64 (64-bit architectures) */
#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */
#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */
字段
magic 魔数,系统加载器通过改字段快速,判断该文件是用于32位or64位。32位-0xfeedface 64位-0xfeedfacf
cputype CPU类型以及子类型字段,该字段确保系统可以将适合的二进制文件在当前架构下运行
cpusubtype CPU指定子类型,对于inter,arm,powerpc等CPU架构,其都有各个阶段和等级的CPU芯片,该字段就是详细描述其支持CPU子类型
filetype 说明该mach-o文件类型(可执行文件,库文件,核心转储文件,内核扩展,DYSM文件,动态库)
ncmds 说明加载命令条数
sizeofcmds 表示加载命令大小
flags 标志位,该字段用位表示二进制文件支持的功能,主要是和系统加载,链接相关
reserved 保留字段

Load Commands

Mach-O文件包含非常详细的加载指令,这些指令非常清晰地指示加载器如何设置并且加载二进制数据。Load Commands紧紧跟着二进制文件头。

Segment name
LC_SEGMENT_64 将文件中(32位或64位)的段映射到进程地址空间中
LC_DYLD_INFO_ONLY 动态库信息以及地址重定向重要的信息
LC_SYMTAB 符号表地址
LC_DYSYMTAB 动态符号表地址
LC_LOAD_DYLINKER 使用何种动态加载库
LC_UUID 文件的唯一标识
LC_VERSION_MIN_MACOSX 二进制文件要求的最低操作系统版本
LC_SOURCE_VERSION 构建该二进制文件使用的源代码版本
LC_MAIN 设置程序主线程的入口地址和栈大小
LC_LOAD_DYLIB 加载额外的动态库,仔细看这个命令格式,动态库地址和名,当前版本号,兼容版本号,该设计比较合理,如果对于动态库有版本管理能力
LC_FUNCTION_STARTS 函数起始地址表

Section

Section name
__text 主程序代码
__stubs 用于动态库链接的桩
__stub_helper 用于动态库链接的桩
__cstring 常亮字符串符号表描述信息,通过该区信息,可以获得常亮字符串符号表地址
__unwind_info
__objc_methname 保存着Objc 里面selector 的名字
__objc_classname 保存Objc类的名字
__objc_methtype 保存Objc类的一些信息(函数签名)
__objc_classlist Objective-C 的类列表
__objc_nlclslist Objective-C 的 +load 函数列表,比 __mod_init_func 更早执行
__objc_catlist categories
__objc_protolist protocol
__objc_imageinfo 保存文件中objc 执行代码的一些信息
__objc_selrefs 指向selectors 的引用
__objc_protorefs 指向protocol 的引用
__objc_classrefs 指向classes 的引用
__objc_superrefs 指向super classes 的引用
__mod_init_func 初始化的全局函数地址,在 main 之前被调用
__bss 未初始化的静态变量
_got 存储引用符号的实际地址,类似于动态符号表

以上仅个人学习记录,有错请指教。

你可能感兴趣的:(Mach-O --- 基础)