diff options
| author | André Zwing <nerv@dawncrow.de> | 2025-05-12 18:28:38 +0200 |
|---|---|---|
| committer | André Zwing <nerv@dawncrow.de> | 2025-05-19 23:46:29 +0200 |
| commit | e07ec82344dd8d87c1a246bb9cfb4d74b8450842 (patch) | |
| tree | addcceac09adafe4d92980dcbc753c23f4be0627 | |
| parent | 37eb5492ba5d58672620d77e01b1bd497cce00d9 (diff) | |
| download | box64-e07ec82344dd8d87c1a246bb9cfb4d74b8450842.tar.gz box64-e07ec82344dd8d87c1a246bb9cfb4d74b8450842.zip | |
[WOW64] Implement BTCpuSimulate
| -rw-r--r-- | src/dynarec/arm64/arm64_epilog.S | 3 | ||||
| -rw-r--r-- | src/dynarec/arm64/arm64_next.S | 3 | ||||
| -rw-r--r-- | src/emu/x64emu_private.h | 3 | ||||
| -rw-r--r-- | wow64/compiler.h | 17 | ||||
| -rw-r--r-- | wow64/wowbox64.c | 39 |
5 files changed, 64 insertions, 1 deletions
diff --git a/src/dynarec/arm64/arm64_epilog.S b/src/dynarec/arm64/arm64_epilog.S index 57f23200..4a15895b 100644 --- a/src/dynarec/arm64/arm64_epilog.S +++ b/src/dynarec/arm64/arm64_epilog.S @@ -19,6 +19,9 @@ arm64_epilog: stp x24, x25, [x0, (8 * 14)] stp x26, x27, [x0, (8 * 16)] // put back reg value in emu, including EIP (so x27 must be EIP now) //restore all used register +#ifdef _WIN32 + ldr x18, [x0, 3120] +#endif add sp, x28, 0 //vpop {d8-d15} ldp x19, x20, [sp, (8 * 0)] diff --git a/src/dynarec/arm64/arm64_next.S b/src/dynarec/arm64/arm64_next.S index e900fbec..950b7dd3 100644 --- a/src/dynarec/arm64/arm64_next.S +++ b/src/dynarec/arm64/arm64_next.S @@ -22,6 +22,9 @@ arm64_next: stp x16, x17, [sp, (8 * 8)] stp x18, x27, [sp, (8 * 10)] // also save x27(rip) to allow change in LinkNext +#ifdef _WIN32 + ldr x18, [x0, 3120] +#endif mov x2, x30 // "from" is in lr, so put in x2 add x3, sp, 8*11 // x3 is address to change rip // call the function diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h index 21f270f1..15e85fa4 100644 --- a/src/emu/x64emu_private.h +++ b/src/emu/x64emu_private.h @@ -124,6 +124,9 @@ typedef struct x64emu_s { uintptr_t old_savedsp; #endif + #ifdef _WIN32 + uint64_t win64_teb; + #endif int type; // EMUTYPE_xxx define #ifdef BOX32 int libc_err; // copy of errno from libc diff --git a/wow64/compiler.h b/wow64/compiler.h index 45dfc4ef..9abafa74 100644 --- a/wow64/compiler.h +++ b/wow64/compiler.h @@ -1,11 +1,28 @@ #ifndef __COMPILER_H_ #define __COMPILER_H_ +#include <stdint.h> + /* Things missing from mingw64 right now */ #define ThreadWow64Context (29) +#define WOW64_TLS_CPURESERVED (1) +#define WOW64_TLS_MAX_NUMBER (19) + +typedef struct _WOW64_CPURESERVED +{ + USHORT Flags; + USHORT Machine; +} WOW64_CPURESERVED; NTSTATUS WINAPI RtlWow64GetCurrentCpuArea(USHORT *, void **, void **); NTSYSAPI NTSTATUS WINAPI LdrGetDllHandle(LPCWSTR, ULONG, const UNICODE_STRING*, HMODULE*); NTSYSAPI void* WINAPI RtlFindExportedRoutineByName(HMODULE, const char*); +static inline uintptr_t calculate_fs(void) +{ +/* until mingw64 has WowTebOffset in the TEB struct */ +uint8_t* teb = (uint8_t*)NtCurrentTeb(); +return (uintptr_t)(teb + *(int32_t*)(teb + 0x180c)); +} + #endif //__COMPILER_H_ diff --git a/wow64/wowbox64.c b/wow64/wowbox64.c index 20d714c9..8d0097c3 100644 --- a/wow64/wowbox64.c +++ b/wow64/wowbox64.c @@ -2,6 +2,7 @@ * Copyright 2022-2025 André Zwing * Copyright 2023 Alexandre Julliard */ +#include <stddef.h> #include <stdio.h> #include <windows.h> #include <ntstatus.h> @@ -16,6 +17,7 @@ #include "emu/x87emu_private.h" #include "x64trace.h" #include "box64context.h" +#include "box64cpu.h" #include "wine/debug.h" uintptr_t box64_pagesize = 4096; @@ -125,6 +127,11 @@ NTSTATUS WINAPI BTCpuProcessInit(void) void **p__wine_unix_call_dispatcher; __wine_dbg_output("[BOX64] BTCpuProcessInit\n"); +#define STATIC_ASSERT(COND, MSG) typedef char static_assertion_##MSG[(!!(COND))*2-1] +/* otherwise adjust arm64_epilog.S and arm64_next.S */ +STATIC_ASSERT(offsetof(x64emu_t, win64_teb) == 3120, offset_of_b_must_be_4); +#undef STATIC_ASSERT + LoadEnvVariables(); memset(bopcode, 0xc3, sizeof(bopcode)); @@ -171,7 +178,37 @@ NTSTATUS WINAPI BTCpuSetContext(HANDLE thread, HANDLE process, void* unknown, WO void WINAPI BTCpuSimulate(void) { - // NYI + WOW64_CPURESERVED *cpu = NtCurrentTeb()->TlsSlots[WOW64_TLS_CPURESERVED]; + x64emu_t *emu = NtCurrentTeb()->TlsSlots[0]; // FIXME + WOW64_CONTEXT *ctx = (WOW64_CONTEXT *)(cpu + 1); + CONTEXT entry_context; + + RtlCaptureContext(&entry_context); + NtCurrentTeb()->TlsSlots[WOW64_TLS_MAX_NUMBER] = &entry_context; + + R_EAX = ctx->Eax; + R_EBX = ctx->Ebx; + R_ECX = ctx->Ecx; + R_EDX = ctx->Edx; + R_ESI = ctx->Esi; + R_EDI = ctx->Edi; + R_EBP = ctx->Ebp; + R_RIP = ctx->Eip; + R_ESP = ctx->Esp; + R_CS = ctx->SegCs & 0xffff; + R_DS = ctx->SegDs & 0xffff; + R_ES = ctx->SegEs & 0xffff; + R_FS = ctx->SegFs & 0xffff; + R_GS = ctx->SegGs & 0xffff; + R_SS = ctx->SegSs & 0xffff; + emu->eflags.x64 = ctx->EFlags; + emu->segs_offs[_FS] = calculate_fs(); + emu->win64_teb = (uint64_t)NtCurrentTeb(); + + if (box64env.dynarec) + DynaRun(emu); + else + Run(emu, 0); } NTSTATUS WINAPI BTCpuThreadInit(void) |