mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Cause the correct type of exception. Never ignore EXEC_ADDR exceptions.
This commit is contained in:
parent
6b4356a060
commit
f6b2070e47
5 changed files with 26 additions and 15 deletions
|
@ -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() {
|
||||
|
|
|
@ -88,7 +88,6 @@ enum class MemoryExceptionType {
|
|||
WRITE_WORD,
|
||||
READ_BLOCK,
|
||||
WRITE_BLOCK,
|
||||
EXEC_ADDR,
|
||||
};
|
||||
enum class ExecExceptionType {
|
||||
JUMP,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue