Returns true if exception dispatch should be halted and the execution context restored to Ptrs->Context
| 866 | |
| 867 | // Returns true if exception dispatch should be halted and the execution context restored to Ptrs->Context |
| 868 | bool BTCpuResetToConsistentStateImpl(EXCEPTION_POINTERS* Ptrs) { |
| 869 | auto* Context = Ptrs->ContextRecord; |
| 870 | auto* Exception = Ptrs->ExceptionRecord; |
| 871 | auto Thread = GetTLS().ThreadState(); |
| 872 | FEXCORE_PROFILE_ACCUMULATION(Thread, AccumulatedSignalTime); |
| 873 | |
| 874 | if (Exception->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { |
| 875 | const auto FaultAddress = static_cast<uint64_t>(Exception->ExceptionInformation[1]); |
| 876 | |
| 877 | if (FEX::Windows::CallRetStack::HandleAccessViolation(Thread, FaultAddress, Context->X25)) { |
| 878 | return true; |
| 879 | } |
| 880 | |
| 881 | if (OvercommitTracker && OvercommitTracker->HandleAccessViolation(FaultAddress)) { |
| 882 | return true; |
| 883 | } |
| 884 | |
| 885 | if (Context::HandleSuspendInterrupt(Context, FaultAddress)) { |
| 886 | LogMan::Msg::DFmt("Resumed from suspend"); |
| 887 | return true; |
| 888 | } |
| 889 | |
| 890 | if (Thread) { |
| 891 | std::scoped_lock Lock(ThreadCreationMutex); |
| 892 | FEXCORE_PROFILE_INSTANT_INCREMENT(Thread, AccumulatedSMCCount, 1); |
| 893 | if (InvalidationTracker->HandleRWXAccessViolation(Thread, Context->Pc, FaultAddress)) { |
| 894 | if (CTX->IsAddressInCodeBuffer(Thread, Context->Pc) && !CTX->IsCurrentBlockSingleInst(Thread) && |
| 895 | CTX->IsAddressInCurrentBlock(Thread, FaultAddress & FEXCore::Utils::FEX_PAGE_MASK, FEXCore::Utils::FEX_PAGE_SIZE)) { |
| 896 | Context::ReconstructThreadState(Context); |
| 897 | LogMan::Msg::DFmt("Handled inline self-modifying code: pc: {:X} rip: {:X} fault: {:X}", Context->Pc, |
| 898 | Thread->CurrentFrame->State.rip, FaultAddress); |
| 899 | |
| 900 | // Adjust context to return to the dispatcher, reloading SRA from thread state |
| 901 | const auto& Config = SignalDelegator->GetConfig(); |
| 902 | Context->Pc = Config.AbsoluteLoopTopAddressFillSRA; |
| 903 | Context->X1 = 1; // Set ENTRY_FILL_SRA_SINGLE_INST_REG to force a single step |
| 904 | } else { |
| 905 | LogMan::Msg::DFmt("Handled self-modifying code: pc: {:X} fault: {:X}", Context->Pc, FaultAddress); |
| 906 | } |
| 907 | return true; |
| 908 | } |
| 909 | } |
| 910 | } |
| 911 | |
| 912 | if (!Thread || !IsAddressInJit(Context->Pc)) { |
| 913 | return false; |
| 914 | } |
| 915 | |
| 916 | FEXCORE_PROFILE_INSTANT_INCREMENT(Thread, AccumulatedSIGBUSCount, 1); |
| 917 | if (Exception->ExceptionCode == EXCEPTION_DATATYPE_MISALIGNMENT && Context::HandleUnalignedAccess(Context)) { |
| 918 | LogMan::Msg::DFmt("Handled unaligned atomic: new pc: {:X}", Context->Pc); |
| 919 | return true; |
| 920 | } |
| 921 | |
| 922 | LogMan::Msg::DFmt("Reconstructing context"); |
| 923 | |
| 924 | WOW64_CONTEXT WowContext = Context::ReconstructWowContext(Context); |
| 925 | LogMan::Msg::DFmt("pc: {:X} eip: {:X}", Context->Pc, WowContext.Eip); |
no test coverage detected