Mac OS X ABI Mach-O File Format Reference(1)

1,263 阅读26分钟

Mac OS X ABI Mach-O File Format Reference(2)

Mac OS X ABI Mach-O File Format Reference(3)

Overview

This document describes the structure of the Mach-O (Mach object) file format, which is the standard used to store programs and libraries on disk in the Mac OS X application binary interface (ABI). To understand how the Xcode tools work with Mach-O files, and to perform low-level debugging tasks, you need to understand this information.

本文档描述了Mach- o (Mach object)文件格式的结构,这是Mac OS X应用程序二进制接口(ABI)中用于在磁盘上存储程序和库的标准格式。要理解Xcode工具如何处理Mach-O文件,并执行 low-level 调试任务,您需要理解这些信息。

The Mach-O file format provides both intermediate (during the build process) and final (after linking the final product) storage of machine code and data. It was designed as a flexible replacement for the BSD a.out format, to be used by the compiler and the static linker and to contain statically linked executable code at runtime. Features for dynamic linking were added as the goals of Mac OS X evolved, resulting in a single file format for both statically linked and dynamically linked code.

Mach-O文件格式提供了机器代码和数据的中间(在构建过程中)和最终(在链接最终产品之后)存储。它被设计为一个灵活的替代BSD a.out输出格式,由编译器和静态链接器使用,并在运行时包含静态链接的可执行代码。随着Mac OS X目标的发展,动态链接的特性也被添加进来,从而为静态链接和动态链接代码提供了一种单一的文件格式。

Basic Structure

A Mach-O file contains three major regions (as shown in Figure 1):

一个Mach-O文件包含三个主要区域(如图1所示):

  • At the beginning of every Mach-O file is a header structure that identifies the file as a Mach-O file. The header also contains other basic file type information, indicates the target architecture, and contains flags specifying options that affect the interpretation of the rest of the file.

    在每个Mach-O文件的开头都有一个头结构,它将文件标识为一个Mach-O文件。头文件还包含其他基本文件类型信息,指示目标体系结构,并包含指定影响文件其余部分解释的选项的标志。

  • Directly following the header are a series of variable-size load commands that specify the layout and linkage characteristics of the file. Among other information, the load commands can specify:

    头文件后面是一系列大小可变的load commands,它们指定文件的布局和链接特性。在其他信息中,load commands可以指定:

    • The initial layout of the file in virtual memory

      文件在虚拟内存中的初始布局

    • The location of the symbol table (used for dynamic linking)

      符号表的位置(用于动态链接)

    • The initial execution state of the main thread of the program

      程序主线程的初始执行状态

    • The names of shared libraries that contain definitions for the main executable’s imported symbols

      包含主可执行文件导入符号定义的共享库的名称

  • Following the load commands, all Mach-O files contain the data of one or more segments. Each segment contains zero or more sections. Each section of a segment contains code or data of some particular type. Each segment defines a region of virtual memory that the dynamic linker maps into the address space of the process. The exact number and layout of segments and sections is specified by the load commands and the file type.

    按照load commands, Mach-O文件都包含一个或多个segment的数据。每个段包含零个或多个sections。段的每个section都包含某种特定类型的代码或数据。每个segment定义一个虚拟内存区域,动态链接器将该区域映射到进程的地址空间。segmentsections的确切数量和布局由load commands和文件类型指定。

  • In user-level fully linked Mach-O files, the last segment is the link edit segment. This segment contains the tables of link edit information, such as the symbol table, string table, and so forth, used by the dynamic loader to link an executable file or Mach-O bundle to its dependent libraries.

    在用户级完全链接的Mach-O文件中,最后一个段是链接编辑段。此段包含链接编辑信息的表,如符号表、字符串表等,动态加载程序使用这些表将可执行文件或Mach-O包链接到其依赖库。

    Figure 1 Mach-O file format basic structure

Various tables within a Mach-O file refer to sections by number. Section numbering begins at 1 (not 0) and continues across segment boundaries. Thus, the first segment in a file may contain sections 1 and 2 and the second segment may contain sections 3 and 4.

Mach-O文件中的各种表都是按编号引用节的。节编号从1(不是0)开始,并跨越段边界。因此,文件中的第一个段可以包含第1节和第2节,第二个段可以包含第3节和第4节。

When using the Stabs debugging format, the symbol table also holds debugging information. When using DWARF, debugging information is stored in the image’s corresponding dSYM file, specified by the uuid_command (page 20) structure

当使用Stabs调试格式时,符号表还包含调试信息。使用DWARF时,调试信息存储在image对应的dSYM文件中,该文件由uuid_command 结构指定

Header Structure and Load Commands

A Mach-O file contains code and data for one architecture. The header structure of a Mach-O file specifies the target architecture, which allows the kernel to ensure that, for example, code intended for PowerPC-based Macintosh computers is not executed on Intel-based Macintosh computers.

一个Mach-O文件包含一个架构的代码和数据。Mach-O文件的头结构指定了目标体系结构,这允许内核确保,例如,针对基于powerpc的Macintosh计算机的代码不会在基于intel的Macintosh计算机上执行。

You can group multiple Mach-O files (one for each architecture you want to support) in one binary using the format described in “Universal Binaries and 32-bit/64-bit PowerPC Binaries” (page 55).

您可以使用“Universal Binaries and 32-bit/64-bit PowerPC Binaries”中描述的格式将多个Mach-O文件(每个体系结构一个)分组到一个二进制文件中。

Note: Binaries that contain object files for more than one architecture are not Mach-O files. They archive one or more Mach-O files.

注意:包含多个体系结构的目标文件的二进制文件不是Mach-O文件。他们存档一个或多个Mach-O文件。

Segments and sections are normally accessed by name. Segments, by convention, are named using all uppercase letters preceded by two underscores (for example, _TEXT); sections should be named using all lowercase letters preceded by two underscores (for example, __text). This naming convention is standard, although not required for the tools to operate correctly.

Segmentssections通常按名称访问。按照惯例,Segments的命名使用所有大写字母加上两个下划线(例如,__ TEXT); sections的命名应该使用所有小写字母加上两个下划线(例如,__ text)。这只是一个规范的命名约定,不强制要求必须这样做

Segments

A segment defines a range of bytes in a Mach-O file and the addresses and memory protection attributes at which those bytes are mapped into virtual memory when the dynamic linker loads the application. As such, segments are always virtual memory page aligned. A segment contains zero or more sections.

segment在Mach-O文件中定义一个字节范围,以及地址和内存保护属性,当动态链接器加载应用程序时,这些字节被映射到虚拟内存中。因此,segments始终是虚拟内存页面对齐的。一个segment包含零个或多个sections

Segments that require more memory at runtime than they do at build time can specify a larger in-memory size than they actually have on disk. For example, the __PAGEZERO segment generated by the linker for PowerPC executable files has a virtual memory size of one page but an on-disk size of 0.

Because __PAGEZERO contains no data, there is no need for it to occupy any space in the executable file.

运行时比构建时需要更多内存的段可以指定比它们在磁盘上实际拥有的更大的内存大小。例如,链接器为PowerPC可执行文件生成的__ PAGEZERO段的虚拟内存大小为一页,而磁盘大小为0。由于__ PAGEZERO不包含数据,因此不需要占用可执行文件中的任何空间。

Note: Sections that are to be filled with zeros must always be placed at the end of the segment. Otherwise, the standard tools will not be able to successfully manipulate the Mach-O file.

注意:要用零填充的部分必须始终放在段的末尾。否则,标准工具将无法成功地操作Mach-O文件。

For compactness, an intermediate object file contains only one segment. This segment has no name; it contains all the sections destined ultimately for different segments in the final object file. The data structure that defines a section (page 23) contains the name of the segment the section is intended for, and the static linker places each section in the final object file accordingly.

为了紧凑性,中间对象文件只包含一个segment。这个segment没有名字;它包含为最终目标文件中的不同segment指定的所有sections。定义section的数据结构(第23页)包含节的目标段的名称,静态链接器将每个节相应地放在最终目标文件中。

For best performance, segments should be aligned on virtual memory page boundaries—4096 bytes for PowerPC and x86 processors. To calculate the size of a segment, add up the size of each section, then round up the sum to the next virtual memory page boundary (4096 bytes, or 4 kilobytes). Using this algorithm, the minimum size of a segment is 4 kilobytes, and thereafter it is sized at 4 kilobyte increments.

为了获得最佳性能,段应该对齐到虚拟内存页边界上—PowerPC和x86处理器的4096字节。要计算段的大小,请将每个段的大小相加,然后将总和四舍五入到下一个虚拟内存页边界(4096字节,或4 kb)。使用这种算法,一个段的最小大小是4 kb,然后以4 kb的增量进行调整。

The header and load commands are considered part of the first segment of the file for paging purposes. In an executable file, this generally means that the headers and load commands live at the start of the __ TEXT segment because that is the first segment that contains data. The __PAGEZERO segment contains no data on disk, so it’s ignored for this purpose.

出于分页的目的,headerload commands被认为是文件第一segment的一部分。在一个可执行文件中,这通常意味着headersload commands位于__ TEXT segment的开头,因为这是包含数据的第一个segment。由于__PAGEZERO segment没有包含任何数据,因此忽略了它。

These are the segments the standard Mac OS X development tools (contained in the Xcode Tools CD) may include in a Mac OS X executable:

以下是标准Mac OS X开发工具(包含在Xcode tools CD中)可能包含在Mac OS X可执行文件中的部分:

  • The static linker creates a __ PAGEZERO segment as the first segment of an executable file. This segment is located at virtual memory location 0 and has no protection rights assigned, the combination of which causes accesses to NULL, a common C programming error, to immediately crash. The __ PAGEZERO segment is the size of one full VM page for the current architecture (for Intel-based and PowerPC-based Macintosh computers, this is 4096 bytes or 0x1000 in hexadecimal). Because there is no data in the __PAGEZERO segment, it occupies no space in the file (the file size in the segment command is 0).

    静态链接器创建一个__PAGEZERO segment 作为可执行文件的第一个segment。这个segment位于虚拟内存位置0,没有分配任何保护权限,两者的组合会导致对NULL的访问立即崩溃,这是一个常见的C编程错误。对于当前的体系结构(对于基于intel和基于powerpc的Macintosh计算机,这是4096字节,或者十六进制是0x1000), _ PAGEZEROsegment的大小相当于一个完整的VM页面。因为在PAGEZERO段中没有数据,所以它在文件中不占空间(segment命令中的文件大小为0)。

  • The __ TEXT segment contains executable code and other read-only data. To allow the kernel to map it directly from the executable into sharable memory, the static linker sets this segment’s virtual memory permissions to disallow writing. When the segment is mapped into memory, it can be shared among all processes interested in its contents. (This is primarily used with frameworks, bundles, and shared libraries, but it is possible to run multiple copies of the same executable in Mac OS X, and this applies in that case as well.) The read-only attribute also means that the pages that make up the __ TEXT segment never need to be written back to disk. When the kernel needs to free up physical memory, it can simply discard one or more __TEXT pages and re-read them from disk when they are next needed.

    TEXT segment包含可执行代码和其他只读数据。为了允许内核将它直接从可执行文件映射到可共享内存,静态链接器将这个段的虚拟内存权限设置为不允许写入。当段被映射到内存中时,它可以在对其内容感兴趣的所有进程之间共享。(这主要用于框架、捆绑包和共享库,但也可以在Mac OS X中运行同一可执行文件的多个副本,在这种情况下也是适用的。)只读属性还意味着组成TEXT段的页面永远不需要写回磁盘。当内核需要释放物理内存时,它可以简单地丢弃一个或多个TEXT页面,然后在下次需要时从磁盘重新读取它们。

  • The __ DATA segment contains writable data. The static linker sets the virtual memory permissions of this segment to allow both reading and writing. Because it is writable, the __ DATA segment of a framework or other shared library is logically copied for each process linking with the library. When memory pages such as those making up the __DATA segment are readable and writable, the kernel marks them copy-on-write; therefore when a process writes to one of these pages, that process receives its own private copy of the page.

    DATA段包含可写数据。静态链接器设置此段的虚拟内存权限为允许读写。因为它是可写的,所以framework或其他共享库的DATA segment在逻辑上被复制到与库链接的每个进程。当组成DATA段的内存页可读可写时,内核将它们标记为copy-on-write; 因此,当一个进程写到其中一个页面时,该进程将收到该页面的私有副本。

  • The __OBJC segment contains data used by the Objective-C language runtime support library.

    __OBJC段包含OC运行时支持库使用的数据。

  • The __IMPORT segment contains symbol stubs and non-lazy pointers to symbols not defined in

    the executable. This segment is generated only for executables targeted for the IA-32 architecture.

    __IMPORT段含符号存根和指向可执行文件中未定义的符号的非懒加载指针。此段只在IA-32架构下的可执行文件中生成

  • The __LINKEDIT segment contains raw data used by the dynamic linker, such as symbol, string, and relocation table entries.

    __LINKEDIT段包含动态链接器使用的原始数据,例如符号、字符串和重定位表条目。

Sections

The __ TEXT and __ DATA segments may contain a number of standard sections, listed in Table 1, Table 2 (page 11), and Table 3 (page 11). The __OBJC segment contains a number of sections that are private to the Objective-C compiler. Note that the static linker and file analysis tools use the section type and attributes (instead of the section name) to determine how they should treat the section. The section name, type and attributes are explained further in the description of the section (page 23) data type.

TEXT和DATA segments可以包含许多标准sections,如表1、表2和表3中列出。__OBJC段包含许多对Objective-C编译器私有的部分。注意,静态链接器和文件分析工具使用section类型和属性(而不是section name)来确定它们应该如何处理这个sectionsection名称、类型和属性将在section数据类型描述中进一步解释。

Table 1 The sections of a __TEXT segment

Segment and section nameContents
__ TEXT, __textExecutable machine code. The compiler generally places only executable
code in this section, no tables or data of any sort.
可执行的机器代码。编译器通常只将可执行代码放在这一节中,没有任何类型的表或数据。
__ TEXT, __cstringConstant C strings. A C string is a sequence of non-null bytes that ends
with a null byte ('\0'). The static linker coalesces constant C string values,
removing duplicates, when building the final product.
常数C字符串。C字符串是一个以空字节('\0')结尾的非空字节序列。静态链接器在构建最终产品时合并常量C字符串值,删除重复项。
__ TEXT, __picsymbol_stubPosition-independent indirect symbol stubs. See “Dynamic Code
Generation” in Mach-O Programming Topics for more information.
位置无关的间接符号存根。有关更多信息,请参阅Mach-O编程主题中的“动态代码生成”。
__ TEXT, __symbol_stubIndirect symbol stubs. See “Dynamic Code Generation” in Mach-O
Programming Topics
for more information.
间接的象征存根。有关更多信息,请参阅Mach-O编程主题中的“动态代码生成”。
__ TEXT, __constInitialized constant variables. The compiler places all nonrelocatable data
declared const in this section. (The compiler typically places uninitialized constant variables in a zero-filled section.)
初始化常数变量。编译器将在本节中放置所有声明的const的不可重定位数据。(编译器通常将未初始化的常量变量放在一个零填充的部分。)
__ TEXT, __literal44-byte literal values. The compiler places single-precision floating point
constants in this section. The static linker coalesces these values, removing
duplicates, when building the final product. With some architectures,
it’s more efficient for the compiler to use immediate load instructions
rather than adding to this section.
4字节的文本值。编译器在本节中放置单精度浮点常量。静态链接器在构建最终产品时合并这些值,删除重复项。对于某些架构,编译器使用立即加载指令比添加到本节更有效。
__ TEXT, __literal88-byte literal values. The compiler places double-precision floating point
constants in this section. The static linker coalesces these values, removing
duplicates, when building the final product. With some architectures,
it’s more efficient for the compiler to use immediate load instructions
rather than adding to this section.
8字节文字值。编译器在本节中放置双精度浮点常量。静态链接器在构建最终产品时合并这些值,删除重复项。对于某些架构,编译器使用立即加载指令比添加到本节更有效。

Table 2 The sections of a __DATA segment

Segment and section nameContents
__ DATA, __dataInitialized mutable variables, such as writable C strings and data arrays.
初始化可变变量,如可写C字符串和数据数组。
__ DATA, __la_symbol_ptrLazy symbol pointers, which are indirect references to functions
imported from a different file. See “Dynamic Code Generation” in
Mach-O Programming Topics for more information.
懒加载符号指针,是对从不同文件导入的函数的间接引用。有关更多信息,请参阅Mach-O编程主题中的“动态代码生成”。
__ DATA, __nl_symbol_ptrNon-lazy symbol pointers, which are indirect references to data items imported from a different file. See “Dynamic Code Generation” in Mach-O Programming Topics for more information.
非懒加载符号指针,是对从其他文件导入的函数的间接引用。有关详细信息,请参阅Mach-O Programming Topics中的“Dynamic Code Generatio”。
__ DATA, __dyldPlaceholder section used by the dynamic linker.
动态链接器使用的占位section
__ DATA, __constInitialized relocatable constant variables.
初始化可重定位常量变量。
__ DATA, __mod_init_funcModule initialization functions. The C++ compiler places static
constructors here.
模块初始化方法,c++的静态构造函数在这里放
__ DATA, __mod_term_funcModule termination functions.
退出方法,类似析构函数
__ DATA, __bssData for uninitialized static variables (for example, static int i;).
未初始化静态变量的数据(例如,static int i;)
__ DATA, __commonUninitialized imported symbol definitions (for example, int i;)
located in the global scope (outside of a function declaration).
位于全局范围(函数声明之外)中的未初始化全局符号的定义(例如,int i;)

Table 3 The sections of a __IMPORT segment

Segment and section nameContents
__ IMPORT, __jump_tableStubs for calls to functions in a dynamic library.
动态库中函数调用的存根。
__ IMPORT, __pointersNon-lazy symbol pointers, which are direct references to functions
imported from a different file.
非懒加载符号指针,它们直接引用从其他文件导入的函数

Note: Compilers or any tools that create Mach-O files are free to define additional section names. These additional names do not appear in Table

注意:编译器或任何创建mach-o文件的工具都可以自由定义附加的节名。这些附加名称不出现在表中

Data Types

This reference describes the data types that compose a Mach-O file. Values for integer types in all Mach-O data structures are written using the host CPU’s byte ordering scheme, except for fat_header (page 56) and fat_arch (page 56), which are written in big-endian byte order.

此参考描述组成mach-o文件的数据类型。所有mach-o数据结构中的整数类型的值都是使用主机cpu的字节顺序方案编写的,除了fat_header(第56页)和fat_arch(第56页)之外,它们都是以大端字节顺序编写的。

Header Data Structure

mach_header

Specifies the general attributes of a file. Appears at the beginning of object files targeted to 32-bit architectures. Declared in /usr/include/mach-o/loader.h. See also mach_header_64 (page 14).

/*
 * 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) */
  • magic

    An integer containing a value identifying this file as a 32-bit Mach-O file. Use the constant MH_MAGIC if the file is intended for use on a CPU with the same endianness as the computer on which the compiler is running. The constant MH_CIGAM can be used when the byte ordering scheme of the target machine is the reverse of the host CPU.

    一个整数将文件标识为32位Mach-O文件。如果文件要在与运行编译器的计算机具有相同端点的CPU上使用,请使用常量MH_MAGIC。当目标机器的字节排序方案与主机cpu相反时,可以使用常数MH_CIGAM。(大小端值不相同)

  • cputype

    An integer indicating the architecture you intend to use the file on. Appropriate values include:

    一个整数,指示要在其上使用文件的体系结构。适当的值包括:

    #include <mach/machine.h>
    
    /*
     *	Machine types known by all.
     */
     
    #define CPU_TYPE_ANY		((cpu_type_t) -1)
    
    #define CPU_TYPE_VAX		((cpu_type_t) 1)
    /* skip				((cpu_type_t) 2)	*/
    /* skip				((cpu_type_t) 3)	*/
    /* skip				((cpu_type_t) 4)	*/
    /* skip				((cpu_type_t) 5)	*/
    #define	CPU_TYPE_MC680x0	((cpu_type_t) 6)
    #define CPU_TYPE_X86		((cpu_type_t) 7)
    #define CPU_TYPE_I386		CPU_TYPE_X86		/* compatibility */
    #define	CPU_TYPE_X86_64		(CPU_TYPE_X86 | CPU_ARCH_ABI64)
    
    /* skip CPU_TYPE_MIPS		((cpu_type_t) 8)	*/
    /* skip 			((cpu_type_t) 9)	*/
    #define CPU_TYPE_MC98000	((cpu_type_t) 10)
    #define CPU_TYPE_HPPA           ((cpu_type_t) 11)
    #define CPU_TYPE_ARM		((cpu_type_t) 12)
    #define CPU_TYPE_ARM64		(CPU_TYPE_ARM | CPU_ARCH_ABI64)
    #define CPU_TYPE_MC88000	((cpu_type_t) 13)
    #define CPU_TYPE_SPARC		((cpu_type_t) 14)
    #define CPU_TYPE_I860		((cpu_type_t) 15)
    /* skip	CPU_TYPE_ALPHA		((cpu_type_t) 16)	*/
    /* skip				((cpu_type_t) 17)	*/
    #define CPU_TYPE_POWERPC		((cpu_type_t) 18)
    #define CPU_TYPE_POWERPC64		(CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
    
  • cpusubtype

    An integer specifying the exact model of the CPU. To run on all PowerPC or x86 processors supported by the Mac OS X kernel, this should be set to CPU_SUBTYPE_POWERPC_ALL or CPU_SUBTYPE_I386_ALL.

    一个整数,指定CPU的确切型号。要在Mac OS X内核支持的所有PowerPC或x86处理器上运行,应将其设置为CPU_Subtype_PowerPC_All或CPU_Subtype_i386_All。

    #define CPU_SUBTYPE_ARM_ALL             ((cpu_subtype_t) 0)
    #define CPU_SUBTYPE_X86_ALL		((cpu_subtype_t)3)
    
  • filetype

    An integer indicating the usage and alignment of the file. Valid values for this field include:

    /*
     * A core file is in MH_CORE format and can be any in an arbritray legal
     * Mach-O file.
     *
     * Constants for the filetype field of the mach_header
     */
    #define	MH_OBJECT	0x1		/* relocatable object file */
    #define	MH_EXECUTE	0x2		/* demand paged executable file */
    #define	MH_FVMLIB	0x3		/* fixed VM shared library file */
    #define	MH_CORE		0x4		/* core file */
    #define	MH_PRELOAD	0x5		/* preloaded executable file */
    #define	MH_DYLIB	0x6		/* dynamically bound shared library */
    #define	MH_DYLINKER	0x7		/* dynamic link editor */
    #define	MH_BUNDLE	0x8		/* dynamically bound bundle file */
    #define	MH_DYLIB_STUB	0x9		/* shared library stub for static */
    					/*  linking only, no section contents */
    #define	MH_DSYM		0xa		/* companion file with only debug */
    					/*  sections */
    #define	MH_KEXT_BUNDLE	0xb		/* x86_64 kexts */
    
    • The MH_OBJECT file type is the format used for intermediate object files. It is a very compact format containing all its sections in one segment. The compiler and assembler usually create one MH_OBJECT file for each source code file. By convention, the file name extension for this format is .o.

      MH_OBJECT文件类型是用于中间对象文件的格式。它是一种非常紧凑的格式,将其所有部分都包含在一个段中。编译器和汇编程序通常为每个源代码文件创建一个MH_OBJECT文件。按照惯例,此格式的文件扩展名为.o。

    • The MH_EXECUTE file type is the format used by standard executable programs.

      MH_EXECUTE file type是标准可执行程序使用的格式。

    • The MH_BUNDLE file type is the type typically used by code that you load at runtime (typically called bundles or plug-ins). By convention, the file name extension for this format is .bundle.

      MH_BUNDLE文件类型是运行时加载的代码通常使用的类型(通常称为bundle或插件)。按照惯例,此格式的文件扩展名为.bundle。

    • The MH_DYLIB file type is for dynamic shared libraries. It contains some additional tables to support multiple modules. By convention, the file name extension for this format is .dylib, except for the main shared library of a framework, which does not usually have a file name extension.

      MH_DYLIB文件类型用于动态共享库。它包含一些额外的表来支持多个模块。按照惯例,此格式的文件扩展名为.dylib,但框架的主共享库除外,它通常没有文件扩展名。

    • The MH_PRELOAD file type is an executable format used for special-purpose programs that are not loaded by the Mac OS X kernel, such as programs burned into programmable ROM chips. Do not confuse this file type with the MH_PREBOUND flag, which is a flag that the static linker sets in the header structure to mark a prebound image.

      MH_PRELOAD文件类型是一种可执行格式,用于mac os x内核未加载的特殊用途程序,例如烧录到可编程ROM芯片中的程序。不要将此文件类型与MH_PREBOUND标志混淆,MH_PREBOUND标志是静态链接器在头结构中设置的用于标记预绑定图像的标志。

    • The MH_CORE file type is used to store core files, which are traditionally created when a program crashes. Core files store the entire address space of a process at the time it crashed. You can later run gdb on the core file to figure out why the crash occurred.

      MH_CORE文件类型用于存储核心文件,这些文件通常在程序崩溃时创建。核心文件存储进程崩溃时的整个地址空间。您可以稍后在核心文件上运行gdb来找出崩溃的原因。

    • The MH_DYLINKER file type is the type of a dynamic linker shared library. This is the type of the dyld file.

      MH_DYLINKER文件类型是动态链接器共享库的类型。这是dyld文件的类型。

    • The MH_DSYM file type designates files that store symbol information for a corresponding binary file.

      MH_DSYM文件类型指定存储相应二进制文件的符号信息的文件。

  • ncmds

    An integer indicating the number of load commands following the header structure.

    指定架构load commands的个数

  • sizeofcmds

    An integer indicating the number of bytes occupied by the load commands following the header structure. 所有load commands的size

  • flags

    An integer containing a set of bit flags that indicate the state of certain optional features of the Mach-O file format. These are the masks you can use to manipulate this field:

    一个整数,包含一组位标志,指示mach-o文件格式某些可选功能的状态。以下是可用于操作此字段的掩码:

    /* Constants for the flags field of the mach_header */
    #define	MH_NOUNDEFS	0x1		/* the object file has no undefined
    					   references */
    #define	MH_INCRLINK	0x2		/* the object file is the output of an
    					   incremental link against a base file
    					   and can't be link edited again */
    #define MH_DYLDLINK	0x4		/* the object file is input for the
    					   dynamic linker and can't be staticly
    					   link edited again */
    #define MH_BINDATLOAD	0x8		/* the object file's undefined
    					   references are bound by the dynamic
    					   linker when loaded. */
    #define MH_PREBOUND	0x10		/* the file has its dynamic undefined
    					   references prebound. */
    #define MH_SPLIT_SEGS	0x20		/* the file has its read-only and
    					   read-write segments split */
    #define MH_LAZY_INIT	0x40		/* the shared library init routine is
    					   to be run lazily via catching memory
    					   faults to its writeable segments
    					   (obsolete) */
    #define MH_TWOLEVEL	0x80		/* the image is using two-level name
    					   space bindings */
    #define MH_FORCE_FLAT	0x100		/* the executable is forcing all images
    					   to use flat name space bindings */
    #define MH_NOMULTIDEFS	0x200		/* this umbrella guarantees no multiple
    					   defintions of symbols in its
    					   sub-images so the two-level namespace
    					   hints can always be used. */
    #define MH_NOFIXPREBINDING 0x400	/* do not have dyld notify the
    					   prebinding agent about this
    					   executable */
    #define MH_PREBINDABLE  0x800           /* the binary is not prebound but can
    					   have its prebinding redone. only used
                                               when MH_PREBOUND is not set. */
    #define MH_ALLMODSBOUND 0x1000		/* indicates that this binary binds to
                                               all two-level namespace modules of
    					   its dependent libraries. only used
    					   when MH_PREBINDABLE and MH_TWOLEVEL
    					   are both set. */ 
    #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000/* safe to divide up the sections into
    					    sub-sections via symbols for dead
    					    code stripping */
    #define MH_CANONICAL    0x4000		/* the binary has been canonicalized
    					   via the unprebind operation */
    #define MH_WEAK_DEFINES	0x8000		/* the final linked image contains
    					   external weak symbols */
    #define MH_BINDS_TO_WEAK 0x10000	/* the final linked image uses
    					   weak symbols */
    
    #define MH_ALLOW_STACK_EXECUTION 0x20000/* When this bit is set, all stacks 
    					   in the task will be given stack
    					   execution privilege.  Only used in
    					   MH_EXECUTE filetypes. */
    #define MH_ROOT_SAFE 0x40000           /* When this bit is set, the binary 
    					  declares it is safe for use in
    					  processes with uid zero */
                                             
    #define MH_SETUID_SAFE 0x80000         /* When this bit is set, the binary 
    					  declares it is safe for use in
    					  processes when issetugid() is true */
    
    #define MH_NO_REEXPORTED_DYLIBS 0x100000 /* When this bit is set on a dylib, 
    					  the static linker does not need to
    					  examine dependent dylibs to see
    					  if any are re-exported */
    #define	MH_PIE 0x200000			/* When this bit is set, the OS will
    					   load the main executable at a
    					   random address.  Only used in
    					   MH_EXECUTE filetypes. */
    #define	MH_DEAD_STRIPPABLE_DYLIB 0x400000 /* Only for use on dylibs.  When
    					     linking against a dylib that
    					     has this bit set, the static linker
    					     will automatically not create a
    					     LC_LOAD_DYLIB load command to the
    					     dylib if no symbols are being
    					     referenced from the dylib. */
    #define MH_HAS_TLV_DESCRIPTORS 0x800000 /* Contains a section of type 
    					    S_THREAD_LOCAL_VARIABLES */
    
    #define MH_NO_HEAP_EXECUTION 0x1000000	/* When this bit is set, the OS will
    					   run the main executable with
    					   a non-executable heap even on
    					   platforms (e.g. i386) that don't
    					   require it. Only used in MH_EXECUTE
    					   filetypes. */
    
    #define MH_APP_EXTENSION_SAFE 0x02000000 /* The code was linked for use in an
    					    application extension. */
    
    #define	MH_NLIST_OUTOFSYNC_WITH_DYLDINFO 0x04000000 /* The external symbols
    					   listed in the nlist symbol table do
    					   not include all the symbols listed in
    					   the dyld info. */
    
    #define	MH_SIM_SUPPORT 0x08000000	/* Allow LC_MIN_VERSION_MACOS and
    					   LC_BUILD_VERSION load commands with
    					   the platforms macOS, macCatalyst,
    					   iOSSimulator, tvOSSimulator and
    					   watchOSSimulator. */
    					   
    #define MH_DYLIB_IN_CACHE 0x80000000	/* Only for use on dylibs. When this bit
    					   is set, the dylib is part of the dyld
    					   shared cache, rather than loose in
    					   the filesystem. */
    
    • MH_NOUNDEFS—The object file contained no undefined references when it was built.

      ​ 对象文件在生成时不包含未定义的引用

    • MH_INCRLINK The object file is the output of an incremental link against a base file and cannot be linked again

      对象文件是对基本文件的增量链接的输出,并且无法再次链接

    • MH_DYLDLINK

      • The file is input for the dynamic linker and cannot be statically linked again.

        该文件是动态链接器的输入,不能再次静态链接。

    • MH_TWOLEVEL

      • The image is using two-level namespace bindings

        Image正在使用两级命名空间绑定

    • MH_BINDATLOAD

      • The dynamic linker should bind the undefined references when the file

        is loaded.

        动态链接器应该在文件加载时绑定未定义的引用

    • MH_PREBOUND

      • The file’s undefined references are prebound.

        文件的未定义引用是预先绑定的。

    • MH_PREBINDABLE

      • This file is not prebound but can have its prebinding redone. Used only when MH_PREBEOUND is not set
      • 此文件不是预绑定的,但可以重新进行预绑定。仅在未设置MH_PREBEOUND时使用
    • MH_NOFIXPREBINDING

      • The dynamic linker doesn’t notify the prebinding agent about this executable.

        动态链接器不会将此可执行文件通知预绑定代理。

    • MH_ALLMODSBOUND

      • Indicates that this binary binds to all two-level namespace modules of its dependent libraries. Used only when MH_PREBINDABLE and MH_TWOLEVEL are set.
      • 指示此二进制文件绑定到其依赖库的所有两级命名空间模块。仅当设置了MH_PREBINDABLE和MH_TWOLEVEL时使用。
    • MH_CANONICAL

      • This file has been canonicalized by unprebinding—clearing prebinding information from the file. See the redo_prebinding man page for details
      • 此文件已通过取消绑定从文件中清除预绑定信息来规范化。有关详细信息,请参阅重做预绑定手册页
    • MH_SPLIT_SEGS

      • The file has its read-only and read-write segments split.
      • 文件的只读段和读写段被拆分。
    • MH_FORCE_FLAT

      • The executable is forcing all images to use flat namespace bindings.
      • 可执行文件正在强制所有映像使用平面命名空间绑定。
    • MH_SUBSECTIONS_VIA_SYMBOLS

      • The sections of the object file can be divided into individual blocks. These blocks are dead-stripped if they are not used by other code. See “Linking” in Xcode User Guide for details.
      • 对象文件的各个部分可以划分为单独的块。如果其他代码不使用这些块,则它们将被完全剥离。有关详细信息,请参阅Xcode用户指南中的“链接”。
    • MH_NOMULTIDEFS

      • This umbrella guarantees there are no multiple definitions of symbols in its subimages. As a result, the two-level namespace hints can always be used.
      • 这把伞保证了它的子图像中没有符号的多重定义。因此,始终可以使用两级命名空间提示。
    • MH_PIE

      • When this bit is set, the OS will load the main executable at a random address. Only used in MH_EXECUTE filetypes
      • 随机地址分布,ASLR 用于MH_EXECUTE filetype
  • Special Considerations

    For all file types, except MH_OBJECT, segments must be aligned on page boundaries for the given CPU architecture: 4096 bytes for PowerPC and x86 processors. This allows the kernel to page virtual memory directly from the segment into the address space of the process. The header and load commands must be aligned as part of the data of the first segment stored on disk (which would be the __TEXT segment, in the file types described in filetype).

    对于除MH_OBJECT以外的所有文件类型,对于给定的cpu体系结构,段必须在页面边界上对齐:对于powerpc和x86处理器,为4096字节。这允许内核将虚拟内存直接从段分页到进程的地址空间。headerload commands存储在磁盘上的第一个段的数据的一部分对齐(在filetype中描述的文件类型中,第一个段是__TEXT段)