Mach-O文件結(jié)構(gòu)

image.png
-
Header部分:描述文件基本信息(如CPU、架構(gòu)、文件類型、加載命令個數(shù))
-
loadCommands部分:描述各個Data部分的內(nèi)存分布,對系統(tǒng)內(nèi)核加載器和動態(tài)連接器起指導(dǎo)作用
-
Data部分:存放代碼與數(shù)據(jù)
- __PAGEZERO段:空指針陷阱段,映射到虛擬內(nèi)存空間的第一頁,用于捕捉對NULL指針的引用
- __TEXT 段: 包含了執(zhí)行代碼以及其他只讀數(shù)據(jù)的,當(dāng)這個段被映射到內(nèi)存后,可以被所有進(jìn)程共享。(這主要用在frameworks, bundles和共享庫等程序中,也可以為同一個可執(zhí)行文件的多個進(jìn)程拷貝使用)
section 描述 __text 代碼實(shí)現(xiàn) __stubs 符號樁,本質(zhì)上就是段會直接跳入到lazybinding的表的對應(yīng)項(xiàng)指針指向的地址的代碼 __stubs_helper 輔助函數(shù),上述lazybinding表中沒有找到符號地址都指向這 __cstring C string字符串常量 __ustring Unicode string中文常量 __objc_methname OC方法名稱 __objc_classname OC類名 __objc_methtype OC方法類型 __entitlements 簽名證書 __unwid_info 用于存儲異常情況信息 __const 初始化的常量 - __DATA段: 包含了程序數(shù)據(jù),該段可寫;
section 描述 __const 未始化的常量 __bss 沒有初始化和初始化為0 的全局變量 __nl_symbol_prt / __got 非lazy-binding的指針表 __la_symbol_prt lazy-binding的指針表,每個表項(xiàng)中的指針一開始指向stub_helper __cfstring CoreFoundation string __objc_classlist OC類列表 __objc_catlist OC分類列表 __objc_protollist OC協(xié)議列表 __objc_imageinfo OC鏡像信息 __objc_const OC類信息、方法列表、屬性列表、變量列表 __objc_selfrefs OC類實(shí)例自引用(self) __objc_classfrefs OC類類自引用 __objc_superrefs OC類超類引用(super) __objc_ivar OC屬性 __objc_data OC類ISA - __LINKEDIT段: 含有為動態(tài)鏈接庫使用的原始數(shù)據(jù),比如符號,字符串,重定位表?xiàng)l目等等。
App啟動流程

- 將Mach-O中Segment與符號表等數(shù)據(jù)映射到內(nèi)存中
- 調(diào)用dyld(the dynamic link editor)程序,動態(tài)鏈接器
- 加載UUID與構(gòu)建二進(jìn)制是的的源碼版本等信息
- 設(shè)置程序主線程的
main函數(shù)入口地址和棧大小 - 設(shè)置依賴的動態(tài)庫
- 加載代碼開始地址、代碼段內(nèi)的非指令的表、代碼簽名
- 系統(tǒng)kernel做好啟動程序的初始準(zhǔn)備后,動態(tài)鏈接依賴庫,并由runtime負(fù)責(zé)加載成objc定義的結(jié)構(gòu),所有初始化工作結(jié)束后,dyld調(diào)用真正的main函數(shù)
從kernel留下的原始調(diào)用棧引導(dǎo)和啟動自己
-
將程序依賴的動態(tài)鏈接庫遞歸加載進(jìn)內(nèi)存,系統(tǒng)有緩存機(jī)制
- 交由imageLoader讀取image,其中包含了我們的類,方法等各種符號
- 由于runtime向dyld綁定了回調(diào),當(dāng)image加載到內(nèi)存后,dyld會通知runtime進(jìn)行處理
- runtime接手后調(diào)用map_images做解析和處理,接下來load_images中調(diào)用call_load_methods方法,遍歷所有加載進(jìn)來的Class,按繼承層級依次調(diào)用Class的+load方法和Category的+load方法
non-lazy符號立即link到可執(zhí)行文件,lazy的存表里
找到可執(zhí)行文件的main函數(shù),準(zhǔn)備參數(shù)并調(diào)用
程序執(zhí)行中負(fù)責(zé)綁定lazy符號、提供runtime dynamic loading services、提供調(diào)試器接口。
程序main函數(shù)return后執(zhí)行static terminator
某些場景下main函數(shù)結(jié)束后調(diào)libSystem的_exit函數(shù)。

