咱們在前面學習了,編譯最終會生成mach-o文件,那麼mach-o結構是怎麼的呢?linux
Mach-O實際上是Mach Object文件格式的縮寫,是mac以及iOS上可執行文件的格式, 相似於windows上的PE格式 (Portable Executable ), linux上的elf格式 (Executable and Linking Format)小程序
記錄編譯後的可執行文件,對象代碼,共享庫,動態加載代碼和內存轉儲的文件格式。不一樣於 xml 這樣的文件,它只是二進制字節流,裏面有不一樣的包含元信息的數據塊,好比字節順序,cpu 類型,塊大小等。文件內容是不能夠修改的,由於在 .app 目錄中有個 _CodeSignature 的目錄,裏面包含了程序代碼的簽名,這個簽名的做用就是保證簽名後 .app 裏的文件,包括資源文件,Mach-O 文件都不可以更改。windows
咱們打開machOView bash
在系統源碼中也能夠看到結構體Load commands是一張包含不少內容的表。 內容包括區域的位置、符號表、動態符號表等。 微信
上圖Load Commons中的大部分字段在下表中能夠找到相關的含義符號 | 含義 |
---|---|
LC_SEGMENT_64 | 將文件中(32位或64位)的段映射到進程地址空間中 |
LC_DYLD_INFO_ONLY | 動態連接相關信息 |
LC_SYMTAB | 符號地址 |
LC_DYSYMTAB | 動態符號表地址 |
LC_LOAD_DYLINKER | 使用誰加載,咱們使用dyld |
LC_UUID | 文件的UUID |
LC_VERSION_MIN_MACOSX | 支持最低的操做系統版本 |
LC_SOURCE_VERSION | 源代碼版本 |
LC_MAIN | 設置程序主線程的入口地址和棧大小 |
LC_LOAD_DYLIB | 依賴庫的路徑,包含三方庫 |
LC_FUNCTION_STARTS | 函數起始地址表 |
LC_CODE_SIGNATURE | 代碼簽名 |
其中LC_LOAD_DYLINKER和LC_LOAD_DYLIBapp
Data 一般是對象文件中最大的部分,包含Segement的具體數據,如靜態C字符串,帶參數/不帶參數的OC方法,帶參數/不帶參數的C函數。函數
使用命令xcrun size -x -l -m main查看segment中的內容學習
顯示爲測試
Mac-mini-2:測試mac jxq$ xcrun size -x -l -m main
Segment __PAGEZERO: 0x100000000 (vmaddr 0x0 fileoff 0)
Segment __TEXT: 0x1000 (vmaddr 0x100000000 fileoff 0)
Section __text: 0x52 (addr 0x100000ef0 offset 3824)
Section __stubs: 0x18 (addr 0x100000f42 offset 3906)
Section __stub_helper: 0x38 (addr 0x100000f5c offset 3932)
Section __cstring: 0x1b (addr 0x100000f94 offset 3988)
Section __unwind_info: 0x48 (addr 0x100000fb0 offset 4016)
total 0x105
Segment __DATA: 0x1000 (vmaddr 0x100001000 fileoff 4096)
Section __nl_symbol_ptr: 0x8 (addr 0x100001000 offset 4096)
Section __got: 0x8 (addr 0x100001008 offset 4104)
Section __la_symbol_ptr: 0x20 (addr 0x100001010 offset 4112)
Section __cfstring: 0x20 (addr 0x100001030 offset 4144)
Section __objc_imageinfo: 0x8 (addr 0x100001050 offset 4176)
total 0x58
Segment __LINKEDIT: 0x1000 (vmaddr 0x100002000 fileoff 8192)
total 0x100003000
複製代碼
這裏咱們大概瞭解了mach-o文件的內容,那麼mach-o是如何執行的呢? 咱們將在下一篇文章,動態連接學習。spa