Skip to content

Commit

Permalink
Merge pull request #4164 from bylaws/swwow
Browse files Browse the repository at this point in the history
WOW64: Set the software CPU area flag
  • Loading branch information
Sonicadvance1 authored Nov 19, 2024
2 parents d5c9655 + 830bd34 commit 22058c0
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
3 changes: 3 additions & 0 deletions Source/Windows/ARM64EC/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@ static void RethrowGuestException(const EXCEPTION_RECORD& Rec, ARM64_NT_CONTEXT&
Args->Rec = FEX::Windows::HandleGuestException(Fault, Rec, Args->Context.Pc, Args->Context.X8);
if (Args->Rec.ExceptionCode == EXCEPTION_SINGLE_STEP) {
Args->Context.Cpsr &= ~(1 << 21); // PSTATE.SS
} else if (Args->Rec.ExceptionCode == EXCEPTION_BREAKPOINT) {
// INT3 will set RIP to the instruction following it, undo this (any edge cases with multibyte instructions that trigger breakpoints are bugs present in Windows also)
Args->Context.Pc -= 1;
}

Context.Sp = reinterpret_cast<uint64_t>(Args);
Expand Down
7 changes: 3 additions & 4 deletions Source/Windows/Common/Exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ HandleGuestException(FEXCore::Core::CpuStateFrame::SynchronousFaultDataStruct& F
switch (Fault.TrapNo) {
case FEXCore::X86State::X86_TRAPNO_DB: Dst.ExceptionCode = EXCEPTION_SINGLE_STEP; return Dst;
case FEXCore::X86State::X86_TRAPNO_BP:
Rip -= 1;
Dst.ExceptionAddress = reinterpret_cast<void*>(Rip);
Dst.ExceptionAddress = reinterpret_cast<void*>(Rip - 1);
Dst.ExceptionCode = EXCEPTION_BREAKPOINT;
Dst.NumberParameters = 1;
Dst.ExceptionInformation[0] = 0;
Expand All @@ -44,9 +43,9 @@ HandleGuestException(FEXCore::Core::CpuStateFrame::SynchronousFaultDataStruct& F
if ((Fault.err_code & 0b111) == 0b010) {
switch (Fault.err_code >> 3) {
case 0x2d:
Rip += 2;
Rip += 3;
Dst.ExceptionCode = EXCEPTION_BREAKPOINT;
Dst.ExceptionAddress = reinterpret_cast<void*>(Rip + 1);
Dst.ExceptionAddress = reinterpret_cast<void*>(Rip);
Dst.NumberParameters = 1;
Dst.ExceptionInformation[0] = Rax; // RAX
// Note that ExceptionAddress doesn't equal the reported context RIP here, this discrepancy expected and not having it can trigger anti-debug logic.
Expand Down
8 changes: 8 additions & 0 deletions Source/Windows/WOW64/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ struct TLS {
explicit TLS(_TEB* TEB)
: TEB(TEB) {}

WOW64INFO& Wow64Info() const {
return *reinterpret_cast<WOW64INFO*>(TEB->TlsSlots[WOW64_TLS_WOW64INFO]);
}

std::atomic<uint32_t>& ControlWord() const {
// TODO: Change this when libc++ gains std::atomic_ref support
return reinterpret_cast<std::atomic<uint32_t>&>(TEB->TlsSlots[FEXCore::ToUnderlying(Slot::CONTROL_WORD)]);
Expand Down Expand Up @@ -479,6 +483,9 @@ void BTCpuProcessInit() {
if (Sym) {
WineUnixCall = *reinterpret_cast<decltype(WineUnixCall)*>(Sym);
}

// wow64.dll will only initialise the cross-process queue if this is set
GetTLS().Wow64Info().CpuFlags = WOW64_CPUFLAGS_SOFTWARE;
}

void BTCpuProcessTerm(HANDLE Handle, BOOL After, ULONG Status) {}
Expand Down Expand Up @@ -705,6 +712,7 @@ bool BTCpuResetToConsistentStateImpl(EXCEPTION_POINTERS* Ptrs) {
if (Exception->ExceptionCode == EXCEPTION_SINGLE_STEP) {
WowContext.EFlags &= ~(1 << FEXCore::X86State::RFLAG_TF_LOC);
}
// wow64.dll will handle adjusting PC in the dispatched context after a breakpoint

BTCpuSetContext(GetCurrentThread(), GetCurrentProcess(), nullptr, &WowContext);
Context::UnlockJITContext();
Expand Down
13 changes: 13 additions & 0 deletions Source/Windows/include/winternl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ extern "C" {
#define NtCurrentProcess() ((HANDLE) ~(ULONG_PTR)0)
#define NtCurrentThread() ((HANDLE) ~(ULONG_PTR)1)

#define WOW64_TLS_WOW64INFO 10
#define WOW64_TLS_MAX_NUMBER 19

#define WOW64_CPUFLAGS_SOFTWARE 0x02

#define STATUS_EMULATION_SYSCALL ((NTSTATUS)0x40000039)

#ifdef _M_ARM_64EC
Expand Down Expand Up @@ -342,6 +345,16 @@ typedef struct __TEB { /* win32/win64 */
GUID EffectiveContainerId; /* ff0/1828 */
} __TEB, *__PTEB;

typedef struct _WOW64INFO {
ULONG NativeSystemPageSize;
ULONG CpuFlags;
ULONG Wow64ExecuteFlags;
ULONG unknown;
ULONGLONG SectionHandle;
ULONGLONG CrossProcessWorkList;
USHORT NativeMachineType;
USHORT EmulatedMachineType;
} WOW64INFO;

typedef struct _THREAD_BASIC_INFORMATION {
NTSTATUS ExitStatus;
Expand Down

0 comments on commit 22058c0

Please sign in to comment.