對Link Map File的初步認識

什么是Link Map File

Link Map File中文直譯為鏈接映射文件,它是在Xcode生成可執(zhí)行文件的同時生成的鏈接信息文件,用于描述可執(zhí)行文件的構(gòu)造部分,包括了代碼段和數(shù)據(jù)段的分布情況。Xcode在生成可執(zhí)行文件的時候默認情況下不生成該文件,需要開發(fā)者手動設(shè)置Target --> Build Setting --> Write Link Map File為YES:


Link Map Setting

這里還可以設(shè)置Link Map存放的位置,默認的位置為:

$(TARGET_TEMP_DIR)/$(PRODUCT_NAME)-LinkMap-$(CURRENT_VARIANT)-$(CURRENT_ARCH).txt

例如:

/Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/LinkMapTest-LinkMap-normal-x86_64.txt

開發(fā)者也可以根據(jù)自己的需要自行設(shè)置該文件的位置。

Link Map File的組成

打開Link Map File,里面包含了以下幾個部分:

1. Path

# Path: /Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Products/Debug-iphonesimulator/LinkMapTest.app/LinkMapTest

Path是生成可執(zhí)行文件的路徑。

2. Arch

# Arch: x86_64

Arch指代架構(gòu)類型。

3. Object files:

# Object files:
[ 0] linker synthesized
[ 1] /Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/LinkMapTest.app-Simulated.xcent
[ 2] /Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/Objects-normal/x86_64/ViewController.o
[ 3] /Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/Objects-normal/x86_64/main.o
[ 4] /Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/Objects-normal/x86_64/AppDelegate.o
[ 5] /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.1.sdk/System/Library/Frameworks//Foundation.framework/Foundation.tbd
[6]/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.1.sdk/usr/lib/libobjc.tbd
[7]/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.1.sdk/System/Library/Frameworks//UIKit.framework/UIKit.tbd

Object Files列舉了可執(zhí)行文件里所有的obj以及tbd。每一行代表對文件的編號。例如ViewController.o文件,其編號為2。編號的具體作用稍后介紹。

4. Sections

# Sections:
# Address   Size        Segment Section
0x100001730 0x00000333  __TEXT  __text
0x100001A64 0x0000002A  __TEXT  __stubs
0x100001A90 0x00000056  __TEXT  __stub_helper
0x100001AE6 0x00000A27  __TEXT  __objc_methname
0x10000250D 0x0000003C  __TEXT  __objc_classname
0x100002549 0x0000086D  __TEXT  __objc_methtype
0x100002DB6 0x0000007A  __TEXT  __cstring
0x100002E30 0x00000182  __TEXT  __entitlements
0x100002FB4 0x00000048  __TEXT  __unwind_info
0x100003000 0x00000010  __DATA  __nl_symbol_ptr
0x100003010 0x00000010  __DATA  __got
0x100003020 0x00000038  __DATA  __la_symbol_ptr
0x100003058 0x00000010  __DATA  __objc_classlist
0x100003068 0x00000010  __DATA  __objc_protolist
0x100003078 0x00000008  __DATA  __objc_imageinfo
0x100003080 0x00000BE8  __DATA  __objc_const
0x100003C68 0x00000010  __DATA  __objc_selrefs
0x100003C78 0x00000008  __DATA  __objc_classrefs
0x100003C80 0x00000008  __DATA  __objc_superrefs
0x100003C88 0x00000008  __DATA  __objc_ivar
0x100003C90 0x000000A0  __DATA  __objc_data
0x100003D30 0x000000C0  __DATA  __data

單從字面含義理解:每個Section包含了Address、Size、Segment以及Section。介紹之前,這里先簡單介紹一下Mach-O文件。
上面第一部分的Path是可執(zhí)行文件的路徑,使用iTerm進去到該文件夾,然后使用file命令即可查看該文件的類型:

file LinkMapTest

輸出結(jié)果為:

LinkMapTest: Mach-O 64-bit executable x86_64

可以知道該文件是一個Mach-O格式的文件,它是iOS系統(tǒng)應(yīng)用執(zhí)行文件格式。Mach-O文件中的虛擬地址最終會被映射到物理地址上,這些地址會被分為不同的段類型:_ _ TEXT 、_ _ DATA以及_ _ LINKEDIT等。各個段的含義如下:

  1. _ _ TEXT包含了被執(zhí)行的代碼。這些代碼是只讀、可執(zhí)行
  2. _ _ DATA包含了包含了將會被更改的數(shù)據(jù),例如全局變量、靜態(tài)變量等,可讀寫,但是不可執(zhí)行
  3. _ _ LINKEDIT 包含了加載程序的元數(shù)據(jù),比如函數(shù)名稱和地址,只讀。

Segment又被劃分成了不同的Section,不同的Section存儲了不同的信息,例如 _ _ objc _ methname 為方法的名稱。
再回顧上面的Sections,Address是起始位置、Size是大小、Segment是段、Section。

5. Symbols

# Address   Size        File  Name
0x100001730 0x0000003C  [  2] -[ViewController viewDidLoad]
0x100001770 0x00000092  [  3] _main
0x100001810 0x00000080  [  4] -[AppDelegate application:didFinishLaunchingWithOptions:]
0x100001890 0x00000040  [  4] -[AppDelegate applicationWillResignActive:]
0x1000018D0 0x00000040  [  4] -[AppDelegate applicationDidEnterBackground:]
0x100001910 0x00000040  [  4] -[AppDelegate applicationWillEnterForeground:]
0x100001950 0x00000040  [  4] -[AppDelegate applicationDidBecomeActive:]
0x100001990 0x00000040  [  4] -[AppDelegate applicationWillTerminate:]
0x1000019D0 0x00000020  [  4] -[AppDelegate window]
0x1000019F0 0x00000040  [  4] -[AppDelegate setWindow:]
0x100001A30 0x00000033  [  4] -[AppDelegate .cxx_destruct]
0x100001A64 0x00000006  [  5] _NSStringFromClass
0x100001A6A 0x00000006  [  7] _UIApplicationMain
0x100001A70 0x00000006  [  6] _objc_autoreleasePoolPop
0x100001A76 0x00000006  [  6] _objc_autoreleasePoolPush
0x100001A7C 0x00000006  [  6] _objc_msgSendSuper2
0x100001A82 0x00000006  [  6] _objc_retainAutoreleasedReturnValue
0x100001A88 0x00000006  [  6] _objc_storeStrong
0x100001A90 0x00000010  [  0] helper helper
0x100001AA0 0x0000000A  [  5] _NSStringFromClass
0x100001AAA 0x0000000A  [  6] _objc_autoreleasePoolPop
0x100001AB4 0x0000000A  [  6] _objc_autoreleasePoolPush
0x100001ABE 0x0000000A  [  6] _objc_msgSendSuper2
0x100001AC8 0x0000000A  [  6] _objc_retainAutoreleasedReturnValue
0x100001AD2 0x0000000A  [  6] _objc_storeStrong
0x100001ADC 0x0000000A  [  7] _UIApplicationMain
0x100001AE6 0x0000000C  [  2] literal string: viewDidLoad
. . .

根據(jù)Sections的起始地址,可以將Symbols分為Sections個數(shù)的組,例如0x100001730到0x100001A64之間,就是 _ _ test代碼區(qū)。
Symbols包含的信息有:

  1. Address:起始地址
  2. Size:所占內(nèi)存大小,這里使用16進制表示。
  3. File:該Name所在的文件編號,也就是Object files部分的中括號的數(shù)字,例如-[ViewController viewDidLoad]對應(yīng)的文件編號為2,根據(jù)Object files部分可以看到所屬的文件為:ViewController.o。這樣可以計算某個o文件所占內(nèi)存的大小。只需要把Symbols中編號為o編號Symbols累加統(tǒng)計即可。
  4. Name就是該Sybmols的名稱。

6. Dead Stripped Symbols

# Dead Stripped Symbols:
#           Size        File  Name
<<dead>>    0x00000018  [  2] CIE
<<dead>>    0x00000018  [  3] CIE
<<dead>>    0x00000006  [  4] literal string: class
<<dead>>    0x00000008  [  4] literal string: v16@0:8
<<dead>>    0x00000018  [  4] CIE
. . .

上面便是對Link map file做了簡單的介紹。

itools

花了兩天的時間,根據(jù)對Link Map File的學(xué)習(xí),使用Ruby寫了一個腳本文件,可以方便地統(tǒng)計出指定Link Map File中的組件或者tbd占用內(nèi)存大小,類似:

AppDelegate.o          8.50KB
ViewController.o          735B
LinkMapDemo.app-Simulated.xcent          386B
main.o          192B
 linker synthesized          128B
libobjc.tbd          120B
Foundation.tbd          24B
UIKit.tbd          24B
總大小為(僅供參考):10.07KB

想了解更多可以訪問itools

總結(jié)

  1. 蘋果開發(fā)還是有很多細節(jié)的東西需要去學(xué)習(xí)去了解。
  2. 學(xué)習(xí)一門腳本語言,也會給平時的開發(fā)帶來很大的方便。

參考

  1. Mach-O可執(zhí)行文件
  2. iOS調(diào)優(yōu)|深入理解Link Map File
  3. iOS APP可執(zhí)行文件的組成

轉(zhuǎn)載請注明出處:http://www.itdecent.cn/p/f003df0d0861

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容