···33extern objcdarwin_class_lookup
44extern objc_msg_lookup
55extern sel_get_any_uid
66+extern objcdarwin_SaveRegisters
77+extern objcdarwin_RestoreRegisters
6879%ifidn __OUTPUT_FORMAT__, elf64
810911BITS 64
1012section text
11131212-SaveRegisters:
1313- pop r11
1414-1515- push r9
1616- push r8
1717- push rcx
1818- push rdx
1919- push rsi
2020- push rdi
2121-2222- ; save xmms?
2323- jmp r11
2424-2525-RestoreRegisters:
2626- pop r11
2727- pop rdi
2828- pop rsi
2929- pop rdx
3030- pop rcx
3131- pop r8
3232- pop r9
3333- jmp r11
3434-3514__darwin_objc_msgSend:
3615 ; Procedure:
3716 ; 1) get the converted GNU class from an Apple class
···3918 ; 3) run objc_msg_lookup
4019 ; 4) jump to the pointer returned by objc_msg_lookup
41204242- call SaveRegisters
2121+ call objcdarwin_SaveRegisters WRT ..plt
4322 call objcdarwin_class_lookup WRT ..plt
4423 mov [rsp], rax ; save the converted value
4524···4928 ; rax now has the GNU selector
5029 ; move rax to the second argument
5130 mov rsi, rax
3131+ mov [rsp+8], rax
5232 ; restore the first argument
5333 mov rdi, [rsp]
5434 call objc_msg_lookup WRT ..plt
55355656- call RestoreRegisters
3636+ call objcdarwin_RestoreRegisters WRT ..plt
5737 jmp rax
58385939%elifidn __OUTPUT_FORMAT__, elf
60406141BITS 32
6242section text
6363-6464-;;;;;;;;;;;;;;;;;;;;;;;;;;;; TODO!!!
65436644__darwin_objc_msgSend:
6745 ;enter 8
+52-51
src/libobjcdarwin/objc_msgSend_fixup.nasm
···11-global objc_msgSend_fixup
11+global __darwin_objc_msgSend_fixup
2233+extern objcdarwin_class_lookup
34extern objc_msg_lookup
45extern sel_get_any_uid
66+extern objcdarwin_SaveRegisters
77+extern objcdarwin_RestoreRegisters
5869%ifidn __OUTPUT_FORMAT__, elf64
710811BITS 64
912section text
10131111-SaveRegisters:
1212- pop r11
1313- push rdi
1414- push rsi
1515- push rdx
1616- push rcx
1717- push r8
1818- push r9
1919- ; save xmms?
2020- jmp r11
2121-2222-RestoreRegisters:
2323- pop r11
2424- pop r9
2525- pop r8
2626- pop rcx
2727- pop rdx
2828- pop rsi
2929- pop rdi
3030- jmp r11
1414+;__darwin_objc_msgSend_fixed:
1515+; add rsi, 8
1616+; jmp __darwin_objc_msgSend WRT ..plt
31173232-objc_msgSend_fixup:
1818+__darwin_objc_msgSend_fixup:
3319 ; Procedure:
3434- ; 1) convert Apple selector to GNU
3535- ; 2) run objc_msg_lookup
3636- ; 3) save the method address into the second argument
3737- ; 4) save the right selector into the second argument
3838- ; 5) jump to the pointer returned by objc_msg_lookup
2020+ ; 1) get the converted GNU class from an Apple class
2121+ ; 2) convert Apple selector to GNU
2222+ ; 3) run objc_msg_lookup
2323+ ; 4) jump to the pointer returned by objc_msg_lookup
39244040- call SaveRegisters
2525+ call objcdarwin_SaveRegisters WRT ..plt
2626+ call objcdarwin_class_lookup WRT ..plt
2727+ mov [rsp], rax ; save the converted value
2828+4129 ; move the second argument into the first argument
4242- mov rdi, rsi
4343- add rdi, 8 ; selector name is the second pointer in struct
3030+ mov rdi, [rsp+8]
3131+ add rdi, 8 ; the selector itself is the second element of what we receive as SEL
3232+ mov rdi, [rdi]
4433 call sel_get_any_uid WRT ..plt
4534 ; rax now has the GNU selector
4646- mov rsi, [rsp+8] ; put the second argument back to rsi
4747- mov [rsi+8], rax ; store the GNU selector
4848- add rsi, 8 ; pass the selector itself
3535+ ; move rax to the second argument
3636+ mov rsi, rax
3737+4938 ; restore the first argument
5039 mov rdi, [rsp]
5140 call objc_msg_lookup WRT ..plt
4141+4242+ ; optimize the next call by fixing the function pointer
4343+ mov rsi, [rsp+8]
4444+ ;mov [rsi], rax ; TODO: fixups not working, the target method still isn't getting the selector it expects
52455353- call RestoreRegisters
5454- ; can we do it like this? don't we still need a proxy?
5555- mov [rsi], rax ; fix the pointer to make the call direct next time
4646+ call objcdarwin_RestoreRegisters WRT ..plt
5647 jmp rax
57485849%elifidn __OUTPUT_FORMAT__, elf
···6051BITS 32
6152section text
62536363-objc_msgSend_fixup:
6464- ; swap the first two arguments
5454+__darwin_objc_msgSend_fixup:
5555+6556 mov ecx, [esp+4]
6666- xchg [esp+8], ecx
6767- add ecx, 4 ; move to the second struct element
6868- mov [esp+4], ecx
5757+ push ecx ; arg for func call
5858+5959+ call objcdarwin_class_lookup ;WRT ..plt
6060+6161+ add esp, 4 ; remove argument
6262+ mov [esp+4], eax ; change the class id
6363+6464+ mov ecx, [esp+8] ; second argument
6565+ add ecx, 4 ; the selector itself is the second element of what we receive as SEL
6666+ mov ecx, [ecx]
6767+ push ecx
69687070- call sel_get_any_uid WRT ..plt
6969+ call sel_get_any_uid ;WRT ..plt
71707272- ; eax now has the GNU selector
7373- ; swap the arguments back
7171+ add esp, 4
7272+ mov [esp+8], eax
74737575- mov ecx, [esp+4]
7676- mov [ecx], eax ; fix the selector in the original struct
7474+ push eax ; reuse the sel_get_any_uid retval
7575+ mov eax, [esp+8]
7676+ push eax ; class id
77777878- ; swap the arguments back
7979- mov ecx, [esp+4]
8080- xchg [esp+8], ecx
8181- mov [esp+4], ecx
8282- call objc_msg_lookup WRT ..plt
7878+ call objc_msg_lookup ;WRT ..plt
7979+ add esp, 8
8080+8181+ ; optimize the next call by fixing the function pointer
8282+ mov ecx, [esp+8]
8383+ ;mov [ecx], eax ; TODO: fixups not working, the target method still isn't getting the selector it expects
83848485 jmp eax
8586
+77
src/libobjcdarwin/objc_msgSend_stret.nasm
···11+global __darwin_objc_msgSend_stret
22+33+extern objcdarwin_class_lookup
44+extern objc_msg_lookup
55+extern sel_get_any_uid
66+extern objcdarwin_SaveRegisters
77+extern objcdarwin_RestoreRegisters
88+99+%ifidn __OUTPUT_FORMAT__, elf64
1010+1111+BITS 64
1212+section text
1313+1414+; Compared to ordinary msgSend, arguments are shifted by one - first arg is the stret
1515+__darwin_objc_msgSend_stret:
1616+ ; Procedure:
1717+ ; 1) get the converted GNU class from an Apple class
1818+ ; 2) convert Apple selector to GNU
1919+ ; 3) run objc_msg_lookup
2020+ ; 4) jump to the pointer returned by objc_msg_lookup
2121+2222+ call objcdarwin_SaveRegisters WRT ..plt
2323+ mov rdi, rsi
2424+ call objcdarwin_class_lookup WRT ..plt
2525+ mov [rsp+8], rax ; save the converted value
2626+2727+ ; move the second argument into the first argument
2828+ mov rdi, [rsp+16]
2929+ call sel_get_any_uid WRT ..plt
3030+ ; rax now has the GNU selector
3131+ ; move rax to the second argument
3232+ mov rsi, rax
3333+ mov [rsp+16], rax
3434+ ; restore the first argument
3535+ mov rdi, [rsp+8]
3636+ call objc_msg_lookup WRT ..plt
3737+3838+ call objcdarwin_RestoreRegisters WRT ..plt
3939+ jmp rax
4040+4141+%elifidn __OUTPUT_FORMAT__, elf
4242+4343+BITS 32
4444+section text
4545+4646+__darwin_objc_msgSend_stret:
4747+4848+ mov ecx, [esp+8]
4949+ push ecx ; arg for func call
5050+5151+ call objcdarwin_class_lookup ;WRT ..plt
5252+5353+ add esp, 4 ; remove argument
5454+ mov [esp+8], eax ; change the class id
5555+5656+ mov ecx, [esp+12] ; second argument
5757+ push ecx
5858+5959+ call sel_get_any_uid ;WRT ..plt
6060+6161+ add esp, 4
6262+ mov [esp+12], eax
6363+6464+ push eax ; reuse the sel_get_any_uid retval
6565+ mov eax, [esp+12]
6666+ push eax ; class id
6767+6868+ call objc_msg_lookup ;WRT ..plt
6969+ add esp, 8
7070+7171+ jmp eax
7272+7373+%else
7474+7575+%error "Unsupported platform"
7676+7777+%endif