diff --git a/Core/Core.cpp b/Core/Core.cpp index 362f3a44e3..e7d95c685a 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -398,7 +398,6 @@ const char *MemoryExceptionTypeAsString(MemoryExceptionType type) { case MemoryExceptionType::WRITE_WORD: return "Write Word"; case MemoryExceptionType::READ_BLOCK: return "Read Block"; case MemoryExceptionType::WRITE_BLOCK: return "Read/Write Block"; - case MemoryExceptionType::EXEC_ADDR: return "Bad Exec Addr"; default: return "N/A"; } @@ -461,17 +460,15 @@ void Core_ExecException(u32 address, u32 pc, ExecExceptionType type) { const char *desc = ExecExceptionTypeAsString(type); WARN_LOG(MEMMAP, "%s: Invalid destination %08x PC %08x LR %08x", desc, address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); - if (!g_Config.bIgnoreBadMemAccess) { - ExceptionInfo &e = g_exceptionInfo; - e = {}; - e.type = ExceptionType::BAD_EXEC_ADDR; - e.info = ""; - e.exec_type = type; - e.address = address; - e.pc = pc; - Core_EnableStepping(true); - host->SetDebugMode(true); - } + ExceptionInfo &e = g_exceptionInfo; + e = {}; + e.type = ExceptionType::BAD_EXEC_ADDR; + e.info = ""; + e.exec_type = type; + e.address = address; + e.pc = pc; + Core_EnableStepping(true); + host->SetDebugMode(true); } void Core_Break() { diff --git a/Core/Core.h b/Core/Core.h index 7353523470..21facdb735 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -88,7 +88,6 @@ enum class MemoryExceptionType { WRITE_WORD, READ_BLOCK, WRITE_BLOCK, - EXEC_ADDR, }; enum class ExecExceptionType { JUMP, diff --git a/Core/MIPS/ARM/ArmAsm.cpp b/Core/MIPS/ARM/ArmAsm.cpp index 44176dc293..ed06c4065e 100644 --- a/Core/MIPS/ARM/ArmAsm.cpp +++ b/Core/MIPS/ARM/ArmAsm.cpp @@ -204,6 +204,7 @@ void ArmJit::GenerateFixedCode() { LDR(R0, CTXREG, offsetof(MIPSState, pc)); // TODO: In practice, do we ever run code from uncached space (| 0x40000000)? If not, we can remove this BIC. BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF + dispatcherFetch = GetCodePtr(); LDR(R0, MEMBASEREG, R0); AND(R1, R0, Operand2(0xFF, 4)); // rotation is to the right, in 2-bit increments. BIC(R0, R0, Operand2(0xFF, 4)); diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index 50322a65bc..b6e3138913 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -184,6 +184,9 @@ public: const u8 *GetDispatcher() const override { return dispatcher; } + bool IsAtDispatchFetch(const u8 *ptr) const override { + return ptr == dispatcherFetch; + } void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override; void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override; @@ -311,6 +314,7 @@ public: const u8 *dispatcherCheckCoreState; const u8 *dispatcherPCInR0; const u8 *dispatcher; + const u8 *dispatcherFetch; const u8 *dispatcherNoCheck; const u8 *restoreRoundingMode; diff --git a/Core/MemFault.cpp b/Core/MemFault.cpp index 4db12f0ab1..4ebec040a1 100644 --- a/Core/MemFault.cpp +++ b/Core/MemFault.cpp @@ -53,7 +53,7 @@ void MemFault_Init() { } bool MemFault_MayBeResumable() { - return g_lastCrashAddress != nullptr && g_lastMemoryExceptionType != MemoryExceptionType::EXEC_ADDR; + return g_lastCrashAddress != nullptr; } void MemFault_IgnoreLastCrash() { @@ -166,7 +166,17 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { } if (isAtDispatch) { - type = MemoryExceptionType::EXEC_ADDR; + u32 targetAddr = currentMIPS->pc; // bad approximation +#if PPSSPP_ARCH(AMD64) + // We know which register the address is in, look in Asm.cpp. + targetAddr = context->Rax; +#endif + // TODO: Do the other archs. + Core_ExecException(targetAddr, currentMIPS->pc, ExecExceptionType::JUMP); + // Redirect execution to a crash handler that will switch to CoreState::CORE_RUNTIME_ERROR immediately. + context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler(); + ERROR_LOG(MEMMAP, "Bad execution access detected, halting: %08x (last known pc %08x, host: %p)", targetAddr, currentMIPS->pc, (void *)hostAddress); + return true; } else if (success) { if (info.isMemoryWrite) { type = MemoryExceptionType::WRITE_WORD;