mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 13:00:15 +02:00
Windows: Rise a non-continuable excetpion for STATUS_STACK_BUFFER_OVERRUN
This commit is contained in:
1 parent
9f511d5d78
commit
d704bd3cef
5 files changed
+20
-3
No files matched your search
@@ -121,6 +121,7 @@ ExitFunctionSuspendPoint:
|
||||
// Allows for continuing from a full native context, as the NTDLL NtContinue export takes in an x64 context with EC and
|
||||
// the conversion to that loses the ARM64EC ABI-disallowed registers that FEX uses.
|
||||
DIRECT_SYSCALL_WRAPPER("#NtContinueNative", WineNtContinueSyscallId, 0x43)
|
||||
DIRECT_SYSCALL_WRAPPER("#NtRaiseExceptionNative", WineNtRaiseExceptionSyscallId, 0x174)
|
||||
|
||||
// Both of these are wrapped as FEX needs them to setup its call checker at startup time and their NTDLL thunks could
|
||||
// already be patched by then (and because the call checker isn't installed, their patched x86 versions would be invoked
|
||||
|
||||
@@ -87,10 +87,12 @@ void* WineSyscallDispatcher;
|
||||
uint64_t WineNtContinueSyscallId;
|
||||
uint64_t WineNtAllocateVirtualMemorySyscallId;
|
||||
uint64_t WineNtProtectVirtualMemorySyscallId;
|
||||
uint64_t WineNtRaiseExceptionSyscallId;
|
||||
|
||||
NTSTATUS NtContinueNative(ARM64_NT_CONTEXT* NativeContext, BOOLEAN Alert);
|
||||
NTSTATUS NtAllocateVirtualMemoryNative(HANDLE, PVOID*, ULONG_PTR, SIZE_T*, ULONG, ULONG);
|
||||
NTSTATUS NtProtectVirtualMemoryNative(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG*);
|
||||
NTSTATUS NtRaiseExceptionNative(EXCEPTION_RECORD*, ARM64_NT_CONTEXT*, BOOL);
|
||||
static fextl::string AppConfigName {};
|
||||
|
||||
[[noreturn]]
|
||||
@@ -260,6 +262,8 @@ void ParseWineSyscallNumbers(HMODULE NtDll) {
|
||||
WineNtAllocateVirtualMemorySyscallId = CurSyscallId;
|
||||
} else if (strcmp(it->Name, "NtProtectVirtualMemory") == 0) {
|
||||
WineNtProtectVirtualMemorySyscallId = CurSyscallId;
|
||||
} else if (strcmp(it->Name, "NtRaiseException") == 0) {
|
||||
WineNtRaiseExceptionSyscallId = CurSyscallId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -500,7 +504,8 @@ static void RethrowGuestException(const EXCEPTION_RECORD& Rec, ARM64_NT_CONTEXT&
|
||||
EFlags &= ~(1 << FEXCore::X86State::RFLAG_TF_RAW_LOC);
|
||||
CTX->SetFlagsFromCompactedEFLAGS(Thread, EFlags);
|
||||
|
||||
Args->Rec = FEX::Windows::HandleGuestException(Fault, Rec, Args->Context.Pc, Args->Context.X8, Args->Context.X0);
|
||||
BOOL FirstChance = TRUE;
|
||||
Args->Rec = FEX::Windows::HandleGuestException(Fault, Rec, Args->Context.Pc, Args->Context.X8, Args->Context.X0, FirstChance);
|
||||
if (Args->Rec.ExceptionCode == EXCEPTION_SINGLE_STEP) {
|
||||
Args->Context.Cpsr &= ~(1 << 21); // PSTATE.SS
|
||||
} else if (Args->Rec.ExceptionCode == EXCEPTION_BREAKPOINT) {
|
||||
@@ -508,6 +513,9 @@ static void RethrowGuestException(const EXCEPTION_RECORD& Rec, ARM64_NT_CONTEXT&
|
||||
Args->Context.Pc -= 1;
|
||||
}
|
||||
|
||||
if (!FirstChance) {
|
||||
NtRaiseExceptionNative(&Args->Rec, &Args->Context, FirstChance);
|
||||
}
|
||||
Context.Sp = reinterpret_cast<uint64_t>(Args);
|
||||
Context.Pc = KiUserExceptionDispatcher;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace FEX::Windows {
|
||||
template<typename TReg>
|
||||
static inline EXCEPTION_RECORD HandleGuestException(FEXCore::Core::CpuStateFrame::SynchronousFaultDataStruct& Fault,
|
||||
const EXCEPTION_RECORD& Src, TReg& Rip, TReg Rax, TReg Cx) {
|
||||
const EXCEPTION_RECORD& Src, TReg& Rip, TReg Rax, TReg Cx, BOOL& FirstChance) {
|
||||
EXCEPTION_RECORD Dst = Src;
|
||||
Dst.ExceptionAddress = reinterpret_cast<void*>(Rip);
|
||||
|
||||
@@ -51,9 +51,11 @@ static inline EXCEPTION_RECORD HandleGuestException(FEXCore::Core::CpuStateFrame
|
||||
return Dst;
|
||||
case 0x29:
|
||||
Dst.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
|
||||
Dst.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
|
||||
Dst.ExceptionAddress = reinterpret_cast<void*>(Rip);
|
||||
Dst.NumberParameters = 1;
|
||||
Dst.ExceptionInformation[0] = Cx;
|
||||
FirstChance = FALSE;
|
||||
return Dst;
|
||||
case 0x2c: Dst.ExceptionCode = STATUS_ASSERTION_FAILURE; return Dst;
|
||||
case 0x2d:
|
||||
|
||||
@@ -942,7 +942,8 @@ bool BTCpuResetToConsistentStateImpl(EXCEPTION_POINTERS* Ptrs) {
|
||||
LogMan::Msg::DFmt("pc: {:X} eip: {:X}", Context->Pc, WowContext.Eip);
|
||||
|
||||
auto& Fault = Thread->CurrentFrame->SynchronousFaultData;
|
||||
*Exception = FEX::Windows::HandleGuestException(Fault, *Exception, WowContext.Eip, WowContext.Eax, WowContext.Ecx);
|
||||
BOOL FirstChance = TRUE;
|
||||
*Exception = FEX::Windows::HandleGuestException(Fault, *Exception, WowContext.Eip, WowContext.Eax, WowContext.Ecx, FirstChance);
|
||||
if (Exception->ExceptionCode == EXCEPTION_SINGLE_STEP) {
|
||||
WowContext.EFlags &= ~(1 << FEXCore::X86State::RFLAG_TF_RAW_LOC);
|
||||
}
|
||||
@@ -951,6 +952,10 @@ bool BTCpuResetToConsistentStateImpl(EXCEPTION_POINTERS* Ptrs) {
|
||||
BTCpuSetContext(GetCurrentThread(), GetCurrentProcess(), nullptr, &WowContext);
|
||||
Context::UnlockJITContext(TLS);
|
||||
|
||||
if (!FirstChance) {
|
||||
NtRaiseException(Exception, TLS.EntryContext(), FirstChance);
|
||||
}
|
||||
|
||||
// Replace the host context with one captured before JIT entry so host code can unwind
|
||||
memcpy(Context, TLS.EntryContext(), sizeof(*Context));
|
||||
|
||||
|
||||
@@ -557,6 +557,7 @@ NTSTATUS WINAPI NtQueryDirectoryFile(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO
|
||||
BOOLEAN, PUNICODE_STRING, BOOLEAN);
|
||||
NTSTATUS WINAPI NtQueryValueKey(HANDLE, const UNICODE_STRING*, KEY_VALUE_INFORMATION_CLASS, void*, DWORD, DWORD*);
|
||||
NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE, LPCVOID, MEMORY_INFORMATION_CLASS, PVOID, SIZE_T, SIZE_T*);
|
||||
NTSTATUS WINAPI NtRaiseException(EXCEPTION_RECORD*, CONTEXT*, BOOL);
|
||||
NTSTATUS WINAPI NtReadFile(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER, PULONG);
|
||||
NTSTATUS WINAPI NtSetContextThread(HANDLE, const CONTEXT*);
|
||||
NTSTATUS WINAPI NtSuspendThread(HANDLE, PULONG);
|
||||
|
||||
Reference in new issue
Block a user