@@ -11,11 +11,11 @@ tags:
1111
1212## 进程
1313
14- App 的本质是一个可执行程序,是一段计算机代码和数据的集合。从操作系统的角度来看,App 的本质是一个进程 。进程是计算机中正在运行的程序的实例。在操作系统中,进程是操作系统分配资源和调度执行的基本单位。每个进程都有自己的内存空间、寄存器集合、文件句柄、网络连接等资源,它们可以独立地运行和被管理。
14+ App 的本质是一个可执行程序,是一段计算机代码和数据的集合。从操作系统的角度来看,App 的本质是一个 ** 进程 ** 。进程是计算机中正在运行的程序的实例。在操作系统中,进程是操作系统分配资源和调度执行的基本单位。每个进程都有自己的内存空间、寄存器集合、文件句柄、网络连接等资源,它们可以独立地运行和被管理。
1515
16- 进程是操作系统中最基本的资源分配和调度单位。操作系统通过进程控制块( Process Control Block,PCB) 来管理进程,PCB 包含了进程的状态、进程 ID、进程优先级、内存使用情况、文件句柄等信息。当操作系统需要切换到另一个进程时,它会保存当前进程的上下文,然后加载另一个进程的上下文,从而实现进程之间的切换。
16+ 进程是操作系统中最基本的资源分配和调度单位。操作系统通过进程控制块 ` PCB( Process Control Block) ` 来管理进程,` PCB ` 包含了进程的状态、进程 ID、进程优先级、内存使用情况、文件句柄等信息。当操作系统需要切换到另一个进程时,它会保存当前进程的上下文,然后加载另一个进程的上下文,从而实现进程之间的切换。
1717
18- 在 macOS 中,PCB 被称为 proc。[ proc 结构体] ( https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/proc_internal.h.auto.html ) 是 macOS 内核中非常重要的数据结构,用于描述进程在内核中的状态和信息。
18+ 在 ` macOS ` 中,` PCB ` 被称为 ` proc ` 。[ proc 结构体] ( https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/proc_internal.h.auto.html ) 是 ` macOS ` 内核中非常重要的数据结构,用于描述进程在内核中的状态和信息。
1919``` c
2020struct proc {
2121 LIST_ENTRY (proc) p_list; /* List of all processes. * /
@@ -43,25 +43,25 @@ struct proc {
4343 /* 以下其他字段已省略 */
4444};
4545```
46- proc 包含了大量的字段和指针,用于描述进程的各种属性和资源使用情况,例如进程状态(p_stat)、进程 ID(p_pid)、进程名称(p_comm)、进程优先级(p_priority)、进程内存使用情况(p_vmspace)、文件描述符表(p_fd)、线程列表(p_threadlist)等。
46+ ` proc ` 包含了大量的字段和指针,用于描述进程的各种属性和资源使用情况,例如进程状态(` p_stat ` )、进程 ID(` p_pid ` )、进程名称(` p_comm ` )、进程优先级(` p_priority ` )、进程内存使用情况(` p_vmspace ` )、文件描述符表(` p_fd ` )、线程列表(` p_threadlist ` )等。
4747
4848## Mach-O 文件
4949
50- 在 App 加载到内存成为进程之前,macOS 上的可执行文件是 Mach-O 文件。Mach-O 文件包含了可执行代码、数据、符号表、动态链接信息等多个部分,是 macOS 中应用程序和库文件的基本格式。
50+ 在 App 加载到内存成为进程之前,macOS 上的可执行文件是 ` Mach-O ` 文件。` Mach-O ` 文件包含了可执行代码、数据、符号表、动态链接信息等多个部分,是 ` macOS ` 中应用程序和库文件的基本格式。
5151
52- Mach-O 文件的格式可以分为文件头(Header)、加载命令(Load commands)和数据区(Raw segment data)三个部分。
52+ ` Mach-O ` 文件的格式可以分为文件头(` Header ` )、加载命令(` Load commands ` )和数据区(` Raw segment data ` )三个部分。
5353
5454![ Mach-O] ( /assets/img/post/post-2023-06-01/mach_o.png ) {: width="972" height="589" .w-50 .normal}
5555_ Mach-O file_
5656
57- 包含多个 CPU 架构的 Mach-O 文件被称为 Fat Binary。可以通过 file 命令查看 Mach-O 文件的 CPU 架构。
57+ 包含多个 CPU 架构的 ` Mach-O ` 文件被称为 ` Fat Binary ` 。可以通过 ` file ` 命令查看 ` Mach-O ` 文件的 CPU 架构。
5858``` bash
5959$ file /System/Applications/Calculator.app/Contents/MacOS/Calculator
6060/System/Applications/Calculator.app/Contents/MacOS/Calculator: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
6161/System/Applications/Calculator.app/Contents/MacOS/Calculator (for architecture x86_64): Mach-O 64-bit executable x86_64
6262/System/Applications/Calculator.app/Contents/MacOS/Calculator (for architecture arm64e): Mach-O 64-bit executable arm64e
6363```
64- Fat Binary 对应的 fat_header 在操作系统中的数据结构定义是 [ fat_header] ( https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/fat.h.auto.html ) 。
64+ ` Fat Binary ` 对应的 ` fat_header ` 在操作系统中的数据结构定义是 [ ** fat_header** ] ( https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/fat.h.auto.html ) 。
6565
6666``` c
6767struct fat_header {
@@ -78,15 +78,15 @@ struct fat_arch {
7878};
7979```
8080
81- 可以看到,macOS 系统的计算器程序 Mach-O 文件,是包含了 x86_64 和 arm64e 两种 CPU 架构的 Fat Binary。
82- > iOS 系统自 iOS 11.0 版本以后,不再支持 armv7, armv7s 等架构,只支持 arm64 架构。所以仅支持 iOS 11.0 以后版本的项目,打包产物的 Fat Binary 只有 arm64 架构的 Mach-O 文件。这也是 Xcode 14.0 取消了 bitcode 的原因,因为不再需要编译成 bitcode 中间产物,且 bitcode 转译会消耗 AppStore 的服务器资源
81+ 可以看到,macOS 系统的计算器程序 ` Mach-O ` 文件,是包含了 ` x86_64 ` 和 ` arm64e ` 两种 CPU 架构的 ` Fat Binary ` 。
82+ > iOS 系统自 iOS 11.0 版本以后,不再支持 ` armv7 ` , ` armv7s ` 等架构,只支持 ` arm64 ` 架构。所以仅支持 ` iOS 11.0 ` 以后版本的项目,打包产物的 ` Fat Binary ` 只有 ` arm64 ` 架构的 ` Mach-O ` 文件。这也是 ` Xcode 14.0 ` 取消了 ` bitcode ` 的原因,因为不再需要编译成 ` bitcode ` 中间产物,且 ` bitcode ` 转译会消耗 AppStore 的服务器资源
8383 {: .prompt-tip }
8484
8585### 文件头(haeder)
8686
87- Mach-O 文件头包含了文件类型、CPU 类型、加载命令数量等信息。Mach-O 文件支持多种文件类型,包括可执行文件、动态链接库、框架等。CPU 类型指定了可执行文件适用的 CPU 架构,例如 x86、 x86_64、 armv7、 arm64 等。加载命令数量指定了文件中包含的加载命令数量。
87+ ` Mach-O ` 文件头包含了文件类型、CPU 类型、加载命令数量等信息。` Mach-O ` 文件支持多种文件类型,包括可执行文件、动态链接库、框架等。CPU 类型指定了可执行文件适用的 CPU 架构,例如 ` x86 ` 、 ` x86_64 ` 、 ` armv7 ` 、 ` arm64 ` 等。加载命令数量指定了文件中包含的加载命令数量。
8888
89- ` otool ` 命令是 macOS 和 iOS 等操作系统上的一个工具,用于查看可执行文件、动态库和框架等二进制文件的信息。它可以用来查看二进制文件的头部信息、节表、符号表、动态链接信息等。
89+ ` otool ` 命令是 ` macOS ` 和 ` iOS ` 等操作系统上的一个工具,用于查看可执行文件、动态库和框架等二进制文件的信息。它可以用来查看二进制文件的头部信息、节表、符号表、动态链接信息等。
9090
9191``` bash
9292$ otool -h /System/Applications/Calculator.app/Contents/MacOS/Calculator
@@ -96,15 +96,15 @@ Mach header
9696 0xfeedfacf 16777228 2 0x80 2 29 4208 0x00200085
9797```
9898
99- 除了 ` otools ` 命令,还可以使用 MachOView 工具通过图形化页面来查看 Mach-O 文件
99+ 除了 ` otools ` 命令,还可以使用 ` MachOView ` 工具通过图形化页面来查看 ` Mach-O ` 文件
100100``` bash
101101brew install machoview
102102```
103103![ MachOView] ( /assets/img/post/post-2023-06-01/machoview.png ) {: width="972" height="589" .w-100 .normal}
104104_ MachOView_
105105
106106
107- Fat Binary 中,每个架构都有一个 header 文件头,被称为 [ mach_header] ( https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/loader.h.auto.html ) 。64 位架构的 mach_header 会多一个保留字段。
107+ ` Fat Binary ` 中,每个架构都有一个 ` header ` 文件头,被称为 [ ** mach_header** ] ( https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/loader.h.auto.html ) 。64 位架构的 ` mach_header ` 会多一个保留字段。
108108``` c
109109/*
110110 * The 32-bit mach header appears at the very beginning of the object file for
@@ -142,11 +142,11 @@ struct mach_header_64 {
142142```
143143## 加载命令(Load commands)
144144
145- Mach-O 文件中的加载命令(Load Command)用于描述可执行文件的各个段的属性和位置等信息,操作系统会根据这些信息将可执行文件加载到内存中。每个 Load Command 描述了一个特定的段或区域。常见的 Load Command 包括:
146- - LC_SEGMENT 和 LC_SEGMENT_64:描述可执行代码和数据的段信息;
147- - LC_SYMTAB 和 LC_DYSYMTAB:描述符号表和动态符号表信息;
148- - LC_LOAD_DYLIB 和 LC_LOAD_WEAK_DYLIB:描述动态链接库的信息;
149- - LC_MAIN:描述程序入口点的信息。
145+ ` Mach-O` 文件中的加载命令(` Load Command` )用于描述可执行文件的各个段的属性和位置等信息,操作系统会根据这些信息将可执行文件加载到内存中。每个 ` Load Command` 描述了一个特定的段或区域。常见的 ` Load Command` 包括:
146+ - ` LC_SEGMENT` 和 ` LC_SEGMENT_64` :描述可执行代码和数据的段信息;
147+ - ` LC_SYMTAB` 和 ` LC_DYSYMTAB` :描述符号表和动态符号表信息;
148+ - ` LC_LOAD_DYLIB` 和 ` LC_LOAD_WEAK_DYLIB` :描述动态链接库的信息;
149+ - ` LC_MAIN` :描述程序入口点的信息。
150150
151151[load_command](https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/loader.h.auto.html)
152152
@@ -159,7 +159,7 @@ struct load_command {
159159
160160## 数据区(Raw segment data)
161161
162- Mach-O 文件的数据区包含了多个段(Segment),每个段包含了不同类型的数据。常见的段包括 __TEXT、 __DATA、 __LINKEDIT 等。其中,__TEXT 段包含了代码和只读数据,__DATA 段包含了全局变量和静态变量等数据,__LINKEDIT 段包含了符号表和重定位信息等。
162+ ` Mach-O` 文件的数据区包含了多个段(` Segment` ),每个段包含了不同类型的数据。常见的段包括 ` __TEXT`、` __DATA`、` __LINKEDIT` 等。其中,` __TEXT` 段包含了代码和只读数据,` __DATA` 段包含了全局变量和静态变量等数据,` __LINKEDIT` 段包含了符号表和重定位信息等。
163163
164164[segment](https:// opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/loader.h.auto.html)
165165```c
@@ -178,9 +178,9 @@ struct segment_command_64 { /* for 64-bit architectures */
178178};
179179```
180180
181- 在 Mach-O 文件中,每个 Segment 包含一个或多个 section,每个 section 包含了一组相关的数据或代码。例如,在一个可执行文件中,常见的 Segment 包括 __ TEXT、__ DATA、 __ LINKEDIT 等,每个 Segment 包含了多个 section,例如 __ TEXT 包含了 __ text、 __ cstring、 __ stub 等多个 section。
181+ 在 ` Mach-O ` 文件中,每个 ` Segment ` 包含一个或多个 ` section ` ,每个 ` section ` 包含了一组相关的数据或代码。例如,在一个可执行文件中,常见的 ` Segment ` 包括 __ TEXT、` __DATA ` 、 ` __LINKEDIT ` 等,每个 ` Segment ` 包含了多个 ` section ` ,例如 ` __TEXT ` 包含了 ` __text ` 、 ` __cstring ` 、 ` __stub ` 等多个 ` section ` 。
182182
183- Section 是 Mach-O 文件中的一个子单元,它是 Segment 中的一个子段,包含了一组相关的数据或代码。每个 Section 都有一个名称和一个类型,例如 __ text、 __ data、 __ cstring 等。在 Mach-O 文件中,Section 的名称和类型通常与编译器和链接器相关,不同的编译器和链接器可能会使用不同的名称和类型。
183+ ` Section ` 是 ` Mach-O ` 文件中的一个子单元,它是 ` Segment ` 中的一个子段,包含了一组相关的数据或代码。每个 ` Section ` 都有一个名称和一个类型,例如 ` __text ` 、 ` __data ` 、 ` __cstring ` 等。在 ` Mach-O ` 文件中,` Section ` 的名称和类型通常与编译器和链接器相关,不同的编译器和链接器可能会使用不同的名称和类型。
184184
185185``` c
186186struct section_64 { /* for 64-bit architectures * /
0 commit comments