Commit d9adc902 authored by Alexandre Julliard's avatar Alexandre Julliard

rpcrt4: Add stubless proxy support for ARM64.

parent d01470ad
...@@ -196,6 +196,50 @@ static inline void init_thunk( struct thunk *thunk, unsigned int index ) ...@@ -196,6 +196,50 @@ static inline void init_thunk( struct thunk *thunk, unsigned int index )
thunk->func = call_stubless_func; 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__ */ #else /* __i386__ */
#warning You must implement stubless proxies for your CPU #warning You must implement stubless proxies for your CPU
......
...@@ -183,6 +183,23 @@ typedef struct ...@@ -183,6 +183,23 @@ typedef struct
DWORD offset; DWORD offset;
} vtbl_method_t; } 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 #else
#warning You must implement delegated proxies/stubs for your CPU #warning You must implement delegated proxies/stubs for your CPU
......
...@@ -1169,6 +1169,35 @@ __ASM_GLOBAL_FUNC( call_server_func, ...@@ -1169,6 +1169,35 @@ __ASM_GLOBAL_FUNC( call_server_func,
"5:\tblx r4\n\t" "5:\tblx r4\n\t"
"mov SP, r5\n\t" "mov SP, r5\n\t"
"pop {r4, r5, PC}" ) "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 #else
#warning call_server_func not implemented for your architecture #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) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment