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到22的所有内容,段中各部分的意义分别:
段 | 内容 | 内容详情 |
---|---|---|
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 |
借助lldb查看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)
如上表中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