clang -rewrite-objc main.m
將obj文件重寫爲 c, c++文件前端
clang -Xclang -ast-dump -fsyntax-only main.m
生成文件生成樹ios
clang -Xclang -dump-tokens main.m
這裏會把代碼切成一個個 Token,好比大小括號,等於號還有字符串等c++
根據一個簡單的例子來觀察是如何進行編譯的objective-c
#import <Foundation/Foundation.h>
#define DEFINEEight 8
int main(){
@autoreleasepool {
int eight = DEFINEEight;
int six = 6;
NSString* site = [[NSString alloc] initWithUTF8String:"starming"];
int rank = eight + six;
NSLog(@"%@ rank %d", site, rank);
}
return 0;
}
複製代碼
在命令行編譯shell
xcrun -sdk iphoneos clang -arch armv7 -F Foundation -fobjc-arc -c main.m -o main.o
xcrun -sdk iphoneos clang main.o -arch armv7 -fobjc-arc -framework Foundation -o main
# 這樣還無法看清clang的所有過程,能夠經過-E查看clang在預處理處理這步作了什麼。
clang -E main.m
# 執行完後能夠看到文件
# 1 "/System/Library/Frameworks/Foundation.framework/Headers/FoundationLegacySwiftCompatibility.h" 1 3
# 185 "/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h" 2 3
# 2 "main.m" 2
int main(){
@autoreleasepool {
int eight = 8;
int six = 6;
NSString* site = [[NSString alloc] initWithUTF8String:"starming"];
int rank = eight + six;
NSLog(@"%@ rank %d", site, rank);
}
return 0;
}
# 這個過程的處理包括宏的替換,頭文件的導入,以及相似#if的處理。預處理完成後就會進行詞法分析,這裏會把代碼切成一個個 Token,好比大小括號,等於號還有字符串等。
clang -fmodules -fsyntax-only -Xclang -dump-tokens main.m
# 而後是語法分析,驗證語法是否正確,而後將全部節點組成抽象語法樹 AST 。
clang -fmodules -fsyntax-only -Xclang -ast-dump main.m
# 完成這些步驟後就能夠開始IR中間代碼的生成了,CodeGen 會負責將語法樹自頂向下遍歷逐步翻譯成 LLVM IR,IR 是編譯過程的前端的輸出後端的輸入。
clang -S -fobjc-arc -emit-llvm main.m -o main.ll
# 這裏 LLVM 會去作些優化工做,在 Xcode 的編譯設置裏也能夠設置優化級別-01,-03,-0s,還能夠寫些本身的 Pass。
# Pass 是 LLVM 優化工做的一個節點,一個節點作些事,一塊兒加起來就構成了 LLVM 完整的優化和轉化。
# 若是開啓了 bitcode 蘋果會作進一步的優化,有新的後端架構仍是能夠用這份優化過的 bitcode 去生成。
clang -emit-llvm -c main.m -o main.bc
# 生成彙編
clang -S -fobjc-arc main.m -o main.s
# 生成目標文件
clang -fmodules -c main.m -o main.o
# 生成可執行文件,這樣就可以執行看到輸出結果
clang main.o -o main
# 執行
./main
# 輸出
starming rank 14
複製代碼
下面是完整步驟後端
在 Xcode 中查看 clang 編譯 .m 文件的過程xcode
使用編譯 Masonry 框架的 MASCompositeConstraint.m 爲例, 首先對任務進行描述bash
CompileC /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Objects-normal/x86_64/MASCompositeConstraint.o
Masonry/Masonry/MASCompositeConstraint.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
複製代碼
更新工做路徑,同時設置 PATHsession
cd /Users/lanya/Desktop/Neuer_iOS/Pods
export LANG=en_US.US-ASCII
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
複製代碼
接下來是實際的編譯命令架構
先介紹一下 clang 的命令參數,再看👇的編譯命令會更容易理解
clang 命令參數
-x 編譯語言好比objective-c
-arch 編譯的架構,好比arm7
-f 以-f開頭的。
-W 以-W開頭的,能夠經過這些定製編譯警告
-D 以-D開頭的,指的是預編譯宏,經過這些宏能夠實現條件編譯
-iPhoneSimulator11.1.sdk 編譯採用的iOS SDK版本
-I 把編譯信息寫入指定的輔助文件
-F 須要的Framework
-c 標識符指明須要運行預處理器,語法分析,類型檢查,LLVM生成優化以及彙編代碼生成.o文件
-o 編譯結果
複製代碼
具體的編譯過程
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x objective-c -arch x86_64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu11 -fobjc-arc -fmodules -gmodules -fmodules-cache-path=/Users/lanya/Library/Developer/Xcode/DerivedData/ModuleCache -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fbuild-session-file=/Users/lanya/Library/Developer/Xcode/DerivedData/ModuleCache/Session.modulevalidation -fmodules-validate-once-per-build-session -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module -fmodule-name=Masonry -fapplication-extension -Wno-trigraphs -fpascal-strings -O0 -fno-common -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation -Wunreachable-code -Wno-implicit-atomic-properties -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-arc-repeated-use-of-weak -Wduplicate-method-match -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wundeclared-selector -Wno-deprecated-implementations -DPOD_CONFIGURATION_DEBUG=1 -DDEBUG=1 -DCOCOAPODS=1 -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk -fasm-blocks -fstrict-aliasing -Wprotocol -Wdeprecated-declarations -mios-simulator-version-min=8.0 -g -Wno-sign-conversion -Winfinite-recursion -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wunguarded-availability -fobjc-abi-version=2 -fobjc-legacy-dispatch -index-store-path /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Index/DataStore -iquote /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Masonry-generated-files.hmap -I/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Masonry-own-target-headers.hmap -I/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Masonry-all-non-framework-target-headers.hmap -ivfsoverlay /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/all-product-headers.yaml -iquote /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Masonry-project-headers.hmap -I/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Products/Debug-iphonesimulator/Masonry/include -I/Users/lanya/Desktop/Neuer_iOS/Pods/Headers/Private -I/Users/lanya/Desktop/Neuer_iOS/Pods/Headers/Public -I/Users/lanya/Desktop/Neuer_iOS/Pods/Headers/Public/PgyUpdate -I/Users/lanya/Desktop/Neuer_iOS/Pods/Headers/Public/Pgyer -I/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/DerivedSources/x86_64 -I/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/DerivedSources -F/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Products/Debug-iphonesimulator/Masonry -include /Users/lanya/Desktop/Neuer_iOS/Pods/Target\ Support\ Files/Masonry/Masonry-prefix.pch -MMD -MT dependencies -MF /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Objects-normal/x86_64/MASCompositeConstraint.d --serialize-diagnostics /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Objects-normal/x86_64/MASCompositeConstraint.dia -c /Users/lanya/Desktop/Neuer_iOS/Pods/Masonry/Masonry/MASCompositeConstraint.m -o /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Objects-normal/x86_64/MASCompositeConstraint.o
複製代碼
編譯完第三方庫後會進行構建咱們程序的 target
Create product structure
Process product packaging
Run custom shell script 'Check Pods Manifest.lock'
Compile ... 各個項目中的.m文件
Link /Users/... 路徑
Copy ... 靜態文件
Compile asset catalogs
Compile Storyboard file ...
Process info.plist
Link Storyboards
Run custom shell script 'Embed Pods Frameworks'
Run custom shell script 'Copy Pods Resources'
...
Touch NEUer.app
Sign NEUer.app
複製代碼
Target 在 Build 過程的控制
Build Phases
Bulid Rules
Bulid Settings
pbxproj 工程文件
* build 過程控制的這些設置都會被保存在工程文件 .pbxproj 裏。在這個文件中能夠找 rootObject 的 ID 值
* 而後根據這個 ID 找到 main 工程的定義。
```objective-c
/* Begin PBXProject section */
2EC5E1AA1E7814B200BAB0EF /* Project object */ = {
isa = PBXProject;
......
/* End PBXProject section */
```
* 在 targets 裏會指向各個 taget 的定義
```objective-c
targets = (
2EC5E1B11E7814B200BAB0EF /* EWork */,
);
// 根據 2EC5E1B11E7814B200BAB0EF 能夠找到具體各個的定義
/**
這個裏面又有更多的 ID 能夠獲得更多的定義,其中 buildConfigurationList 指向了可用的配置項,包含 Debug 和 Release。能夠看到還有 buildPhases,buildRules 和 dependencies 都可以經過這裏索引找到更詳細的定義。
*/
/* Begin PBXNativeTarget section */
2EC5E1B11E7814B200BAB0EF /* EWork */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2EC5E1CC1E7814B200BAB0EF /* Build configuration list for PBXNativeTarget "EWork" */;
buildPhases = (
73F5AAE2AEC5EE766978C0E2 /* [CP] Check Pods Manifest.lock */,
2EC5E1AE1E7814B200BAB0EF /* Sources */,
2EC5E1AF1E7814B200BAB0EF /* Frameworks */,
2EC5E1B01E7814B200BAB0EF /* Resources */,
B42D03564A9A71BAD7183E61 /* [CP] Embed Pods Frameworks */,
4672989246AFA7B2776DFA56 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = EWork;
productName = EWork;
productReference = 2EC5E1B21E7814B200BAB0EF /* EWork.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
// 好比 XCConfigurationList
/* Begin XCConfigurationList section */
2EC5E1AD1E7814B200BAB0EF /* Build configuration list for PBXProject "EWork" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2EC5E1CA1E7814B200BAB0EF /* Debug */,
2EC5E1CB1E7814B200BAB0EF /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2EC5E1CC1E7814B200BAB0EF /* Build configuration list for PBXNativeTarget "EWork" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2EC5E1CD1E7814B200BAB0EF /* Debug */,
2EC5E1CE1E7814B200BAB0EF /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
```
複製代碼
編譯後生成的二進制內容 Link Map File
LinkMapFile
首先來講一說什麼是 LinkMap
爲何要使用 LinkMap
當一箇中大型iOS項目在不斷迭代更新的過程當中,代碼量日漸壯大,須要重構和review的代碼也愈來愈多,可一旦代碼達到必定程度後變得不是那麼可控,爲了使得項目還能夠持續可集成穩健的開發下去,縮小iOS安裝包大小是必需要作的事情,一般會從壓縮圖片和音頻文件開始,使用開發工具查找冗餘不用的資源文件,這一階段以後只能經過對代碼的重構來達到可執行文件總體瘦身的效果。當從事參與的一個項目在不斷迭代過程當中,App的安裝包在不斷變大,經過本身的shell腳本分析,多達幾十萬行,這時候很是有瘦身的必要,這其中包括了.h.m.mm.cpp.rss格式文件。觀察項目中引入的Pods文件及相關第三方庫,多達上百個庫,這時候這樣一箇中大型App就涉及到應用瘦身的問題,如何纔能有效解決代碼不可控的問題,如何能提升項目中底層基礎架構的穩定性及健壯性,相信LinkMap能給予咱們一些答案。
LinkMap 的構成
# Path: /Users/lanya/Library/Developer/Xcode/DerivedData/littleTest-fcueraakmygtmodagachcreqjbjw/Build/Products/Debug/littleTest
# Arch: x86_64
LinkMap服務的開啓方式及文件目錄
Xcode->Project->Build Settings-> Search map -> 設置 Write Link Map Files 選項爲YES
(這裏須要注意的是否是設置Pods.xcodeproj的LinkMap而是xxx-xxxxx.xcodeproj,其餘項目也要去設置主工程的對應編譯選項,以此類推~/Library/Developer/Xcode/DerivedData/xxx-xxx-fwtuexpkzxsfkjaootcqwizogrhf/Build/Intermediates/xx-xxx.build/Debug-iphonesimulator/xxx-xxx.build/xxx-xxx-LinkMap-normal-x86_64.txt
/Users/lanya/Library/Developer/Xcode/DerivedData/littleTest-fcueraakmygtmodagachcreqjbjw/Build/Intermediates.noindex/littleTest.build/Debug/littleTest.build/littleTest-LinkMap-normal-x86_64.txt
如今來講一說 LinkMap 各部分的做用
App的完整的目標文件列表(#Object files): 這個部分的內容都是 .m 文件編譯後的 .o 和須要 link 的 .a 文件。前面是文件編號,後面是文件路徑。
# Object files:
[ 0] linker synthesized
[ 1] /Users/lanya/Library/Developer/Xcode/DerivedData/littleTest-fcueraakmygtmodagachcreqjbjw/Build/Intermediates.noindex/littleTest.build/Debug/littleTest.build/Objects-normal/x86_64/main.o
[ 2] /Users/lanya/Library/Developer/Xcode/DerivedData/littleTest-fcueraakmygtmodagachcreqjbjw/Build/Intermediates.noindex/littleTest.build/Debug/littleTest.build/Objects-normal/x86_64/Test.o
[ 3] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks//Foundation.framework/Foundation.tbd
[ 4] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/lib/libobjc.tbd
複製代碼
App的段表(#Section):這裏描述的是每一個 Section 在可執行文件中的位置和大小。每一個 Section 的 Segment 的類型分爲 __TEXT 代碼段和 __DATA 數據段兩種。
# Sections:
# Address Size Segment Section
0x100000B10 0x000002D9 __TEXT __text
0x100000DEA 0x00000054 __TEXT __stubs
0x100000E40 0x0000009C __TEXT __stub_helper
0x100000EDC 0x0000006E __TEXT __objc_methname
0x100000F4A 0x0000003B __TEXT __cstring
0x100000F85 0x00000007 __TEXT __objc_classname
0x100000F8C 0x0000001D __TEXT __objc_methtype
0x100000FAC 0x00000048 __TEXT __unwind_info
0x100001000 0x00000010 __DATA __nl_symbol_ptr
0x100001010 0x00000070 __DATA __la_symbol_ptr
0x100001080 0x00000060 __DATA __cfstring
0x1000010E0 0x00000008 __DATA __objc_classlist
0x1000010E8 0x00000008 __DATA __objc_imageinfo
0x1000010F0 0x00000170 __DATA __objc_const
0x100001260 0x00000020 __DATA __objc_selrefs
0x100001280 0x00000008 __DATA __objc_classrefs
0x100001288 0x00000008 __DATA __objc_superrefs
0x100001290 0x00000010 __DATA __objc_ivar
0x1000012A0 0x00000050 __DATA __objc_data
複製代碼
App中具體目標文件在對應的section中的位置和大小(#Symbols):Symbols 是對 Sections 進行了再劃分。這裏會描述全部的 methods,ivar 和字符串,及它們對應的地址,大小,文件編號信息。
# Symbols:
# Address Size File Name
0x100000B10 0x00000106 [ 1] _main
0x100000C20 0x000000A0 [ 2] -[Test init]
0x100000CC0 0x00000060 [ 2] -[Test setObject:]
0x100000D20 0x00000040 [ 2] -[Test obj]
0x100000D60 0x00000040 [ 2] -[Test setObj:]
0x100000DA0 0x00000049 [ 2] -[Test .cxx_destruct]
0x100000DEA 0x00000006 [ 3] _NSHomeDirectory
0x100000DF0 0x00000006 [ 3] _NSLog
0x100000DF6 0x00000006 [ 4] _objc_autoreleasePoolPop
0x100000DFC 0x00000006 [ 4] _objc_autoreleasePoolPush
0x100000E02 0x00000006 [ 4] _objc_autoreleaseReturnValue
0x100000E08 0x00000006 [ 4] _objc_destroyWeak
0x100000E0E 0x00000006 [ 4] _objc_loadWeakRetained
0x100000E14 0x00000006 [ 4] _objc_msgSend
0x100000E1A 0x00000006 [ 4] _objc_msgSendSuper2
0x100000E20 0x00000006 [ 4] _objc_release
0x100000E26 0x00000006 [ 4] _objc_retain
0x100000E2C 0x00000006 [ 4] _objc_retainAutoreleasedReturnValue
0x100000E32 0x00000006 [ 4] _objc_storeStrong
0x100000E38 0x00000006 [ 4] _objc_storeWeak
0x100000E40 0x00000010 [ 0] helper helper
0x100000E50 0x0000000A [ 3] _NSHomeDirectory
0x100000E5A 0x0000000A [ 3] _NSLog
0x100000E64 0x0000000A [ 4] _objc_autoreleasePoolPop
0x100000E6E 0x0000000A [ 4] _objc_autoreleasePoolPush
0x100000E78 0x0000000A [ 4] _objc_autoreleaseReturnValue
0x100000E82 0x0000000A [ 4] _objc_destroyWeak
0x100000E8C 0x0000000A [ 4] _objc_loadWeakRetained
0x100000E96 0x0000000A [ 4] _objc_msgSend
0x100000EA0 0x0000000A [ 4] _objc_msgSendSuper2
0x100000EAA 0x0000000A [ 4] _objc_release
0x100000EB4 0x0000000A [ 4] _objc_retain
0x100000EBE 0x0000000A [ 4] _objc_retainAutoreleasedReturnValue
0x100000EC8 0x0000000A [ 4] _objc_storeStrong
0x100000ED2 0x0000000A [ 4] _objc_storeWeak
0x100000EDC 0x00000006 [ 1] literal string: alloc
0x100000EE2 0x00000014 [ 1] literal string: initWithUTF8String:
0x100000EF6 0x00000020 [ 1] literal string: stringByAppendingPathComponent:
0x100000F16 0x00000005 [ 2] literal string: init
0x100000F1B 0x0000000B [ 2] literal string: setObject:
0x100000F26 0x0000000E [ 2] literal string: .cxx_destruct
0x100000F34 0x00000004 [ 2] literal string: obj
0x100000F38 0x00000008 [ 2] literal string: setObj:
0x100000F40 0x00000005 [ 2] literal string: obj_
0x100000F45 0x00000005 [ 2] literal string: _obj
0x100000F4A 0x00000009 [ 1] literal string: starming
0x100000F53 0x0000000B [ 1] literal string: %@ rank %d
0x100000F5E 0x00000013 [ 1] literal string: Documents/neuer.db
0x100000F71 0x00000003 [ 1] literal string: %@
0x100000F74 0x00000004 [ 2] literal string: obj
0x100000F78 0x0000000D [ 2] literal string: T@,W,N,V_obj
0x100000F85 0x00000005 [ 2] literal string: Test
0x100000F8A 0x00000002 [ 2] literal string:
0x100000F8C 0x00000008 [ 2] literal string: @16@0:8
0x100000F94 0x0000000B [ 2] literal string: v24@0:8@16
0x100000F9F 0x00000008 [ 2] literal string: v16@0:8
0x100000FA7 0x00000002 [ 2] literal string: @
0x100000FAC 0x00000048 [ 0] compact unwind info
0x100001000 0x00000008 [ 0] non-lazy-pointer-to-local: dyld_stub_binder
0x100001008 0x00000008 [ 0] non-lazy-pointer
0x100001010 0x00000008 [ 3] _NSHomeDirectory
0x100001018 0x00000008 [ 3] _NSLog
0x100001020 0x00000008 [ 4] _objc_autoreleasePoolPop
0x100001028 0x00000008 [ 4] _objc_autoreleasePoolPush
0x100001030 0x00000008 [ 4] _objc_autoreleaseReturnValue
0x100001038 0x00000008 [ 4] _objc_destroyWeak
0x100001040 0x00000008 [ 4] _objc_loadWeakRetained
0x100001048 0x00000008 [ 4] _objc_msgSend
0x100001050 0x00000008 [ 4] _objc_msgSendSuper2
0x100001058 0x00000008 [ 4] _objc_release
0x100001060 0x00000008 [ 4] _objc_retain
0x100001068 0x00000008 [ 4] _objc_retainAutoreleasedReturnValue
0x100001070 0x00000008 [ 4] _objc_storeStrong
0x100001078 0x00000008 [ 4] _objc_storeWeak
0x100001080 0x00000020 [ 1] CFString
0x1000010A0 0x00000020 [ 1] CFString
0x1000010C0 0x00000020 [ 1] CFString
0x1000010E0 0x00000008 [ 2] anon
0x1000010E8 0x00000008 [ 0] objc image info
0x1000010F0 0x00000048 [ 2] l_OBJC_METACLASS_RO_$_Test
0x100001138 0x00000080 [ 2] l_OBJC_$_INSTANCE_METHODS_Test
0x1000011B8 0x00000048 [ 2] l_OBJC_$_INSTANCE_VARIABLES_Test
0x100001200 0x00000018 [ 2] l_OBJC_$_PROP_LIST_Test
0x100001218 0x00000048 [ 2] l_OBJC_CLASS_RO_$_Test
0x100001260 0x00000008 [ 1] pointer-to-literal-cstring
0x100001268 0x00000008 [ 1] pointer-to-literal-cstring
0x100001270 0x00000008 [ 1] pointer-to-literal-cstring
0x100001278 0x00000008 [ 2] pointer-to-literal-cstring
0x100001280 0x00000008 [ 1] objc-class-ref
0x100001288 0x00000008 [ 2] anon
0x100001290 0x00000008 [ 2] _OBJC_IVAR_$_Test.obj_
0x100001298 0x00000008 [ 2] _OBJC_IVAR_$_Test._obj
0x1000012A0 0x00000028 [ 2] _OBJC_CLASS_$_Test
0x1000012C8 0x00000028 [ 2] _OBJC_METACLASS_$_Test
複製代碼
dSYM
/Users/用戶名/Library/Developer/Xcode/DerivedData/littleTest-fcueraakmygtmodagachcreqjbjw/Build/Products/Release
find /Applications/Xcode.app -name symbolicatecrash -type f
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
Mach-O 文件
含義:Mach-O,是Mach object文件格式的縮寫,是一種可執行文件、目標代碼、共享程序庫、動態加載代碼和核心DUMP。是a.out格式的一種替代。Mach-O 提供更多的可擴展性和更快的符號表信息存取。Mach-O應用在基於Mach核心的系統上,目前NeXTSTEP、Darwin、Mac OS X(iPhone)都是使用這種可執行文件格式。
記錄編譯後的可執行文件,對象代碼,共享庫,動態加載代碼和內存轉儲的文件格式。不一樣於 xml 這樣的文件,它只是二進制字節流,裏面有不一樣的包含元信息的數據塊,好比字節順序,cpu 類型,塊大小等。文件內容是不能夠修改的,由於在 .app 目錄中有個 _CodeSignature 的目錄,裏面包含了程序代碼的簽名,這個簽名的做用就是保證簽名後 .app 裏的文件,包括資源文件,Mach-O 文件都不可以更改。
Mach-O 的內容:
先看看描述這個文件的結構體
struct mach_header {
uint32_t magic;
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
uint32_t filetype;
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
};
struct segment_command {
uint32_t cmd;
uint32_t cmdsize;
char segname[16];
uint32_t vmaddr;
uint32_t vmsize;
uint32_t fileoff;
uint32_t filesize;
vm_prot_t maxprot;
vm_prot_t initprot;
uint32_t nsects;
uint32_t flags;
};
複製代碼
Mach-O 文件參考文章
dyld動態連接
參考文章: 深刻剖析iOS編譯