Commit fb8ae8ca authored by Alexandre Julliard's avatar Alexandre Julliard

rpcrt4: Move the stubless delegating thunks to a separate file.

And build them as x86-64 code on ARM64EC.
parent d28f4fd0
......@@ -71,105 +71,14 @@ HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub);
BOOL fill_stubless_table(IUnknownVtbl *vtbl, DWORD num);
const IUnknownVtbl *get_delegating_vtbl(DWORD num_methods);
#define THUNK_ENTRY_FIRST_BLOCK() \
THUNK_ENTRY(3) \
THUNK_ENTRY(4) \
THUNK_ENTRY(5) \
THUNK_ENTRY(6) \
THUNK_ENTRY(7) \
THUNK_ENTRY(8) \
THUNK_ENTRY(9) \
THUNK_ENTRY(10) \
THUNK_ENTRY(11) \
THUNK_ENTRY(12) \
THUNK_ENTRY(13) \
THUNK_ENTRY(14) \
THUNK_ENTRY(15) \
THUNK_ENTRY(16) \
THUNK_ENTRY(17) \
THUNK_ENTRY(18) \
THUNK_ENTRY(19) \
THUNK_ENTRY(20) \
THUNK_ENTRY(21) \
THUNK_ENTRY(22) \
THUNK_ENTRY(23) \
THUNK_ENTRY(24) \
THUNK_ENTRY(25) \
THUNK_ENTRY(26) \
THUNK_ENTRY(27) \
THUNK_ENTRY(28) \
THUNK_ENTRY(29) \
THUNK_ENTRY(30) \
THUNK_ENTRY(31)
#define NB_THUNK_ENTRIES 1024
#define THUNK_ENTRY_BLOCK(block) \
THUNK_ENTRY(32 * (block) + 0) \
THUNK_ENTRY(32 * (block) + 1) \
THUNK_ENTRY(32 * (block) + 2) \
THUNK_ENTRY(32 * (block) + 3) \
THUNK_ENTRY(32 * (block) + 4) \
THUNK_ENTRY(32 * (block) + 5) \
THUNK_ENTRY(32 * (block) + 6) \
THUNK_ENTRY(32 * (block) + 7) \
THUNK_ENTRY(32 * (block) + 8) \
THUNK_ENTRY(32 * (block) + 9) \
THUNK_ENTRY(32 * (block) + 10) \
THUNK_ENTRY(32 * (block) + 11) \
THUNK_ENTRY(32 * (block) + 12) \
THUNK_ENTRY(32 * (block) + 13) \
THUNK_ENTRY(32 * (block) + 14) \
THUNK_ENTRY(32 * (block) + 15) \
THUNK_ENTRY(32 * (block) + 16) \
THUNK_ENTRY(32 * (block) + 17) \
THUNK_ENTRY(32 * (block) + 18) \
THUNK_ENTRY(32 * (block) + 19) \
THUNK_ENTRY(32 * (block) + 20) \
THUNK_ENTRY(32 * (block) + 21) \
THUNK_ENTRY(32 * (block) + 22) \
THUNK_ENTRY(32 * (block) + 23) \
THUNK_ENTRY(32 * (block) + 24) \
THUNK_ENTRY(32 * (block) + 25) \
THUNK_ENTRY(32 * (block) + 26) \
THUNK_ENTRY(32 * (block) + 27) \
THUNK_ENTRY(32 * (block) + 28) \
THUNK_ENTRY(32 * (block) + 29) \
THUNK_ENTRY(32 * (block) + 30) \
THUNK_ENTRY(32 * (block) + 31)
#define ALL_THUNK_ENTRIES \
THUNK_ENTRY_FIRST_BLOCK() \
THUNK_ENTRY_BLOCK(1) \
THUNK_ENTRY_BLOCK(2) \
THUNK_ENTRY_BLOCK(3) \
THUNK_ENTRY_BLOCK(4) \
THUNK_ENTRY_BLOCK(5) \
THUNK_ENTRY_BLOCK(6) \
THUNK_ENTRY_BLOCK(7) \
THUNK_ENTRY_BLOCK(8) \
THUNK_ENTRY_BLOCK(9) \
THUNK_ENTRY_BLOCK(10) \
THUNK_ENTRY_BLOCK(11) \
THUNK_ENTRY_BLOCK(12) \
THUNK_ENTRY_BLOCK(13) \
THUNK_ENTRY_BLOCK(14) \
THUNK_ENTRY_BLOCK(15) \
THUNK_ENTRY_BLOCK(16) \
THUNK_ENTRY_BLOCK(17) \
THUNK_ENTRY_BLOCK(18) \
THUNK_ENTRY_BLOCK(19) \
THUNK_ENTRY_BLOCK(20) \
THUNK_ENTRY_BLOCK(21) \
THUNK_ENTRY_BLOCK(22) \
THUNK_ENTRY_BLOCK(23) \
THUNK_ENTRY_BLOCK(24) \
THUNK_ENTRY_BLOCK(25) \
THUNK_ENTRY_BLOCK(26) \
THUNK_ENTRY_BLOCK(27) \
THUNK_ENTRY_BLOCK(28) \
THUNK_ENTRY_BLOCK(29) \
THUNK_ENTRY_BLOCK(30) \
THUNK_ENTRY_BLOCK(31)
struct delegating_vtbl
{
IUnknownVtbl vtbl;
const void *methods[NB_THUNK_ENTRIES - 3];
};
#define NB_THUNK_ENTRIES (32 * 32)
extern const struct delegating_vtbl delegating_vtbl;
#endif /* __WINE_CPSF_H */
......@@ -102,94 +102,6 @@ HRESULT CStdStubBuffer_Construct(REFIID riid,
return S_OK;
}
static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv)
{
*ppv = pUnk;
return S_OK;
}
static ULONG WINAPI delegating_AddRef(IUnknown *pUnk)
{
return 1;
}
static ULONG WINAPI delegating_Release(IUnknown *pUnk)
{
return 1;
}
/* The idea here is to replace the first param on the stack
ie. This (which will point to cstdstubbuffer_delegating_t)
with This->stub_buffer.pvServerObject and then jump to the
relevant offset in This->stub_buffer.pvServerObject's vtbl.
*/
#ifdef __i386__
#define THUNK_ENTRY_SIZE 20
#define THUNK_ENTRY(num) \
".balign 4\n\t" \
"mov 4(%esp),%eax\n\t" \
"mov 0x10(%eax),%eax\n\t" \
"mov %eax,4(%esp)\n\t" \
"mov (%eax),%eax\n\t" \
".byte 0xff,0xa0\n\t" /* jmp *offset(%eax) */ \
".long 4*("#num")\n\t"
#elif defined(__x86_64__)
#define THUNK_ENTRY_SIZE 16
#define THUNK_ENTRY(num) \
".balign 4\n\t" \
"movq 0x20(%rcx),%rcx\n\t" \
"movq (%rcx),%rax\n\t" \
".byte 0xff,0xa0\n\t" /* jmp *offset(%rax) */ \
".long 8*("#num")\n\t"
#elif defined(__arm__)
#define THUNK_ENTRY_SIZE 12
#define THUNK_ENTRY(num) \
".balign 4\n\t" \
"ldr r0, [r0, #0x10]\n\t" \
"ldr ip, [r0]\n\t" \
"ldr pc, [ip, #(4*("#num"))]\n\t"
#elif defined(__aarch64__)
#define THUNK_ENTRY_SIZE 20
#define THUNK_ENTRY(num) \
"ldr x0, [x0, #0x20]\n\t" \
"ldr x16, [x0]\n\t" \
"mov x17, #("#num")\n\t" \
"ldr x16, [x16, x17, lsl #3]\n\t" \
"br x16\n\t"
#else
#warning You must implement delegated proxies/stubs for your CPU
#define THUNK_ENTRY_SIZE 0
#define THUNK_ENTRY(num) ""
#endif
extern void vtbl_thunks(void);
__ASM_GLOBAL_FUNC( vtbl_thunks, ALL_THUNK_ENTRIES )
#undef THUNK_ENTRY
static const struct
{
IUnknownVtbl vtbl;
const void *methods[NB_THUNK_ENTRIES - 3];
} delegating_vtbl =
{
{ delegating_QueryInterface, delegating_AddRef, delegating_Release },
{
#define THUNK_ENTRY(num) (char *)vtbl_thunks + ((num) - 3) * THUNK_ENTRY_SIZE,
ALL_THUNK_ENTRIES
#undef THUNK_ENTRY
}
};
BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num)
{
......
......@@ -30,6 +30,7 @@
#include "winbase.h"
#include "objbase.h"
#include "rpcproxy.h"
#include "cpsf.h"
#include "wine/asm.h"
#define ALL_THUNK_ENTRIES \
......@@ -231,3 +232,90 @@ __ASM_GLOBAL_FUNC( call_stubless_func,
__ASM_GLOBAL_FUNC( stubless_thunks, ALL_THUNK_ENTRIES )
#undef T
/* The idea here is to replace the first param on the stack
ie. This (which will point to cstdstubbuffer_delegating_t)
with This->stub_buffer.pvServerObject and then jump to the
relevant offset in This->stub_buffer.pvServerObject's vtbl.
*/
#ifdef __i386__
#define T(num) \
".balign 4\n\t" \
".globl " __ASM_NAME("NdrProxyForwardingFunction" #num) "\n" \
__ASM_NAME("NdrProxyForwardingFunction" #num) ":\n\t" \
"mov 4(%esp),%eax\n\t" \
"mov 0x10(%eax),%eax\n\t" \
"mov %eax,4(%esp)\n\t" \
"mov (%eax),%eax\n\t" \
".byte 0xff,0xa0\n\t" /* jmp *offset(%eax) */ \
".long 4*"#num"\n\t"
#elif defined __x86_64__
#define T(num) \
".balign 4\n\t" \
".globl " __ASM_NAME("NdrProxyForwardingFunction" #num) "\n" \
__ASM_NAME("NdrProxyForwardingFunction" #num) ":\n\t" \
"movq 0x20(%rcx),%rcx\n\t" \
"movq (%rcx),%rax\n\t" \
".byte 0xff,0xa0\n\t" /* jmp *offset(%rax) */ \
".long 8*"#num"\n\t"
#elif defined __aarch64__
#define T(num) \
".globl NdrProxyForwardingFunction" #num "\n" \
"NdrProxyForwardingFunction" #num ":\n\t" \
"ldr x0, [x0, #0x20]\n\t" \
"ldr x16, [x0]\n\t" \
"mov x17, #"#num"\n\t" \
"ldr x16, [x16, x17, lsl #3]\n\t" \
"br x16\n\t"
#elif defined __arm__
#define T(num) \
".balign 4\n\t" \
".globl NdrProxyForwardingFunction" #num "\n" \
"NdrProxyForwardingFunction" #num ":\n\t" \
"ldr r0, [r0, #0x10]\n\t" \
"ldr ip, [r0]\n\t" \
"ldr pc, [ip, #(4*"#num")]\n\t"
#endif /* __i386__ */
__ASM_GLOBAL_FUNC( vtbl_thunks, ALL_THUNK_ENTRIES )
#undef T
static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv)
{
*ppv = pUnk;
return S_OK;
}
static ULONG WINAPI delegating_AddRef(IUnknown *pUnk)
{
return 1;
}
static ULONG WINAPI delegating_Release(IUnknown *pUnk)
{
return 1;
}
#define T(num) extern void NdrProxyForwardingFunction##num(void);
ALL_THUNK_ENTRIES
#undef T
const struct delegating_vtbl delegating_vtbl =
{
{ delegating_QueryInterface, delegating_AddRef, delegating_Release },
{
#define T(num) (void *)NdrProxyForwardingFunction##num,
ALL_THUNK_ENTRIES
#undef T
}
};
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