diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index b4df4f942aea..71415569e5e3 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -427,12 +427,20 @@ bool Arm64Jit::DescribeCodePtr(const u8 *ptr, std::string &name) { name = "loadStaticRegisters"; else { u32 addr = blocks.GetAddressFromBlockPtr(ptr); - std::vector numbers; - blocks.GetBlockNumbersFromAddress(addr, &numbers); - if (!numbers.empty()) { - const JitBlock *block = blocks.GetBlock(numbers[0]); + // Returns 0 when it's valid, but unknown. + if (addr == 0) { + name = "(unknown or deleted block)"; + return true; + } else if (addr != (u32)-1) { + name = "(outside space)"; + return true; + } + + int number = blocks.GetBlockNumberFromAddress(addr); + if (number != -1) { + const JitBlock *block = blocks.GetBlock(number); if (block) { - name = StringFromFormat("(block %d at %08x)", numbers[0], block->originalAddress); + name = StringFromFormat("(block %d at %08x)", number, block->originalAddress); return true; } } diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index e822c5c47dd1..db4fb8cf289e 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -375,6 +375,15 @@ void JitBlockCache::GetBlockNumbersFromAddress(u32 em_address, std::vector block_numbers->push_back(i); } +int JitBlockCache::GetBlockNumberFromAddress(u32 em_address) { + for (int i = 0; i < num_blocks_; i++) { + if (blocks_[i].ContainsAddress(em_address)) + return i; + } + + return -1; +} + u32 JitBlockCache::GetAddressFromBlockPtr(const u8 *ptr) const { if (!codeBlock_->IsInSpace(ptr)) return (u32)-1; diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index f8836160ea15..6fde09d91573 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -143,6 +143,8 @@ class JitBlockCache : public JitBlockCacheDebugInterface { // Returns a list of block numbers - only one block can start at a particular address, but they CAN overlap. // This one is slow so should only be used for one-shots from the debugger UI, not for anything during runtime. void GetBlockNumbersFromAddress(u32 em_address, std::vector *block_numbers); + // Similar to above, but only the first matching address. + int GetBlockNumberFromAddress(u32 em_address); int GetBlockNumberFromEmuHackOp(MIPSOpcode inst, bool ignoreBad = false) const; u32 GetAddressFromBlockPtr(const u8 *ptr) const; diff --git a/Core/MemFault.cpp b/Core/MemFault.cpp index eb10f880cafc..49e349d44a71 100644 --- a/Core/MemFault.cpp +++ b/Core/MemFault.cpp @@ -44,6 +44,7 @@ namespace Memory { static int64_t g_numReportedBadAccesses = 0; const uint8_t *g_lastCrashAddress; MemoryExceptionType g_lastMemoryExceptionType; +static bool inCrashHandler = false; std::unordered_set g_ignoredAddresses; @@ -88,6 +89,10 @@ static bool DisassembleNativeAt(const uint8_t *codePtr, int instructionSize, std } bool HandleFault(uintptr_t hostAddress, void *ctx) { + if (inCrashHandler) + return false; + inCrashHandler = true; + SContext *context = (SContext *)ctx; const uint8_t *codePtr = (uint8_t *)(context->CTX_PC); @@ -100,6 +105,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { bool inJitSpace = MIPSComp::jit && MIPSComp::jit->CodeInRange(codePtr); if (!inJitSpace) { // This is a crash in non-jitted code. Not something we want to handle here, ignore. + inCrashHandler = false; return false; } @@ -114,8 +120,10 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { bool invalidHostAddress = hostAddress == (uintptr_t)0xFFFFFFFFFFFFFFFFULL; if (hostAddress < baseAddress || hostAddress >= baseAddress + addressSpaceSize) { // Host address outside - this was a different kind of crash. - if (!invalidHostAddress) + if (!invalidHostAddress) { + inCrashHandler = false; return false; + } } @@ -182,6 +190,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { // 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); + inCrashHandler = false; return true; } else if (success) { if (info.isMemoryWrite) { @@ -218,6 +227,8 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler(); ERROR_LOG(MEMMAP, "Bad memory access detected! %08x (%p) Stopping emulation. Info:\n%s", guestAddress, (void *)hostAddress, infoString.c_str()); } + + inCrashHandler = false; return true; } diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 94aa462c1fc1..568cc7c2fea5 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -1145,13 +1145,7 @@ UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) { JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache(); if (!blockCache) return UI::EVENT_DONE; - std::vector blockNum; - blockCache->GetBlockNumbersFromAddress(currentMIPS->pc, &blockNum); - if (blockNum.size() > 0) { - currentBlock_ = blockNum[0]; - } else { - currentBlock_ = -1; - } + currentBlock_ = blockCache->GetBlockNumberFromAddress(currentMIPS->pc); UpdateDisasm(); return UI::EVENT_DONE; }