Alexandre Julliard : rpcrt4: Add stubless proxy support for ARM64.
Alexandre Julliard
julliard at winehq.org
Fri Sep 27 15:56:29 CDT 2019
Module: wine
Branch: master
Commit: d9adc902f88445fb1a33825775884de394124d71
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d9adc902f88445fb1a33825775884de394124d71
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Sep 27 12:39:49 2019 +0200
rpcrt4: Add stubless proxy support for ARM64.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/rpcrt4/cproxy.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
dlls/rpcrt4/cstub.c | 17 +++++++++++++++++
dlls/rpcrt4/ndr_stubless.c | 29 +++++++++++++++++++++++++++++
3 files changed, 90 insertions(+)
diff --git a/dlls/rpcrt4/cproxy.c b/dlls/rpcrt4/cproxy.c
index 3b9467735b..968c7b5156 100644
--- a/dlls/rpcrt4/cproxy.c
+++ b/dlls/rpcrt4/cproxy.c
@@ -196,6 +196,50 @@ static inline void init_thunk( struct thunk *thunk, unsigned int index )
thunk->func = call_stubless_func;
}
+#elif defined(__aarch64__)
+
+extern void call_stubless_func(void);
+__ASM_GLOBAL_FUNC( call_stubless_func,
+ "stp x29, x30, [sp, #-0x90]!\n\t"
+ "mov x29, sp\n\t"
+ "stp d0, d1, [sp, #0x10]\n\t"
+ "stp d2, d3, [sp, #0x20]\n\t"
+ "stp d4, d5, [sp, #0x30]\n\t"
+ "stp d6, d7, [sp, #0x40]\n\t"
+ "stp x0, x1, [sp, #0x50]\n\t"
+ "stp x2, x3, [sp, #0x60]\n\t"
+ "stp x4, x5, [sp, #0x70]\n\t"
+ "stp x6, x7, [sp, #0x80]\n\t"
+ "ldr x0, [x0]\n\t" /* This->lpVtbl */
+ "ldr x0, [x0, #-16]\n\t" /* MIDL_STUBLESS_PROXY_INFO */
+ "ldp x1, x4, [x0, #8]\n\t" /* info->ProcFormatString, FormatStringOffset */
+ "ldrh w4, [x4, x16, lsl #1]\n\t" /* info->FormatStringOffset[index] */
+ "add x1, x1, x4\n\t" /* info->ProcFormatString + offset */
+ "ldr x0, [x0]\n\t" /* info->pStubDesc */
+ "add x2, sp, #0x50\n\t" /* stack */
+ "add x3, sp, #0x10\n\t" /* fpu_stack */
+ "bl " __ASM_NAME("ndr_client_call") "\n\t"
+ "ldp x29, x30, [sp], #0x90\n\t"
+ "ret" )
+
+struct thunk
+{
+ DWORD ldr_index; /* ldr w16, index */
+ DWORD ldr_func; /* ldr x17, func */
+ DWORD br; /* br x17 */
+ DWORD index;
+ void *func;
+};
+
+static inline void init_thunk( struct thunk *thunk, unsigned int index )
+{
+ thunk->ldr_index = 0x18000070; /* ldr w16,index */
+ thunk->ldr_func = 0x58000071; /* ldr x17,func */
+ thunk->br = 0xd61f0220; /* br x17 */
+ thunk->index = index;
+ thunk->func = call_stubless_func;
+}
+
#else /* __i386__ */
#warning You must implement stubless proxies for your CPU
diff --git a/dlls/rpcrt4/cstub.c b/dlls/rpcrt4/cstub.c
index 607e9d4bc8..1903a5f0c9 100644
--- a/dlls/rpcrt4/cstub.c
+++ b/dlls/rpcrt4/cstub.c
@@ -183,6 +183,23 @@ typedef struct
DWORD offset;
} vtbl_method_t;
+#elif defined(__aarch64__)
+
+static const DWORD opcodes[] =
+{
+ 0xf9401000, /* ldr x0, [x0,#32] */
+ 0xf9400010, /* ldr x16, [x0] */
+ 0x18000071, /* ldr w17, offset */
+ 0xf8716a10, /* ldr x16, [x16,x17] */
+ 0xd61f0200 /* br x16 */
+};
+
+typedef struct
+{
+ DWORD opcodes[ARRAY_SIZE(opcodes)];
+ DWORD offset;
+} vtbl_method_t;
+
#else
#warning You must implement delegated proxies/stubs for your CPU
diff --git a/dlls/rpcrt4/ndr_stubless.c b/dlls/rpcrt4/ndr_stubless.c
index bceecdc827..cc52ee27e8 100644
--- a/dlls/rpcrt4/ndr_stubless.c
+++ b/dlls/rpcrt4/ndr_stubless.c
@@ -1169,6 +1169,35 @@ __ASM_GLOBAL_FUNC( call_server_func,
"5:\tblx r4\n\t"
"mov SP, r5\n\t"
"pop {r4, r5, PC}" )
+#elif defined __aarch64__
+LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char *args, unsigned int stack_size);
+__ASM_GLOBAL_FUNC( call_server_func,
+ "stp x29, x30, [sp, #-16]!\n\t"
+ "mov x29, sp\n\t"
+ "add x3, x2, #15\n\t"
+ "lsr x3, x3, #4\n\t"
+ "sub sp, sp, x3, lsl #4\n\t"
+ "cbz x2, 2f\n"
+ "1:\tsub x2, x2, #8\n\t"
+ "ldr x4, [x1, x2]\n\t"
+ "str x4, [sp, x2]\n\t"
+ "cbnz x2, 1b\n"
+ "2:\tmov x8, x0\n\t"
+ "cbz x3, 3f\n\t"
+ "ldp x0, x1, [sp], #16\n\t"
+ "cmp x3, #1\n\t"
+ "b.le 3f\n\t"
+ "ldp x2, x3, [sp], #16\n\t"
+ "cmp x3, #2\n\t"
+ "b.le 3f\n\t"
+ "ldp x4, x5, [sp], #16\n\t"
+ "cmp x3, #3\n\t"
+ "b.le 3f\n\t"
+ "ldp x6, x7, [sp], #16\n"
+ "3:\tblr x8\n\t"
+ "mov sp, x29\n\t"
+ "ldp x29, x30, [sp], #16\n\t"
+ "ret" )
#else
#warning call_server_func not implemented for your architecture
LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size)
More information about the wine-cvs
mailing list