| 526 | } |
| 527 | |
| 528 | static void RethrowGuestException(const EXCEPTION_RECORD& Rec, ARM64_NT_CONTEXT& Context) { |
| 529 | const auto& Config = SignalDelegator->GetConfig(); |
| 530 | auto* Thread = GetCPUArea().ThreadState(); |
| 531 | auto& Fault = Thread->CurrentFrame->SynchronousFaultData; |
| 532 | uint64_t GuestSp = Context.X[Config.SRAGPRMapping[static_cast<size_t>(FEXCore::X86State::REG_RSP)]]; |
| 533 | auto* Args = reinterpret_cast<KiUserExceptionDispatcherStackLayout*>(FEXCore::AlignDown(GuestSp, 64)) - 1; |
| 534 | |
| 535 | LogMan::Msg::DFmt("Reconstructing context"); |
| 536 | if (!IsDispatcherAddress(Context.Pc)) { |
| 537 | ReconstructThreadState(Thread, Context); |
| 538 | } |
| 539 | Args->Context = StoreStateToPackedECContext(Thread, Context.Fpcr, Context.Fpsr); |
| 540 | LogMan::Msg::DFmt("pc: {:X} rip: {:X}", Context.Pc, Args->Context.Pc); |
| 541 | |
| 542 | // X64 Windows always clears TF, DF and AF when handling an exception, restoring after. |
| 543 | // Current ARM64EC windows can only restore NZCV+SS when returning from an exception and other flags are left untouched from the handler context. |
| 544 | // TODO: Can extend wine to support this by mapping the remaining EFlags into reserved cpsr members. |
| 545 | uint32_t EFlags = CTX->ReconstructCompactedEFLAGS(Thread, false, nullptr, 0); |
| 546 | EFlags &= ~(1 << FEXCore::X86State::RFLAG_TF_RAW_LOC); |
| 547 | CTX->SetFlagsFromCompactedEFLAGS(Thread, EFlags); |
| 548 | |
| 549 | Args->Rec = FEX::Windows::HandleGuestException(Fault, Rec, Args->Context.Pc, Args->Context.X8); |
| 550 | if (Args->Rec.ExceptionCode == EXCEPTION_SINGLE_STEP) { |
| 551 | Args->Context.Cpsr &= ~(1 << 21); // PSTATE.SS |
| 552 | } else if (Args->Rec.ExceptionCode == EXCEPTION_BREAKPOINT) { |
| 553 | // 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) |
| 554 | Args->Context.Pc -= 1; |
| 555 | } |
| 556 | |
| 557 | Context.Sp = reinterpret_cast<uint64_t>(Args); |
| 558 | Context.Pc = KiUserExceptionDispatcher; |
| 559 | } |
| 560 | |
| 561 | class ECSyscallHandler : public FEXCore::HLE::SyscallHandler, public FEXCore::Allocator::FEXAllocOperators { |
| 562 | public: |
no test coverage detected