LinkMap篇(二)

DYLD 符号绑定

fangyang$ ./jtool --pages ../SampleApp.app/SampleApp 
0x0-0x3000  __TEXT
    0xd80-0x17d9    __TEXT.__text
    0x17da-0x1846   __TEXT.__stubs
    0x1848-0x190c   __TEXT.__stub_helper
    0x190c-0x23de   __TEXT.__objc_methname
    0x23de-0x2429   __TEXT.__objc_classname
    0x2429-0x2c78   __TEXT.__objc_methtype
    0x2c78-0x2da7   __TEXT.__cstring
    0x2da8-0x2e1c   __TEXT.__gcc_except_tab
    0x2e1c-0x2f86   __TEXT.__entitlements
    0x2f88-0x2ffc   __TEXT.__unwind_info
0x3000-0x5000   __DATA
    0x3000-0x3010   __DATA.__nl_symbol_ptr
    0x3010-0x3030   __DATA.__got
    0x3030-0x30c0   __DATA.__la_symbol_ptr
    0x30c0-0x30f0   __DATA.__const
    0x30f0-0x3190   __DATA.__cfstring
    0x3190-0x31a8   __DATA.__objc_classlist
    0x31a8-0x31b8   __DATA.__objc_protolist
    0x31b8-0x31c0   __DATA.__objc_imageinfo
    0x31c0-0x3f98   __DATA.__objc_const
    0x3f98-0x3fe0   __DATA.__objc_selrefs
    0x3fe0-0x4008   __DATA.__objc_classrefs
    0x4008-0x4010   __DATA.__objc_superrefs
    0x4010-0x4030   __DATA.__objc_ivar
    0x4030-0x4120   __DATA.__objc_data
    0x4120-0x41e8   __DATA.__data
0x5000-0x9ac0   __LINKEDIT
    0x5000-0x50e8   Rebase Info     (opcodes)
    0x50e8-0x52f8   Binding Info    (opcodes)
    0x52f8-0x54d0   Lazy Bind Info  (opcodes)
    0x54d0-0x55b0   Exports                  
    0x55d0-0x62a0   Symbol Table
    0x55d0-0x55d0   Data In Code
    0x62a0-0x6348   Indirect Symbol Table
    0x6348-0x7478   String Table
    0x7480-0x9ac0   Code signature

__LINKEDIT段包括load command 3中的所有内容,段中各部分的意义分别:

内容 内容详情
LC_DYLD_INFO[ONLY] rebase,bind,lazy bind,weak bind,export info Image rebase info - contains rebasing opcodes
symbol binding info:引入的符号
Image symbol binding info:懒引入的符号,如果编译的时候使用了 ld's -bind_at_load选项,这项会是0
Image symbol binding info:弱引入的符号(若在依赖的framework中找不到弱引入的符号会将符号地址置NULL,相比于非弱引入的符号找不到会加载失败)
Image symbol binding info:此image导出的符号
LC_SEGMENT_SPLIT_INFO 段分隔 段分隔信息
LC_FUNCTION_STARTS 函数起始信息 函数起始点信息 (ULEB128)
LC_DATA_IN_CODE 代码中的数据区域 数据区域信息(ULEB128)
LC_CODE_SIGN_DRS 代码签名DRs 依赖的dylibs的代码签名DRs
LC_SYMTAB/LC_DYSYMTAB 符号表,间接符号表,string table nlist格式的符号表,间接符号表,符号名字的数组
LC_CODE_SIGNATURE 代码签名 代码签名blob
stubs与stub_helper
fangyang$ lldb SampleApp.app/SampleApp 
(lldb) target create "SampleApp.app/SampleApp"
Current executable set to 'SampleApp.app/SampleApp' (x86_64).

#section __TEXT.__stubs

(lldb) x/40i 0x1000017da
0x1000017da: ff 25 50 18 00 00  jmpq   *0x1850(%rip)#跳转到[下条指令地址+0x1850]的位置
0x1000017e0: ff 25 52 18 00 00  jmpq   *0x1852(%rip)
0x1000017e6: ff 25 54 18 00 00  jmpq   *0x1854(%rip)
0x1000017ec: ff 25 56 18 00 00  jmpq   *0x1856(%rip)
...
0x100001846: 00 00              addb   %al, (%rax)

#section __TEXT.__stub_helper

(lldb) x/40i 0x100001848
0x100001848: 4c 8d 1d b9 17 00 00  leaq   0x17b9(%rip), %r11
0x10000184f: 41 53                 pushq  %r11
0x100001851: ff 25 a9 17 00 00     jmpq   *0x17a9(%rip)
0x100001857: 90                    nop    
0x100001858: 68 00 00 00 00        pushq  $0x0
0x10000185d: e9 e6 ff ff ff        jmp    0x100001848
0x100001862: 68 0d 00 00 00        pushq  $0xd
0x100001867: e9 dc ff ff ff        jmp    0x100001848
...
0x10000188a: 68 f7 00 00 00        pushq  $0xf7
0x10000188f: e9 b4 ff ff ff        jmp    0x100001848
0x100001894: 68 12 01 00 00        pushq  $0x112                    ; imm = 0x112 
0x100001899: e9 aa ff ff ff        jmp    0x100001848
0x10000189e: 68 27 01 00 00        pushq  $0x127                    ; imm = 0x127 
0x1000018a3: e9 a0 ff ff ff        jmp    0x100001848
0x1000018a8: 68 3b 01 00 00        pushq  $0x13b                    ; imm = 0x13B 
0x1000018ad: e9 96 ff ff ff        jmp    0x100001848
...
0x1000018c6: 68 af 01 00 00        pushq  $0x1af                    ; imm = 0x1AF 
0x1000018cb: e9 78 ff ff ff        jmp    0x100001848
...
0x1000018f8: 68 c8 01 00 00        pushq  $0x1c8                    ; imm = 0x1C8 
0x1000018fd: e9 46 ff ff ff        jmp    0x100001848
0x100001902: 68 26 00 00 00        pushq  $0x26
0x100001907: e9 3c ff ff ff        jmp    0x100001848

以0x10000183a symbol stub for _objc_storeStrong为例,0x10000183a位于__TEXT.__stubs中,相应的stub内容为

(lldb) x/i 0x10000183a
0x10000183a: ff 25 70 18 00 00  jmpq   *0x1870(%rip)
warning: Not all bytes (12/15) were able to be read from 0x10000183a.
(lldb) p/x 0x10000183a+0x1870+0x6
(long) $5 = 0x00000001000030b0

stub中的jmpq指令跳转的目标地址为0x1000030b0,对应__DATA.__la_symbol_ptr 中的_objc_storeStrong(执行文件中此处还并不是_objc_storeStrong的真正地址,真正地址会在可执行文件加载时,在DYLD绑定阶段填写为其真实函数地址),而0x1000030b0中的内容为0x1000018c6,指向的是stub helper;同时__DATA.__nl_symbol_ptr中的内容其实为空,nonlazy 符号的绑定与lazy 符号的绑定过程相同,只是绑定的时机不同,nonlazy符号是在运行过程中第一次使用时才会触发绑定

(lldb) x/2w 0x1000030b0
0x1000030b0: 0x000018c6 0x00000001
(lldb) x/4w 0x100003000
0x100003000: 0
0x100003004: 0
0x100003008: 0
0x10000300c: 0

绑定操作数据 DYLD_INFO

DYLD是依赖LC_DYLD_INFO[ONLY]中的信息来做rebase,bind,lazy bind,weak bind和export符号的,这个段内使用的是ULEB128编码的“指令”来做符号的绑定,比如想绑定地址 0x1000030b0 (位于 __DATA 段, 开始于0x100003000) 到符号_objc_storeStrong, 定义在第13个 loaded dylib, libobjc.A.dylib. 绑定操作如下所示:

SET_DYLIB_ORDINAL_IMM(13)
SET_SYMBOL_TRAILING_FLAGS_IMM(0, "_objc_storeStrong")
SET_SEGMENT_AND_OFFSET_ULEB(2, 0xb0)  ; usually __DATA通常是第2个segment.
DO_BIND()

二进制通常会是
0x1d 0x40 "_objc_storeStrong\0" 0x72 0xb0 0x90

符号表

包括符号表LC_SYMTAB和间接符号表LC_DYSYMTAB

fangyang$ ./jtool -l ../SampleApp.app/SampleApp 
LC 00: LC_SEGMENT_64          Mem: 0x000000000-0x100000000  __PAGEZERO
LC 01: LC_SEGMENT_64          Mem: 0x100000000-0x100003000  __TEXT
    Mem: 0x100000d80-0x1000017d9        __TEXT.__text   (Normal)
    Mem: 0x1000017da-0x100001846        __TEXT.__stubs  (Symbol Stubs)
    Mem: 0x100001848-0x10000190c        __TEXT.__stub_helper    (Normal)
    Mem: 0x10000190c-0x1000023de        __TEXT.__objc_methname  (C-String Literals)
    Mem: 0x1000023de-0x100002429        __TEXT.__objc_classname (C-String Literals)
    Mem: 0x100002429-0x100002c78        __TEXT.__objc_methtype  (C-String Literals)
    Mem: 0x100002c78-0x100002da7        __TEXT.__cstring    (C-String Literals)
...
LC 02: LC_SEGMENT_64          Mem: 0x100003000-0x100005000  __DATA
    Mem: 0x100003000-0x100003010        __DATA.__nl_symbol_ptr  (Non-Lazy Symbol Ptrs)
    Mem: 0x100003010-0x100003030        __DATA.__got    (Non-Lazy Symbol Ptrs)
    Mem: 0x100003030-0x1000030c0        __DATA.__la_symbol_ptr  (Lazy Symbol Ptrs)
...
    Mem: 0x100003190-0x1000031a8        __DATA.__objc_classlist (Normal)
...
    Mem: 0x100003f98-0x100003fe0        __DATA.__objc_selrefs   (Literal Pointers)
    Mem: 0x100003fe0-0x100004008        __DATA.__objc_classrefs (Normal)
    Mem: 0x100004008-0x100004010        __DATA.__objc_superrefs (Normal)
...
LC 03: LC_SEGMENT_64          Mem: 0x100005000-0x10000a000  __LINKEDIT
LC 04: LC_DYLD_INFO          
LC 05: LC_SYMTAB             
    Symbol table is at offset 0x55d0 (21968), 205 entries
    String table is at offset 0x6348 (25416), 4400 bytes
LC 06: LC_DYSYMTAB           
      164 local symbols at index     0
        9 external symbols at index  164
       32 undefined symbols at index 173
       No TOC
       No modtab
       42 Indirect symbols at offset 0x62a0

LC 07: LC_LOAD_DYLINKER         /usr/lib/dyld
LC 08: LC_UUID                  UUID: 35B44905-3939-3540-92C8-9B124DA2B6A
LC 09: LC_VERSION_MIN_IPHONEOS  Minimum iOS version:    10.3.0
LC 10: LC_SOURCE_VERSION        Source Version:          0.0.0.0.0
LC 11: LC_MAIN                  Entry Point:             0x1680 (Mem: 0x100001680)
LC 12: LC_LOAD_DYLIB            /System/Library/Frameworks/Foundation.framework/Foundation
...
LC 19: LC_RPATH                 @executable_path/Frameworks
LC 20: LC_FUNCTION_STARTS       Offset: 21936, Size: 32 (0x55b0-0x55d0) 
LC 21: LC_DATA_IN_CODE          Offset: 21968, Size: 0 (0x55d0-0x55d0) 
LC 22: LC_CODE_SIGNATURE        Offset: 29824, Size: 9792 (0x7480-0x9ac0) 
~~~~ shell
如上表中LC_SYMTAB部分所示,符号表是由nlist(_64)结构的数组,而字符串表是一组顺序排列的NULL结尾字符串,间接符号表LC_DYSYMTAB实际是指向主符号表(LC_SYMTAB)中索引index的数组,它与__DATA.__nl_symbol_ptr和__DATA.__lazy_symbol配合使用
~~~~/*
 * For the two types of symbol pointers sections and the symbol stubs section
 * they have indirect symbol table entries.  For each of the entries in the
 * section the indirect symbol table entries, in corresponding order in the
 * indirect symbol table, start at the index stored in the reserved1 field
 * of the section structure.  Since the indirect symbol table entries
 * correspond to the entries in the section the number of indirect symbol table
 * entries is inferred from the size of the section divided by the size of the
 * entries in the section.  For symbol pointers sections the size of the entries
 * in the section is 4 bytes and for symbol stubs sections the byte size of the
 * stubs is stored in the reserved2 field of the section structure.
 */
#define S_NON_LAZY_SYMBOL_POINTERS      0x6     /* section with only non-lazy
                                                   symbol pointers */
#define S_LAZY_SYMBOL_POINTERS          0x7     /* section with only lazy symbol
                                                   pointers */
#define S_SYMBOL_STUBS                  0x8     /* section with only symbol
                                                   stubs, byte size of stub in
                                                   the reserved2 field */

以上述提到的_objc_storeStrong符号指向__DATA.__la_symbol_ptr中0x1000030b0为例,0x1000030b0存放的是libobjc.dylib中_objc_storeStrong真正的函数地址,而绑定这个地址需要使用到__DATA.__la_symbol_ptr表0x1000030b0真正位于这个section中的第N项,然后到间接符号表中以__DATA.__la_symbol_ptr表中存的reserved1为起始偏移,按reserved1+N为地址取出存放在间接符号表中的符号表中的索引X,再取符号表的第X项的nlist结构,这个结构包含了符号类型,符号名字符串,关联的section及函数地址等信息,可以参照fishhook的做法理解这个过程
这3种section类型作为flag会出现在__nl_symbol_ptr,__lazy_symbol,_GOT(Global Offset Table,non_lazy_symbol_pointers),非lazy符号指针在加载时绑定,若绑定失败则二进制文件加载失败,lazy符号是在首次使用的时候绑定,而首次使用绑定的时候执行的代码位于__TEXT.__stub_helper,这部分的代码是特定于架构的,可以回顾上面x86_64 __stub_helper区的代码,arm64下代码如下:

#arm64 下stub_helper内容,跟上面x86_64的指令不一样,因为这部分是特定于架构的
fangyang$ ./jtool -dA __TEXT.__stub_helper ../SampleApp 

Disassembling from file offset 0x6960, Address 0x100006960 
   100006960    ADR    X17, #5824           ; ->R17 = 0x100008020 
   100006964    NOP                     ;
   100006968    STP    X16, X17, [SP, #-16]!    ;
   10000696c    NOP                     ;
   100006970    LDR    X16, #5800       ; X16 = *(100008018) = -libSystem.B.dylib::dyld_stub_binder-
   100006974    BR     X16                      ;  0x24107f9b0dc02a00
   100006978    LDR    W16, #8          ; X16 = *(100006980) = 0x0 ... ?..
   10000697c    B      0x100006960
   100006980    DCD    0x0
   100006984    LDR    W16, #8          ; X16 = *(10000698c) = 0xd ... ?..
   100006988    B      0x100006960
   10000698c    DCD    0xd
   100006990    LDR    W16, #8          ; X16 = *(100006998) = 0xa4 ... ?..
   100006994    B      0x100006960
   100006998    DCD    0xa4
   10000699c    LDR    W16, #8          ; X16 = *(1000069a4) = 0xc3 ... ?..
   1000069a0    B      0x100006960
   1000069a4    DCD    0xc3
   1000069a8    LDR    W16, #8          ; X16 = *(1000069b0) = 0xe3 ... ?..
   1000069ac    B      0x100006960
   1000069b0    DCD    0xe3
...
   100006a44    LDR    W16, #8          ; X16 = *(100006a4c) = 0x26 ... ?..
   100006a48    B      0x100006960
   100006a4c    DCD    0x26

__TEXT.__stub_helper包含一个函数,它会调用dyld_stub_binder,stub_helper中的其它项都跳转到这个函数,X16的值即为绑定相应的符号的dyld代码在opcodes中的偏移,绑定代码opcodes如下:

#来自arm64数据,对应段数据为
# Address   Size        Segment Section
0x100005D30 0x00000B58  __TEXT  __text
0x100006888 0x000000D8  __TEXT  __stubs
0x100006960 0x000000F0  __TEXT  __stub_helper
0x100006A50 0x00000AD2  __TEXT  __objc_methname
0x100007522 0x0000004B  __TEXT  __objc_classname
0x10000756D 0x0000084F  __TEXT  __objc_methtype
0x100007DBC 0x0000012F  __TEXT  __cstring
0x100007EEC 0x00000074  __TEXT  __gcc_except_tab
0x100007F60 0x000000A0  __TEXT  __unwind_info
0x100008000 0x00000028  __DATA  __got
0x100008028 0x00000090  __DATA  __la_symbol_ptr
0x1000080C0 0x00000030  __DATA  __const
0x1000080F0 0x000000A0  __DATA  __cfstring
0x100008190 0x00000018  __DATA  __objc_classlist
0x1000081A8 0x00000010  __DATA  __objc_protolist
0x1000081B8 0x00000008  __DATA  __objc_imageinfo
0x1000081C0 0x00000DD8  __DATA  __objc_const
0x100008F98 0x00000048  __DATA  __objc_selrefs
0x100008FE0 0x00000028  __DATA  __objc_classrefs
0x100009008 0x00000008  __DATA  __objc_superrefs
0x100009010 0x00000010  __DATA  __objc_ivar
0x100009020 0x000000F0  __DATA  __objc_data
0x100009110 0x000000C8  __DATA  __data

fangyang$ ./jtool -opcodes ../SampleApp
binding opcodes:
0x0000 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(1)  #设置为第一个LC_LOAD_DYLIB,对应当前这个arm64可执行文件中是动态库/System/Library/Frameworks/Foundation.framework/Foundation
0x0001 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _OBJC_CLASS_$_NSNumber) #设置符号名为_OBJC_CLASS_$_NSNumber
0x0019 BIND_OPCODE_SET_TYPE_IMM(1) #设置类型为指针
0x001A BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000FF8) #设置段为#2 (__DATA)
0x001D BIND_OPCODE_DO_BIND() #ROW

#下一条命令继承了上条的所有值,但覆写了符号名
0x001E BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _OBJC_CLASS_$_NSString)
0x0036 BIND_OPCODE_ADD_ADDR_ULEB(0xFFFFFFFFFFFFFFE0)
0x0041 BIND_OPCODE_DO_BIND()
0x0042 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)  #libobjc.dylib
0x0043 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _OBJC_CLASS_$_NSObject)
0x005B BIND_OPCODE_ADD_ADDR_ULEB(0x00000008)
0x005D BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB(0x000000F8)
0x0060 BIND_OPCODE_DO_BIND()
0x0061 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _OBJC_METACLASS_$_NSObject)
0x007D BIND_OPCODE_ADD_ADDR_ULEB(0xFFFFFFFFFFFFFF50)
0x0088 BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED(0x00000028)
0x0089 BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED(0x00000050)
0x008A BIND_OPCODE_DO_BIND()
0x008B BIND_OPCODE_DO_BIND()
0x008C BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, __objc_empty_cache)
0x00A0 BIND_OPCODE_ADD_ADDR_ULEB(0xFFFFFFFFFFFFFF60)
0x00AB BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB(-160, 0x00000020)
0x00AE BIND_OPCODE_DO_BIND()
0x00AF BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(3) #libc++.dylib
0x00B0 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, ___gxx_personality_v0)
0x00C7 BIND_OPCODE_ADD_ADDR_ULEB(0xFFFFFFFFFFFFEF08)
0x00D2 BIND_OPCODE_DO_BIND()
0x00D3 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(4) #libsystem.dylib
0x00D4 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, __NSConcreteStackBlock)
0x00EC BIND_OPCODE_ADD_ADDR_ULEB(0xFFFFFFFFFFFFFFF0)
0x00F7 BIND_OPCODE_DO_BIND()
0x00F8 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, __dispatch_main_q)
0x010B BIND_OPCODE_ADD_ADDR_ULEB(0x00000008)
0x010D BIND_OPCODE_DO_BIND()
0x010E BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, dyld_stub_binder)
0x0120 BIND_OPCODE_DO_BIND()
0x0121 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(5) #corefoundation
0x0122 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, ___CFConstantStringClassReference)
0x0145 BIND_OPCODE_ADD_ADDR_ULEB(0x000000D0)
0x0148 BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB(208, 0x00000018)
0x014B BIND_OPCODE_DO_BIND()
0x014C BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(6) #UIKit
0x014D BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _OBJC_CLASS_$_UIResponder)
0x0168 BIND_OPCODE_ADD_ADDR_ULEB(0x00000F28)
0x016B BIND_OPCODE_DO_BIND()
0x016C BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _OBJC_CLASS_$_UIViewController)
0x018C BIND_OPCODE_ADD_ADDR_ULEB(0xFFFFFFFFFFFFFF80)
0x0197 BIND_OPCODE_DO_BIND()
0x0198 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _OBJC_METACLASS_$_UIResponder)
0x01B7 BIND_OPCODE_ADD_ADDR_ULEB(0x00000048)
0x01B9 BIND_OPCODE_DO_BIND()
0x01BA BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _OBJC_METACLASS_$_UIViewController)
0x01DE BIND_OPCODE_ADD_ADDR_ULEB(0xFFFFFFFFFFFFFFD0)
0x01E9 BIND_OPCODE_DO_BIND()
0x01EA BIND_OPCODE_DONE
0x01EB BIND_OPCODE_DONE
0x01EC BIND_OPCODE_DONE
0x01ED BIND_OPCODE_DONE
0x01EE BIND_OPCODE_DONE
0x01EF BIND_OPCODE_DONE
lazy binding opcodes:
0x0000 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000028)
0x0002 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(1)
0x0003 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _NSLog)
0x000B BIND_OPCODE_DO_BIND()
0x000C BIND_OPCODE_DONE
0x000D BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000030)
0x000F BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(1)
0x0010 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _NSStringFromClass)
0x0024 BIND_OPCODE_DO_BIND()
0x0025 BIND_OPCODE_DONE
0x0026 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000038)
0x0028 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(6)
0x0029 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _UIApplicationMain)
0x003D BIND_OPCODE_DO_BIND()
0x003E BIND_OPCODE_DONE
0x003F BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000040)
0x0041 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(4)
0x0042 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, __Block_object_assign)
0x0059 BIND_OPCODE_DO_BIND()
0x005A BIND_OPCODE_DONE
0x005B BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000048)
0x005D BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(4)
0x005E BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, __Block_object_dispose)
0x0076 BIND_OPCODE_DO_BIND()
0x0077 BIND_OPCODE_DONE
0x0078 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000050)
0x007A BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(4)
0x007B BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, __Unwind_Resume)
0x008C BIND_OPCODE_DO_BIND()
0x008D BIND_OPCODE_DONE
0x008E BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000058)
0x0090 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(4)
0x0091 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _dispatch_async)
0x00A2 BIND_OPCODE_DO_BIND()
0x00A3 BIND_OPCODE_DONE
0x00A4 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000060)
0x00A6 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
0x00A7 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _objc_autoreleasePoolPop)
0x00C1 BIND_OPCODE_DO_BIND()
0x00C2 BIND_OPCODE_DONE
0x00C3 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000068)
0x00C5 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
0x00C6 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _objc_autoreleasePoolPush)
0x00E1 BIND_OPCODE_DO_BIND()
0x00E2 BIND_OPCODE_DONE
0x00E3 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000070)
0x00E5 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
0x00E6 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _objc_msgSend)
0x00F5 BIND_OPCODE_DO_BIND()
0x00F6 BIND_OPCODE_DONE
0x00F7 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000078)
0x00F9 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
0x00FA BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _objc_msgSendSuper2)
0x010F BIND_OPCODE_DO_BIND()
0x0110 BIND_OPCODE_DONE
0x0111 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000080)
0x0114 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
0x0115 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _objc_release)
0x0124 BIND_OPCODE_DO_BIND()
0x0125 BIND_OPCODE_DONE
0x0126 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000088)
0x0129 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
0x012A BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _objc_retain)
0x0138 BIND_OPCODE_DO_BIND()
0x0139 BIND_OPCODE_DONE
0x013A BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000090)
0x013D BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
0x013E BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _objc_retainAutorelease)
0x0157 BIND_OPCODE_DO_BIND()
0x0158 BIND_OPCODE_DONE
0x0159 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000098)
0x015C BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
0x015D BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _objc_retainAutoreleaseReturnValue)
0x0181 BIND_OPCODE_DO_BIND()
0x0182 BIND_OPCODE_DONE
0x0183 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x000000A0)
0x0186 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
0x0187 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _objc_retainAutoreleasedReturnValue)
0x01AC BIND_OPCODE_DO_BIND()
0x01AD BIND_OPCODE_DONE
0x01AE BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x000000A8)
0x01B1 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
0x01B2 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _objc_storeStrong)
0x01C5 BIND_OPCODE_DO_BIND()
0x01C6 BIND_OPCODE_DONE
0x01C7 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x000000B0)
0x01CA BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(4)
0x01CB BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _puts)
0x01D2 BIND_OPCODE_DO_BIND()
0x01D3 BIND_OPCODE_DONE
0x01D4 BIND_OPCODE_DONE
0x01D5 BIND_OPCODE_DONE
0x01D6 BIND_OPCODE_DONE
0x01D7 BIND_OPCODE_DONE
##
0xc000-0x10ee0  __LINKEDIT
    0xc000-0xc0e8   Rebase Info     (opcodes)
    0xc0e8-0xc2d8   Binding Info    (opcodes)
    0xc2d8-0xc4b0   Lazy Bind Info  (opcodes)
##

Linkmap中各section涵义

segment section 作用
__TEXT __text 函数,方法及block helper等编译成的汇编代码
__TEXT __stubs 调用的外部符号,符号地址在符号表中,分非lazy与lazy绑定,过程如上
__TEXT __stub_helper 借助dyld_stub_binder进行lazy绑定的指令段
__TEXT _objc_classname OC类名C字符串
__TEXT _objc_methname OC方法名C字符串
__TEXT _objc_methtype 所有方法type encodings字符串
__TEXT __cstring 代码中出现的字符串
__TEXT __gcc_except_tab
__TEXT __unwind_info
__DATA __nl_symbol_ptr 内容一般为0,会在load阶段被dyld填写为symbol地址
__DATA __la_symbol_ptr 内容指向stub_helper中对应的绑定代码的偏移
__DATA __objc_classlist OC类信息,OBJC_CLASS$_SampleObject,,类信息加载过程
__DATA __objc_selrefs 指向__objc_methname中的方法名字符串
__DATA __objc_const l_OBJC__INSTANCE_METHODS_SampleObject等method_list数据,l_OBJC_METACLASS_RO_SampleObject等元类数据,l_OBJC_CLASS_RO_SampleObject,l_OBJC_PROP_LIST_SampleObject,l_OBJC$_INSTANCE_VARIABLES_SampleObject
__DATA __objc_ivar 实例变量对应的property, 实例变量名,类型数据
__objc_classlist
(lldb) x/2x 0x100003190
0x100003190: 0x00004030 0x00000001
(lldb) x/2x 0x100003198
0x100003198: 0x000040a8 0x00000001
(lldb) x/2x 0x1000031a0                          
0x1000031a0: 0x000040f8 0x00000001
(lldb) x/10x 0x1000040f8    //_OBJC_CLASS_$_SampleObject内容
0x1000040f8: 0x000040d0 0x00000001 0x00000000 0x00000000    //_OBJC_METACLASS_$_SampleObject  0(实际是_OBJC_CLASS_$_NSObject)
0x100004108: 0x00000000 0x00000000 0x00000000 0x00000000  // 0(实际是__objc_empty_cache) 0
0x100004118: 0x00003f50 0x00000001  //l_OBJC_CLASS_RO_$_SampleObject

__objc_selrefs
(lldb) x/2x 0x100003F98
0x100003f98: 0x0000190c 0x00000001  //指向__objc_methname中的ViewDidLoad
(lldb) x/2x 0x100003Fa0
0x100003fa0: 0x00001918 0x00000001 //指向 __objc_methname中的didReceiveMemoryWarning
对应的汇编代码如下:
.section    __DATA,__objc_data
    .globl  _OBJC_CLASS_$_SampleObject ## @"OBJC_CLASS_$_SampleObject"
    .p2align    3
_OBJC_CLASS_$_SampleObject:
    .quad   _OBJC_METACLASS_$_SampleObject
    .quad   _OBJC_CLASS_$_NSObject
    .quad   __objc_empty_cache
    .quad   0
    .quad   l_OBJC_CLASS_RO_$_SampleObject
__objc_const
(lldb) x/50x 0x100003de8    // l_OBJC_$_INSTANCE_METHODS_SampleObject
0x100003de8: 0x00000018 0x00000008 0x0000233c 0x00000001
0x100003df8: 0x00002606 0x00000001 0x00001060 0x00000001
0x100003e08: 0x00002309 0x00000001 0x00002429 0x00000001
0x100003e18: 0x00001620 0x00000001 0x0000235c 0x00000001
0x100003e28: 0x00002b73 0x00000001 0x00001510 0x00000001
0x100003e38: 0x00002368 0x00000001 0x00002431 0x00000001
0x100003e48: 0x00001530 0x00000001 0x00002378 0x00000001
0x100003e58: 0x00002b73 0x00000001 0x00001570 0x00000001
0x100003e68: 0x00002383 0x00000001 0x00002431 0x00000001
0x100003e78: 0x00001590 0x00000001 0x00002392 0x00000001
0x100003e88: 0x00002c1b 0x00000001 0x000015d0 0x00000001
0x100003e98: 0x0000239b 0x00000001 0x00002c53 0x00000001 setSampleId:(__TEXT.__objc_methname)  v24@0:8Q16(__TEXT.__objc_methtype)
0x100003ea8: 0x000015f0 0x00000001  -[SampleObject setSampleId:](__TEXT.__text)
(lldb) x/18x 0x100003f50   //l_OBJC_CLASS_RO_$_SampleObject(包含instance method,instance variables及proplist信息)
0x100003f50: 0x00000184 0x00000008 0x00000020 0x00000000
0x100003f60: 0x00002427 0x00000001 0x0000241a 0x00000001  //__objc_classname, __objc_classname
0x100003f70: 0x00003de8 0x00000001 0x00000000 0x00000000//l_OBJC_$_INSTANCE_METHODS_SampleObject
0x100003f80: 0x00003eb0 0x00000001 0x00000000 0x00000000 //l_OBJC_$_INSTANCE_VARIABLES_SampleObject
0x100003f90: 0x00003f18 0x00000001    //l_OBJC_$_PROP_LIST_SampleObject
(lldb) x/14x 0x100003f18    //l_OBJC_$_PROP_LIST_SampleObject
0x100003f18: 0x00000010 0x00000003 0x00002d37 0x00000001    //sampleName
0x100003f28: 0x00002d42 0x00000001 0x00002d60 0x00000001 //T@"NSString",&,N,V_sampleName,   sampleId
0x100003f38: 0x00002d69 0x00000001 0x00002d79 0x00000001 //TQ,N,V_sampleId  , propertyObj 
0x100003f48: 0x00002d85 0x00000001 //T@"NSObject",&,N,V_propertyObj
(lldb) x/26x 0x100003eb0      //l_OBJC_$_INSTANCE_VARIABLES_SampleObject 结构为属性名,实例名,类型
0x100003eb0: 0x00000020 0x00000003 0x00004018 0x00000001  // _OBJC_IVAR_$_SampleObject._propertyObj (__objc_ivar)  
0x100003ec0: 0x000023a8 0x00000001 0x00002c5e 0x00000001
0x100003ed0: 0x00000003 0x00000008 0x00004020 0x00000001
0x100003ee0: 0x000023b5 0x00000001 0x00002c6a 0x00000001
0x100003ef0: 0x00000003 0x00000008 0x00004028 0x00000001
0x100003f00: 0x000023c1 0x00000001 0x00002c76 0x00000001
0x100003f10: 0x00000003 0x00000008

clang -fobjc-nonfragile-abi -fnext-runtime -S SampleObject.mm 编译为汇编代码之后的形式如下:

    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 10, 12
    .p2align    4, 0x90
"-[SampleObject getSomeResultWithString:number:]": ## @"\01-[SampleObject getSomeResultWithString:number:]"
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp0:
    .cfi_def_cfa_offset 16
Ltmp1:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp2:
    .cfi_def_cfa_register %rbp
    subq    $160, %rsp
    leaq    L__unnamed_cfstring_.2(%rip), %rax
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    movq    %rcx, -32(%rbp)
    movq    L_OBJC_CLASSLIST_REFERENCES_$_(%rip), %rcx
    movq    -24(%rbp), %rdx
    movq    -32(%rbp), %r8
    movq    L_OBJC_SELECTOR_REFERENCES_(%rip), %rsi
    movq    %rcx, %rdi
    movq    %rdx, -160(%rbp)        ## 8-byte Spill
    movq    %rax, %rdx
    movq    -160(%rbp), %rcx        ## 8-byte Reload
    movb    $0, %al
    callq   _objc_msgSend
    movq    __dispatch_main_q@GOTPCREL(%rip), %rcx
    leaq    -152(%rbp), %rdx
    leaq    -96(%rbp), %rsi
    leaq    ___block_descriptor_tmp(%rip), %rdi
    leaq    "___47-[SampleObject getSomeResultWithString:number:]_block_invoke"(%rip), %r8
    movq    __NSConcreteStackBlock@GOTPCREL(%rip), %r9
    leaq    ___Block_byref_object_dispose_(%rip), %r10
    leaq    ___Block_byref_object_copy_(%rip), %r11
    movq    %rax, -40(%rbp)
    movq    $123, -48(%rbp)
    movq    $0, -96(%rbp)
    movq    %rsi, -88(%rbp)
    movl    $1375731712, -80(%rbp)  ## imm = 0x52000000
    movl    $48, -76(%rbp)
    movq    %r11, -72(%rbp)
    movq    %r10, -64(%rbp)
    movq    $0, -56(%rbp)
    movq    %r9, -152(%rbp)
    movl    $-1040187392, -144(%rbp) ## imm = 0xC2000000
    movl    $0, -140(%rbp)
    movq    %r8, -136(%rbp)
    movq    %rdi, -128(%rbp)
    movq    -40(%rbp), %rax
    movq    %rax, -120(%rbp)
    movq    -48(%rbp), %rax
    movq    %rax, -104(%rbp)
    movq    %rsi, -112(%rbp)
    movq    %rcx, %rdi
    movq    %rdx, %rsi
    callq   _dispatch_async
    movl    $8, %esi
    leaq    -96(%rbp), %rax
    movq    %rax, %rdi
    callq   __Block_object_dispose
    addq    $160, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
___Block_byref_object_copy_:            ## @__Block_byref_object_copy_
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp3:
    .cfi_def_cfa_offset 16
Ltmp4:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp5:
    .cfi_def_cfa_register %rbp
    subq    $32, %rsp
    movl    $131, %edx
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    -8(%rbp), %rsi
    addq    $40, %rsi
    movq    -16(%rbp), %rdi
    movq    40(%rdi), %rdi
    movq    %rdi, -24(%rbp)         ## 8-byte Spill
    movq    %rsi, %rdi
    movq    -24(%rbp), %rsi         ## 8-byte Reload
    callq   __Block_object_assign
    addq    $32, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
___Block_byref_object_dispose_:         ## @__Block_byref_object_dispose_
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp6:
    .cfi_def_cfa_offset 16
Ltmp7:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp8:
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movl    $131, %esi
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rdi
    movq    40(%rdi), %rdi
    callq   __Block_object_dispose
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
"___47-[SampleObject getSomeResultWithString:number:]_block_invoke": ## @"__47-[SampleObject getSomeResultWithString:number:]_block_invoke"
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp9:
    .cfi_def_cfa_offset 16
Ltmp10:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp11:
    .cfi_def_cfa_register %rbp
    subq    $48, %rsp
    leaq    L__unnamed_cfstring_.4(%rip), %rax
    movq    %rdi, -8(%rbp)
    movq    %rdi, %rcx
    movq    %rcx, -16(%rbp)
    movq    L_OBJC_CLASSLIST_REFERENCES_$_(%rip), %rcx
    movq    _cntstr(%rip), %rdx
    movq    32(%rdi), %r8
    movq    48(%rdi), %r9
    movq    L_OBJC_SELECTOR_REFERENCES_(%rip), %rsi
    movq    %rdi, -32(%rbp)         ## 8-byte Spill
    movq    %rcx, %rdi
    movq    %rdx, -40(%rbp)         ## 8-byte Spill
    movq    %rax, %rdx
    movq    -40(%rbp), %rcx         ## 8-byte Reload
    movb    $0, %al
    callq   _objc_msgSend
    leaq    L__unnamed_cfstring_.6(%rip), %rcx
    movq    %rax, -24(%rbp)
    movq    -24(%rbp), %rsi
    movq    %rcx, %rdi
    movb    $0, %al
    callq   _NSLog
    movq    -24(%rbp), %rcx
    movq    L_OBJC_SELECTOR_REFERENCES_.8(%rip), %rsi
    movq    %rcx, %rdi
    callq   _objc_msgSend
    movq    %rax, %rdi
    callq   _puts
    movq    -24(%rbp), %rcx
    movq    -32(%rbp), %rdx         ## 8-byte Reload
    movq    40(%rdx), %rsi
    movq    8(%rsi), %rsi
    movq    %rcx, 40(%rsi)
    movl    %eax, -44(%rbp)         ## 4-byte Spill
    addq    $48, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
___copy_helper_block_:                  ## @__copy_helper_block_
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp12:
    .cfi_def_cfa_offset 16
Ltmp13:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp14:
    .cfi_def_cfa_register %rbp
    subq    $32, %rsp
    movl    $3, %edx
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    -16(%rbp), %rsi
    movq    -8(%rbp), %rdi
    movq    %rdi, %rax
    addq    $32, %rax
    movq    32(%rsi), %rcx
    movq    %rdi, -24(%rbp)         ## 8-byte Spill
    movq    %rax, %rdi
    movq    %rsi, -32(%rbp)         ## 8-byte Spill
    movq    %rcx, %rsi
    callq   __Block_object_assign
    movl    $8, %edx
    movq    -24(%rbp), %rax         ## 8-byte Reload
    addq    $40, %rax
    movq    -32(%rbp), %rcx         ## 8-byte Reload
    movq    40(%rcx), %rsi
    movq    %rax, %rdi
    callq   __Block_object_assign
    addq    $32, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
___destroy_helper_block_:               ## @__destroy_helper_block_
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp15:
    .cfi_def_cfa_offset 16
Ltmp16:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp17:
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movl    $3, %esi
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rdi
    movq    32(%rdi), %rax
    movq    %rdi, -16(%rbp)         ## 8-byte Spill
    movq    %rax, %rdi
    callq   __Block_object_dispose
    movl    $8, %esi
    movq    -16(%rbp), %rax         ## 8-byte Reload
    movq    40(%rax), %rdi
    callq   __Block_object_dispose
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
"-[SampleObject propertyObj]":          ## @"\01-[SampleObject propertyObj]"
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp18:
    .cfi_def_cfa_offset 16
Ltmp19:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp20:
    .cfi_def_cfa_register %rbp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    -8(%rbp), %rsi
    movq    _OBJC_IVAR_$_SampleObject._propertyObj(%rip), %rdi
    movq    (%rsi,%rdi), %rax
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
"-[SampleObject setPropertyObj:]":      ## @"\01-[SampleObject setPropertyObj:]"
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp21:
    .cfi_def_cfa_offset 16
Ltmp22:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp23:
    .cfi_def_cfa_register %rbp
    subq    $32, %rsp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    movq    -16(%rbp), %rsi
    movq    -8(%rbp), %rdx
    movq    _OBJC_IVAR_$_SampleObject._propertyObj(%rip), %rcx
    movq    -24(%rbp), %rdi
    movq    %rdi, -32(%rbp)         ## 8-byte Spill
    movq    %rdx, %rdi
    movq    -32(%rbp), %rdx         ## 8-byte Reload
    callq   _objc_setProperty_nonatomic
    addq    $32, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
"-[SampleObject sampleName]":           ## @"\01-[SampleObject sampleName]"
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp24:
    .cfi_def_cfa_offset 16
Ltmp25:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp26:
    .cfi_def_cfa_register %rbp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    -8(%rbp), %rsi
    movq    _OBJC_IVAR_$_SampleObject._sampleName(%rip), %rdi
    movq    (%rsi,%rdi), %rax
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
"-[SampleObject setSampleName:]":       ## @"\01-[SampleObject setSampleName:]"
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp27:
    .cfi_def_cfa_offset 16
Ltmp28:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp29:
    .cfi_def_cfa_register %rbp
    subq    $32, %rsp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    movq    -16(%rbp), %rsi
    movq    -8(%rbp), %rdx
    movq    _OBJC_IVAR_$_SampleObject._sampleName(%rip), %rcx
    movq    -24(%rbp), %rdi
    movq    %rdi, -32(%rbp)         ## 8-byte Spill
    movq    %rdx, %rdi
    movq    -32(%rbp), %rdx         ## 8-byte Reload
    callq   _objc_setProperty_nonatomic
    addq    $32, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
"-[SampleObject sampleId]":             ## @"\01-[SampleObject sampleId]"
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp30:
    .cfi_def_cfa_offset 16
Ltmp31:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp32:
    .cfi_def_cfa_register %rbp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    -8(%rbp), %rsi
    movq    _OBJC_IVAR_$_SampleObject._sampleId(%rip), %rdi
    movq    (%rsi,%rdi), %rax
    popq    %rbp
    retq
    .cfi_endproc

    .p2align    4, 0x90
"-[SampleObject setSampleId:]":         ## @"\01-[SampleObject setSampleId:]"
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp33:
    .cfi_def_cfa_offset 16
Ltmp34:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp35:
    .cfi_def_cfa_register %rbp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    movq    -24(%rbp), %rdx
    movq    -8(%rbp), %rsi
    movq    _OBJC_IVAR_$_SampleObject._sampleId(%rip), %rdi
    movq    %rdx, (%rsi,%rdi)
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz  "SampleObjectKey"

    .section    __DATA,__cfstring
    .p2align    3               ## @_unnamed_cfstring_
L__unnamed_cfstring_:
    .quad   ___CFConstantStringClassReference
    .long   1992                    ## 0x7c8
    .space  4
    .quad   L_.str
    .quad   15                      ## 0xf

    .section    __DATA,__data
    .globl  _cntstr                 ## @cntstr
    .p2align    3
_cntstr:
    .quad   L__unnamed_cfstring_

    .section    __DATA,__objc_classrefs,regular,no_dead_strip
    .p2align    3               ## @"OBJC_CLASSLIST_REFERENCES_$_"
L_OBJC_CLASSLIST_REFERENCES_$_:
    .quad   _OBJC_CLASS_$_NSString

    .section    __TEXT,__cstring,cstring_literals
L_.str.1:                               ## @.str.1
    .asciz  "%@:%@"

    .section    __DATA,__cfstring
    .p2align    3               ## @_unnamed_cfstring_.2
L__unnamed_cfstring_.2:
    .quad   ___CFConstantStringClassReference
    .long   1992                    ## 0x7c8
    .space  4
    .quad   L_.str.1
    .quad   5                       ## 0x5

    .section    __TEXT,__objc_methname,cstring_literals
L_OBJC_METH_VAR_NAME_:                  ## @OBJC_METH_VAR_NAME_
    .asciz  "stringWithFormat:"

    .section    __DATA,__objc_selrefs,literal_pointers,no_dead_strip
    .p2align    3               ## @OBJC_SELECTOR_REFERENCES_
L_OBJC_SELECTOR_REFERENCES_:
    .quad   L_OBJC_METH_VAR_NAME_

    .section    __TEXT,__cstring,cstring_literals
L_.str.3:                               ## @.str.3
    .asciz  "%@:%@:%lul"

    .section    __DATA,__cfstring
    .p2align    3               ## @_unnamed_cfstring_.4
L__unnamed_cfstring_.4:
    .quad   ___CFConstantStringClassReference
    .long   1992                    ## 0x7c8
    .space  4
    .quad   L_.str.3
    .quad   10                      ## 0xa

    .section    __TEXT,__cstring,cstring_literals
L_.str.5:                               ## @.str.5
    .asciz  "composite string:%@,succeeded"

    .section    __DATA,__cfstring
    .p2align    3               ## @_unnamed_cfstring_.6
L__unnamed_cfstring_.6:
    .quad   ___CFConstantStringClassReference
    .long   1992                    ## 0x7c8
    .space  4
    .quad   L_.str.5
    .quad   29                      ## 0x1d

    .section    __TEXT,__objc_methname,cstring_literals
L_OBJC_METH_VAR_NAME_.7:                ## @OBJC_METH_VAR_NAME_.7
    .asciz  "UTF8String"

    .section    __DATA,__objc_selrefs,literal_pointers,no_dead_strip
    .p2align    3               ## @OBJC_SELECTOR_REFERENCES_.8
L_OBJC_SELECTOR_REFERENCES_.8:
    .quad   L_OBJC_METH_VAR_NAME_.7

    .section    __TEXT,__cstring,cstring_literals
L_.str.9:                               ## @.str.9
    .asciz  "v8@?0"

    .section    __DATA,__const
    .p2align    4               ## @__block_descriptor_tmp
___block_descriptor_tmp:
    .quad   0                       ## 0x0
    .quad   56                      ## 0x38
    .quad   ___copy_helper_block_
    .quad   ___destroy_helper_block_
    .quad   L_.str.9
    .quad   272                     ## 0x110

    .private_extern _OBJC_IVAR_$_SampleObject._propertyObj ## @"OBJC_IVAR_$_SampleObject._propertyObj"
    .section    __DATA,__objc_ivar
    .globl  _OBJC_IVAR_$_SampleObject._propertyObj
    .p2align    3
_OBJC_IVAR_$_SampleObject._propertyObj:
    .quad   8                       ## 0x8

    .private_extern _OBJC_IVAR_$_SampleObject._sampleName ## @"OBJC_IVAR_$_SampleObject._sampleName"
    .globl  _OBJC_IVAR_$_SampleObject._sampleName
    .p2align    3
_OBJC_IVAR_$_SampleObject._sampleName:
    .quad   16                      ## 0x10

    .private_extern _OBJC_IVAR_$_SampleObject._sampleId ## @"OBJC_IVAR_$_SampleObject._sampleId"
    .globl  _OBJC_IVAR_$_SampleObject._sampleId
    .p2align    3
_OBJC_IVAR_$_SampleObject._sampleId:
    .quad   24                      ## 0x18

    .section    __TEXT,__objc_classname,cstring_literals
L_OBJC_CLASS_NAME_:                     ## @OBJC_CLASS_NAME_
    .asciz  "SampleObject"

    .section    __DATA,__objc_const
    .p2align    3               ## @"\01l_OBJC_METACLASS_RO_$_SampleObject"
l_OBJC_METACLASS_RO_$_SampleObject:
    .long   1                       ## 0x1
    .long   40                      ## 0x28
    .long   40                      ## 0x28
    .space  4
    .quad   0
    .quad   L_OBJC_CLASS_NAME_
    .quad   0
    .quad   0
    .quad   0
    .quad   0
    .quad   0

    .section    __DATA,__objc_data
    .globl  _OBJC_METACLASS_$_SampleObject ## @"OBJC_METACLASS_$_SampleObject"
    .p2align    3
_OBJC_METACLASS_$_SampleObject:
    .quad   _OBJC_METACLASS_$_NSObject
    .quad   _OBJC_METACLASS_$_NSObject
    .quad   __objc_empty_cache
    .quad   0
    .quad   l_OBJC_METACLASS_RO_$_SampleObject

    .section    __TEXT,__objc_methname,cstring_literals
L_OBJC_METH_VAR_NAME_.10:               ## @OBJC_METH_VAR_NAME_.10
    .asciz  "getSomeResultWithString:number:"

    .section    __TEXT,__objc_methtype,cstring_literals
L_OBJC_METH_VAR_TYPE_:                  ## @OBJC_METH_VAR_TYPE_
    .asciz  "v32@0:8@16@24"

    .section    __TEXT,__objc_methname,cstring_literals
L_OBJC_METH_VAR_NAME_.11:               ## @OBJC_METH_VAR_NAME_.11
    .asciz  "propertyObj"

    .section    __TEXT,__objc_methtype,cstring_literals
L_OBJC_METH_VAR_TYPE_.12:               ## @OBJC_METH_VAR_TYPE_.12
    .asciz  "@16@0:8"

    .section    __TEXT,__objc_methname,cstring_literals
L_OBJC_METH_VAR_NAME_.13:               ## @OBJC_METH_VAR_NAME_.13
    .asciz  "setPropertyObj:"

    .section    __TEXT,__objc_methtype,cstring_literals
L_OBJC_METH_VAR_TYPE_.14:               ## @OBJC_METH_VAR_TYPE_.14
    .asciz  "v24@0:8@16"

    .section    __TEXT,__objc_methname,cstring_literals
L_OBJC_METH_VAR_NAME_.15:               ## @OBJC_METH_VAR_NAME_.15
    .asciz  "sampleName"

L_OBJC_METH_VAR_NAME_.16:               ## @OBJC_METH_VAR_NAME_.16
    .asciz  "setSampleName:"

L_OBJC_METH_VAR_NAME_.17:               ## @OBJC_METH_VAR_NAME_.17
    .asciz  "sampleId"

    .section    __TEXT,__objc_methtype,cstring_literals
L_OBJC_METH_VAR_TYPE_.18:               ## @OBJC_METH_VAR_TYPE_.18
    .asciz  "Q16@0:8"

    .section    __TEXT,__objc_methname,cstring_literals
L_OBJC_METH_VAR_NAME_.19:               ## @OBJC_METH_VAR_NAME_.19
    .asciz  "setSampleId:"

    .section    __TEXT,__objc_methtype,cstring_literals
L_OBJC_METH_VAR_TYPE_.20:               ## @OBJC_METH_VAR_TYPE_.20
    .asciz  "v24@0:8Q16"

    .section    __DATA,__objc_const
    .p2align    3               ## @"\01l_OBJC_$_INSTANCE_METHODS_SampleObject"
l_OBJC_$_INSTANCE_METHODS_SampleObject:
    .long   24                      ## 0x18
    .long   7                       ## 0x7
    .quad   L_OBJC_METH_VAR_NAME_.10
    .quad   L_OBJC_METH_VAR_TYPE_
    .quad   "-[SampleObject getSomeResultWithString:number:]"
    .quad   L_OBJC_METH_VAR_NAME_.11
    .quad   L_OBJC_METH_VAR_TYPE_.12
    .quad   "-[SampleObject propertyObj]"
    .quad   L_OBJC_METH_VAR_NAME_.13
    .quad   L_OBJC_METH_VAR_TYPE_.14
    .quad   "-[SampleObject setPropertyObj:]"
    .quad   L_OBJC_METH_VAR_NAME_.15
    .quad   L_OBJC_METH_VAR_TYPE_.12
    .quad   "-[SampleObject sampleName]"
    .quad   L_OBJC_METH_VAR_NAME_.16
    .quad   L_OBJC_METH_VAR_TYPE_.14
    .quad   "-[SampleObject setSampleName:]"
    .quad   L_OBJC_METH_VAR_NAME_.17
    .quad   L_OBJC_METH_VAR_TYPE_.18
    .quad   "-[SampleObject sampleId]"
    .quad   L_OBJC_METH_VAR_NAME_.19
    .quad   L_OBJC_METH_VAR_TYPE_.20
    .quad   "-[SampleObject setSampleId:]"

    .section    __TEXT,__objc_methname,cstring_literals
L_OBJC_METH_VAR_NAME_.21:               ## @OBJC_METH_VAR_NAME_.21
    .asciz  "_propertyObj"

    .section    __TEXT,__objc_methtype,cstring_literals
L_OBJC_METH_VAR_TYPE_.22:               ## @OBJC_METH_VAR_TYPE_.22
    .asciz  "@\"NSObject\""

    .section    __TEXT,__objc_methname,cstring_literals
L_OBJC_METH_VAR_NAME_.23:               ## @OBJC_METH_VAR_NAME_.23
    .asciz  "_sampleName"

    .section    __TEXT,__objc_methtype,cstring_literals
L_OBJC_METH_VAR_TYPE_.24:               ## @OBJC_METH_VAR_TYPE_.24
    .asciz  "@\"NSString\""

    .section    __TEXT,__objc_methname,cstring_literals
L_OBJC_METH_VAR_NAME_.25:               ## @OBJC_METH_VAR_NAME_.25
    .asciz  "_sampleId"

    .section    __TEXT,__objc_methtype,cstring_literals
L_OBJC_METH_VAR_TYPE_.26:               ## @OBJC_METH_VAR_TYPE_.26
    .asciz  "Q"

    .section    __DATA,__objc_const
    .p2align    3               ## @"\01l_OBJC_$_INSTANCE_VARIABLES_SampleObject"
l_OBJC_$_INSTANCE_VARIABLES_SampleObject:
    .long   32                      ## 0x20
    .long   3                       ## 0x3
    .quad   _OBJC_IVAR_$_SampleObject._propertyObj
    .quad   L_OBJC_METH_VAR_NAME_.21
    .quad   L_OBJC_METH_VAR_TYPE_.22
    .long   3                       ## 0x3
    .long   8                       ## 0x8
    .quad   _OBJC_IVAR_$_SampleObject._sampleName
    .quad   L_OBJC_METH_VAR_NAME_.23
    .quad   L_OBJC_METH_VAR_TYPE_.24
    .long   3                       ## 0x3
    .long   8                       ## 0x8
    .quad   _OBJC_IVAR_$_SampleObject._sampleId
    .quad   L_OBJC_METH_VAR_NAME_.25
    .quad   L_OBJC_METH_VAR_TYPE_.26
    .long   3                       ## 0x3
    .long   8                       ## 0x8

    .section    __TEXT,__cstring,cstring_literals
L_OBJC_PROP_NAME_ATTR_:                 ## @OBJC_PROP_NAME_ATTR_
    .asciz  "sampleName"

L_OBJC_PROP_NAME_ATTR_.27:              ## @OBJC_PROP_NAME_ATTR_.27
    .asciz  "T@\"NSString\",&,N,V_sampleName"

L_OBJC_PROP_NAME_ATTR_.28:              ## @OBJC_PROP_NAME_ATTR_.28
    .asciz  "sampleId"

L_OBJC_PROP_NAME_ATTR_.29:              ## @OBJC_PROP_NAME_ATTR_.29
    .asciz  "TQ,N,V_sampleId"

L_OBJC_PROP_NAME_ATTR_.30:              ## @OBJC_PROP_NAME_ATTR_.30
    .asciz  "propertyObj"

L_OBJC_PROP_NAME_ATTR_.31:              ## @OBJC_PROP_NAME_ATTR_.31
    .asciz  "T@\"NSObject\",&,N,V_propertyObj"

    .section    __DATA,__objc_const
    .p2align    3               ## @"\01l_OBJC_$_PROP_LIST_SampleObject"
l_OBJC_$_PROP_LIST_SampleObject:
    .long   16                      ## 0x10
    .long   3                       ## 0x3
    .quad   L_OBJC_PROP_NAME_ATTR_
    .quad   L_OBJC_PROP_NAME_ATTR_.27
    .quad   L_OBJC_PROP_NAME_ATTR_.28
    .quad   L_OBJC_PROP_NAME_ATTR_.29
    .quad   L_OBJC_PROP_NAME_ATTR_.30
    .quad   L_OBJC_PROP_NAME_ATTR_.31

    .p2align    3               ## @"\01l_OBJC_CLASS_RO_$_SampleObject"
l_OBJC_CLASS_RO_$_SampleObject:
    .long   0                       ## 0x0
    .long   8                       ## 0x8
    .long   32                      ## 0x20
    .space  4
    .quad   0
    .quad   L_OBJC_CLASS_NAME_
    .quad   l_OBJC_$_INSTANCE_METHODS_SampleObject
    .quad   0
    .quad   l_OBJC_$_INSTANCE_VARIABLES_SampleObject
    .quad   0
    .quad   l_OBJC_$_PROP_LIST_SampleObject

    .section    __DATA,__objc_data
    .globl  _OBJC_CLASS_$_SampleObject ## @"OBJC_CLASS_$_SampleObject"
    .p2align    3
_OBJC_CLASS_$_SampleObject:
    .quad   _OBJC_METACLASS_$_SampleObject
    .quad   _OBJC_CLASS_$_NSObject
    .quad   __objc_empty_cache
    .quad   0
    .quad   l_OBJC_CLASS_RO_$_SampleObject

    .section    __DATA,__objc_classlist,regular,no_dead_strip
    .p2align    3               ## @"OBJC_LABEL_CLASS_$"
L_OBJC_LABEL_CLASS_$:
    .quad   _OBJC_CLASS_$_SampleObject

    .section    __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
    .long   0
    .long   64


.subsections_via_symbols

参考:
app 可执行文件中类信息及其加载
stub_helper
dyld
stub
dyld-dynamic-linking

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,757评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,478评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,540评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,593评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,903评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,329评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,659评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,383评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,055评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,337评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,864评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,227评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,820评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,999评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,750评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,365评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,260评论 2 258

推荐阅读更多精彩内容