diff --git a/Source/Windows/ARM64EC/Module.S b/Source/Windows/ARM64EC/Module.S index e182db3de..365931332 100644 --- a/Source/Windows/ARM64EC/Module.S +++ b/Source/Windows/ARM64EC/Module.S @@ -64,12 +64,10 @@ ExitFunctionEC: strb wzr, [x17, #0x0] // ChpeV2CpuAreaInfo->InSimulation ldr x17, [x17, #0x20] // ChpeV2CpuAreaInfo->SuspendDoorbell ldr w17, [x17] - cbz w17, no_suspend -.global ExitFunctionSuspendPoint -ExitFunctionSuspendPoint: - brk #0xCAFE - // Will resume here -no_suspend: + cbnz w17, ExitFunctionSuspendPoint + +.global ExitFunctionSuspendResumePoint +ExitFunctionSuspendResumePoint: // Either return to an exit thunk (return to ARM64EC function) or call an entry thunk (call to ARM64EC function). // It is assumed that a 'blr x16' instruction is only ever used to call into x86 code from an exit thunk, and that all // exported ARM64EC functions have a 4-byte offset to their entry thunk immediately before their first instruction. @@ -99,6 +97,11 @@ ret_sp_misaligned: ldr lr, [lr, #:lo12:X64ReturnInstr] br x17 +.global ExitFunctionSuspendPoint +ExitFunctionSuspendPoint: + brk #0xCAFE + // Resume will jump back to `ExitFunctionSuspendResumePoint` + // Makes a wrapper for calling a system call directly, skipping the usual ntdll thunks #define HASH # #define DIRECT_SYSCALL_WRAPPER(Name, WineIdName, WindowsId) \ diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index 28c25cfc7..8df18573c 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -69,6 +69,7 @@ extern IMAGE_DOS_HEADER __ImageBase; // Provided by the linker extern void* ExitFunctionEC; extern void* CheckCall; extern void* ExitFunctionSuspendPoint; +extern void* ExitFunctionSuspendResumePoint; void* X64ReturnInstr; // See Module.S uintptr_t NtDllBase; @@ -676,7 +677,7 @@ bool ResetToConsistentStateImpl(const ThreadCPUArea CPUArea, EXCEPTION_RECORD* E // A suspend interrupt can occur in ExitFunctionEC before InSimulation is unset and set SuspendDoorbell. If this // occurs then it is still our duty to cooperatively suspend with an appropriate context. To support this, after // unsetting InSimulation a brk #0xCAFE instruction will be raised that we can handle here. - NativeContext->Pc += 4; // Skip over the brk instruction when we resume + NativeContext->Pc = reinterpret_cast(ExitFunctionSuspendResumePoint); // Jump to the suspend resume point. *CPUArea.Area->SuspendDoorbell = 0; return true; }