diff options
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 6 | ||||
| -rw-r--r-- | src/emu/x64run.c | 6 | ||||
| -rw-r--r-- | src/os/emit_signal_wine.c | 54 | ||||
| -rw-r--r-- | src/os/os_wine.c | 8 | ||||
| -rw-r--r-- | wow64/include/wine/compiler.h (renamed from wow64/compiler.h) | 22 | ||||
| -rw-r--r-- | wow64/wowbox64.c | 10 |
6 files changed, 78 insertions, 28 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 59a4c5e3..6feae03c 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -2646,14 +2646,14 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xCD: u8 = F8; -#ifdef _WIN32 + #ifdef _WIN32 NOTEST(x1); SMEND(); GETIP(addr); STORE_XEMU_CALL(xRIP); MOV32w(x1, u8); LDRx_U12(xR8, xEmu, offsetof(x64emu_t, win64_teb)); - CALL_S(x86Int, -1); + CALL_S(native_int, -1); LOAD_XEMU_CALL(xRIP); TABLE64(x3, addr); // expected return address CMPSx_REG(xRIP, x3); @@ -2664,7 +2664,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin LOAD_XEMU_REM(); jump_to_epilog(dyn, 0, xRIP, ninst); break; -#endif + #endif if(box64_wine && (u8==0x2D || u8==0x2C || u8==0x29)) { INST_NAME("INT 29/2c/2d"); // lets do nothing diff --git a/src/emu/x64run.c b/src/emu/x64run.c index aaf27b18..078a7ea9 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -1531,6 +1531,11 @@ x64emurun: break; case 0xCD: /* INT n */ tmp8u = F8; + #ifdef _WIN32 + EmitInterruption(emu, tmp8u, (void*)R_RIP); + STEP; + addr = R_RIP; + #else // this is a privilege opcode... if(box64_wine && tmp8u==0x2D) { // lets ignore the INT 2D @@ -1567,6 +1572,7 @@ x64emurun: STEP2; #endif } + #endif break; case 0xCE: /* INTO */ if(!rex.is32bits) { diff --git a/src/os/emit_signal_wine.c b/src/os/emit_signal_wine.c index 0539a818..ef0a0f65 100644 --- a/src/os/emit_signal_wine.c +++ b/src/os/emit_signal_wine.c @@ -1,22 +1,64 @@ +/* + * Copyright 2022-2025 André Zwing + * Copyright 2023 Alexandre Julliard + */ +#include <signal.h> +#include <windows.h> +#include <winternl.h> + #include "x64emu.h" +#include "debug.h" #include "custommem.h" +#include "wine/compiler.h" void EmitSignal(x64emu_t* emu, int sig, void* addr, int code) { - // FIXME + EXCEPTION_RECORD rec; + + switch (sig) { + case SIGILL: + printf_log(LOG_DEBUG, "SIGILL at %p with code %d\n", addr, code); + rec.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION; + break; + case SIGSEGV: + printf_log(LOG_DEBUG, "SIGSEGV at %p with code %d\n", addr, code); + rec.ExceptionCode = STATUS_ACCESS_VIOLATION; + break; + default: + printf_log(LOG_INFO, "Warning, unknown signal %d at %p with code %d\n", sig, addr, code); + rec.ExceptionCode = STATUS_ACCESS_VIOLATION; + break; + } + rec.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + rec.ExceptionRecord = NULL; + rec.ExceptionAddress = addr; + rec.NumberParameters = 0; + RtlRaiseException(&rec); } void CheckExec(x64emu_t* emu, uintptr_t addr) { - // FIXME } -void EmitInterruption(x64emu_t* emu, int num, void* addr) +void EmitDiv0(x64emu_t* emu, void* addr, int code) { - // FIXME + EXCEPTION_RECORD rec; + rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO; + rec.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + rec.ExceptionRecord = NULL; + rec.ExceptionAddress = addr; + rec.NumberParameters = 0; + RtlRaiseException(&rec); } -void EmitDiv0(x64emu_t* emu, void* addr, int code) +void EmuInt3(void* emu, void* addr) { - // FIXME + EXCEPTION_RECORD rec; + + rec.ExceptionCode = STATUS_BREAKPOINT; + rec.ExceptionFlags = 0; + rec.ExceptionRecord = NULL; + rec.ExceptionAddress = addr; + rec.NumberParameters = 0; + RtlRaiseException(&rec); } diff --git a/src/os/os_wine.c b/src/os/os_wine.c index 937371c7..83be99b2 100644 --- a/src/os/os_wine.c +++ b/src/os/os_wine.c @@ -5,6 +5,7 @@ #include <winternl.h> #include "os.h" +#include "debug.h" #include "wine/debug.h" #define HandleToULong(h) ((ULONG)(ULONG_PTR)(h)) @@ -39,22 +40,21 @@ void* GetSeg43Base() void* GetSegmentBase(uint32_t desc) { - // FIXME + printf_log(LOG_NONE, "GetSegmentBase NYI\n"); return NULL; } -void EmuInt3(void* emu, void* addr) { } void* EmuFork(void* emu, int forktype) { return NULL; } void EmuX64Syscall(void* emu) { - // FIXME + printf_log(LOG_NONE, "EmuX64Syscall NYI\n"); } void EmuX86Syscall(void* emu) { - // FIXME + printf_log(LOG_NONE, "EmuX86Syscall NYI\n"); } const char* GetBridgeName(void* p) diff --git a/wow64/compiler.h b/wow64/include/wine/compiler.h index eac844e5..f206c40d 100644 --- a/wow64/compiler.h +++ b/wow64/include/wine/compiler.h @@ -4,9 +4,9 @@ #include <stdint.h> /* Things missing from mingw64 right now */ -#define ThreadWow64Context (29) -#define WOW64_TLS_CPURESERVED (1) -#define WOW64_TLS_MAX_NUMBER (19) +#define ThreadWow64Context (29) +#define WOW64_TLS_CPURESERVED (1) +#define WOW64_TLS_MAX_NUMBER (19) #define WOW64_CPURESERVED_FLAG_RESET_STATE (1) typedef enum _MEMORY_INFORMATION_CLASS { @@ -26,8 +26,7 @@ typedef enum _MEMORY_INFORMATION_CLASS { MemoryBadInformationAllProcesses, } MEMORY_INFORMATION_CLASS; -typedef struct _WOW64_CPURESERVED -{ +typedef struct _WOW64_CPURESERVED { USHORT Flags; USHORT Machine; } WOW64_CPURESERVED; @@ -51,21 +50,22 @@ typedef struct _XMM_SAVE_AREA32 { BYTE Reserved4[96]; } XMM_SAVE_AREA32; -#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 ) +#define NtCurrentProcess() ((HANDLE)(LONG_PTR) - 1) -NTSTATUS WINAPI RtlWow64GetCurrentCpuArea(USHORT *, void **, void **); -NTSTATUS WINAPI Wow64SystemServiceEx(UINT, UINT*); +NTSTATUS WINAPI RtlWow64GetCurrentCpuArea(USHORT*, void**, void**); +NTSTATUS WINAPI Wow64SystemServiceEx(UINT, UINT*); NTSYSAPI NTSTATUS WINAPI LdrGetDllHandle(LPCWSTR, ULONG, const UNICODE_STRING*, HMODULE*); NTSYSAPI NTSTATUS WINAPI NtContinue(PCONTEXT, BOOLEAN); NTSYSAPI NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE, LPCVOID, MEMORY_INFORMATION_CLASS, PVOID, SIZE_T, SIZE_T*); NTSYSAPI void* WINAPI RtlFindExportedRoutineByName(HMODULE, const char*); NTSYSAPI void DECLSPEC_NORETURN WINAPI RtlRaiseStatus(NTSTATUS); +NTSYSAPI void WINAPI RtlRaiseException(EXCEPTION_RECORD*); 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)); + /* 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 0aa10a22..a985ef69 100644 --- a/wow64/wowbox64.c +++ b/wow64/wowbox64.c @@ -9,7 +9,6 @@ #include <winternl.h> #include <winnt.h> -#include "compiler.h" #include "debug.h" #include "os.h" #include "custommem.h" @@ -22,6 +21,7 @@ #include "box64cpu.h" #include "box64cpu_util.h" #include "rbtree.h" +#include "wine/compiler.h" #include "wine/debug.h" uintptr_t box64_pagesize = 4096; @@ -210,6 +210,8 @@ STATIC_ASSERT(offsetof(x64emu_t, win64_teb) == 3120, offset_of_b_must_be_4); printf_log(LOG_INFO, "libwowbox64.dll process initializing.\n"); + PrintEnvVariables(&box64env, LOG_INFO); + memset(bopcode, 0xc3, sizeof(bopcode)); memset(unxcode, 0xc3, sizeof(unxcode)); bopcode[0] = 0x2ecd; @@ -346,7 +348,7 @@ NTSTATUS WINAPI BTCpuTurboThunkControl(ULONG enable) return STATUS_SUCCESS; } -void x86IntImpl(x64emu_t *emu, int code) +void EmitInterruptionImpl(x64emu_t *emu, int code) { int inst_off = box64env.dynarec ? 2 : 0; @@ -429,10 +431,10 @@ static void __attribute__((naked)) SEHFrameTrampoline2Args(void* Arg0, int Arg1, ".seh_endproc" ); } -void x86Int(void* emu, int code) +void EmitInterruption(x64emu_t* emu, int num, void* addr) { CONTEXT *entry_context = NtCurrentTeb()->TlsSlots[WOW64_TLS_MAX_NUMBER]; - SEHFrameTrampoline2Args(emu, code, (void*)x86IntImpl, entry_context->Sp, entry_context->Pc); + SEHFrameTrampoline2Args(emu, num, (void*)EmitInterruptionImpl, entry_context->Sp, entry_context->Pc); NtCurrentTeb()->TlsSlots[WOW64_TLS_MAX_NUMBER] = entry_context; } |