Merge pull request #4164 from bylaws/swwow
Some checks failed
Build + Test / build_plus_test ([self-hosted ARMv8.0]) (push) Has been cancelled
Build + Test / build_plus_test ([self-hosted ARMv8.2]) (push) Has been cancelled
Build + Test / build_plus_test ([self-hosted ARMv8.4]) (push) Has been cancelled
GLIBC fault test / glibc_fault_test ([self-hosted ARM64]) (push) Has been cancelled
Hostrunner tests / hostrunner_tests ([self-hosted x64]) (push) Has been cancelled
Instruction Count CI run / instcountci_tests ([self-hosted ARM64]) (push) Has been cancelled
Instruction Count CI run / instcountci_tests ([self-hosted x64]) (push) Has been cancelled
Mingw build / mingw_build ([self-hosted ARM64 mingw]) (push) Has been cancelled
Mingw build / mingw_build ([self-hosted ARM64EC mingw ARM64]) (push) Has been cancelled
Vixl Simulator run / vixl_simulator ([self-hosted ARMv8.4]) (push) Has been cancelled
Vixl Simulator run / vixl_simulator ([self-hosted x64]) (push) Has been cancelled

WOW64: Set the software CPU area flag
This commit is contained in:
Ryan Houdek 2024-11-19 09:39:33 -08:00 committed by GitHub
commit 22058c06a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 27 additions and 4 deletions

View File

@ -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);

View File

@ -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;
@ -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.

View File

@ -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)]);
@ -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) {}
@ -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();

View File

@ -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
@ -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;