1 2#if defined(_M_IX86) || defined(_M_AMD64) 3#include <asm.inc> 4#elif defined(_M_ARM) 5#include <kxarm.h> 6#endif 7 8#ifdef _M_IX86 9.code32 10 11EXTERN _ndr_client_call:PROC 12 13PUBLIC _call_stubless_func 14_call_stubless_func: 15 16 mov ecx, [esp+4] /* This Pointer */ 17 mov ecx, [ecx] /* This->lpVtbl */ 18 mov ecx, [ecx-8] /* MIDL_STUBLESS_PROXY_INFO */ 19 mov edx, [ecx+8] /* Info->FormatStringOffset */ 20 movzx edx, word ptr [edx+eax*2] /* FormatStringOffset[index] */ 21 add edx, [ecx+4] /* info->ProcFormatString + offset */ 22 movzx eax, byte ptr [edx+1] /* Oi_flags */ 23 and eax, 8 /* Oi_HAS_RPCFLAGS */ 24 shr eax, 1 25 movzx eax, word ptr [edx+eax+4] /* arguments size */ 26 push eax 27 lea eax, [esp+8] /* &This */ 28 push eax 29 push edx /* format string */ 30 push [ecx] /* info->pstubdesc */ 31 call _ndr_client_call 32 lea esp, [esp+12] 33 pop edx /* arguments size */ 34 mov ecx, [esp] /* return address */ 35 add esp, edx 36 jmp ecx 37 38#elif _M_AMD64 39.code64 40 41EXTERN ndr_client_call:PROC 42 43PUBLIC call_stubless_func 44FUNC call_stubless_func 45 mov [rsp + 8], rcx 46 .SAVEREG rcx, 8 47 mov [rsp + 10h], rdx 48 .SAVEREG rdx, 10h 49 mov [rsp + 18h], r8 50 .SAVEREG r8, 18h 51 mov [rsp + 20h], r9 52 .SAVEREG r9, 20h 53 sub rsp, 38h 54 .ALLOCSTACK 38h 55 .ENDPROLOG 56 57 lea r8, [rsp +38h + 8] /* &This */ 58 mov rcx, [rcx] /* This->lpVtbl */ 59 mov rcx, [rcx - 10h] /* MIDL_STUBLESS_PROXY_INFO */ 60 mov rdx, [rcx + 10h] /* info->FormatStringOffset */ 61 movzx rdx, word ptr [rdx+r10*2] /* FormatStringOffset[index] */ 62 add rdx, [rcx + 8] /* info->ProcFormatString + offset */ 63 mov rcx, [rcx] /* info->pStubDesc */ 64 65 movsd qword ptr [rsp + 20h], xmm1 66 movsd qword ptr [rsp + 28h], xmm2 67 movsd qword ptr [rsp + 30h], xmm3 68 lea r9, [rsp + 18h] /* fpu_args */ 69 call ndr_client_call 70 add rsp, 38h 71 ret 72ENDFUNC 73 74PUBLIC call_server_func 75FUNC call_server_func 76 push rbp 77 .PUSHREG rbp 78 mov rbp, rsp 79 push rsi 80 .PUSHREG rsi 81 push rdi 82 .PUSHREG rdi 83 .ENDPROLOG 84 85 mov rax, rcx /* function to call */ 86 mov rcx, 32 /* allocate max(32,stack_size) bytes of stack space */ 87 cmp r8, rcx 88 cmovg rcx, r8 89 sub rsp, rcx 90 and rsp, NOT 15 91 mov rcx, r8 92 shr rcx, 3 93 mov rdi, rsp 94 mov rsi, rdx 95 rep movsq /* copy arguments */ 96 mov rcx, [rsp] 97 mov rdx, [rsp + 8] 98 mov r8, [rsp + 16] 99 mov r9, [rsp + 24] 100 101 /* Usually the 64 bit SSE2 version of movd is called movq, as in GCC code 102 (see https://www.felixcloutier.com/x86/movd:movq). But there is another 103 movq with different encoding, which does not accept an integer register 104 as source (see https://www.felixcloutier.com/x86/movq). Older versions 105 of ML64 get confused and do not accept movq with integer registers, 106 but they translate movd to 64 bit, when 64 bit registers are used as 107 source, so we use that here. */ 108 movd xmm0, rcx 109 movd xmm1, rdx 110 movd xmm2, r8 111 movd xmm3, r9 112 call rax 113 114 lea rsp, [rbp - 16] /* restore stack */ 115 pop rdi 116 pop rsi 117 pop rbp 118 ret 119ENDFUNC 120 121 122PUBLIC NdrClientCall2 123FUNC NdrClientCall2 124 mov [rsp + 18h], r8 125 .SAVEREG r8, 18h 126 mov [rsp + 20h], r9 127 .SAVEREG r9, 20h 128 sub rsp, 28h 129 .ALLOCSTACK 28h 130 .ENDPROLOG 131 132 lea r8, [rsp + 28h + 18h] 133 xor r9, r9 134 call ndr_client_call 135 136 add rsp, 28h 137 ret 138ENDFUNC 139 140EXTERN ndr_async_client_call:PROC 141PUBLIC NdrAsyncClientCall 142FUNC NdrAsyncClientCall 143 mov [rsp + 18h], r8 144 .SAVEREG r8, 18h 145 mov [rsp + 20h], r9 146 .SAVEREG r9, 20h 147 sub rsp, 28h 148 .ALLOCSTACK 28h 149 .ENDPROLOG 150 151 lea r8, [rsp + 28h + 18h] 152 call ndr_async_client_call 153 154 add rsp, 28h 155 ret 156ENDFUNC 157 158#elif _M_ARM 159TEXTAREA 160 161 LEAF_ENTRY call_stubless_func 162 163 /* Unimplemented */ 164 __assertfail 165 bx lr 166 167 LEAF_END call_stubless_func 168 169 LEAF_ENTRY call_server_func 170 171 /* Unimplemented */ 172 __assertfail 173 bx lr 174 175 LEAF_END call_server_func 176 177#endif 178 179END 180