diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-02-12 23:02:39 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-02-12 23:02:39 +0100 |
| commit | 6d6de880eb9faabbc83ff31b62dd91e5bb4a490b (patch) | |
| tree | d2c5caa2c1b5cc8b169cce9972d9dae2b8c5cb08 /src | |
| parent | a65bf79ad94babab7f132ed6b8674f9f490bc4a0 (diff) | |
| download | box64-6d6de880eb9faabbc83ff31b62dd91e5bb4a490b.tar.gz box64-6d6de880eb9faabbc83ff31b62dd91e5bb4a490b.zip | |
Also needed a RunFunctionWindows, following the Windows Calling Convention (and now d3datapter9 works)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/include/callback.h | 3 | ||||
| -rwxr-xr-x | src/tools/callback.c | 44 | ||||
| -rw-r--r-- | src/wrapped/wrappedd3dadapter9.c | 6 |
3 files changed, 50 insertions, 3 deletions
diff --git a/src/include/callback.h b/src/include/callback.h index dae26f1e..eecbc3d2 100755 --- a/src/include/callback.h +++ b/src/include/callback.h @@ -10,5 +10,8 @@ uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...); uint64_t RunSafeFunction(box64context_t *context, uintptr_t fnc, int nargs, ...); // use emu state to run function uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJumpExit, uintptr_t fnc, int nargs, ...); +// using the Windows x64 calling convention +uint64_t RunFunctionWindows(box64context_t *context, uintptr_t fnc, int nargs, ...); + #endif //__CALLBACK_H__ \ No newline at end of file diff --git a/src/tools/callback.c b/src/tools/callback.c index d3d5101e..9aafa6d8 100755 --- a/src/tools/callback.c +++ b/src/tools/callback.c @@ -163,3 +163,47 @@ uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, in return R_RAX; } + +EXPORTDYN +uint64_t RunFunctionWindows(box64context_t *context, uintptr_t fnc, int nargs, ...) +{ + (void)context; + + x64emu_t *emu = thread_get_emu(); + int align = (nargs>4)?(((nargs-4)&1)):0; + int stackn = align + ((nargs>4)?(nargs-4):0); + + Push64(emu, R_RBP); // push rbp + R_RBP = R_RSP; // mov rbp, rsp + + R_RSP -= stackn*sizeof(void*); // need to push in reverse order + + uint64_t *p = (uint64_t*)R_RSP; + + va_list va; + va_start (va, nargs); + for (int i=0; i<nargs; ++i) { + if(i<4) { + int nn[] = {_CX, _DX, _R8, _R9}; + emu->regs[nn[i]].q[0] = va_arg(va, uint64_t); + } else { + *p = va_arg(va, uint64_t); + p++; + } + } + va_end (va); + + R_RSP -= 32; // ShadowArea + + uintptr_t oldip = R_RIP; + DynaCall(emu, fnc); + + if(oldip==R_RIP) { + R_RSP = R_RBP; // mov rsp, rbp + R_RBP = Pop64(emu); // pop rbp + } + + uint64_t ret = R_RAX; + + return ret; +} \ No newline at end of file diff --git a/src/wrapped/wrappedd3dadapter9.c b/src/wrapped/wrappedd3dadapter9.c index b67b064e..b7f08eda 100644 --- a/src/wrapped/wrappedd3dadapter9.c +++ b/src/wrapped/wrappedd3dadapter9.c @@ -224,7 +224,7 @@ static void freeMy() #define GOV(ns, ret, fn, args, call) \ static uintptr_t my_##ns##_##fn##_fct = 0; \ static ret my_##ns##_##fn(UNPACK args) { \ - ret r = (ret)RunFunction(my_context, my_##ns##_##fn##_fct, UNPACK call); \ + ret r = (ret)RunFunctionWindows(my_context, my_##ns##_##fn##_fct, UNPACK call); \ /* no closing brace */ #define GOV_1(ns, ret, fn, t1) \ @@ -318,13 +318,13 @@ typedef struct my_Direct3D9 { unsigned my_Direct3D9_AddRef(void *This) { my_Direct3D9 *my = This; - return RunFunction(my_context, (uintptr_t)(*my->real)->AddRef, 1, my->real); + return RunFunctionWindows(my_context, (uintptr_t)(*my->real)->AddRef, 1, my->real); } unsigned my_Direct3D9_Release(void *This) { my_Direct3D9 *my = This; - return RunFunction(my_context, (uintptr_t)(*my->real)->Release, 1, my->real); + return RunFunctionWindows(my_context, (uintptr_t)(*my->real)->Release, 1, my->real); } IDirect3D9Vtbl my_Direct3D9_vtbl = { |