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