diff --git a/Core/Debugger/DisassemblyManager.cpp b/Core/Debugger/DisassemblyManager.cpp index 3f7165d163..6eb7b003fa 100644 --- a/Core/Debugger/DisassemblyManager.cpp +++ b/Core/Debugger/DisassemblyManager.cpp @@ -1031,3 +1031,88 @@ std::string DisassembleRange(u32 start, u32 size, bool displaySymbols, MIPSDebug return result; } + +void DisassemblyLineInfo::ToString(char *text, size_t bufSize, u32 curAddress) const { + text[0] = 0; + if (type == DISTYPE_OPCODE) { + if (info.hasRelevantAddress && IsLikelyStringAt(info.relevantAddress)) { + snprintf(text, sizeof(text), "[%08X] = \"%s\"", info.relevantAddress, Memory::GetCharPointer(info.relevantAddress)); + } + + if (info.isDataAccess) { + if (!Memory::IsValidRange(info.dataAddress, info.dataSize)) { + snprintf(text, sizeof(text), "Invalid address %08X", info.dataAddress); + } else { + bool isFloat = MIPSGetInfo(info.encodedOpcode) & (IS_FPU | IS_VFPU); + switch (info.dataSize) { + case 1: + snprintf(text, sizeof(text), "[%08X] = %02X", info.dataAddress, Memory::ReadUnchecked_U8(info.dataAddress)); + break; + case 2: + snprintf(text, sizeof(text), "[%08X] = %04X", info.dataAddress, Memory::ReadUnchecked_U16(info.dataAddress)); + break; + case 4: + { + u32 dataInt = Memory::ReadUnchecked_U32(info.dataAddress); + u32 dataFloat = Memory::ReadUnchecked_Float(info.dataAddress); + std::string dataString; + if (isFloat) + dataString = StringFromFormat("%08X / %f", dataInt, dataFloat); + else + dataString = StringFromFormat("%08X", dataInt); + + const std::string addressSymbol = g_symbolMap->GetLabelString(dataInt); + if (!addressSymbol.empty()) { + snprintf(text, sizeof(text), "[%08X] = %s (%s)", info.dataAddress, addressSymbol.c_str(), dataString.c_str()); + } else { + snprintf(text, sizeof(text), "[%08X] = %s", info.dataAddress, dataString.c_str()); + } + break; + } + case 16: + { + uint32_t dataInt[4]; + float dataFloat[4]; + for (int i = 0; i < 4; ++i) { + dataInt[i] = Memory::ReadUnchecked_U32(info.dataAddress + i * 4); + dataFloat[i] = Memory::ReadUnchecked_Float(info.dataAddress + i * 4); + } + std::string dataIntString = StringFromFormat("%08X,%08X,%08X,%08X", dataInt[0], dataInt[1], dataInt[2], dataInt[3]); + std::string dataFloatString = StringFromFormat("%f,%f,%f,%f", dataFloat[0], dataFloat[1], dataFloat[2], dataFloat[3]); + + snprintf(text, sizeof(text), "[%08X] = %s / %s", info.dataAddress, dataIntString.c_str(), dataFloatString.c_str()); + break; + } + } + } + } + + if (info.isBranch) { + const std::string addressSymbol = g_symbolMap->GetLabelString(info.branchTarget); + if (addressSymbol.empty()) { + snprintf(text, sizeof(text), "%08X", info.branchTarget); + } else { + snprintf(text, sizeof(text), "%08X = %s", info.branchTarget, addressSymbol.c_str()); + } + } + } else if (type == DISTYPE_DATA) { + u32 start = g_symbolMap->GetDataStart(curAddress); + if (start == -1) + start = curAddress; + + u32 diff = curAddress - start; + const std::string label = g_symbolMap->GetLabelString(start); + + if (!label.empty()) { + if (diff != 0) + snprintf(text, sizeof(text), "%08X (%s) + %08X", start, label.c_str(), diff); + else + snprintf(text, sizeof(text), "%08X (%s)", start, label.c_str()); + } else { + if (diff != 0) + snprintf(text, sizeof(text), "%08X + %08X", start, diff); + else + snprintf(text, sizeof(text), "%08X", start); + } + } +} diff --git a/Core/Debugger/DisassemblyManager.h b/Core/Debugger/DisassemblyManager.h index 7c8fc8dc17..39179f124a 100644 --- a/Core/Debugger/DisassemblyManager.h +++ b/Core/Debugger/DisassemblyManager.h @@ -34,13 +34,14 @@ typedef u32 HashType; enum DisassemblyLineType { DISTYPE_OPCODE, DISTYPE_DATA, DISTYPE_OTHER }; -struct DisassemblyLineInfo -{ +struct DisassemblyLineInfo { DisassemblyLineType type; MIPSAnalyst::MipsOpcodeInfo info; std::string name; std::string params; u32 totalSize; + + void ToString(char *dest, size_t size, u32 curAddress) const; }; enum DisasmLineType { LINE_UP, LINE_DOWN, LINE_RIGHT }; diff --git a/GPU/Common/GPUDebugInterface.cpp b/GPU/Common/GPUDebugInterface.cpp index 959d6d7c72..8cfd1686b9 100644 --- a/GPU/Common/GPUDebugInterface.cpp +++ b/GPU/Common/GPUDebugInterface.cpp @@ -683,12 +683,12 @@ uint32_t GEExpressionFunctions::getReferenceValue(uint32_t referenceIndex) { return 0; case GEReferenceIndex::OP: if (gpu_->GetCurrentDisplayList(list)) { - return Memory::Read_U32(list.pc); + return Memory::IsValid4AlignedAddress(list.pc) ? Memory::ReadUnchecked_U32(list.pc) : 0; } return 0; case GEReferenceIndex::DATA: if (gpu_->GetCurrentDisplayList(list)) { - return Memory::Read_U32(list.pc) & 0x00FFFFFF; + return Memory::IsValid4AlignedAddress(list.pc) ? Memory::ReadUnchecked_U32(list.pc) & 0x00FFFFFF : 0; } return 0; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 43b6819292..d826852896 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1670,10 +1670,10 @@ std::vector GPUCommon::DisassembleOpRange(u32 startpc, u32 endpc) { GPUDebugOp info; // Don't trigger a pause. - u32 prev = Memory::IsValidAddress(startpc - 4) ? Memory::Read_U32(startpc - 4) : 0; + u32 prev = Memory::IsValid4AlignedAddress(startpc - 4) ? Memory::ReadUnchecked_U32(startpc - 4) : 0; result.reserve((endpc - startpc) / 4); for (u32 pc = startpc; pc < endpc; pc += 4) { - u32 op = Memory::IsValidAddress(pc) ? Memory::Read_U32(pc) : 0; + u32 op = Memory::IsValid4AlignedAddress(pc) ? Memory::ReadUnchecked_U32(pc) : 0; GeDisassembleOp(pc, op, prev, buffer, sizeof(buffer)); prev = op; @@ -2151,8 +2151,17 @@ GPUDebug::NotifyResult GPUCommon::NotifyCommand(u32 pc, GPUBreakpoints *breakpoi if (debugBreak) { breakpoints->ClearTempBreakpoints(); - u32 op = Memory::Read_U32(pc); - auto info = DisassembleOp(pc, op); + GPUDebugOp info; + if (Memory::IsValid4AlignedAddress(pc)) { + op = Memory::ReadUnchecked_U32(pc); + info = DisassembleOp(pc, op); + } else { + op = 0; + info.pc = pc; + info.cmd = 0; + info.op = 0; + info.desc = "(invalid address)"; + } NOTICE_LOG(Log::GeDebugger, "Waiting at %08x, %s", pc, info.desc.c_str()); skipPcOnce_ = pc; diff --git a/UI/ImDebugger/ImDisasmView.cpp b/UI/ImDebugger/ImDisasmView.cpp index b2384761eb..b4aaac9fbe 100644 --- a/UI/ImDebugger/ImDisasmView.cpp +++ b/UI/ImDebugger/ImDisasmView.cpp @@ -888,90 +888,7 @@ void ImDisasmView::updateStatusBarText() { char text[512]; DisassemblyLineInfo line; g_disassemblyManager.getLine(curAddress_, true, line, debugger_); - - text[0] = 0; - if (line.type == DISTYPE_OPCODE) { - if (line.info.hasRelevantAddress && IsLikelyStringAt(line.info.relevantAddress)) { - snprintf(text, sizeof(text), "[%08X] = \"%s\"", line.info.relevantAddress, Memory::GetCharPointer(line.info.relevantAddress)); - } - - if (line.info.isDataAccess) { - if (!Memory::IsValidRange(line.info.dataAddress, line.info.dataSize)) { - snprintf(text, sizeof(text), "Invalid address range %08X (size %d)", line.info.dataAddress, line.info.dataSize); - } else { - bool isFloat = MIPSGetInfo(line.info.encodedOpcode) & (IS_FPU | IS_VFPU); - switch (line.info.dataSize) { - case 1: - snprintf(text, sizeof(text), "[%08X] = %02X", line.info.dataAddress, Memory::ReadUnchecked_U8(line.info.dataAddress)); - break; - case 2: - snprintf(text, sizeof(text), "[%08X] = %04X", line.info.dataAddress, Memory::ReadUnchecked_U16(line.info.dataAddress)); - break; - case 4: - { - u32 dataInt = Memory::ReadUnchecked_U32(line.info.dataAddress); - u32 dataFloat = Memory::ReadUnchecked_Float(line.info.dataAddress); - std::string dataString; - if (isFloat) - dataString = StringFromFormat("%08X / %f", dataInt, dataFloat); - else - dataString = StringFromFormat("%08X", dataInt); - - const std::string addressSymbol = g_symbolMap->GetLabelString(dataInt); - if (!addressSymbol.empty()) { - snprintf(text, sizeof(text), "[%08X] = %s (%s)", line.info.dataAddress, addressSymbol.c_str(), dataString.c_str()); - } else { - snprintf(text, sizeof(text), "[%08X] = %s", line.info.dataAddress, dataString.c_str()); - } - break; - } - case 16: - { - uint32_t dataInt[4]; - float dataFloat[4]; - for (int i = 0; i < 4; ++i) { - dataInt[i] = Memory::ReadUnchecked_U32(line.info.dataAddress + i * 4); - dataFloat[i] = Memory::ReadUnchecked_Float(line.info.dataAddress + i * 4); - } - std::string dataIntString = StringFromFormat("%08X,%08X,%08X,%08X", dataInt[0], dataInt[1], dataInt[2], dataInt[3]); - std::string dataFloatString = StringFromFormat("%f,%f,%f,%f", dataFloat[0], dataFloat[1], dataFloat[2], dataFloat[3]); - - snprintf(text, sizeof(text), "[%08X] = %s / %s", line.info.dataAddress, dataIntString.c_str(), dataFloatString.c_str()); - break; - } - } - } - } - - if (line.info.isBranch) { - const std::string addressSymbol = g_symbolMap->GetLabelString(line.info.branchTarget); - if (addressSymbol.empty()) { - snprintf(text, sizeof(text), "%08X", line.info.branchTarget); - } else { - snprintf(text, sizeof(text), "%08X = %s", line.info.branchTarget, addressSymbol.c_str()); - } - } - } else if (line.type == DISTYPE_DATA) { - u32 start = g_symbolMap->GetDataStart(curAddress_); - if (start == -1) - start = curAddress_; - - u32 diff = curAddress_ - start; - const std::string label = g_symbolMap->GetLabelString(start); - - if (!label.empty()) { - if (diff != 0) - snprintf(text, sizeof(text), "%08X (%s) + %08X", start, label.c_str(), diff); - else - snprintf(text, sizeof(text), "%08X (%s)", start, label.c_str()); - } else { - if (diff != 0) - snprintf(text, sizeof(text), "%08X + %08X", start, diff); - else - snprintf(text, sizeof(text), "%08X", start); - } - } - + line.ToString(text, sizeof(text), curAddress_); statusBarText_ = text; const std::string label = g_symbolMap->GetLabelString(line.info.opcodeAddress); diff --git a/UI/ImDebugger/ImStructViewer.cpp b/UI/ImDebugger/ImStructViewer.cpp index e45d1a1085..1ff47c8be9 100644 --- a/UI/ImDebugger/ImStructViewer.cpp +++ b/UI/ImDebugger/ImStructViewer.cpp @@ -131,12 +131,17 @@ static void DrawIntBuiltInEditPopup(const u32 address, const u32 length) { } static void DrawBuiltInContent(const BuiltIn &builtIn, const u32 address) { + if (!Memory::IsValidRange(address, address + 8)) { + // Check a little too crude, but... + ImGui::Text("(invalid address: %08x)", address); + return; + } switch (builtIn.type) { case BuiltInType::Bool: - ImGui::Text("= %s", Memory::Read_U8(address) ? "true" : "false"); + ImGui::Text("= %s", Memory::ReadUnchecked_U8(address) ? "true" : "false"); break; case BuiltInType::Char: { - const u8 value = Memory::Read_U8(address); + const u8 value = Memory::ReadUnchecked_U8(address); if (std::isprint(value)) { ImGui::Text("= %x '%c'", value, value); } else { @@ -145,26 +150,26 @@ static void DrawBuiltInContent(const BuiltIn &builtIn, const u32 address) { break; } case BuiltInType::Int8: - ImGui::Text("= %x", Memory::Read_U8(address)); + ImGui::Text("= %x", Memory::ReadUnchecked_U8(address)); break; case BuiltInType::Int16: - ImGui::Text("= %x", Memory::Read_U16(address)); + ImGui::Text("= %x", Memory::ReadUnchecked_U16(address)); break; case BuiltInType::Int32: - ImGui::Text("= %x", Memory::Read_U32(address)); + ImGui::Text("= %x", Memory::ReadUnchecked_U32(address)); break; case BuiltInType::Int64: - ImGui::Text("= %llx", Memory::Read_U64(address)); + ImGui::Text("= %llx", Memory::ReadUnchecked_U64(address)); break; case BuiltInType::TerminatedString: if (Memory::IsValidNullTerminatedString(address)) { ImGui::Text("= \"%s\"", Memory::GetCharPointerUnchecked(address)); } else { - ImGui::Text("= %x ", Memory::Read_U8(address), address); + ImGui::Text("= %x ", Memory::ReadUnchecked_U8(address), address); } break; case BuiltInType::Float: - ImGui::Text("= %f", Memory::Read_Float(address)); + ImGui::Text("= %f", Memory::ReadUnchecked_Float(address)); break; case BuiltInType::Void: ImGui::Text(""); @@ -176,15 +181,18 @@ static void DrawBuiltInContent(const BuiltIn &builtIn, const u32 address) { } static u64 ReadMemoryInt(const u32 address, const u32 length) { + if (!Memory::IsValidRange(address, length)) { + return 0; + } switch (length) { case 1: - return Memory::Read_U8(address); + return Memory::ReadUnchecked_U8(address); case 2: - return Memory::Read_U16(address); + return Memory::ReadUnchecked_U16(address); case 4: - return Memory::Read_U32(address); + return Memory::ReadUnchecked_U32(address); case 8: - return Memory::Read_U64(address); + return Memory::ReadUnchecked_U64(address); default: return 0; } diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index d77313c4ce..214f64cd88 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -1197,91 +1197,7 @@ void CtrlDisAsmView::updateStatusBarText() DisassemblyLineInfo line; g_disassemblyManager.getLine(curAddress,true,line, debugger); - text[0] = 0; - if (line.type == DISTYPE_OPCODE) - { - if (line.info.hasRelevantAddress && IsLikelyStringAt(line.info.relevantAddress)) { - snprintf(text, sizeof(text), "[%08X] = \"%s\"", line.info.relevantAddress, Memory::GetCharPointer(line.info.relevantAddress)); - } - - if (line.info.isDataAccess) { - if (!Memory::IsValidAddress(line.info.dataAddress)) { - snprintf(text, sizeof(text), "Invalid address %08X",line.info.dataAddress); - } else { - bool isFloat = MIPSGetInfo(line.info.encodedOpcode) & (IS_FPU | IS_VFPU); - switch (line.info.dataSize) { - case 1: - snprintf(text, sizeof(text), "[%08X] = %02X",line.info.dataAddress,Memory::Read_U8(line.info.dataAddress)); - break; - case 2: - snprintf(text, sizeof(text), "[%08X] = %04X",line.info.dataAddress,Memory::Read_U16(line.info.dataAddress)); - break; - case 4: - { - u32 dataInt = Memory::Read_U32(line.info.dataAddress); - u32 dataFloat = Memory::Read_Float(line.info.dataAddress); - std::string dataString; - if (isFloat) - dataString = StringFromFormat("%08X / %f", dataInt, dataFloat); - else - dataString = StringFromFormat("%08X", dataInt); - - const std::string addressSymbol = g_symbolMap->GetLabelString(dataInt); - if (!addressSymbol.empty()) { - snprintf(text, sizeof(text), "[%08X] = %s (%s)", line.info.dataAddress, addressSymbol.c_str(), dataString.c_str()); - } else { - snprintf(text, sizeof(text), "[%08X] = %s", line.info.dataAddress, dataString.c_str()); - } - break; - } - case 16: - { - uint32_t dataInt[4]; - float dataFloat[4]; - for (int i = 0; i < 4; ++i) { - dataInt[i] = Memory::Read_U32(line.info.dataAddress + i * 4); - dataFloat[i] = Memory::Read_Float(line.info.dataAddress + i * 4); - } - std::string dataIntString = StringFromFormat("%08X,%08X,%08X,%08X", dataInt[0], dataInt[1], dataInt[2], dataInt[3]); - std::string dataFloatString = StringFromFormat("%f,%f,%f,%f", dataFloat[0], dataFloat[1], dataFloat[2], dataFloat[3]); - - snprintf(text, sizeof(text), "[%08X] = %s / %s", line.info.dataAddress, dataIntString.c_str(), dataFloatString.c_str()); - break; - } - } - } - } - - if (line.info.isBranch) - { - const std::string addressSymbol = g_symbolMap->GetLabelString(line.info.branchTarget); - if (addressSymbol.empty()) - { - snprintf(text, sizeof(text), "%08X", line.info.branchTarget); - } else { - snprintf(text, sizeof(text), "%08X = %s",line.info.branchTarget,addressSymbol.c_str()); - } - } - } else if (line.type == DISTYPE_DATA) { - u32 start = g_symbolMap->GetDataStart(curAddress); - if (start == -1) - start = curAddress; - - u32 diff = curAddress-start; - const std::string label = g_symbolMap->GetLabelString(start); - - if (!label.empty()) { - if (diff != 0) - snprintf(text, sizeof(text), "%08X (%s) + %08X",start,label.c_str(),diff); - else - snprintf(text, sizeof(text), "%08X (%s)",start,label.c_str()); - } else { - if (diff != 0) - snprintf(text, sizeof(text), "%08X + %08X",start,diff); - else - snprintf(text, sizeof(text), "%08X",start); - } - } + line.ToString(text, sizeof(text), curAddress); SendMessage(GetParent(wnd),WM_DEB_SETSTATUSBARTEXT,0,(LPARAM)text);