| 384 | } |
| 385 | |
| 386 | bool HandleSuspendInterrupt(CONTEXT* Context, uint64_t FaultAddress) { |
| 387 | if (FaultAddress != reinterpret_cast<uint64_t>(&GetTLS().ThreadState()->InterruptFaultPage)) { |
| 388 | return false; |
| 389 | } |
| 390 | |
| 391 | void* TmpAddress = reinterpret_cast<void*>(FaultAddress); |
| 392 | SIZE_T TmpSize = FEXCore::Utils::FEX_PAGE_SIZE; |
| 393 | ULONG TmpProt; |
| 394 | NtProtectVirtualMemory(NtCurrentProcess(), &TmpAddress, &TmpSize, PAGE_READWRITE, &TmpProt); |
| 395 | |
| 396 | // Since interrupts only happen at the start of blocks, the reconstructed state should be entirely accurate |
| 397 | ReconstructThreadState(Context); |
| 398 | |
| 399 | // Yield to the suspender |
| 400 | UnlockJITContext(); |
| 401 | LockJITContext(); |
| 402 | |
| 403 | // Adjust context to return to the dispatcher, reloading SRA from thread state |
| 404 | const auto& Config = SignalDelegator->GetConfig(); |
| 405 | Context->Pc = Config.AbsoluteLoopTopAddressFillSRA; |
| 406 | Context->X1 = 0; // Set ENTRY_FILL_SRA_SINGLE_INST_REG |
| 407 | return true; |
| 408 | } |
| 409 | } // namespace Context |
| 410 | |
| 411 | // Calls a 2-argument function `Func` setting the parent unwind frame information to the given SP and PC |
no test coverage detected