LinkMap
文件是 Xcode
产生可执行文件的同时生成的链接信息,用来描述可执行文件的构造成分,包括代码段 __TEXT
和数据段 __DATA
的分布情况。只要设置 Project->Build Settings->Write Link Map File
为 YES
,并设置 Path to Link Map File
,build
完后就可以在设置的路径看到 LinkMap
文件了:
image.png
LinkMap
的路径:
/Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-boyphtjpmytnckgosnyjctscvngm/Build/Intermediates.noindex/XXXX.build/Debug-iphoneos/XXXX.build/XXXX-LinkMap-normal-arm64.txt
一份完整的 LinkMap
文件中包含了一下几个部分:
# Path: /Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-boyphtjpmytnckgosnyjctscvngm/Build/Products/Debug-iphoneos/XXXXapp/XXXX
# Arch: arm64
# Object files: [ 0] linker synthesized [ 1] /Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-boyphtjpmytnckgosnyjctscvngm/Build/Intermediates.noindex/XXXX.build/Debug-iphoneos/XXXX.build/Objects-normal/arm64/QMGameReport.o [ 2] /Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-boyphtjpmytnckgosnyjctscvngm/Build/Intermediates.noindex/XXXX.build/Debug-iphoneos/XXXX.build/Objects-normal/arm64/QMNewAnimationManager.o [ 3] /Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-boyphtjpmytnckgosnyjctscvngm/Build/Intermediates.noindex/XXXX.build/Debug-iphoneos/XXXX.build/Objects-normal/arm64/QMCocosAnimationView.o ...
第一部分列举可执行文件里所有链接的 .o
文件,以及每个文件的编号。
# Sections: # Address Size Segment Section 0x100004180 0x027ECF28 __TEXT __text 0x1027F10A8 0x00005130 __TEXT __stubs 0x1027F61D8 0x000048B4 __TEXT __stub_helper 0x1027FAAA0 0x00131318 __TEXT __const 0x10292BDC0 0x0018FFDF __TEXT __cstring 0x102ABBDA0 0x0001839E __TEXT __ustring 0x102AD413E 0x000EC936 __TEXT __objc_methname 0x102BC0A74 0x00013E5F __TEXT __objc_classname 0x102BD48D3 0x00023F8A __TEXT __objc_methtype 0x102BF8860 0x00106C50 __TEXT __gcc_except_tab 0x102CFF4B0 0x0004FF6C __TEXT __unwind_info 0x102D4F420 0x00000BBC __TEXT __eh_frame 0x102D50000 0x00001A30 __DATA __got 0x102D51A30 0x00003620 __DATA __la_symbol_ptr 0x102D55050 0x000003D8 __DATA __mod_init_func 0x102D55428 0x00000008 __DATA __mod_term_func 0x102D55430 0x000DFAC0 __DATA __const 0x102E34EF0 0x00097920 __DATA __cfstring 0x102ECC810 0x00006430 __DATA __objc_classlist 0x102ED2C40 0x000000C0 __DATA __objc_nlclslist 0x102ED2D00 0x00000958 __DATA __objc_catlist 0x102ED3658 0x00000108 __DATA __objc_nlcatlist 0x102ED3760 0x000012B8 __DATA __objc_protolist 0x102ED4A18 0x00000008 __DATA __objc_imageinfo 0x102ED4A20 0x0033CE60 __DATA __objc_const 0x103211880 0x0003B238 __DATA __objc_selrefs 0x10324CAB8 0x000000A0 __DATA __objc_protorefs 0x10324CB58 0x00005F78 __DATA __objc_classrefs 0x103252AD0 0x00004400 __DATA __objc_superrefs 0x103256ED0 0x000126B0 __DATA __objc_ivar 0x103269580 0x0003EA30 __DATA __objc_data 0x1032A7FC0 0x000C89E0 __DATA __data 0x1033709A0 0x00310E68 __DATA __bss 0x103682000 0x00104C40 __DATA __common
第二部分是可执行文件的段表,描述各个段在可执行文件中的地址和大小,段类型以及段名称。第一列是段的地址,第二列是段占用大小;第三列是段类型,代码段和数据段,数据类型分为两种不同类型,一种是 __TEXT
,用于保存程序代码段经过编译后的机器码,另外一种是 __DATA
用于保存诸如全局变量或者局部变量;第四列是段名称,如 __text
段是可执行机器码,__cstring
段是字符串常量, __bss
表示未初始化的全局变量及局部静态变量,__const
表示的是对应的不可变的变量。当然这一切的数据都是文件占用空间,并不是运行时的占用空间。
# Symbols: # Address Size File Name 0x100004180 0x000002A4 [ 1] -[QMGameReport initWithFrame:isNightMode:] 0x100004424 0x00000264 [ 1] -[QMGameReport setConnerRadiusForBackgroundView] 0x100004688 0x00000034 [ 1] _CGSizeMake 0x1000046BC 0x00000120 [ 1] -[QMGameReport showInView:] 0x1000047DC 0x00000040 [ 1] ___27-[QMGameReport showInView:]_block_invoke 0x10000481C 0x0000004C [ 1] ___copy_helper_block_ 0x100004868 0x00000030 [ 1] ___destroy_helper_block_ 0x100004898 0x00000064 [ 1] -[QMGameReport tapClick:] 0x1000048FC 0x000001F0 [ 1] -[QMGameReport dismiss] 0x100004AEC 0x00000040 [ 1] ___23-[QMGameReport dismiss]_block_invoke 0x100004B2C 0x0000004C [ 1] ___copy_helper_block_.276 0x100004B78 0x00000030 [ 1] ___destroy_helper_block_.277 0x100004BA8 0x00000040 [ 1] ___23-[QMGameReport dismiss]_block_invoke.279 0x100004BE8 0x0000004C [ 1] ___copy_helper_block_.282 0x100004C34 0x00000030 [ 1] ___destroy_helper_block_.283 0x100004C64 0x00000AFC [ 1] -[QMGameReport setUpconfigItem] 0x100005760 0x0000005C [ 1] _CGRectMake 0x1000057BC 0x0000039C [ 1] -[QMGameReport reportAction:] ...
第三部分详细描述每个 .o
文件在每个段的分布情况,按第二部分 Sections
顺序展示。例如序号 1
的 QMGameReport.o
文件,-[QMGameReport initWithFrame:isNightMode:]
方法在 __TEXT
的 Segment
里面 .__text
的 Section
段地址是 0x100004180
,占用大小是116字节。根据序号累加每个 .o
文件在每个段的占用大小,从而计算出每个 .o
文件在可执行文件的占用大小,进而算出每个静态库、每个功能模块代码占用大小。
这里要注意的地方是,由于 __DATA
的 Segment
里面 .__bbs
的 Section
是代表未初始化的静态变量,Size
表示应用运行时占用的堆大小,并不占用可执行文件,所以计算 .o
占用大小时,要排除这个段的 Size
。
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句