rizin/test/db/cmd/cmd_avD
Anton Angelov 95f94ae258
refactor: SwissTable implementation for ht (#5860)
* Add ht benchmarks
* Initial implementation
* Finalize native per-group lookup support
* Lookup SSE2 implementation
* Improve hashing
* Add support for custom elem_size
* Avoid double h2 hashing when reserving slot
* Make custom elem_size support conditional
* Fix issues with bitwise and default lookup implementations
* Implement deletion trick optimization
* Track growth_size instead of deleted_slots
* Refactor SDB to access ht via API instead of internals
* Modify SDB tests which rely on hashtable order
* Fix SDB build warnings
* Fix bug with finding next power of two
* foreach_kv to return a bool result
* Change SDB diff order expected by serialize_analysis unit test
* Fix bug in the bitwise lookup implementation
* Remove second call to rz_core_init() which causes memory leaks
* Update some regression tests to accept reordered output
* Adapt ht clear to new implementation
* Use fini_kv_pair and fix 1 potential leak on malloc failure
* Fix cmd/types test after merge
* Avoid second call to calsize_key and avoid iter leaks on malloc failure
* Improve hash distribution
* Extend benchmark suite
* Fix bug with string hashing
* Branchless write to mirrored ctrl bytes
* Simplify string hash and remove potential UB
* Move RZ_PREFETCH macro to rz_types.h
* Add SSE2 discovery in Meson
* Forward SDB string hash function to ht string hash
* Try to revert test_cpu_profiles() to avoid relying on a baked SDB file
* Revert SDB/CDB hash function change
* Fix SDB reference to HT hash function instead of CDB hash
* Change calloc to malloc
* Avoid storing/checking key_len and key_value if they are ut64
* Improve string hash function
* Rename default hash functions
* Improve bench code
* linter.yml: set clang-path to point to llvm-18
2026-03-02 12:31:35 +08:00

1224 lines
No EOL
66 KiB
Text

NAME=cxx class analysis simple (x86-64)
FILE=bins/elf/analysis/x86-class-C
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; DATA XREF from sym._start_c @ 0x40074b
;-- rip:
/ int main(int argc, char **argv, char **envp);
| ; var struct C *var_20h @ stack - 0x20
| 0x0040088d push rbp
| 0x0040088e mov rbp, rsp
| 0x00400891 push rbx
| 0x00400892 sub rsp, 0x18
| 0x00400896 mov edi, 0x10 ; 16
| 0x0040089b call sym.imp.operator_new_unsigned_long
| 0x004008a0 mov rbx, rax
| 0x004008a3 mov esi, 0x05 ; int64_t arg2
| 0x004008a8 mov rdi, rbx ; int64_t arg1
| 0x004008ab call method.C.C_int ; method.C.C_int(int64_t arg1, int64_t arg2)
| 0x004008b0 mov qword [var_20h], rbx
| 0x004008b4 mov rax, qword [var_20h]
| 0x004008b8 mov rax, qword [rax]
| 0x004008bb mov rdx, qword [rax]
| 0x004008be mov rax, qword [var_20h]
| 0x004008c2 mov rdi, rax
| 0x004008c5 call rdx ; Virtual Call : method.C.print
| 0x004008c7 mov eax, 0x00
| 0x004008cc add rsp, 0x18
| 0x004008d0 pop rbx
| 0x004008d1 pop rbp
\ 0x004008d2 ret
EOF
RUN
NAME=cxx class analysis for inherited classes (x86-64)
FILE=bins/elf/analysis/x86-class-inherit
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; DATA XREF from sym._start_c @ 0x40096b
;-- rip:
/ int main(int argc, char **argv, char **envp);
| ; var struct Human *var_30h @ stack - 0x30
| ; var struct Cat *var_28h @ stack - 0x28
| ; var struct Dog *var_20h @ stack - 0x20
| 0x00400aad push rbp
| 0x00400aae mov rbp, rsp
| 0x00400ab1 push r12
| 0x00400ab3 push rbx
| 0x00400ab4 sub rsp, 0x20
| 0x00400ab8 mov edi, 0x08
| 0x00400abd call sym.imp.operator_new_unsigned_long
| 0x00400ac2 mov rbx, rax
| 0x00400ac5 mov rdi, rbx ; int64_t arg1
| 0x00400ac8 call method.Dog.Dog ; method.Dog.Dog(int64_t arg1)
| 0x00400acd mov qword [var_20h], rbx
| 0x00400ad1 mov rax, qword [var_20h]
| 0x00400ad5 mov rax, qword [rax]
| 0x00400ad8 add rax, 0x10 ; 16
| 0x00400adc mov rdx, qword [rax]
| 0x00400adf mov rax, qword [var_20h]
| 0x00400ae3 mov rdi, rax
| 0x00400ae6 call rdx ; Virtual Call : method.Dog.run
| 0x00400ae8 mov edi, 0x08
| 0x00400aed call sym.imp.operator_new_unsigned_long
| 0x00400af2 mov rbx, rax
| 0x00400af5 mov rdi, rbx ; int64_t arg1
| 0x00400af8 call method.Cat.Cat ; method.Cat.Cat(int64_t arg1)
| 0x00400afd mov qword [var_28h], rbx
| 0x00400b01 mov rax, qword [var_28h]
| 0x00400b05 mov rax, qword [rax]
| 0x00400b08 add rax, 0x10 ; 16
| 0x00400b0c mov rdx, qword [rax]
| 0x00400b0f mov rax, qword [var_28h]
| 0x00400b13 mov rdi, rax
| 0x00400b16 call rdx ; Virtual Call : method.Cat.run
| 0x00400b18 mov edi, 0x08
| 0x00400b1d call sym.imp.operator_new_unsigned_long
| 0x00400b22 mov rbx, rax
| 0x00400b25 mov rdi, rbx ; int64_t arg1
| 0x00400b28 call method.Human.Human ; method.Human.Human(int64_t arg1)
| 0x00400b2d mov qword [var_30h], rbx
| 0x00400b31 mov rax, qword [var_30h]
| 0x00400b35 mov rax, qword [rax]
| 0x00400b38 add rax, 0x10 ; 16
| 0x00400b3c mov rdx, qword [rax]
| 0x00400b3f mov rax, qword [var_30h]
| 0x00400b43 mov rdi, rax
| 0x00400b46 call rdx ; Virtual Call : method.Human.run
| 0x00400b48 mov rax, qword [var_20h]
| 0x00400b4c test rax, rax
| ,=< 0x00400b4f jz 0x400b60
| | 0x00400b51 mov rdx, qword [rax]
| | 0x00400b54 add rdx, 0x08
| | 0x00400b58 mov rdx, qword [rdx]
| | 0x00400b5b mov rdi, rax
| | 0x00400b5e call rdx ; Virtual Call : sym.Dog::_Dog_0x400e6e
| `-> 0x00400b60 mov rax, qword [var_28h]
| 0x00400b64 test rax, rax
| ,=< 0x00400b67 jz 0x400b78
| | 0x00400b69 mov rdx, qword [rax]
| | 0x00400b6c add rdx, 0x08
| | 0x00400b70 mov rdx, qword [rdx]
| | 0x00400b73 mov rdi, rax
| | 0x00400b76 call rdx ; Virtual Call : sym.Cat::_Cat_0x400d78
| `-> 0x00400b78 mov rax, qword [var_30h]
| 0x00400b7c test rax, rax
| ,=< 0x00400b7f jz 0x400b90
| | 0x00400b81 mov rdx, qword [rax]
| | 0x00400b84 add rdx, 0x08
| | 0x00400b88 mov rdx, qword [rdx]
| | 0x00400b8b mov rdi, rax
| | 0x00400b8e call rdx ; Virtual Call : sym.Human::_Human_0x400f64
| | ;-- rbp:
| `-> 0x00400b90 mov eax, 0x00
| ,=< 0x00400b95 jmp 0x400be8
..
| ;-- r12:
| ;-- rbx:
| | ; CODE XREF from main @ 0x400b95
| `-> 0x00400be8 add rsp, 0x20
| 0x00400bec pop rbx
| 0x00400bed pop r12
| 0x00400bef pop rbp
\ 0x00400bf0 ret
EOF
RUN
NAME=cxx class analysis for classes with conditionals (x86-64)
FILE=bins/elf/analysis/x86-class-conditional
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; DATA XREF from sym._start_c @ 0x400a3b
;-- rip:
/ int main(int argc, char **argv, char **envp);
| ; var int var_24h @ stack - 0x24
| ; var union RZ_var_20h_HYBRID var_20h @ stack - 0x20
| 0x00400b7d push rbp
| 0x00400b7e mov rbp, rsp
| 0x00400b81 push r12
| 0x00400b83 push rbx
| 0x00400b84 sub rsp, 0x10
| 0x00400b88 mov edi, 0x00 ; time_t *timer
| 0x00400b8d call sym.imp.time ; time_t time(time_t *timer)
| 0x00400b92 mov edi, eax ; int seed
| 0x00400b94 call sym.imp.srand ; void srand(int seed)
| 0x00400b99 call sym.imp.rand ; int rand(void)
| 0x00400b9e mov dword [var_24h], eax
| 0x00400ba1 mov ecx, dword [var_24h]
| 0x00400ba4 movsxd rax, ecx
| 0x00400ba7 imul rax, rax, 0x55555556
| 0x00400bae shr rax, 0x20
| 0x00400bb2 mov rdx, rax
| 0x00400bb5 mov eax, ecx
| 0x00400bb7 sar eax, 0x1f
| 0x00400bba sub edx, eax
| 0x00400bbc mov eax, edx
| 0x00400bbe add eax, eax
| 0x00400bc0 add eax, edx
| 0x00400bc2 sub ecx, eax
| 0x00400bc4 mov edx, ecx
| 0x00400bc6 cmp edx, 0x02 ; 2
| ,=< 0x00400bc9 jnz 0x400c00
| | 0x00400bcb mov edi, 0x08
| | 0x00400bd0 call sym.imp.operator_new_unsigned_long
| | 0x00400bd5 mov rbx, rax
| | 0x00400bd8 mov rdi, rbx ; int64_t arg1
| | 0x00400bdb call method.Dog.Dog ; method.Dog.Dog(int64_t arg1)
| | 0x00400be0 mov qword [var_20h.var_20h], rbx
| | 0x00400be4 mov rax, qword [var_20h.var_20h]
| | 0x00400be8 mov rax, qword [rax]
| | 0x00400beb add rax, 0x10 ; 16
| | 0x00400bef mov rdx, qword [rax]
| | 0x00400bf2 mov rax, qword [var_20h.var_20h]
| | 0x00400bf6 mov rdi, rax
| | 0x00400bf9 call rdx ; Virtual Call : method.Dog.run / method.Human.run / method.Cat.run
| ,==< 0x00400bfb jmp 0x400c8c
| |`-> 0x00400c00 mov ecx, dword [var_24h]
| | 0x00400c03 movsxd rax, ecx
| | 0x00400c06 imul rax, rax, 0x55555556
| | 0x00400c0d shr rax, 0x20
| | 0x00400c11 mov rdx, rax
| | 0x00400c14 mov eax, ecx
| | 0x00400c16 sar eax, 0x1f
| | 0x00400c19 sub edx, eax
| | 0x00400c1b mov eax, edx
| | 0x00400c1d add eax, eax
| | 0x00400c1f add eax, edx
| | 0x00400c21 sub ecx, eax
| | 0x00400c23 mov edx, ecx
| | 0x00400c25 cmp edx, 0x01 ; 1
| |,=< 0x00400c28 jnz 0x400c5c
| || 0x00400c2a mov edi, 0x08
| || 0x00400c2f call sym.imp.operator_new_unsigned_long
| || 0x00400c34 mov rbx, rax
| || 0x00400c37 mov rdi, rbx ; int64_t arg1
| || 0x00400c3a call method.Cat.Cat ; method.Cat.Cat(int64_t arg1)
| || 0x00400c3f mov qword [var_20h.var_20h], rbx
| || 0x00400c43 mov rax, qword [var_20h.var_20h]
| || 0x00400c47 mov rax, qword [rax]
| || 0x00400c4a add rax, 0x10 ; 16
| || 0x00400c4e mov rdx, qword [rax]
| || 0x00400c51 mov rax, qword [var_20h.var_20h]
| || 0x00400c55 mov rdi, rax
| || 0x00400c58 call rdx ; Virtual Call : method.Dog.run / method.Human.run / method.Cat.run
| ,===< 0x00400c5a jmp 0x400c8c
| ||`-> 0x00400c5c mov edi, 0x08
| || 0x00400c61 call sym.imp.operator_new_unsigned_long
| || 0x00400c66 mov rbx, rax
| || 0x00400c69 mov rdi, rbx ; int64_t arg1
| || 0x00400c6c call method.Human.Human ; method.Human.Human(int64_t arg1)
| || 0x00400c71 mov qword [var_20h.var_20h], rbx
| || 0x00400c75 mov rax, qword [var_20h.var_20h]
| || 0x00400c79 mov rax, qword [rax]
| || 0x00400c7c add rax, 0x10 ; 16
| || 0x00400c80 mov rdx, qword [rax]
| || 0x00400c83 mov rax, qword [var_20h.var_20h]
| || 0x00400c87 mov rdi, rax
| || 0x00400c8a call rdx ; Virtual Call : method.Dog.run / method.Human.run / method.Cat.run
| || ; CODE XREFS from main @ 0x400bfb, 0x400c5a
| ``--> 0x00400c8c mov rax, qword [var_20h.var_20h]
| 0x00400c90 mov rax, qword [rax]
| 0x00400c93 add rax, 0x18 ; 24
| 0x00400c97 mov rdx, qword [rax]
| 0x00400c9a mov rax, qword [var_20h.var_20h]
| 0x00400c9e mov rdi, rax
| 0x00400ca1 call rdx ; Virtual Call : method.Dog.walk / method.Human.walk / method.Cat.walk
| 0x00400ca3 mov rax, qword [var_20h.var_20h]
| 0x00400ca7 test rax, rax
| ,=< 0x00400caa jz 0x400cbb
| | 0x00400cac mov rdx, qword [rax]
| | 0x00400caf add rdx, 0x08
| | 0x00400cb3 mov rdx, qword [rdx]
| | 0x00400cb6 mov rdi, rax
| | 0x00400cb9 call rdx ; Virtual Call : sym.Cat::_Cat_0x400ea4 / sym.Human::_Human_0x401090 / sym.Dog::_Dog_0x400f9a
| `-> 0x00400cbb mov eax, 0x00
| ,=< 0x00400cc0 jmp 0x400d13
..
| ;-- rbp:
| ;-- r12:
| ;-- rbx:
| | ; CODE XREF from main @ 0x400cc0
| `-> 0x00400d13 add rsp, 0x10
| 0x00400d17 pop rbx
| 0x00400d18 pop r12
| 0x00400d1a pop rbp
\ 0x00400d1b ret
EOF
RUN
NAME=cxx class analysis for classes with multiple vtables (x86-64)
FILE=bins/elf/analysis/x86-class-multi-vtable
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; DATA XREF from sym._start_c @ 0x40088b
;-- rip:
/ int main(int argc, char **argv, char **envp);
| ; var struct C *var_20h @ stack - 0x20
| 0x004009cd push rbp
| 0x004009ce mov rbp, rsp
| 0x004009d1 push rbx
| 0x004009d2 sub rsp, 0x18
| 0x004009d6 mov edi, 0x10 ; rflags
| 0x004009db call sym.imp.operator_new_unsigned_long
| ;-- rbp:
| 0x004009e0 mov rbx, rax
| 0x004009e3 mov qword [rbx], 0x00
| 0x004009ea mov qword [rbx+0x08], 0x00
| 0x004009f2 mov rdi, rbx ; int64_t arg1
| 0x004009f5 call method.C.C ; method.C.C(int64_t arg1)
| ;-- rbx:
| 0x004009fa mov qword [var_20h], rbx
| 0x004009fe mov rax, qword [var_20h]
| 0x00400a02 mov rax, qword [rax]
| 0x00400a05 mov rdx, qword [rax]
| 0x00400a08 mov rax, qword [var_20h]
| 0x00400a0c mov rdi, rax
| 0x00400a0f call rdx ; Virtual Call : sym.non_virtual_thunk_to_C::showB / method.C.showA
| 0x00400a11 mov rax, qword [var_20h]
| 0x00400a15 mov rax, qword [rax]
| 0x00400a18 add rax, 0x08
| 0x00400a1c mov rdx, qword [rax]
| 0x00400a1f mov rax, qword [var_20h]
| 0x00400a23 mov rdi, rax
| 0x00400a26 call rdx ; Virtual Call : method.C.showB
| 0x00400a28 mov rax, qword [var_20h]
| 0x00400a2c mov rax, qword [rax]
| 0x00400a2f add rax, 0x10 ; rflags
| 0x00400a33 mov rdx, qword [rax]
| 0x00400a36 mov rax, qword [var_20h]
| 0x00400a3a mov rdi, rax
| 0x00400a3d call rdx ; Virtual Call : method.C.showC
| 0x00400a3f mov eax, 0x00
| 0x00400a44 add rsp, 0x18
| 0x00400a48 pop rbx
| 0x00400a49 pop rbp
\ 0x00400a4a ret
EOF
RUN
NAME=cxx class analysis for inherited classes (arm64)
FILE=bins/mach0/arm64-class-inherit
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; UNKNOWN XREF from aav.0x100000028 @ +0xa8
;-- main:
;-- section.0.__TEXT.__text:
;-- _main:
;-- func.100002878:
;-- pc:
/ entry0(int64_t arg1);
| ; arg int64_t arg1 @ x0
| ; var int64_t var_70h @ stack - 0x70
| ; var int64_t var_68h @ stack - 0x68
| ; var int64_t var_60h @ stack - 0x60
| ; var int64_t var_58h @ stack - 0x58
| ; var int64_t var_50h @ stack - 0x50
| ; var int64_t var_48h @ stack - 0x48
| ; var struct Human *var_30h @ stack - 0x30
| ; var struct Cat *var_28h @ stack - 0x28
| ; var struct Dog *var_20h @ stack - 0x20
| ; var int64_t var_14h @ stack - 0x14
| ; var int64_t var_10h @ stack - 0x10
| ; var int64_t var_8h @ stack - 0x8
| 0x100002878 sub sp, sp, 0x70 ; [00] -r-x section size 4944 named 0.__TEXT.__text
| 0x10000287c stp fp, lr, [var_10h]
| 0x100002880 add fp, sp, 0x60
| 0x100002884 stur wzr, [var_14h] ; arg1
| 0x100002888 mov x0, 8
| 0x10000288c bl sym.imp.operator_new_unsigned_long
| 0x100002890 str x0, [var_48h]
| 0x100002894 bl method.Dog.Dog ; method.Dog.Dog(int64_t arg1)
| ,=< 0x100002898 b 0x10000289c
| | ; CODE XREF from entry0 @ 0x100002898
| `-> 0x10000289c ldr x8, [var_48h] ; [0x28:4]=-1 ; 40
| 0x1000028a0 stur x8, [var_20h]
| 0x1000028a4 ldur x0, [var_20h]
| 0x1000028a8 ldr x8, [x0]
| 0x1000028ac ldr x8, [x8, 0x10] ; [0x10:4]=-1 ; 16
| 0x1000028b0 blr x8 ; Virtual Call : method.Dog.run
| 0x1000028b4 mov x0, 8
| 0x1000028b8 bl sym.imp.operator_new_unsigned_long
| 0x1000028bc str x0, [var_50h]
| 0x1000028c0 bl method.Cat.Cat ; method.Cat.Cat(int64_t arg1)
| ,=< 0x1000028c4 b 0x1000028c8
| | ; CODE XREF from entry0 @ 0x1000028c4
| `-> 0x1000028c8 ldr x8, [var_50h] ; [0x20:4]=-1 ; 32
| 0x1000028cc stur x8, [var_28h]
| 0x1000028d0 ldur x0, [var_28h]
| 0x1000028d4 ldr x8, [x0]
| 0x1000028d8 ldr x8, [x8, 0x10] ; [0x10:4]=-1 ; 16
| 0x1000028dc blr x8 ; Virtual Call : method.Cat.run
| 0x1000028e0 mov x0, 8
| 0x1000028e4 bl sym.imp.operator_new_unsigned_long
| 0x1000028e8 str x0, [var_58h]
| 0x1000028ec bl method.Human.Human ; method.Human.Human(int64_t arg1)
| ,=< 0x1000028f0 b 0x1000028f4
| | ; CODE XREF from entry0 @ 0x1000028f0
| `-> 0x1000028f4 ldr x8, [var_58h] ; [0x18:4]=-1 ; 24
| 0x1000028f8 stur x8, [var_30h]
| 0x1000028fc ldur x0, [var_30h]
| 0x100002900 ldr x8, [x0]
| 0x100002904 ldr x8, [x8, 0x10] ; [0x10:4]=-1 ; 16
| 0x100002908 blr x8 ; Virtual Call : method.Human.run
| 0x10000290c ldur x8, [var_20h]
| 0x100002910 str x8, [var_60h]
| 0x100002914 subs x8, x8, 0
| 0x100002918 cset w8, eq
| ,=< 0x10000291c tbnz w8, 0, 0x100002938
| ,==< 0x100002920 b 0x100002924
| || ; CODE XREF from entry0 @ 0x100002920
| `--> 0x100002924 ldr x0, [var_60h] ; [0x10:4]=-1 ; 16
| | 0x100002928 ldr x8, [x0]
| | 0x10000292c ldr x8, [x8, 8] ; [0x8:4]=-1 ; 8
| | 0x100002930 blr x8 ; Virtual Call : sym.Dog::_Dog_0x100002c18
| ,==< 0x100002934 b 0x100002938
| || ; CODE XREF from entry0 @ 0x100002934
| ``-> 0x100002938 ldur x8, [var_28h]
| 0x10000293c str x8, [var_68h]
| 0x100002940 subs x8, x8, 0
| 0x100002944 cset w8, eq
| ,=< 0x100002948 tbnz w8, 0, 0x100002964
| ,==< 0x10000294c b 0x100002950
| || ; CODE XREF from entry0 @ 0x10000294c
| `--> 0x100002950 ldr x0, [var_68h] ; [0x8:4]=-1 ; 8
| | 0x100002954 ldr x8, [x0]
| | 0x100002958 ldr x8, [x8, 8] ; [0x8:4]=-1 ; 8
| | 0x10000295c blr x8 ; Virtual Call : sym.Cat::_Cat_0x100003940
| ,==< 0x100002960 b 0x100002964
| || ; CODE XREF from entry0 @ 0x100002960
| ``-> 0x100002964 ldur x8, [var_30h]
| 0x100002968 str x8, [sp]
| 0x10000296c subs x8, x8, 0
| 0x100002970 cset w8, eq
| ,=< 0x100002974 tbnz w8, 0, 0x100002990
| ,==< 0x100002978 b 0x10000297c
| || ; CODE XREF from entry0 @ 0x100002978
| `--> 0x10000297c ldr x0, [sp]
| | 0x100002980 ldr x8, [x0]
| | 0x100002984 ldr x8, [x8, 8] ; [0x8:4]=-1 ; 8
| | 0x100002988 blr x8 ; Virtual Call : sym.Human::_Human_0x100003adc
| ,==< 0x10000298c b 0x100002990
| || ; CODE XREF from entry0 @ 0x10000298c
| ``-> 0x100002990 ldur w0, [var_14h]
| 0x100002994 ldp fp, lr, [var_10h]
| 0x100002998 add sp, sp, 0x70
\ 0x10000299c ret
EOF
RUN
NAME=cxx class analysis for classes with conditionals (arm64)
FILE=bins/mach0/arm64-class-conditional
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; UNKNOWN XREF from aav.0x100000028 @ +0xa8
;-- main:
;-- section.0.__TEXT.__text:
;-- _main:
;-- func.10000282c:
;-- pc:
/ entry0(int64_t arg1);
| ; arg int64_t arg1 @ x0
| ; var int64_t var_58h @ stack - 0x58
| ; var int64_t var_50h @ stack - 0x50
| ; var int64_t var_48h @ stack - 0x48
| ; var int64_t var_40h @ stack - 0x40
| ; var int64_t var_24h @ stack - 0x24
| ; var union RZ_var_20h_HYBRID var_20h @ stack - 0x20
| ; var int64_t var_14h @ stack - 0x14
| ; var int64_t var_10h @ stack - 0x10
| ; var int64_t var_8h @ stack - 0x8
| 0x10000282c sub sp, sp, 0x60 ; [00] -r-x section size 4980 named 0.__TEXT.__text
| 0x100002830 stp fp, lr, [var_10h]
| 0x100002834 add fp, sp, 0x50
| 0x100002838 stur wzr, [var_14h] ; arg1
| 0x10000283c mov x0, 0 ; int seed
| 0x100002840 bl sym.imp.time ; time_t time(time_t *timer)
| 0x100002844 bl sym.imp.srand ; void srand(int seed)
| 0x100002848 bl sym.imp.rand ; int rand(void)
| 0x10000284c stur w0, [var_24h]
| 0x100002850 ldur w8, [var_24h]
| 0x100002854 mov w10, 3
| 0x100002858 sdiv w9, w8, w10
| 0x10000285c mul w9, w9, w10
| 0x100002860 subs w8, w8, w9
| 0x100002864 subs w8, w8, 2
| 0x100002868 cset w8, ne
| ,=< 0x10000286c tbnz w8, 0, 0x1000028c0
| ,==< 0x100002870 b 0x100002874
| || ; CODE XREF from entry0 @ 0x100002870
| `--> 0x100002874 mov x0, 8
| | 0x100002878 bl sym.imp.operator_new_unsigned_long
| | 0x10000287c str x0, [var_40h]
| | 0x100002880 bl method.Dog.Dog ; method.Dog.Dog(int64_t arg1)
| ,==< 0x100002884 b 0x100002888
| || ; CODE XREF from entry0 @ 0x100002884
| `--> 0x100002888 ldr x8, [var_40h] ; [0x20:4]=-1 ; 32
| | 0x10000288c stur x8, [var_20h.var_20h]
| | 0x100002890 ldur x0, [var_20h.var_20h]
| | 0x100002894 ldr x8, [x0]
| | 0x100002898 ldr x8, [x8, 0x10] ; [0x10:4]=-1 ; 16
| | 0x10000289c blr x8 ; Virtual Call : method.Dog.run / method.Human.run / method.Cat.run
| ,==< 0x1000028a0 b 0x100002980
..
| ||`-> 0x1000028c0 ldur w8, [var_24h]
| || 0x1000028c4 mov w10, 3
| || 0x1000028c8 sdiv w9, w8, w10
| || 0x1000028cc mul w9, w9, w10
| || 0x1000028d0 subs w8, w8, w9
| || 0x1000028d4 subs w8, w8, 1
| || 0x1000028d8 cset w8, ne
| ||,=< 0x1000028dc tbnz w8, 0, 0x100002930
| ,====< 0x1000028e0 b 0x1000028e4
| |||| ; CODE XREF from entry0 @ 0x1000028e0
| `----> 0x1000028e4 mov x0, 8
| ||| 0x1000028e8 bl sym.imp.operator_new_unsigned_long
| ||| 0x1000028ec str x0, [var_48h]
| ||| 0x1000028f0 bl method.Cat.Cat ; method.Cat.Cat(int64_t arg1)
| ,====< 0x1000028f4 b 0x1000028f8
| |||| ; CODE XREF from entry0 @ 0x1000028f4
| `----> 0x1000028f8 ldr x8, [var_48h] ; [0x18:4]=-1 ; 24
| ||| 0x1000028fc stur x8, [var_20h.var_20h]
| ||| 0x100002900 ldur x0, [var_20h.var_20h]
| ||| 0x100002904 ldr x8, [x0]
| ||| 0x100002908 ldr x8, [x8, 0x10] ; [0x10:4]=-1 ; 16
| ||| 0x10000290c blr x8 ; Virtual Call : method.Dog.run / method.Human.run / method.Cat.run
| ,====< 0x100002910 b 0x10000297c
..
| ||||`-> 0x100002930 mov x0, 8
| |||| 0x100002934 bl sym.imp.operator_new_unsigned_long
| |||| 0x100002938 str x0, [var_50h]
| |||| 0x10000293c bl method.Human.Human ; method.Human.Human(int64_t arg1)
| ||||,=< 0x100002940 b 0x100002944
| ||||| ; CODE XREF from entry0 @ 0x100002940
| ||||`-> 0x100002944 ldr x8, [var_50h] ; [0x10:4]=-1 ; 16
| |||| 0x100002948 stur x8, [var_20h.var_20h]
| |||| 0x10000294c ldur x0, [var_20h.var_20h]
| |||| 0x100002950 ldr x8, [x0]
| |||| 0x100002954 ldr x8, [x8, 0x10] ; [0x10:4]=-1 ; 16
| |||| 0x100002958 blr x8 ; Virtual Call : method.Dog.run / method.Human.run / method.Cat.run
| ||||,=< 0x10000295c b 0x10000297c
..
| |||||| ; CODE XREFS from entry0 @ 0x100002910, 0x10000295c
| ,==`--`-> 0x10000297c b 0x100002980
| ||| || ; CODE XREFS from entry0 @ 0x1000028a0, 0x10000297c
| `----`--> 0x100002980 ldur x0, [var_20h.var_20h]
| || | 0x100002984 ldr x8, [x0]
| || | 0x100002988 ldr x8, [x8, 0x18] ; [0x18:4]=-1 ; 24
| || | 0x10000298c blr x8 ; Virtual Call : method.Dog.walk / method.Human.walk / method.Cat.walk
| || | 0x100002990 ldur x8, [var_20h.var_20h]
| || | 0x100002994 str x8, [var_58h]
| || | 0x100002998 subs x8, x8, 0
| || | 0x10000299c cset w8, eq
| || | ,=< 0x1000029a0 tbnz w8, 0, 0x1000029bc
| || |,==< 0x1000029a4 b 0x1000029a8
| || ||| ; CODE XREF from entry0 @ 0x1000029a4
| || |`--> 0x1000029a8 ldr x0, [var_58h] ; [0x8:4]=-1 ; 8
| || | | 0x1000029ac ldr x8, [x0]
| || | | 0x1000029b0 ldr x8, [x8, 8] ; [0x8:4]=-1 ; 8
| || | | 0x1000029b4 blr x8 ; Virtual Call : sym.Dog::_Dog_0x100002bf0 / sym.Human::_Human_0x100003ab4 / sym.Cat::_Cat_0x100003918
| || |,==< 0x1000029b8 b 0x1000029bc
| || ||| ; CODE XREF from entry0 @ 0x1000029b8
| || |``-> 0x1000029bc ldur w0, [var_14h]
| || | 0x1000029c0 ldp fp, lr, [var_10h]
| || | 0x1000029c4 add sp, sp, 0x60
\ || | 0x1000029c8 ret
EOF
RUN
NAME=cxx class analysis for classes with multiple vtables (arm64)
FILE=bins/mach0/arm64-class-multi-vtable
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; UNKNOWN XREF from aav.0x100000028 @ +0xa8
;-- main:
;-- section.0.__TEXT.__text:
;-- _main:
;-- func.100002ea0:
;-- pc:
/ entry0(int64_t arg1);
| ; arg int64_t arg1 @ x0
| ; var int64_t var_30h @ stack - 0x30
| ; var int64_t var_24h @ stack - 0x24
| ; var struct C *var_20h @ stack - 0x20
| ; var int64_t var_14h @ stack - 0x14
| ; var int64_t var_10h @ stack - 0x10
| ; var int64_t var_8h @ stack - 0x8
| 0x100002ea0 sub sp, sp, 0x30 ; [00] -r-x section size 3740 named 0.__TEXT.__text
| 0x100002ea4 stp fp, lr, [var_10h]
| 0x100002ea8 add fp, sp, 0x20
| 0x100002eac mov w8, 0
| 0x100002eb0 str w8, [var_24h]
| 0x100002eb4 stur wzr, [var_14h] ; arg1
| 0x100002eb8 mov x0, 0x10
| 0x100002ebc bl sym.imp.operator_new_unsigned_long
| 0x100002ec0 str x0, [sp]
| 0x100002ec4 str xzr, [x0]
| 0x100002ec8 str xzr, [x0, 8]
| 0x100002ecc bl method.C.C ; method.C.C(int64_t arg1)
| 0x100002ed0 ldr x0, [sp]
| 0x100002ed4 str x0, [var_20h]
| 0x100002ed8 ldr x0, [var_20h] ; [0x10:4]=-1 ; 16
| 0x100002edc ldr x8, [x0]
| 0x100002ee0 ldr x8, [x8]
| 0x100002ee4 blr x8 ; Virtual Call : sym.non_virtual_thunk_to_C::showB / method.C.showA
| 0x100002ee8 ldr x0, [var_20h] ; [0x10:4]=-1 ; 16
| 0x100002eec ldr x8, [x0]
| 0x100002ef0 ldr x8, [x8, 8] ; [0x8:4]=-1 ; 8
| 0x100002ef4 blr x8 ; Virtual Call : method.C.showB
| 0x100002ef8 ldr x0, [var_20h] ; [0x10:4]=-1 ; 16
| 0x100002efc ldr x8, [x0]
| 0x100002f00 ldr x8, [x8, 0x10] ; [0x10:4]=-1 ; 16
| 0x100002f04 blr x8 ; Virtual Call : method.C.showC
| 0x100002f08 ldr w0, [var_24h] ; [0xc:4]=-1 ; 12
| 0x100002f0c ldp fp, lr, [var_10h]
| 0x100002f10 add sp, sp, 0x30
\ 0x100002f14 ret
EOF
RUN
NAME=cxx class analysis for classes with multiple vtables & w/o rtti (x86)
FILE=bins/elf/analysis/x86-no-rtti-class-multi-vtable
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; DATA XREF from sym._start_c @ 0x40086b
;-- rip:
/ int main(int argc, char **argv, char **envp);
| ; var struct Dog *var_20h @ stack - 0x20
| 0x004009ad push rbp
| 0x004009ae mov rbp, rsp
| 0x004009b1 push r12
| 0x004009b3 push rbx
| 0x004009b4 sub rsp, 0x10
| 0x004009b8 mov edi, 0x10 ; rsi
| 0x004009bd call sym.imp.operator_new_unsigned_long
| 0x004009c2 mov rbx, rax
| 0x004009c5 mov rdi, rbx ; int64_t arg1
| 0x004009c8 call method.Dog.Dog ; method.Dog.Dog(int64_t arg1)
| 0x004009cd mov qword [var_20h], rbx
| 0x004009d1 mov rax, qword [var_20h]
| 0x004009d5 mov rax, qword [rax]
| 0x004009d8 add rax, 0x18 ; 24
| 0x004009dc mov rdx, qword [rax]
| 0x004009df mov rax, qword [var_20h]
| 0x004009e3 mov rdi, rax
| 0x004009e6 call rdx ; Virtual Call : method.Dog.walk
| ;-- rbp:
| 0x004009e8 mov rax, qword [var_20h]
| 0x004009ec mov rax, qword [rax]
| 0x004009ef add rax, 0x10 ; rsi
| 0x004009f3 mov rdx, qword [rax]
| 0x004009f6 mov rax, qword [var_20h]
| 0x004009fa mov rdi, rax
| 0x004009fd call rdx ; Virtual Call : method.Dog.eat / sym.non_virtual_thunk_to_Dog::walk
| ;-- r12:
| 0x004009ff mov rax, qword [var_20h]
| 0x00400a03 test rax, rax
| ,=< 0x00400a06 jz 0x400a17
| | 0x00400a08 mov rdx, qword [rax]
| | 0x00400a0b add rdx, 0x08
| | 0x00400a0f mov rdx, qword [rdx]
| | 0x00400a12 mov rdi, rax
| | 0x00400a15 call rdx ; Virtual Call : sym.non_virtual_thunk_to_Dog::_Dog_0x400ca5 / sym.Dog::_Dog_0x400c7a
| | ;-- rbx:
| `-> 0x00400a17 mov eax, 0x00
| ,=< 0x00400a1c jmp 0x400a39
..
| | ; CODE XREF from main @ 0x400a1c
| `-> 0x00400a39 add rsp, 0x10
| 0x00400a3d pop rbx
| 0x00400a3e pop r12
| 0x00400a40 pop rbp
\ 0x00400a41 ret
EOF
RUN
NAME=cxx class analysis for classes with multiple vtables & w/o rtti (arm64)
FILE=bins/mach0/arm64-no-rtti-class-multi-vtable
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; UNKNOWN XREF from aav.0x100000028 @ +0xa8
;-- main:
;-- section.0.__TEXT.__text:
;-- _main:
;-- func.100002c70:
;-- pc:
/ entry0(int64_t arg1);
| ; arg int64_t arg1 @ x0
| ; var int64_t var_40h @ stack - 0x40
| ; var int64_t var_38h @ stack - 0x38
| ; var struct Dog *var_20h @ stack - 0x20
| ; var int64_t var_14h @ stack - 0x14
| ; var int64_t var_10h @ stack - 0x10
| ; var int64_t var_8h @ stack - 0x8
| 0x100002c70 sub sp, sp, 0x40 ; [00] -r-x section size 4120 named 0.__TEXT.__text
| 0x100002c74 stp fp, lr, [sp, 0lr]
| 0x100002c78 add fp, sp, 0x30
| 0x100002c7c stur wzr, [var_14h] ; arg1
| 0x100002c80 mov x0, 0x10
| 0x100002c84 bl sym.imp.operator_new_unsigned_long
| 0x100002c88 str x0, [var_38h]
| 0x100002c8c bl method.Dog.Dog ; method.Dog.Dog(int64_t arg1)
| ,=< 0x100002c90 b 0x100002c94
| | ; CODE XREF from entry0 @ 0x100002c90
| `-> 0x100002c94 ldr x8, [var_38h] ; [0x8:4]=-1 ; 8
| 0x100002c98 stur x8, [var_20h]
| 0x100002c9c ldur x0, [var_20h]
| 0x100002ca0 ldr x8, [x0]
| 0x100002ca4 ldr x8, [x8, 0x18] ; [0x18:4]=-1 ; 24
| 0x100002ca8 blr x8 ; Virtual Call : method.Dog.walk
| 0x100002cac ldur x0, [var_20h]
| 0x100002cb0 ldr x8, [x0]
| 0x100002cb4 ldr x8, [x8, 0x10] ; [0x10:4]=-1 ; 16
| 0x100002cb8 blr x8 ; Virtual Call : method.Dog.eat / sym.non_virtual_thunk_to_Dog::walk
| 0x100002cbc ldur x8, [var_20h]
| 0x100002cc0 str x8, [sp]
| 0x100002cc4 subs x8, x8, 0
| 0x100002cc8 cset w8, eq
| ,=< 0x100002ccc tbnz w8, 0, 0x100002ce8
| ,==< 0x100002cd0 b 0x100002cd4
| || ; CODE XREF from entry0 @ 0x100002cd0
| `--> 0x100002cd4 ldr x0, [sp]
| | 0x100002cd8 ldr x8, [x0]
| | 0x100002cdc ldr x8, [x8, 8] ; [0x8:4]=-1 ; 8
| | 0x100002ce0 blr x8 ; Virtual Call : sym.non_virtual_thunk_to_Dog::_Dog_0x100003068 / sym.Dog::_Dog_0x100002fbc
| ,==< 0x100002ce4 b 0x100002ce8
| || ; CODE XREF from entry0 @ 0x100002ce4
| ``-> 0x100002ce8 ldur w0, [var_14h]
| 0x100002cec ldp fp, lr, [sp, 0lr]
| 0x100002cf0 add sp, sp, 0x40
\ 0x100002cf4 ret
EOF
RUN
NAME=objc msg dispatch (amd64)
FILE=bins/mach0/objc-employee
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
;-- main:
;-- section.0.__TEXT.__text:
;-- _main:
;-- func.1000018c0:
/ entry0(int64_t arg1, int64_t arg2);
| ; arg int64_t arg1 @ rdi
| ; arg int64_t arg2 @ rsi
| ; var int var_a8h @ stack - 0xa8
| ; var int var_a4h @ stack - 0xa4
| ; var int var_a0h @ stack - 0xa0
| ; var int var_9ch @ stack - 0x9c
| ; var void *var_98h @ stack - 0x98
| ; var int var_8ch @ stack - 0x8c
| ; var void *var_88h @ stack - 0x88
| ; var int var_7ch @ stack - 0x7c
| ; var void *var_78h @ stack - 0x78
| ; var int var_6ch @ stack - 0x6c
| ; var void *var_68h @ stack - 0x68
| ; var int64_t var_60h @ stack - 0x60
| ; var int64_t var_58h @ stack - 0x58
| ; var void *var_50h @ stack - 0x50
| ; var int64_t var_48h @ stack - 0x48
| ; var const char *var_40h @ stack - 0x40
| ; var int64_t var_34h @ stack - 0x34
| ; var int64_t var_30h @ stack - 0x30
| ; var void *var_28h @ stack - 0x28
| ; var const char **format @ stack - 0x20
| ; var int64_t var_18h @ stack - 0x18
| ; var int64_t var_10h @ stack - 0x10
| ; var int64_t var_ch @ stack - 0xc
| 0x1000018c0 push rbp ; [00] -r-x section size 1126 named 0.__TEXT.__text
| 0x1000018c1 mov rbp, rsp
| 0x1000018c4 sub rsp, 0xb0
| 0x1000018cb mov dword [var_ch], 0x00
| 0x1000018d2 mov dword [var_10h], edi ; arg1
| 0x1000018d5 mov qword [var_18h], rsi ; arg2
| 0x1000018d9 call sym.imp.objc_autoreleasePoolPush
| 0x1000018de lea rsi, qword reloc.__CFConstantStringClassReference ; str.cstr.Hello_World_Object
| ; 0x100002010
| 0x1000018e5 mov rdi, rsi
| 0x1000018e8 mov qword [var_48h], rax
| 0x1000018ec mov al, 0x00
| 0x1000018ee call sym.imp.NSLog
| 0x1000018f3 mov rsi, qword [section.15.__DATA.__objc_classrefs] ; [0x100003320:8]=0x100003370 sym.class_Employee ; "p3"
| 0x1000018fa mov rdi, rsi
| 0x1000018fd call sym.imp.objc_alloc_init
| 0x100001902 mov qword [format], rax
| 0x100001906 mov rax, qword [format]
| 0x10000190a mov rsi, qword [section.14.__DATA.__objc_selrefs] ; [0x1000032f8:8]=0x100001ecf section.4.__TEXT.__objc_methname
| 0x100001911 mov rdi, rax
| 0x100001914 call qword [reloc.objc_msgSend] ; [0x100002000:8]=0 ; Message dispatch to method_Employee_sayHello
| 0x10000191a mov rsi, qword [section.15.__DATA.__objc_classrefs] ; [0x100003320:8]=0x100003370 sym.class_Employee ; "p3"
| 0x100001921 mov rdi, qword [section.14.__DATA.__objc_selrefs] ; [0x1000032f8:8]=0x100001ecf section.4.__TEXT.__objc_methname
| 0x100001928 mov qword [var_50h], rdi
| 0x10000192c mov rdi, rsi
| 0x10000192f mov rsi, qword [var_50h]
| 0x100001933 mov qword [var_58h], rax
| 0x100001937 call qword [reloc.objc_msgSend] ; [0x100002000:8]=0 ; Message dispatch to method_Employee_sayHello
| 0x10000193d mov rsi, qword [format]
| 0x100001941 lea rdi, qword str.base__p ; 0x100001dbe ; "base %p\n" ; const char *format
| 0x100001948 mov qword [var_60h], rax
| 0x10000194c mov al, 0x00
| 0x10000194e call sym.imp.printf ; int printf(const char *format)
| 0x100001953 mov rsi, qword [format]
| 0x100001957 mov qword [var_28h], rsi
| 0x10000195b mov rsi, qword [format]
| 0x10000195f mov rdi, qword [data.100003300] ; [0x100003300:8]=0x100001ed8 "p0"
| 0x100001966 mov qword [var_68h], rdi
| 0x10000196a mov rdi, rsi
| 0x10000196d mov rsi, qword [var_68h]
| 0x100001971 mov dword [var_6ch], eax
| 0x100001974 call qword [reloc.objc_msgSend] ; [0x100002000:8]=0
| 0x10000197a mov rsi, qword [var_28h]
| 0x10000197e sub rax, rsi
| 0x100001981 lea rdi, qword str.iii__p__username ; 0x100001dc7 ; "iii %p _username\n" ; const char *format
| 0x100001988 mov rsi, rax
| 0x10000198b mov al, 0x00
| 0x10000198d call sym.imp.printf ; int printf(const char *format)
| 0x100001992 mov rsi, qword [format]
| 0x100001996 mov rdi, qword [data.100003308] ; [0x100003308:8]=0x100001edb "p1"
| 0x10000199d mov qword [var_78h], rdi
| 0x1000019a1 mov rdi, rsi
| 0x1000019a4 mov rsi, qword [var_78h]
| 0x1000019a8 mov dword [var_7ch], eax
| 0x1000019ab call qword [reloc.objc_msgSend] ; [0x100002000:8]=0
| 0x1000019b1 mov rsi, qword [var_28h]
| 0x1000019b5 sub rax, rsi
| 0x1000019b8 lea rdi, qword str.iii__p__firstName ; 0x100001dd9 ; "iii %p _firstName\n" ; const char *format
| 0x1000019bf mov rsi, rax
| 0x1000019c2 mov al, 0x00
| 0x1000019c4 call sym.imp.printf ; int printf(const char *format)
| 0x1000019c9 mov rsi, qword [format]
| 0x1000019cd mov rdi, qword [data.100003310] ; [0x100003310:8]=0x100001ede "p2"
| 0x1000019d4 mov qword [var_88h], rdi
| 0x1000019d8 mov rdi, rsi
| 0x1000019db mov rsi, qword [var_88h]
| 0x1000019df mov dword [var_8ch], eax
| 0x1000019e5 call qword [reloc.objc_msgSend] ; [0x100002000:8]=0
| 0x1000019eb mov rsi, qword [var_28h]
| 0x1000019ef sub rax, rsi
| 0x1000019f2 lea rdi, qword str.iii__p__shortWord ; 0x100001dec ; "iii %p _shortWord\n" ; const char *format
| 0x1000019f9 mov rsi, rax
| 0x1000019fc mov al, 0x00
| 0x1000019fe call sym.imp.printf ; int printf(const char *format)
| 0x100001a03 mov rsi, qword [format]
| 0x100001a07 mov rdi, qword [data.100003318] ; [0x100003318:8]=0x100001ee1 "p3"
| 0x100001a0e mov qword [var_98h], rdi
| 0x100001a15 mov rdi, rsi
| 0x100001a18 mov rsi, qword [var_98h]
| 0x100001a1f mov dword [var_9ch], eax
| 0x100001a25 call qword [reloc.objc_msgSend] ; [0x100002000:8]=0
| 0x100001a2b mov rsi, qword [var_28h]
| 0x100001a2f sub rax, rsi
| 0x100001a32 lea rdi, qword str.iii__p__wideWord ; 0x100001dff ; "iii %p _wideWord\n" ; const char *format
| 0x100001a39 mov rsi, rax
| 0x100001a3c mov al, 0x00
| 0x100001a3e call sym.imp.printf ; int printf(const char *format)
| 0x100001a43 mov rsi, qword [format]
| 0x100001a47 mov qword [var_30h], rsi
| 0x100001a4b mov dword [var_34h], 0x00
| 0x100001a52 mov dword [var_a0h], eax
| ; CODE XREF from entry0 @ 0x100001a8b
| .-> 0x100001a58 cmp dword [var_34h], 0x20
| ,==< 0x100001a5c jnl 0x100001a90
| |: 0x100001a62 mov rax, qword [var_30h]
| |: 0x100001a66 movsxd rcx, dword [var_34h]
| |: 0x100001a6a movzx esi, byte [rax+rcx*1]
| |: 0x100001a6e lea rdi, qword str.02x ; 0x100001e11 ; "%02x " ; const char *format
| |: 0x100001a75 mov al, 0x00
| |: 0x100001a77 call sym.imp.printf ; int printf(const char *format)
| |: 0x100001a7c mov dword [var_a4h], eax
| |: 0x100001a82 mov eax, dword [var_34h]
| |: 0x100001a85 add eax, 0x01
| |: 0x100001a88 mov dword [var_34h], eax
| |`=< 0x100001a8b jmp 0x100001a58
| `--> 0x100001a90 lea rdi, qword data.100001e17 ; 0x100001e17 ; "\n" ; const char *format
| 0x100001a97 mov al, 0x00
| 0x100001a99 call sym.imp.printf ; int printf(const char *format)
| 0x100001a9e lea rdi, qword reloc.__CFConstantStringClassReference.100002030 ; rsi
| ; 0x100002030
| 0x100001aa5 mov qword [var_40h], rdi
| 0x100001aa9 mov rsi, qword [var_40h]
| 0x100001aad lea rdi, qword data.100001e28 ; 0x100001e28 ; "%p\n" ; const char *format
| 0x100001ab4 mov dword [var_a8h], eax
| 0x100001aba mov al, 0x00
| 0x100001abc call sym.imp.printf ; int printf(const char *format)
\ 0x100001ac1 int3
EOF
RUN
NAME=objc msg dispatch (arm64)
FILE=bins/mach0/objc-employee-ios14-arm64
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; UNKNOWN XREF from segment.TEXT @ +0xd0
;-- main:
;-- section.0.__TEXT.__text:
;-- _main:
;-- func.100007714:
/ entry0(int64_t arg1, int64_t arg2);
| ; arg int64_t arg1 @ x0
| ; arg int64_t arg2 @ x1
| ; var int64_t var_80h @ stack - 0x80
| ; var int64_t var_68h @ stack - 0x68
| ; var int64_t var_60h @ stack - 0x60
| ; var int64_t var_58h @ stack - 0x58
| ; var int64_t var_50h @ stack - 0x50
| ; var int64_t var_48h @ stack - 0x48
| ; var int64_t var_3ch @ stack - 0x3c
| ; var int64_t var_38h @ stack - 0x38
| ; var int64_t var_30h @ stack - 0x30
| ; var int64_t var_28h @ stack - 0x28
| ; var int64_t var_20h @ stack - 0x20
| ; var int64_t var_18h @ stack - 0x18
| ; var int64_t var_14h @ stack - 0x14
| ; var int64_t var_10h @ stack - 0x10
| ; var int64_t var_8h @ stack - 0x8
| 0x100007714 sub sp, sp, 0x80 ; [00] -r-x section size 1180 named 0.__TEXT.__text
| 0x100007718 stp fp, lr, [var_10h]
| 0x10000771c add fp, sp, 0x70
| 0x100007720 stur wzr, [var_14h] ; arg1
| 0x100007724 stur w0, [var_18h] ; arg1
| 0x100007728 stur x1, [var_20h] ; arg2
| 0x10000772c bl fcn.100007bd4
| 0x100007730 adrp x8, reloc.dyld_stub_binder ; 0x100008000
| 0x100007734 add x8, x8, 8 ; 0x100008008
| ; reloc.__CFConstantStringClassReference
| 0x100007738 str x0, [var_50h]
| 0x10000773c mov x0, x8
| 0x100007740 bl section.1.__TEXT.__stubs ; section.1.__TEXT.__stubs(void)
| 0x100007744 adrp x8, reloc.NSLog ; 0x10000c000
| 0x100007748 add x8, x8, 0x220 ; 0x10000c220 ; "`\xc2"
| 0x10000774c ldr x0, [x8] ; [0x10000c220:4]=0xc260 ; "`\xc2"
| 0x100007750 str x8, [var_58h]
| 0x100007754 bl fcn.100007bbc
| 0x100007758 stur x0, [var_28h]
| 0x10000775c ldur x0, [var_28h]
| 0x100007760 adrp x8, reloc.NSLog ; 0x10000c000
| 0x100007764 add x8, x8, 0x1f0
| 0x100007768 ldr x1, [x8] ; [0x100007ea9:4]=0x48796173 ; "sayHello"
| 0x10000776c str x8, [var_60h]
| 0x100007770 bl fcn.100007bec ; Message dispatch to method_Employee_sayHello
| 0x100007774 ldr x8, [var_58h] ; [0x28:4]=-1 ; 40
| 0x100007778 ldr x0, [x8]
| 0x10000777c ldr x9, [var_60h] ; [0x20:4]=-1 ; 32
| 0x100007780 ldr x1, [x9]
| 0x100007784 bl fcn.100007bec ; Message dispatch to method_Employee_sayHello
| 0x100007788 ldur x8, [var_28h]
| 0x10000778c adrp x0, data.100007000 ; 0x100007000
| 0x100007790 add x0, x0, 0xd98 ; 0x100007d98 ; "base %p\n"
| 0x100007794 mov x9, sp
| 0x100007798 str x8, [x9]
| 0x10000779c bl fcn.100007c1c
| 0x1000077a0 ldur x8, [var_28h]
| 0x1000077a4 adrp x9, reloc.NSLog ; 0x10000c000
| 0x1000077a8 add x9, x9, 0x1f8
| 0x1000077ac ldr x1, [x9] ; [0x100007eb2:4]=0x65736162 ; "base"
| 0x1000077b0 mov x0, x8
| 0x1000077b4 bl fcn.100007bec ; Message dispatch to method_Employee_base
| 0x1000077b8 stur x0, [var_30h]
| 0x1000077bc ldur x0, [var_28h]
| 0x1000077c0 adrp x8, reloc.NSLog ; 0x10000c000
| 0x1000077c4 add x8, x8, 0x200
| 0x1000077c8 ldr x1, [x8]
| 0x1000077cc bl fcn.100007bec
| 0x1000077d0 ldur x8, [var_30h]
| 0x1000077d4 subs x8, x0, x8
| 0x1000077d8 adrp x0, data.100007000 ; 0x100007000
| 0x1000077dc add x0, x0, 0xda1 ; 0x100007da1 ; "iii %p _username\n"
| 0x1000077e0 mov x9, sp
| 0x1000077e4 str x8, [x9]
| 0x1000077e8 bl fcn.100007c1c
| 0x1000077ec ldur x8, [var_28h]
| 0x1000077f0 adrp x9, reloc.NSLog ; 0x10000c000
| 0x1000077f4 add x9, x9, 0x208
| 0x1000077f8 ldr x1, [x9]
| 0x1000077fc mov x0, x8
| 0x100007800 bl fcn.100007bec
| 0x100007804 ldur x8, [var_30h]
| 0x100007808 subs x8, x0, x8
| 0x10000780c adrp x0, data.100007000 ; 0x100007000
| 0x100007810 add x0, x0, 0xdb3 ; 0x100007db3 ; "iii %p _firstName\n"
| 0x100007814 mov x9, sp
| 0x100007818 str x8, [x9]
| 0x10000781c bl fcn.100007c1c
| 0x100007820 ldur x8, [var_28h]
| 0x100007824 adrp x9, reloc.NSLog ; 0x10000c000
| 0x100007828 add x9, x9, 0x210
| 0x10000782c ldr x1, [x9]
| 0x100007830 mov x0, x8
| 0x100007834 bl fcn.100007bec
| 0x100007838 ldur x8, [var_30h]
| 0x10000783c subs x8, x0, x8
| 0x100007840 adrp x0, data.100007000 ; 0x100007000
| 0x100007844 add x0, x0, 0xdc6 ; 0x100007dc6 ; "iii %p _shortWord\n"
| 0x100007848 mov x9, sp
| 0x10000784c str x8, [x9]
| 0x100007850 bl fcn.100007c1c
| 0x100007854 ldur x8, [var_28h]
| 0x100007858 adrp x9, reloc.NSLog ; 0x10000c000
| 0x10000785c add x9, x9, 0x218
| 0x100007860 ldr x1, [x9]
| 0x100007864 mov x0, x8
| 0x100007868 bl fcn.100007bec
| 0x10000786c ldur x8, [var_30h]
| 0x100007870 subs x8, x0, x8
| 0x100007874 adrp x0, data.100007000 ; 0x100007000
| 0x100007878 add x0, x0, 0xdd9 ; 0x100007dd9 ; "iii %p _wideWord\n"
| 0x10000787c mov x9, sp
| 0x100007880 str x8, [x9]
| 0x100007884 bl fcn.100007c1c
| 0x100007888 ldur x8, [var_28h]
| 0x10000788c stur x8, [var_38h]
| 0x100007890 stur wzr, [var_3ch]
| ; CODE XREF from entry0 @ 0x1000078d0
| .-> 0x100007894 ldur w8, [var_3ch]
| : 0x100007898 cmp w8, 0x20
| ,==< 0x10000789c b.ge 0x1000078d4
| |: 0x1000078a0 ldur x8, [var_38h]
| |: 0x1000078a4 ldursw x9, [var_3ch]
| |: 0x1000078a8 ldrb w10, [x8, x9]
| |: 0x1000078ac adrp x0, data.100007000 ; 0x100007000
| |: 0x1000078b0 add x0, x0, 0xdeb ; 0x100007deb ; "%02x "
| |: 0x1000078b4 mov x8, sp
| |: 0x1000078b8 mov x1, x10
| |: 0x1000078bc str x1, [x8]
| |: 0x1000078c0 bl fcn.100007c1c
| |: 0x1000078c4 ldur w8, [var_3ch]
| |: 0x1000078c8 add w8, w8, 1
| |: 0x1000078cc stur w8, [var_3ch]
| |`=< 0x1000078d0 b 0x100007894
| `--> 0x1000078d4 adrp x0, data.100007000 ; 0x100007000
| 0x1000078d8 add x0, x0, 0xdf1
| 0x1000078dc bl fcn.100007c1c
| 0x1000078e0 adrp x8, reloc.dyld_stub_binder ; 0x100008000
| 0x1000078e4 add x8, x8, 0x28 ; 0x100008028
| ; x9
| 0x1000078e8 mov x0, x8
| 0x1000078ec bl fcn.100007bf8
| 0x1000078f0 add x8, var_48h
| 0x1000078f4 str x0, [var_48h]
| 0x1000078f8 ldr x9, [var_48h] ; x1
| ; [0x38:4]=-1
| 0x1000078fc adrp x0, data.100007000 ; 0x100007000
| 0x100007900 add x0, x0, 0xe02 ; 0x100007e02 ; "%p\n"
| 0x100007904 mov x10, sp
| 0x100007908 str x9, [x10]
| 0x10000790c str x8, [var_68h]
| 0x100007910 bl fcn.100007c1c
| ;-- x30:
| ;-- lr:
| ;-- pc:
\ 0x100007914 brk 1
EOF
RUN
NAME=objc msg dispatch (arm64)
FILE=bins/mach0/objc-employee-ios14-arm64e
CMDS=<<EOF
aaaa
avD @ main
pdf @ main
EOF
EXPECT=<<EOF
; UNKNOWN XREF from segment.TEXT @ +0xd0
;-- main:
;-- section.0.__TEXT.__text:
;-- _main:
;-- func.100007760:
/ entry0(int64_t arg1, int64_t arg2);
| ; arg int64_t arg1 @ x0
| ; arg int64_t arg2 @ x1
| ; var int64_t var_80h @ stack - 0x80
| ; var int64_t var_68h @ stack - 0x68
| ; var int64_t var_60h @ stack - 0x60
| ; var int64_t var_58h @ stack - 0x58
| ; var int64_t var_50h @ stack - 0x50
| ; var int64_t var_48h @ stack - 0x48
| ; var int64_t var_3ch @ stack - 0x3c
| ; var int64_t var_38h @ stack - 0x38
| ; var int64_t var_30h @ stack - 0x30
| ; var void *instance @ stack - 0x28
| ; var int64_t var_20h @ stack - 0x20
| ; var int64_t var_18h @ stack - 0x18
| ; var int64_t var_14h @ stack - 0x14
| ; var int64_t var_10h @ stack - 0x10
| ; var int64_t var_8h @ stack - 0x8
| 0x100007760 pacibsp ; [00] -r-x section size 1208 named 0.__TEXT.__text
| 0x100007764 sub sp, sp, 0x80
| 0x100007768 stp fp, lr, [var_10h]
| 0x10000776c add fp, sp, 0x70
| 0x100007770 stur wzr, [var_14h] ; arg1
| 0x100007774 stur w0, [var_18h] ; arg1
| 0x100007778 stur x1, [var_20h] ; arg2
| 0x10000777c bl sym.imp.objc_autoreleasePoolPush
| 0x100007780 adrp x8, reloc.NSLog ; 0x100008000
| 0x100007784 add x8, x8, 0x50 ; 0x100008050 ; "X\x80\U00000001"
| 0x100007788 str x0, [var_50h]
| 0x10000778c mov x0, x8
| 0x100007790 bl sym.imp.NSLog
| 0x100007794 adrp x8, sym.__OBJC_METACLASS_RO___Employee ; 0x10000c000
| 0x100007798 add x8, x8, 0x1d0 ; 0x10000c1d0
| ; section.14.__DATA.__objc_classrefs
| 0x10000779c ldr x0, [x8] ; [0x10000c1d0:4]=0xc210 ; section.14.__DATA.__objc_classrefs
| 0x1000077a0 str x8, [var_58h]
| 0x1000077a4 bl sym.imp.objc_alloc_init
| 0x1000077a8 stur x0, [instance]
| 0x1000077ac ldur x0, [instance] ; void *instance
| 0x1000077b0 adrp x8, sym.__OBJC_METACLASS_RO___Employee ; 0x10000c000
| 0x1000077b4 add x8, x8, 0x1a0
| 0x1000077b8 ldr x1, [x8] ; [0x100007ea9:4]=0x48796173 ; "sayHello" ; char *selector
| 0x1000077bc str x8, [var_60h]
| 0x1000077c0 bl sym.imp.objc_msgSend ; Message dispatch to method_Employee_sayHello ; void *objc_msgSend(void *instance, char *selector)
| 0x1000077c4 ldr x8, [var_58h] ; [0x28:4]=-1 ; 40
| 0x1000077c8 ldr x0, [x8] ; void *instance
| 0x1000077cc ldr x9, [var_60h] ; [0x20:4]=-1 ; 32
| 0x1000077d0 ldr x1, [x9] ; char *selector
| 0x1000077d4 bl sym.imp.objc_msgSend ; Message dispatch to method_Employee_sayHello ; void *objc_msgSend(void *instance, char *selector)
| 0x1000077d8 ldur x8, [instance]
| 0x1000077dc adrp x0, data.100007000 ; 0x100007000
| 0x1000077e0 add x0, x0, 0xd98 ; 0x100007d98 ; "base %p\n" ; const char *format
| 0x1000077e4 mov x9, sp
| 0x1000077e8 str x8, [x9]
| 0x1000077ec bl sym.imp.printf ; int printf(const char *format)
| 0x1000077f0 ldur x8, [instance]
| 0x1000077f4 adrp x9, sym.__OBJC_METACLASS_RO___Employee ; 0x10000c000
| 0x1000077f8 add x9, x9, 0x1a8
| 0x1000077fc ldr x1, [x9] ; [0x100007eb2:4]=0x65736162 ; "base" ; char *selector
| 0x100007800 mov x0, x8 ; void *instance
| 0x100007804 bl sym.imp.objc_msgSend ; Message dispatch to method_Employee_base ; void *objc_msgSend(void *instance, char *selector)
| 0x100007808 stur x0, [var_30h]
| 0x10000780c ldur x0, [instance] ; void *instance
| 0x100007810 adrp x8, sym.__OBJC_METACLASS_RO___Employee ; 0x10000c000
| 0x100007814 add x8, x8, 0x1b0
| 0x100007818 ldr x1, [x8] ; char *selector
| 0x10000781c bl sym.imp.objc_msgSend ; void *objc_msgSend(void *instance, char *selector)
| 0x100007820 ldur x8, [var_30h]
| 0x100007824 subs x8, x0, x8
| 0x100007828 adrp x0, data.100007000 ; 0x100007000
| 0x10000782c add x0, x0, 0xda1 ; 0x100007da1 ; "iii %p _username\n" ; const char *format
| 0x100007830 mov x9, sp
| 0x100007834 str x8, [x9]
| 0x100007838 bl sym.imp.printf ; int printf(const char *format)
| 0x10000783c ldur x8, [instance]
| 0x100007840 adrp x9, sym.__OBJC_METACLASS_RO___Employee ; 0x10000c000
| 0x100007844 add x9, x9, 0x1b8
| 0x100007848 ldr x1, [x9] ; char *selector
| 0x10000784c mov x0, x8 ; void *instance
| 0x100007850 bl sym.imp.objc_msgSend ; void *objc_msgSend(void *instance, char *selector)
| 0x100007854 ldur x8, [var_30h]
| 0x100007858 subs x8, x0, x8
| 0x10000785c adrp x0, data.100007000 ; 0x100007000
| 0x100007860 add x0, x0, 0xdb3 ; 0x100007db3 ; "iii %p _firstName\n" ; const char *format
| 0x100007864 mov x9, sp
| 0x100007868 str x8, [x9]
| 0x10000786c bl sym.imp.printf ; int printf(const char *format)
| 0x100007870 ldur x8, [instance]
| 0x100007874 adrp x9, sym.__OBJC_METACLASS_RO___Employee ; 0x10000c000
| 0x100007878 add x9, x9, 0x1c0
| 0x10000787c ldr x1, [x9] ; char *selector
| 0x100007880 mov x0, x8 ; void *instance
| 0x100007884 bl sym.imp.objc_msgSend ; void *objc_msgSend(void *instance, char *selector)
| 0x100007888 ldur x8, [var_30h]
| 0x10000788c subs x8, x0, x8
| 0x100007890 adrp x0, data.100007000 ; 0x100007000
| 0x100007894 add x0, x0, 0xdc6 ; 0x100007dc6 ; "iii %p _shortWord\n" ; const char *format
| 0x100007898 mov x9, sp
| 0x10000789c str x8, [x9]
| 0x1000078a0 bl sym.imp.printf ; int printf(const char *format)
| 0x1000078a4 ldur x8, [instance]
| 0x1000078a8 adrp x9, sym.__OBJC_METACLASS_RO___Employee ; 0x10000c000
| 0x1000078ac add x9, x9, 0x1c8
| 0x1000078b0 ldr x1, [x9] ; char *selector
| 0x1000078b4 mov x0, x8 ; void *instance
| 0x1000078b8 bl sym.imp.objc_msgSend ; void *objc_msgSend(void *instance, char *selector)
| 0x1000078bc ldur x8, [var_30h]
| 0x1000078c0 subs x8, x0, x8
| 0x1000078c4 adrp x0, data.100007000 ; 0x100007000
| 0x1000078c8 add x0, x0, 0xdd9 ; 0x100007dd9 ; "iii %p _wideWord\n" ; const char *format
| 0x1000078cc mov x9, sp
| 0x1000078d0 str x8, [x9]
| 0x1000078d4 bl sym.imp.printf ; int printf(const char *format)
| 0x1000078d8 ldur x8, [instance]
| 0x1000078dc stur x8, [var_38h]
| 0x1000078e0 stur wzr, [var_3ch]
| ; CODE XREF from entry0 @ 0x100007920
| .-> 0x1000078e4 ldur w8, [var_3ch]
| : 0x1000078e8 cmp w8, 0x20
| ,==< 0x1000078ec b.ge 0x100007924
| |: 0x1000078f0 ldur x8, [var_38h]
| |: 0x1000078f4 ldursw x9, [var_3ch]
| |: 0x1000078f8 ldrb w10, [x8, x9]
| |: 0x1000078fc adrp x0, data.100007000 ; 0x100007000
| |: 0x100007900 add x0, x0, 0xdeb ; 0x100007deb ; "%02x " ; const char *format
| |: 0x100007904 mov x8, sp
| |: 0x100007908 mov x1, x10
| |: 0x10000790c str x1, [x8]
| |: 0x100007910 bl sym.imp.printf ; int printf(const char *format)
| |: 0x100007914 ldur w8, [var_3ch]
| |: 0x100007918 add w8, w8, 1
| |: 0x10000791c stur w8, [var_3ch]
| |`=< 0x100007920 b 0x1000078e4
| `--> 0x100007924 adrp x0, data.100007000 ; 0x100007000
| 0x100007928 add x0, x0, 0xdf1 ; const char *format
| 0x10000792c bl sym.imp.printf ; int printf(const char *format)
| 0x100007930 adrp x8, reloc.NSLog ; 0x100008000
| 0x100007934 add x8, x8, 0x70 ; 0x100008070 ; "X\x80\U00000001"
| 0x100007938 mov x0, x8 ; void *instance
| 0x10000793c bl sym.imp.objc_retain ; void objc_retain(void *instance)
| 0x100007940 add x8, var_48h
| 0x100007944 str x0, [var_48h]
| 0x100007948 ldr x9, [var_48h] ; [0x38:4]=-1 ; 56
| 0x10000794c adrp x0, data.100007000 ; 0x100007000
| 0x100007950 add x0, x0, 0xe02 ; 0x100007e02 ; "%p\n" ; const char *format
| 0x100007954 mov x10, sp
| 0x100007958 str x9, [x10]
| 0x10000795c str x8, [var_68h]
| 0x100007960 bl sym.imp.printf ; int printf(const char *format)
| ;-- x30:
| ;-- lr:
| ;-- pc:
\ 0x100007964 brk 1
EOF
RUN