diff --git a/common/MemoryInterface.cpp b/common/MemoryInterface.cpp index fc9b71359512c..6d08fac226a63 100644 --- a/common/MemoryInterface.cpp +++ b/common/MemoryInterface.cpp @@ -3,6 +3,8 @@ #include "MemoryInterface.h" +#include + template Value MemoryInterface::Read(u32 address, bool* valid) { @@ -24,6 +26,10 @@ Value MemoryInterface::Read(u32 address, bool* valid) .hi = static_cast(value.hi), }; } + else if constexpr (std::is_same_v) + return std::bit_cast(Read32(address, valid)); + else if constexpr (std::is_same_v) + return std::bit_cast(Read64(address, valid)); else return Value(0); } @@ -48,6 +54,10 @@ bool MemoryInterface::Write(u32 address, Value value) unsigned_value.hi = static_cast(value.hi); return Write128(address, unsigned_value); } + else if constexpr (std::is_same_v) + return Write32(address, std::bit_cast(value)); + else if constexpr (std::is_same_v) + return Write64(address, std::bit_cast(value)); else return false; } @@ -135,4 +145,6 @@ EXPLICITLY_INSTANTIATE_TEMPLATES(u64) EXPLICITLY_INSTANTIATE_TEMPLATES(s64) EXPLICITLY_INSTANTIATE_TEMPLATES(u128) EXPLICITLY_INSTANTIATE_TEMPLATES(s128) +EXPLICITLY_INSTANTIATE_TEMPLATES(float) +EXPLICITLY_INSTANTIATE_TEMPLATES(double) #undef EXPLICITLY_INSTANTIATE_TEMPLATES diff --git a/common/MemoryInterface.h b/common/MemoryInterface.h index f92fbc1788815..0ed5500c4564b 100644 --- a/common/MemoryInterface.h +++ b/common/MemoryInterface.h @@ -12,12 +12,15 @@ concept MemoryAccessType = std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || - std::is_same_v || std::is_same_v; + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v; /// Interface for reading/writing guest memory. class MemoryInterface { public: + virtual ~MemoryInterface() {} + virtual u8 Read8(u32 address, bool* valid = nullptr) = 0; virtual u16 Read16(u32 address, bool* valid = nullptr) = 0; virtual u32 Read32(u32 address, bool* valid = nullptr) = 0; diff --git a/pcsx2-qt/Debugger/DisassemblyView.cpp b/pcsx2-qt/Debugger/DisassemblyView.cpp index 4c932b726cdb9..1de5347e486cc 100644 --- a/pcsx2-qt/Debugger/DisassemblyView.cpp +++ b/pcsx2-qt/Debugger/DisassemblyView.cpp @@ -204,7 +204,7 @@ void DisassemblyView::contextRestoreInstruction() { u32 address = start + i * 4; if (original_instructions[i].has_value()) - cpu->write32(address, *original_instructions[i]); + cpu->Write32(address, *original_instructions[i]); } DebuggerView::broadcastEvent(DebuggerEvents::VMUpdate()); }); @@ -332,11 +332,11 @@ void DisassemblyView::contextStubFunction() const QPointer view(this); Host::RunOnCPUThread([view, address, cpu = &cpu()] { - const u32 first_instruction = cpu->read32(address); - const u32 second_instruction = cpu->read32(address + 4); + const u32 first_instruction = cpu->Read32(address); + const u32 second_instruction = cpu->Read32(address + 4); - cpu->write32(address, 0x03E00008); // jr ra - cpu->write32(address + 4, 0x00000000); // nop + cpu->Write32(address, 0x03E00008); // jr ra + cpu->Write32(address + 4, 0x00000000); // nop QtHost::RunOnUIThread([view, address, first_instruction, second_instruction]() { if (!view) @@ -364,8 +364,8 @@ void DisassemblyView::contextRestoreFunction() m_stubbedFunctions.erase(stub); Host::RunOnCPUThread([address, cpu = &cpu(), first_instruction, second_instruction] { - cpu->write32(address, first_instruction); - cpu->write32(address + 4, second_instruction); + cpu->Write32(address, first_instruction); + cpu->Write32(address + 4, second_instruction); DebuggerView::broadcastEvent(DebuggerEvents::VMUpdate()); }); } @@ -919,7 +919,7 @@ inline QString DisassemblyView::DisassemblyStringFromAddress(u32 address, QFont if (showOpcode) { - const u32 opcode = cpu().read32(address); + const u32 opcode = cpu().Read32(address); lineString = lineString.arg(QtUtils::FilledQStringFromValue(opcode, 16)); } @@ -989,7 +989,7 @@ QString DisassemblyView::FetchSelectionInfo(SelectionInfo selInfo) } else // INSTRUCTIONHEX { - infoBlock += FilledQStringFromValue(cpu().read32(i), 16); + infoBlock += FilledQStringFromValue(cpu().Read32(i), 16); } } return infoBlock; @@ -1050,8 +1050,8 @@ void DisassemblyView::setInstructions(u32 start, u32 end, u32 value) for (u32 i = 0; i < count; i++) { const u32 address = start + i * 4; - original_instructions.emplace_back(cpu->read32(address)); - cpu->write32(address, value); + original_instructions.emplace_back(cpu->Read32(address)); + cpu->Write32(address, value); } QtHost::RunOnUIThread([view, start, count, original_instructions = std::move(original_instructions)]() { diff --git a/pcsx2-qt/Debugger/Memory/MemorySearchView.cpp b/pcsx2-qt/Debugger/Memory/MemorySearchView.cpp index dc833763620f6..e37ef15585708 100644 --- a/pcsx2-qt/Debugger/Memory/MemorySearchView.cpp +++ b/pcsx2-qt/Debugger/Memory/MemorySearchView.cpp @@ -112,46 +112,6 @@ void MemorySearchView::onListSearchResultsContextMenu(QPoint pos) menu->popup(m_ui.listSearchResults->viewport()->mapToGlobal(pos)); } -template -T readValueAtAddress(DebugInterface* cpu, u32 addr); -template <> -float readValueAtAddress(DebugInterface* cpu, u32 addr) -{ - return std::bit_cast(cpu->read32(addr)); -} - -template <> -double readValueAtAddress(DebugInterface* cpu, u32 addr) -{ - return std::bit_cast(cpu->read64(addr)); -} - -template -T readValueAtAddress(DebugInterface* cpu, u32 addr) -{ - T val = 0; - switch (sizeof(T)) - { - case sizeof(u8): - val = cpu->read8(addr); - break; - case sizeof(u16): - val = cpu->read16(addr); - break; - case sizeof(u32): - { - val = cpu->read32(addr); - break; - } - case sizeof(u64): - { - val = cpu->read64(addr); - break; - } - } - return val; -} - template static bool memoryValueComparator(SearchComparison searchComparison, T searchValue, T readValue) { @@ -294,7 +254,7 @@ void searchWorker(DebugInterface* cpu, std::vector& searchResults, if (!cpu->isValidAddress(addr)) continue; - T readValue = readValueAtAddress(cpu, addr); + T readValue = cpu->Read(addr); if (handleSearchComparison(searchComparison, addr, nullptr, searchValue, readValue)) { searchResults.push_back(MemorySearchView::SearchResult(addr, QVariant::fromValue(readValue), searchType)); @@ -308,7 +268,7 @@ void searchWorker(DebugInterface* cpu, std::vector& searchResults, if (!cpu->isValidAddress(addr)) return true; - const auto readValue = readValueAtAddress(cpu, addr); + const auto readValue = cpu->Read(addr); const bool doesMatch = handleSearchComparison(searchComparison, addr, &searchResult, searchValue, readValue); if (doesMatch) @@ -325,7 +285,7 @@ static bool compareByteArrayAtAddress(DebugInterface* cpu, SearchComparison sear const bool isNotOperator = searchComparison == SearchComparison::NotEquals; for (qsizetype i = 0; i < value.length(); i++) { - const char nextByte = cpu->read8(addr + i); + const char nextByte = cpu->Read8(addr + i); switch (searchComparison) { case SearchComparison::Equals: @@ -383,7 +343,7 @@ static QByteArray readArrayAtAddress(DebugInterface* cpu, u32 address, u32 lengt QByteArray readArray; for (u32 i = address; i < address + length; i++) { - readArray.append(cpu->read8(i)); + readArray.append(cpu->Read8(i)); } return readArray; } diff --git a/pcsx2-qt/Debugger/Memory/MemoryView.cpp b/pcsx2-qt/Debugger/Memory/MemoryView.cpp index 091609295fc1c..74a39b16a44fd 100644 --- a/pcsx2-qt/Debugger/Memory/MemoryView.cpp +++ b/pcsx2-qt/Debugger/Memory/MemoryView.cpp @@ -119,7 +119,7 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32 { case MemoryViewType::BYTE: { - const u8 val = static_cast(cpu.read8(thisSegmentsStart, valid)); + const u8 val = cpu.Read8(thisSegmentsStart, &valid); if (penDefault && val == 0) painter.setPen(QColor::fromRgb(145, 145, 155)); // ZERO BYTE COLOUR painter.drawText(valX, y + (rowHeight * i), valid ? FilledQStringFromValue(val, 16) : "??"); @@ -127,7 +127,7 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32 } case MemoryViewType::BYTEHW: { - const u16 val = convertEndian(static_cast(cpu.read16(thisSegmentsStart, valid))); + const u16 val = convertEndian(cpu.Read16(thisSegmentsStart, &valid)); if (penDefault && val == 0) painter.setPen(QColor::fromRgb(145, 145, 155)); // ZERO BYTE COLOUR painter.drawText(valX, y + (rowHeight * i), valid ? FilledQStringFromValue(val, 16) : "????"); @@ -135,7 +135,7 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32 } case MemoryViewType::WORD: { - const u32 val = convertEndian(cpu.read32(thisSegmentsStart, valid)); + const u32 val = convertEndian(cpu.Read32(thisSegmentsStart, &valid)); if (penDefault && val == 0) painter.setPen(QColor::fromRgb(145, 145, 155)); // ZERO BYTE COLOUR painter.drawText(valX, y + (rowHeight * i), valid ? FilledQStringFromValue(val, 16) : "????????"); @@ -143,7 +143,7 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32 } case MemoryViewType::DWORD: { - const u64 val = convertEndian(cpu.read64(thisSegmentsStart, valid)); + const u64 val = convertEndian(cpu.Read64(thisSegmentsStart, &valid)); if (penDefault && val == 0) painter.setPen(QColor::fromRgb(145, 145, 155)); // ZERO BYTE COLOUR painter.drawText(valX, y + (rowHeight * i), valid ? FilledQStringFromValue(val, 16) : "????????????????"); @@ -151,7 +151,7 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32 } case MemoryViewType::FLOAT: { - const u32 intVal = convertEndian(cpu.read32(thisSegmentsStart, valid)); + const u32 intVal = convertEndian(cpu.Read32(thisSegmentsStart, &valid)); float val = 0.0; std::memcpy(&val, &intVal, sizeof(val)); if (penDefault && val == 0.0) @@ -177,7 +177,7 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32 painter.setPen(palette.text().color()); bool valid; - const u8 value = cpu.read8(currentRowAddress + j, valid); + const u8 value = cpu.Read8(currentRowAddress + j, &valid); if (valid) { QChar curChar = QChar::fromLatin1(value); @@ -258,19 +258,19 @@ u128 MemoryViewTable::GetSelectedSegment(DebugInterface& cpu) switch (displayType) { case MemoryViewType::BYTE: - val.lo = cpu.read8(selectedAddress); + val.lo = cpu.Read8(selectedAddress); break; case MemoryViewType::BYTEHW: - val.lo = convertEndian(static_cast(cpu.read16(selectedAddress & ~1))); + val.lo = convertEndian(static_cast(cpu.Read16(selectedAddress & ~1))); break; case MemoryViewType::WORD: - val.lo = convertEndian(cpu.read32(selectedAddress & ~3)); + val.lo = convertEndian(cpu.Read32(selectedAddress & ~3)); break; case MemoryViewType::DWORD: - val._u64[0] = convertEndian(cpu.read64(selectedAddress & ~7)); + val._u64[0] = convertEndian(cpu.Read64(selectedAddress & ~7)); break; case MemoryViewType::FLOAT: - val.lo = convertEndian(cpu.read32(selectedAddress & ~3)); + val.lo = convertEndian(cpu.Read32(selectedAddress & ~3)); break; } return val; @@ -279,13 +279,13 @@ u128 MemoryViewTable::GetSelectedSegment(DebugInterface& cpu) void MemoryViewTable::InsertIntoSelectedHexView(u8 value, DebugInterface& cpu) { const u8 mask = selectedNibbleHI ? 0x0f : 0xf0; - u8 curVal = cpu.read8(selectedAddress) & mask; + u8 curVal = cpu.Read8(selectedAddress) & mask; u8 newVal = value << (selectedNibbleHI ? 4 : 0); curVal |= newVal; const QPointer table(this); Host::RunOnCPUThread([table, address = selectedAddress, &cpu, val = curVal] { - cpu.write8(address, val); + cpu.Write8(address, val); QtHost::RunOnUIThread([table] { if (!table) @@ -323,7 +323,7 @@ bool MemoryViewTable::InsertFloatIntoSelectedHexView(DebugInterface& cpu) const QPointer table(this); Host::RunOnCPUThread([table, address = selectedAddress, &cpu, val = newIntVal] { - cpu.write32(address, val); + cpu.Write32(address, val); QtHost::RunOnUIThread([table] { if (!table) @@ -360,7 +360,7 @@ void MemoryViewTable::InsertAtCurrentSelection(const QString& text, DebugInterfa const QPointer table(this); Host::RunOnCPUThread([table, address = selectedAddress, &cpu, val = newIntVal] { - cpu.write32(address, val); + cpu.Write32(address, val); QtHost::RunOnUIThread([table] { if (!table) @@ -384,7 +384,7 @@ void MemoryViewTable::InsertAtCurrentSelection(const QString& text, DebugInterfa u32 currAddr = address; for (int i = 0; i < input.size(); i++) { - cpu.write8(currAddr, input[i]); + cpu.Write8(currAddr, input[i]); currAddr = nextAddress(currAddr, address, display_type, little_endian); } @@ -552,7 +552,7 @@ bool MemoryViewTable::KeyPress(int key, QChar keychar, DebugInterface& cpu) { const QPointer table(this); Host::RunOnCPUThread([table, address = selectedAddress, &cpu, val = keychar.toLatin1()] { - cpu.write8(address, val); + cpu.Write8(address, val); QtHost::RunOnUIThread([table, address]() { if (!table) @@ -572,7 +572,7 @@ bool MemoryViewTable::KeyPress(int key, QChar keychar, DebugInterface& cpu) { const QPointer table(this); Host::RunOnCPUThread([table, address = selectedAddress, &cpu] { - cpu.write8(address, 0); + cpu.Write8(address, 0); QtHost::RunOnUIThread([table] { if (!table) @@ -865,7 +865,7 @@ void MemoryView::openContextMenu(QPoint pos) void MemoryView::contextCopyByte() { - QApplication::clipboard()->setText(QString::number(cpu().read8(m_table.selectedAddress), 16).toUpper()); + QApplication::clipboard()->setText(QString::number(cpu().Read8(m_table.selectedAddress), 16).toUpper()); } void MemoryView::contextCopySegment() @@ -885,7 +885,7 @@ void MemoryView::contextCopySegment() void MemoryView::contextCopyCharacter() { - QApplication::clipboard()->setText(QChar::fromLatin1(cpu().read8(m_table.selectedAddress)).toUpper()); + QApplication::clipboard()->setText(QChar::fromLatin1(cpu().Read8(m_table.selectedAddress)).toUpper()); } void MemoryView::contextPaste() @@ -913,7 +913,7 @@ void MemoryView::contextGoToAddress() void MemoryView::contextFollowAddress() { bool valid; - u32 address = cpu().read32(m_table.selectedAddress & ~3, valid); + u32 address = cpu().Read32(m_table.selectedAddress & ~3, &valid); if (!valid) return; diff --git a/pcsx2-qt/Debugger/SymbolTree/SymbolTreeLocation.cpp b/pcsx2-qt/Debugger/SymbolTree/SymbolTreeLocation.cpp index 81bfe284d8e64..e34ec9181f18a 100644 --- a/pcsx2-qt/Debugger/SymbolTree/SymbolTreeLocation.cpp +++ b/pcsx2-qt/Debugger/SymbolTree/SymbolTreeLocation.cpp @@ -60,7 +60,7 @@ u8 SymbolTreeLocation::read8(DebugInterface& cpu) const return cpu.getRegister(EECAT_GPR, address)._u8[0]; break; case MEMORY: - return (u8)cpu.read8(address); + return cpu.Read8(address); default: { } @@ -77,7 +77,7 @@ u16 SymbolTreeLocation::read16(DebugInterface& cpu) const return cpu.getRegister(EECAT_GPR, address)._u16[0]; break; case MEMORY: - return (u16)cpu.read16(address); + return cpu.Read16(address); default: { } @@ -94,7 +94,7 @@ u32 SymbolTreeLocation::read32(DebugInterface& cpu) const return cpu.getRegister(EECAT_GPR, address)._u32[0]; break; case MEMORY: - return cpu.read32(address); + return cpu.Read32(address); default: { } @@ -111,7 +111,7 @@ u64 SymbolTreeLocation::read64(DebugInterface& cpu) const return cpu.getRegister(EECAT_GPR, address)._u64[0]; break; case MEMORY: - return cpu.read64(address); + return cpu.Read64(address); default: { } @@ -128,7 +128,7 @@ u128 SymbolTreeLocation::read128(DebugInterface& cpu) const return cpu.getRegister(EECAT_GPR, address); break; case MEMORY: - return cpu.read128(address); + return cpu.Read128(address); default: { } @@ -145,7 +145,7 @@ void SymbolTreeLocation::write8(u8 value, DebugInterface& cpu) const cpu.setRegister(0, address, u128::From32(value)); break; case MEMORY: - cpu.write8(address, value); + cpu.Write8(address, value); break; default: { @@ -162,7 +162,7 @@ void SymbolTreeLocation::write16(u16 value, DebugInterface& cpu) const cpu.setRegister(0, address, u128::From32(value)); break; case MEMORY: - cpu.write16(address, value); + cpu.Write16(address, value); break; default: { @@ -179,7 +179,7 @@ void SymbolTreeLocation::write32(u32 value, DebugInterface& cpu) const cpu.setRegister(0, address, u128::From32(value)); break; case MEMORY: - cpu.write32(address, value); + cpu.Write32(address, value); break; default: { @@ -196,7 +196,7 @@ void SymbolTreeLocation::write64(u64 value, DebugInterface& cpu) const cpu.setRegister(0, address, u128::From64(value)); break; case MEMORY: - cpu.write64(address, value); + cpu.Write64(address, value); break; default: { @@ -213,7 +213,7 @@ void SymbolTreeLocation::write128(u128 value, DebugInterface& cpu) const cpu.setRegister(0, address, value); break; case MEMORY: - cpu.write128(address, value); + cpu.Write128(address, value); break; default: { diff --git a/pcsx2/DebugTools/DebugInterface.cpp b/pcsx2/DebugTools/DebugInterface.cpp index 06167dbb48531..c8715f7875bed 100644 --- a/pcsx2/DebugTools/DebugInterface.cpp +++ b/pcsx2/DebugTools/DebugInterface.cpp @@ -14,6 +14,7 @@ #include "R3000A.h" #include "IopMem.h" #include "VMManager.h" +#include "vtlb.h" #include "common/StringUtil.h" @@ -74,7 +75,7 @@ char* DebugInterface::stringFromPointer(u32 p) // Hopefully the checks in isValidAddress() are sufficient. for (u32 i = 0; i < BUFFER_LEN; i++) { - char c = read8(p + i); + char c = Read8(p + i); buf[i] = c; if (c == 0) @@ -121,7 +122,7 @@ std::optional DebugInterface::getStackFrameSize(const ccc::Function& functi // start of the current function that is in the form of // "addiu $sp, $sp, frame_size" instead. - u32 instruction = read32(function.address().value); + u32 instruction = Read32(function.address().value); if ((instruction & 0xffff0000) == 0x27bd0000) stack_frame_size = -static_cast(instruction & 0xffff); @@ -209,167 +210,140 @@ const char* DebugInterface::longCpuName(BreakPointCpu cpu) return ""; } -// -// R5900DebugInterface -// +// ***************************************************************************** BreakPointCpu R5900DebugInterface::getCpuType() { return BREAKPOINT_EE; } -u32 R5900DebugInterface::read8(u32 address) +static int InvalidReadResult(bool* valid) { - if (!isValidAddress(address)) - return -1; - - u8 value; - if (!vtlb_memSafeReadBytes(address, &value, sizeof(u8))) - return -1; - - return value; + if (valid) + *valid = false; + return -1; } -u32 R5900DebugInterface::read8(u32 address, bool& valid) +u8 R5900DebugInterface::Read8(u32 address, bool* valid) { - if (!(valid = isValidAddress(address))) - return -1; + if (!isValidAddress(address)) + return static_cast(InvalidReadResult(valid)); u8 value; - if (!(valid = vtlb_memSafeReadBytes(address, &value, sizeof(u8)))) - return -1; + if (!vtlb_memSafeReadBytes(address, &value, sizeof(value))) + return static_cast(InvalidReadResult(valid)); + if (valid) + *valid = true; return value; } - -u32 R5900DebugInterface::read16(u32 address) -{ - if (!isValidAddress(address) || address % 2) - return -1; - - u16 value; - if (!vtlb_memSafeReadBytes(address, &value, sizeof(u16))) - return -1; - - return static_cast(value); -} - -u32 R5900DebugInterface::read16(u32 address, bool& valid) +u16 R5900DebugInterface::Read16(u32 address, bool* valid) { - if (!(valid = (isValidAddress(address) || address % 2))) - return -1; + if (!isValidAddress(address)) + return static_cast(InvalidReadResult(valid)); u16 value; - if (!(valid = vtlb_memSafeReadBytes(address, &value, sizeof(u16)))) - return -1; + if (!vtlb_memSafeReadBytes(address, &value, sizeof(value))) + return static_cast(InvalidReadResult(valid)); - return static_cast(value); + if (valid) + *valid = true; + return value; } -u32 R5900DebugInterface::read32(u32 address) +u32 R5900DebugInterface::Read32(u32 address, bool* valid) { - if (!isValidAddress(address) || address % 4) - return -1; + if (!isValidAddress(address)) + return static_cast(InvalidReadResult(valid)); u32 value; - if (!vtlb_memSafeReadBytes(address, &value, sizeof(u32))) - return -1; + if (!vtlb_memSafeReadBytes(address, &value, sizeof(value))) + return static_cast(InvalidReadResult(valid)); + if (valid) + *valid = true; return value; } -u32 R5900DebugInterface::read32(u32 address, bool& valid) +u64 R5900DebugInterface::Read64(u32 address, bool* valid) { - if (!(valid = (isValidAddress(address) || address % 4))) - return -1; + if (!isValidAddress(address)) + return static_cast(InvalidReadResult(valid)); - u32 value; - if (!(valid = vtlb_memSafeReadBytes(address, &value, sizeof(u32)))) - return -1; + u64 value; + if (!vtlb_memSafeReadBytes(address, &value, sizeof(value))) + return static_cast(InvalidReadResult(valid)); + if (valid) + *valid = true; return value; } -u64 R5900DebugInterface::read64(u32 address) +static u128 InvalidReadResult128(bool* valid) { - if (!isValidAddress(address) || address % 8) - return -1; - - u64 value; - if (!vtlb_memSafeReadBytes(address, &value, sizeof(u64))) - return -1; + if (valid) + *valid = false; + u128 value; + value.lo = static_cast(-1); + value.hi = static_cast(-1); return value; } -u64 R5900DebugInterface::read64(u32 address, bool& valid) +u128 R5900DebugInterface::Read128(u32 address, bool* valid) { - if (!(valid = (isValidAddress(address) || address % 8))) - return -1; + if (!isValidAddress(address)) + return InvalidReadResult128(valid); - u64 value; - if (!(valid = vtlb_memSafeReadBytes(address, &value, sizeof(u64)))) - return -1; + u128 value; + if (!vtlb_memSafeReadBytes(address, &value, sizeof(u128))) + return InvalidReadResult128(valid); + + if (valid) + *valid = true; return value; } -u128 R5900DebugInterface::read128(u32 address) +bool R5900DebugInterface::ReadBytes(u32 address, void* dest, u32 size) { - alignas(16) u128 result; - if (!isValidAddress(address) || address % 16) - { - result.hi = result.lo = -1; - return result; - } - - if (!vtlb_memSafeReadBytes(address, &result, sizeof(u128))) - { - result.hi = result.lo = -1; - } - - return result; + return vtlb_memSafeReadBytes(address, dest, size); } -void R5900DebugInterface::write8(u32 address, u8 value) +bool R5900DebugInterface::Write8(u32 address, u8 value) { - if (!isValidAddress(address)) - return; - - vtlb_memSafeWriteBytes(address, &value, sizeof(u8)); + return isValidAddress(address) && vtlb_memSafeWriteBytes(address, &value, sizeof(value)); } -void R5900DebugInterface::write16(u32 address, u16 value) +bool R5900DebugInterface::Write16(u32 address, u16 value) { - if (!isValidAddress(address)) - return; - - vtlb_memSafeWriteBytes(address, &value, sizeof(u16)); + return isValidAddress(address) && vtlb_memSafeWriteBytes(address, &value, sizeof(value)); } -void R5900DebugInterface::write32(u32 address, u32 value) +bool R5900DebugInterface::Write32(u32 address, u32 value) { - if (!isValidAddress(address)) - return; - - vtlb_memSafeWriteBytes(address, &value, sizeof(u32)); + return isValidAddress(address) && vtlb_memSafeWriteBytes(address, &value, sizeof(value)); } -void R5900DebugInterface::write64(u32 address, u64 value) +bool R5900DebugInterface::Write64(u32 address, u64 value) { - if (!isValidAddress(address)) - return; + return isValidAddress(address) && vtlb_memSafeWriteBytes(address, &value, sizeof(value)); +} - vtlb_memSafeWriteBytes(address, &value, sizeof(u64)); +bool R5900DebugInterface::Write128(u32 address, u128 value) +{ + return isValidAddress(address) && vtlb_memSafeWriteBytes(address, &value, sizeof(value)); } -void R5900DebugInterface::write128(u32 address, u128 value) +bool R5900DebugInterface::WriteBytes(u32 address, void* src, u32 size) { - if (!isValidAddress(address)) - return; + return vtlb_memSafeWriteBytes(address, src, size); +} - vtlb_memSafeWriteBytes(address, &value, sizeof(u128)); +bool R5900DebugInterface::CompareBytes(u32 address, void* src, u32 size) +{ + return vtlb_memSafeCmpBytes(address, src, size) == 0; } int R5900DebugInterface::getRegisterCategoryCount() @@ -650,7 +624,7 @@ std::string R5900DebugInterface::disasm(u32 address, bool simplify) { std::string out; - u32 op = read32(address); + u32 op = Read32(address); R5900::disR5900Fasm(out, op, address, simplify); return out; } @@ -748,106 +722,114 @@ BreakPointCpu R3000DebugInterface::getCpuType() return BREAKPOINT_IOP; } -u32 R3000DebugInterface::read8(u32 address) +u8 R3000DebugInterface::Read8(u32 address, bool* valid) { if (!isValidAddress(address)) - return -1; - return iopMemRead8(address); -} + return static_cast(InvalidReadResult(valid)); -u32 R3000DebugInterface::read8(u32 address, bool& valid) -{ - if (!(valid = isValidAddress(address))) - return -1; - return iopMemRead8(address); + u8 value = iopMemRead8(address); + + if (valid) + *valid = true; + return value; } -u32 R3000DebugInterface::read16(u32 address) +u16 R3000DebugInterface::Read16(u32 address, bool* valid) { if (!isValidAddress(address)) - return -1; - return iopMemRead16(address); -} + return static_cast(InvalidReadResult(valid)); -u32 R3000DebugInterface::read16(u32 address, bool& valid) -{ - if (!(valid = isValidAddress(address))) - return -1; - return iopMemRead16(address); + u16 value = iopMemRead16(address); + + if (valid) + *valid = true; + return value; } -u32 R3000DebugInterface::read32(u32 address) +u32 R3000DebugInterface::Read32(u32 address, bool* valid) { if (!isValidAddress(address)) - return -1; - return iopMemRead32(address); -} + return static_cast(InvalidReadResult(valid)); -u32 R3000DebugInterface::read32(u32 address, bool& valid) -{ - if (!(valid = isValidAddress(address))) - return -1; - return iopMemRead32(address); + u32 value = iopMemRead32(address); + + if (valid) + *valid = true; + return value; } -u64 R3000DebugInterface::read64(u32 address) +u64 R3000DebugInterface::Read64(u32 address, bool* valid) { - return 0; + return InvalidReadResult(valid); } -u64 R3000DebugInterface::read64(u32 address, bool& valid) +u128 R3000DebugInterface::Read128(u32 address, bool* valid) { - return 0; + return InvalidReadResult128(valid); } - -u128 R3000DebugInterface::read128(u32 address) +bool R3000DebugInterface::ReadBytes(u32 address, void* dest, u32 size) { - return u128::From32(0); + return iopMemSafeReadBytes(address, dest, size); } -void R3000DebugInterface::write8(u32 address, u8 value) +bool R3000DebugInterface::Write8(u32 address, u8 value) { if (!isValidAddress(address)) - return; + return false; iopMemWrite8(address, value); + return true; } -void R3000DebugInterface::write16(u32 address, u16 value) +bool R3000DebugInterface::Write16(u32 address, u16 value) { if (!isValidAddress(address)) - return; + return false; iopMemWrite16(address, value); + return true; } -void R3000DebugInterface::write32(u32 address, u32 value) +bool R3000DebugInterface::Write32(u32 address, u32 value) { if (!isValidAddress(address)) - return; + return false; iopMemWrite32(address, value); + return true; } -void R3000DebugInterface::write64(u32 address, u64 value) +bool R3000DebugInterface::Write64(u32 address, u64 value) { if (!isValidAddress(address)) - return; + return false; iopMemWrite32(address + 0, value); iopMemWrite32(address + 4, value >> 32); + return true; } -void R3000DebugInterface::write128(u32 address, u128 value) +bool R3000DebugInterface::Write128(u32 address, u128 value) { if (!isValidAddress(address)) - return; + return false; iopMemWrite32(address + 0x0, value._u32[0]); iopMemWrite32(address + 0x4, value._u32[1]); iopMemWrite32(address + 0x8, value._u32[2]); iopMemWrite32(address + 0xc, value._u32[3]); + return true; +} + +bool R3000DebugInterface::WriteBytes(u32 address, void* src, u32 size) +{ + return iopMemSafeWriteBytes(address, src, size); +} + +bool R3000DebugInterface::CompareBytes(u32 address, void* src, u32 size) +{ + return iopMemSafeCmpBytes(address, src, size) == 0; } int R3000DebugInterface::getRegisterCategoryCount() @@ -1016,7 +998,7 @@ std::string R3000DebugInterface::disasm(u32 address, bool simplify) { std::string out; - u32 op = read32(address); + u32 op = Read32(address); R5900::disR5900Fasm(out, op, address, simplify); return out; } @@ -1072,90 +1054,119 @@ std::vector R3000DebugInterface::GetModuleList() const return getIOPModules(); } +// ***************************************************************************** + ElfMemoryReader::ElfMemoryReader(const ccc::ElfFile& elf) : m_elf(elf) { } -u32 ElfMemoryReader::read8(u32 address) +u8 ElfMemoryReader::Read8(u32 address, bool* valid) { std::optional result = m_elf.get_object_virtual(address); if (!result.has_value()) - return 0; + return InvalidReadResult(valid); + if (valid) + *valid = true; return *result; } -u32 ElfMemoryReader::read8(u32 address, bool& valid) +u16 ElfMemoryReader::Read16(u32 address, bool* valid) { - std::optional result = m_elf.get_object_virtual(address); - valid = result.has_value(); - if (!valid) - return 0; + std::optional result = m_elf.get_object_virtual(address); + if (!result.has_value()) + return InvalidReadResult(valid); + if (valid) + *valid = true; return *result; } -u32 ElfMemoryReader::read16(u32 address) +u32 ElfMemoryReader::Read32(u32 address, bool* valid) { - std::optional result = m_elf.get_object_virtual(address); + std::optional result = m_elf.get_object_virtual(address); if (!result.has_value()) - return 0; + return InvalidReadResult(valid); + if (valid) + *valid = true; return *result; } -u32 ElfMemoryReader::read16(u32 address, bool& valid) +u64 ElfMemoryReader::Read64(u32 address, bool* valid) { - std::optional result = m_elf.get_object_virtual(address); - valid = result.has_value(); - if (!valid) - return 0; + std::optional result = m_elf.get_object_virtual(address); + if (!result.has_value()) + return InvalidReadResult(valid); + if (valid) + *valid = true; return *result; } -u32 ElfMemoryReader::read32(u32 address) +u128 ElfMemoryReader::Read128(u32 address, bool* valid) { - std::optional result = m_elf.get_object_virtual(address); + std::optional result = m_elf.get_object_virtual(address); if (!result.has_value()) - return 0; + return InvalidReadResult128(valid); + if (valid) + *valid = true; return *result; } -u32 ElfMemoryReader::read32(u32 address, bool& valid) +bool ElfMemoryReader::ReadBytes(u32 address, void* dest, u32 size) { - std::optional result = m_elf.get_object_virtual(address); - valid = result.has_value(); - if (!valid) - return 0; + std::optional> bytes = m_elf.get_virtual(address, size); + if (!bytes.has_value()) + return false; - return *result; + std::memcpy(dest, bytes->data(), size); + + return true; } -u64 ElfMemoryReader::read64(u32 address) +bool ElfMemoryReader::Write8(u32 address, u8 value) { - std::optional result = m_elf.get_object_virtual(address); - if (!result.has_value()) - return 0; + return false; +} - return *result; +bool ElfMemoryReader::Write16(u32 address, u16 value) +{ + return false; } -u64 ElfMemoryReader::read64(u32 address, bool& valid) +bool ElfMemoryReader::Write32(u32 address, u32 value) { - std::optional result = m_elf.get_object_virtual(address); - valid = result.has_value(); - if (!valid) - return 0; + return false; +} - return *result; +bool ElfMemoryReader::Write64(u32 address, u64 value) +{ + return false; } -// -// MipsExpressionFunctions -// +bool ElfMemoryReader::Write128(u32 address, u128 value) +{ + return false; +} + +bool ElfMemoryReader::WriteBytes(u32 address, void* src, u32 size) +{ + return false; +} + +bool ElfMemoryReader::CompareBytes(u32 address, void* src, u32 size) +{ + std::optional> bytes = m_elf.get_virtual(address, size); + if (!bytes.has_value()) + return false; + + return std::memcmp(src, bytes->data(), size) == 0; +} + +// ***************************************************************************** MipsExpressionFunctions::MipsExpressionFunctions( DebugInterface* cpu, const ccc::SymbolDatabase* symbolDatabase, bool shouldEnumerateSymbols) @@ -1309,7 +1320,7 @@ u64 MipsExpressionFunctions::getReferenceValue(u64 referenceIndex) return m_cpu->getLO()._u64[0]; if (referenceIndex & REF_INDEX_IS_OPSL) { - const u32 OP = m_cpu->read32(m_cpu->getPC()); + const u32 OP = m_cpu->Read32(m_cpu->getPC()); const R5900::OPCODE& opcode = R5900::GetInstruction(OP); if (opcode.flags & IS_MEMORY) { @@ -1373,16 +1384,16 @@ bool MipsExpressionFunctions::getMemoryValue(u32 address, int size, u64& dest, s switch (size) { case 1: - dest = m_cpu->read8(address); + dest = m_cpu->Read8(address); break; case 2: - dest = m_cpu->read16(address); + dest = m_cpu->Read16(address); break; case 4: - dest = m_cpu->read32(address); + dest = m_cpu->Read32(address); break; case 8: - dest = m_cpu->read64(address); + dest = m_cpu->Read64(address); break; } diff --git a/pcsx2/DebugTools/DebugInterface.h b/pcsx2/DebugTools/DebugInterface.h index 8e9b510ed8601..a5f9862265002 100644 --- a/pcsx2/DebugTools/DebugInterface.h +++ b/pcsx2/DebugTools/DebugInterface.h @@ -8,6 +8,8 @@ #include "SymbolGuardian.h" #include "SymbolImporter.h" +#include "common/MemoryInterface.h" + #include enum @@ -38,20 +40,7 @@ inline const std::array DEBUG_CPUS = { BREAKPOINT_IOP, }; -class MemoryReader -{ -public: - virtual u32 read8(u32 address) = 0; - virtual u32 read8(u32 address, bool& valid) = 0; - virtual u32 read16(u32 address) = 0; - virtual u32 read16(u32 address, bool& valid) = 0; - virtual u32 read32(u32 address) = 0; - virtual u32 read32(u32 address, bool& valid) = 0; - virtual u64 read64(u32 address) = 0; - virtual u64 read64(u32 address, bool& valid) = 0; -}; - -class DebugInterface : public MemoryReader +class DebugInterface : public MemoryInterface { public: enum RegisterType @@ -60,13 +49,6 @@ class DebugInterface : public MemoryReader SPECIAL }; - virtual u128 read128(u32 address) = 0; - virtual void write8(u32 address, u8 value) = 0; - virtual void write16(u32 address, u16 value) = 0; - virtual void write32(u32 address, u32 value) = 0; - virtual void write64(u32 address, u64 value) = 0; - virtual void write128(u32 address, u128 value) = 0; - // register stuff virtual int getRegisterCategoryCount() = 0; virtual const char* getRegisterCategoryName(int cat) = 0; @@ -119,20 +101,21 @@ class DebugInterface : public MemoryReader class R5900DebugInterface : public DebugInterface { public: - u32 read8(u32 address) override; - u32 read8(u32 address, bool& valid) override; - u32 read16(u32 address) override; - u32 read16(u32 address, bool& valid) override; - u32 read32(u32 address) override; - u32 read32(u32 address, bool& valid) override; - u64 read64(u32 address) override; - u64 read64(u32 address, bool& valid) override; - u128 read128(u32 address) override; - void write8(u32 address, u8 value) override; - void write16(u32 address, u16 value) override; - void write32(u32 address, u32 value) override; - void write64(u32 address, u64 value) override; - void write128(u32 address, u128 value) override; + u8 Read8(u32 address, bool* valid = nullptr) override; + u16 Read16(u32 address, bool* valid = nullptr) override; + u32 Read32(u32 address, bool* valid = nullptr) override; + u64 Read64(u32 address, bool* valid = nullptr) override; + u128 Read128(u32 address, bool* valid = nullptr) override; + bool ReadBytes(u32 address, void* dest, u32 size) override; + + bool Write8(u32 address, u8 value) override; + bool Write16(u32 address, u16 value) override; + bool Write32(u32 address, u32 value) override; + bool Write64(u32 address, u64 value) override; + bool Write128(u32 address, u128 value) override; + bool WriteBytes(u32 address, void* src, u32 size) override; + + bool CompareBytes(u32 address, void* src, u32 size) override; // register stuff int getRegisterCategoryCount() override; @@ -163,20 +146,21 @@ class R5900DebugInterface : public DebugInterface class R3000DebugInterface : public DebugInterface { public: - u32 read8(u32 address) override; - u32 read8(u32 address, bool& valid) override; - u32 read16(u32 address) override; - u32 read16(u32 address, bool& valid) override; - u32 read32(u32 address) override; - u32 read32(u32 address, bool& valid) override; - u64 read64(u32 address) override; - u64 read64(u32 address, bool& valid) override; - u128 read128(u32 address) override; - void write8(u32 address, u8 value) override; - void write16(u32 address, u16 value) override; - void write32(u32 address, u32 value) override; - void write64(u32 address, u64 value) override; - void write128(u32 address, u128 value) override; + u8 Read8(u32 address, bool* valid = nullptr) override; + u16 Read16(u32 address, bool* valid = nullptr) override; + u32 Read32(u32 address, bool* valid = nullptr) override; + u64 Read64(u32 address, bool* valid = nullptr) override; + u128 Read128(u32 address, bool* valid = nullptr) override; + bool ReadBytes(u32 address, void* dest, u32 size) override; + + bool Write8(u32 address, u8 value) override; + bool Write16(u32 address, u16 value) override; + bool Write32(u32 address, u32 value) override; + bool Write64(u32 address, u64 value) override; + bool Write128(u32 address, u128 value) override; + bool WriteBytes(u32 address, void* src, u32 size) override; + + bool CompareBytes(u32 address, void* src, u32 size) override; // register stuff int getRegisterCategoryCount() override; @@ -205,19 +189,26 @@ class R3000DebugInterface : public DebugInterface }; // Provides access to the loadable segments from the ELF as they are on disk. -class ElfMemoryReader : public MemoryReader +class ElfMemoryReader : public MemoryInterface { public: ElfMemoryReader(const ccc::ElfFile& elf); - u32 read8(u32 address) override; - u32 read8(u32 address, bool& valid) override; - u32 read16(u32 address) override; - u32 read16(u32 address, bool& valid) override; - u32 read32(u32 address) override; - u32 read32(u32 address, bool& valid) override; - u64 read64(u32 address) override; - u64 read64(u32 address, bool& valid) override; + u8 Read8(u32 address, bool* valid = nullptr) override; + u16 Read16(u32 address, bool* valid = nullptr) override; + u32 Read32(u32 address, bool* valid = nullptr) override; + u64 Read64(u32 address, bool* valid = nullptr) override; + u128 Read128(u32 address, bool* valid = nullptr) override; + bool ReadBytes(u32 address, void* dest, u32 size) override; + + bool Write8(u32 address, u8 value) override; + bool Write16(u32 address, u16 value) override; + bool Write32(u32 address, u32 value) override; + bool Write64(u32 address, u64 value) override; + bool Write128(u32 address, u128 value) override; + bool WriteBytes(u32 address, void* src, u32 size) override; + + bool CompareBytes(u32 address, void* src, u32 size) override; protected: const ccc::ElfFile& m_elf; diff --git a/pcsx2/DebugTools/DisassemblyManager.cpp b/pcsx2/DebugTools/DisassemblyManager.cpp index 44ce03558ced0..9306196a4097f 100644 --- a/pcsx2/DebugTools/DisassemblyManager.cpp +++ b/pcsx2/DebugTools/DisassemblyManager.cpp @@ -23,7 +23,7 @@ static u32 computeHash(u32 address, u32 size) u32 hash = 0xBACD7814; while (address < end) { - hash += r5900Debug.read32(address); + hash += r5900Debug.Read32(address); address += 4; } return hash; @@ -918,7 +918,7 @@ void DisassemblyData::createLines() bool inString = false; while (pos < end) { - u8 b = r5900Debug.read8(pos++); + u8 b = r5900Debug.Read8(pos++); if (b >= 0x20 && b <= 0x7F) { if (currentLine.size()+1 >= maxChars) @@ -995,18 +995,18 @@ void DisassemblyData::createLines() switch (type) { case DATATYPE_BYTE: - value = cpu->read8(pos); + value = cpu->Read8(pos); std::snprintf(buffer,std::size(buffer),"0x%02X",value); pos++; break; case DATATYPE_HALFWORD: - value = cpu->read16(pos); + value = cpu->Read16(pos); std::snprintf(buffer,std::size(buffer),"0x%04X",value); pos += 2; break; case DATATYPE_WORD: { - value = cpu->read32(pos); + value = cpu->Read32(pos); const std::string label = cpu->GetSymbolGuardian().SymbolStartingAtAddress(value).name; if (!label.empty()) std::snprintf(buffer,std::size(buffer),"%s",label.c_str()); diff --git a/pcsx2/DebugTools/MIPSAnalyst.cpp b/pcsx2/DebugTools/MIPSAnalyst.cpp index c2570fcb5738d..406ea5c518ace 100644 --- a/pcsx2/DebugTools/MIPSAnalyst.cpp +++ b/pcsx2/DebugTools/MIPSAnalyst.cpp @@ -24,9 +24,9 @@ namespace MIPSAnalyst { - u32 GetJumpTarget(u32 addr, MemoryReader& reader) + u32 GetJumpTarget(u32 addr, MemoryInterface& reader) { - u32 op = reader.read32(addr); + u32 op = reader.Read32(addr); const R5900::OPCODE& opcode = R5900::GetInstruction(op); if ((opcode.flags & IS_BRANCH) && (opcode.flags & BRANCHTYPE_MASK) == BRANCHTYPE_JUMP) @@ -38,9 +38,9 @@ namespace MIPSAnalyst return INVALIDTARGET; } - u32 GetBranchTarget(u32 addr, MemoryReader& reader) + u32 GetBranchTarget(u32 addr, MemoryInterface& reader) { - u32 op = reader.read32(addr); + u32 op = reader.Read32(addr); const R5900::OPCODE& opcode = R5900::GetInstruction(op); int branchType = (opcode.flags & BRANCHTYPE_MASK); @@ -50,9 +50,9 @@ namespace MIPSAnalyst return INVALIDTARGET; } - u32 GetBranchTargetNoRA(u32 addr, MemoryReader& reader) + u32 GetBranchTargetNoRA(u32 addr, MemoryInterface& reader) { - u32 op = reader.read32(addr); + u32 op = reader.Read32(addr); const R5900::OPCODE& opcode = R5900::GetInstruction(op); int branchType = (opcode.flags & BRANCHTYPE_MASK); @@ -67,9 +67,9 @@ namespace MIPSAnalyst return INVALIDTARGET; } - u32 GetSureBranchTarget(u32 addr, MemoryReader& reader) + u32 GetSureBranchTarget(u32 addr, MemoryInterface& reader) { - u32 op = reader.read32(addr); + u32 op = reader.Read32(addr); const R5900::OPCODE& opcode = R5900::GetInstruction(op); if ((opcode.flags & IS_BRANCH) && (opcode.flags & BRANCHTYPE_MASK) == BRANCHTYPE_BRANCH) @@ -115,7 +115,7 @@ namespace MIPSAnalyst return INVALIDTARGET; } - static u32 ScanAheadForJumpback(u32 fromAddr, u32 knownStart, u32 knownEnd, MemoryReader& reader) { + static u32 ScanAheadForJumpback(u32 fromAddr, u32 knownStart, u32 knownEnd, MemoryInterface& reader) { static const u32 MAX_AHEAD_SCAN = 0x1000; // Maybe a bit high... just to make sure we don't get confused by recursive tail recursion. static const u32 MAX_FUNC_SIZE = 0x20000; @@ -134,7 +134,7 @@ namespace MIPSAnalyst u32 furthestJumpbackAddr = INVALIDTARGET; for (u32 ahead = fromAddr; ahead < fromAddr + MAX_AHEAD_SCAN; ahead += 4) { - u32 aheadOp = reader.read32(ahead); + u32 aheadOp = reader.Read32(ahead); u32 target = GetBranchTargetNoRA(ahead, reader); if (target == INVALIDTARGET && ((aheadOp & 0xFC000000) == 0x08000000)) { target = GetJumpTarget(ahead, reader); @@ -158,7 +158,7 @@ namespace MIPSAnalyst if (closestJumpbackAddr != INVALIDTARGET && furthestJumpbackAddr == INVALIDTARGET) { for (u32 behind = closestJumpbackTarget; behind < fromAddr; behind += 4) { - u32 behindOp = reader.read32(behind); + u32 behindOp = reader.Read32(behind); u32 target = GetBranchTargetNoRA(behind, reader); if (target == INVALIDTARGET && ((behindOp & 0xFC000000) == 0x08000000)) { target = GetJumpTarget(behind, reader); @@ -175,7 +175,7 @@ namespace MIPSAnalyst return furthestJumpbackAddr; } - void ScanForFunctions(ccc::SymbolDatabase& database, MemoryReader& reader, u32 startAddr, u32 endAddr, bool generateHashes) { + void ScanForFunctions(ccc::SymbolDatabase& database, MemoryInterface& reader, u32 startAddr, u32 endAddr, bool generateHashes) { std::vector functions; AnalyzedFunction currentFunction = {startAddr}; @@ -200,7 +200,7 @@ namespace MIPSAnalyst continue; } - u32 op = reader.read32(addr); + u32 op = reader.Read32(addr); u32 target = GetBranchTargetNoRA(addr, reader); if (target != INVALIDTARGET) { @@ -288,7 +288,7 @@ namespace MIPSAnalyst // Most functions are aligned to 8 or 16 bytes, so add padding // to this one unless a symbol exists implying a new function // follows immediately. - while (next_symbol == nullptr && ((addr+8) % 16) && reader.read32(addr+8) == 0) + while (next_symbol == nullptr && ((addr+8) % 16) && reader.Read32(addr+8) == 0) addr += 4; currentFunction.end = addr + 4; @@ -373,7 +373,7 @@ namespace MIPSAnalyst info.cpu = cpu; info.opcodeAddress = address; - info.encodedOpcode = cpu->read32(address); + info.encodedOpcode = cpu->Read32(address); u32 op = info.encodedOpcode; const R5900::OPCODE& opcode = R5900::GetInstruction(op); diff --git a/pcsx2/DebugTools/MIPSAnalyst.h b/pcsx2/DebugTools/MIPSAnalyst.h index 06fdcb7f90708..00ed8c2e485ea 100644 --- a/pcsx2/DebugTools/MIPSAnalyst.h +++ b/pcsx2/DebugTools/MIPSAnalyst.h @@ -6,6 +6,8 @@ #include "DebugInterface.h" #include "SymbolGuardian.h" +#include "common/MemoryInterface.h" + #define MIPS_GET_OP(op) ((op>>26) & 0x3F) #define MIPS_GET_FUNC(op) (op & 0x3F) #define MIPS_GET_SA(op) ((op>>6) & 0x1F) @@ -27,7 +29,7 @@ namespace MIPSAnalyst char name[64]; }; - void ScanForFunctions(ccc::SymbolDatabase& database, MemoryReader& reader, u32 startAddr, u32 endAddr, bool generateHashes); + void ScanForFunctions(ccc::SymbolDatabase& database, MemoryInterface& reader, u32 startAddr, u32 endAddr, bool generateHashes); enum LoadStoreLRType { LOADSTORE_NORMAL, LOADSTORE_LEFT, LOADSTORE_RIGHT }; diff --git a/pcsx2/DebugTools/MipsStackWalk.cpp b/pcsx2/DebugTools/MipsStackWalk.cpp index f13a85477cecb..cafcbfeacebd1 100644 --- a/pcsx2/DebugTools/MipsStackWalk.cpp +++ b/pcsx2/DebugTools/MipsStackWalk.cpp @@ -84,7 +84,7 @@ namespace MipsStackWalk u32 stop = pc - 32 * 4; for (; cpu->isValidAddress(pc) && pc >= stop; pc -= 4) { - u32 rawOp = cpu->read32(pc); + u32 rawOp = cpu->Read32(pc); const R5900::OPCODE& op = R5900::GetInstruction(rawOp); // We're looking for a "mov fp, sp" close by a "addiu sp, sp, -N". @@ -113,7 +113,7 @@ namespace MipsStackWalk for (u32 pc = start; cpu->isValidAddress(pc) && pc >= stop; pc -= 4) { - u32 rawOp = cpu->read32(pc); + u32 rawOp = cpu->Read32(pc); const R5900::OPCODE& op = R5900::GetInstruction(rawOp); // Look for RA write to ram @@ -154,7 +154,7 @@ namespace MipsStackWalk frame.stackSize = -_IMM16; if (ra_offset != -1 && cpu->isValidAddress(frame.sp + ra_offset)) { - ra = cpu->read32(frame.sp + ra_offset); + ra = cpu->Read32(frame.sp + ra_offset); } return true; } diff --git a/pcsx2/DebugTools/SymbolGuardian.cpp b/pcsx2/DebugTools/SymbolGuardian.cpp index 341ef4a8519bd..2b95031fe1139 100644 --- a/pcsx2/DebugTools/SymbolGuardian.cpp +++ b/pcsx2/DebugTools/SymbolGuardian.cpp @@ -152,7 +152,7 @@ FunctionInfo SymbolGuardian::FunctionOverlappingAddress(u32 address) const return info; } -void SymbolGuardian::GenerateFunctionHashes(ccc::SymbolDatabase& database, MemoryReader& reader) +void SymbolGuardian::GenerateFunctionHashes(ccc::SymbolDatabase& database, MemoryInterface& reader) { for (ccc::Function& function : database.functions) { @@ -164,7 +164,7 @@ void SymbolGuardian::GenerateFunctionHashes(ccc::SymbolDatabase& database, Memor } } -void SymbolGuardian::UpdateFunctionHashes(ccc::SymbolDatabase& database, MemoryReader& reader) +void SymbolGuardian::UpdateFunctionHashes(ccc::SymbolDatabase& database, MemoryInterface& reader) { for (ccc::Function& function : database.functions) { @@ -182,7 +182,7 @@ void SymbolGuardian::UpdateFunctionHashes(ccc::SymbolDatabase& database, MemoryR source_file.check_functions_match(database); } -std::optional SymbolGuardian::HashFunction(const ccc::Function& function, MemoryReader& reader) +std::optional SymbolGuardian::HashFunction(const ccc::Function& function, MemoryInterface& reader) { if (!function.address().valid()) return std::nullopt; @@ -195,7 +195,7 @@ std::optional SymbolGuardian::HashFunction(const ccc::Functio for (u32 i = 0; i < function.size() / 4; i++) { bool valid; - u32 value = reader.read32(function.address().value + i * 4, valid); + u32 value = reader.Read32(function.address().value + i * 4, &valid); if (!valid) return std::nullopt; diff --git a/pcsx2/DebugTools/SymbolGuardian.h b/pcsx2/DebugTools/SymbolGuardian.h index 48acc3c536bda..e54219334c773 100644 --- a/pcsx2/DebugTools/SymbolGuardian.h +++ b/pcsx2/DebugTools/SymbolGuardian.h @@ -3,19 +3,18 @@ #pragma once -#include -#include -#include -#include -#include +#include "common/MemoryInterface.h" +#include "common/Pcsx2Types.h" #include #include #include -#include "common/Pcsx2Types.h" - -class MemoryReader; +#include +#include +#include +#include +#include struct SymbolInfo { @@ -76,14 +75,14 @@ class SymbolGuardian // Hash all the functions in the database and store the hashes in the // original hash field of said objects. - static void GenerateFunctionHashes(ccc::SymbolDatabase& database, MemoryReader& reader); + static void GenerateFunctionHashes(ccc::SymbolDatabase& database, MemoryInterface& reader); // Hash all the functions in the database that have original hashes and // store the results in the current hash fields of said objects. - static void UpdateFunctionHashes(ccc::SymbolDatabase& database, MemoryReader& reader); + static void UpdateFunctionHashes(ccc::SymbolDatabase& database, MemoryInterface& reader); // Hash a function and return the result. - static std::optional HashFunction(const ccc::Function& function, MemoryReader& reader); + static std::optional HashFunction(const ccc::Function& function, MemoryInterface& reader); // Delete all symbols from modules that have the "is_irx" flag set. void ClearIrxModules();