Debugger: Merge redundant memory interfaces

This commit is contained in:
chaoticgd
2026-04-13 15:48:41 -04:00
committed by Ty
parent d23ba14335
commit ceb53a1626
14 changed files with 371 additions and 393 deletions
+12
View File
@@ -3,6 +3,8 @@
#include "MemoryInterface.h"
#include <bit>
template <MemoryAccessType Value>
Value MemoryInterface::Read(u32 address, bool* valid)
{
@@ -24,6 +26,10 @@ Value MemoryInterface::Read(u32 address, bool* valid)
.hi = static_cast<s64>(value.hi),
};
}
else if constexpr (std::is_same_v<Value, float>)
return std::bit_cast<float>(Read32(address, valid));
else if constexpr (std::is_same_v<Value, double>)
return std::bit_cast<double>(Read64(address, valid));
else
return Value(0);
}
@@ -48,6 +54,10 @@ bool MemoryInterface::Write(u32 address, Value value)
unsigned_value.hi = static_cast<u64>(value.hi);
return Write128(address, unsigned_value);
}
else if constexpr (std::is_same_v<Value, float>)
return Write32(address, std::bit_cast<u32>(value));
else if constexpr (std::is_same_v<Value, double>)
return Write64(address, std::bit_cast<u64>(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
+4 -1
View File
@@ -12,12 +12,15 @@ concept MemoryAccessType = std::is_same_v<Value, u8> || std::is_same_v<Value, s8
std::is_same_v<Value, u16> || std::is_same_v<Value, s16> ||
std::is_same_v<Value, u32> || std::is_same_v<Value, s32> ||
std::is_same_v<Value, u64> || std::is_same_v<Value, s64> ||
std::is_same_v<Value, u128> || std::is_same_v<Value, s128>;
std::is_same_v<Value, u128> || std::is_same_v<Value, s128> ||
std::is_same_v<Value, float> || std::is_same_v<Value, double>;
/// 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;
+11 -11
View File
@@ -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<DisassemblyView> 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)]() {
+4 -44
View File
@@ -112,46 +112,6 @@ void MemorySearchView::onListSearchResultsContextMenu(QPoint pos)
menu->popup(m_ui.listSearchResults->viewport()->mapToGlobal(pos));
}
template <typename T>
T readValueAtAddress(DebugInterface* cpu, u32 addr);
template <>
float readValueAtAddress<float>(DebugInterface* cpu, u32 addr)
{
return std::bit_cast<float>(cpu->read32(addr));
}
template <>
double readValueAtAddress<double>(DebugInterface* cpu, u32 addr)
{
return std::bit_cast<double>(cpu->read64(addr));
}
template <typename T>
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 <typename T>
static bool memoryValueComparator(SearchComparison searchComparison, T searchValue, T readValue)
{
@@ -294,7 +254,7 @@ void searchWorker(DebugInterface* cpu, std::vector<SearchResult>& searchResults,
if (!cpu->isValidAddress(addr))
continue;
T readValue = readValueAtAddress<T>(cpu, addr);
T readValue = cpu->Read<T>(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<SearchResult>& searchResults,
if (!cpu->isValidAddress(addr))
return true;
const auto readValue = readValueAtAddress<T>(cpu, addr);
const auto readValue = cpu->Read<T>(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;
}
+21 -21
View File
@@ -119,7 +119,7 @@ void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32
{
case MemoryViewType::BYTE:
{
const u8 val = static_cast<u8>(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<u16>(static_cast<u16>(cpu.read16(thisSegmentsStart, valid)));
const u16 val = convertEndian<u16>(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<u32>(cpu.read32(thisSegmentsStart, valid));
const u32 val = convertEndian<u32>(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<u64>(cpu.read64(thisSegmentsStart, valid));
const u64 val = convertEndian<u64>(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<u32>(cpu.read32(thisSegmentsStart, valid));
const u32 intVal = convertEndian<u32>(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<u16>(cpu.read16(selectedAddress & ~1)));
val.lo = convertEndian(static_cast<u16>(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<MemoryViewTable> 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<MemoryViewTable> 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<MemoryViewTable> 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<MemoryViewTable> 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<MemoryViewTable> 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;
@@ -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:
{
File diff suppressed because it is too large Load Diff
+49 -58
View File
@@ -8,6 +8,8 @@
#include "SymbolGuardian.h"
#include "SymbolImporter.h"
#include "common/MemoryInterface.h"
#include <string>
enum
@@ -38,20 +40,7 @@ inline const std::array<BreakPointCpu, 2> 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 @@ public:
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 @@ private:
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 @@ public:
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 @@ public:
};
// 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;
+5 -5
View File
@@ -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());
+15 -15
View File
@@ -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<MIPSAnalyst::AnalyzedFunction> 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);
+3 -1
View File
@@ -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 };
+3 -3
View File
@@ -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;
}
+4 -4
View File
@@ -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<ccc::FunctionHash> SymbolGuardian::HashFunction(const ccc::Function& function, MemoryReader& reader)
std::optional<ccc::FunctionHash> SymbolGuardian::HashFunction(const ccc::Function& function, MemoryInterface& reader)
{
if (!function.address().valid())
return std::nullopt;
@@ -195,7 +195,7 @@ std::optional<ccc::FunctionHash> 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;
+10 -11
View File
@@ -3,19 +3,18 @@
#pragma once
#include <atomic>
#include <thread>
#include <functional>
#include <mutex>
#include <shared_mutex>
#include "common/MemoryInterface.h"
#include "common/Pcsx2Types.h"
#include <ccc/ast.h>
#include <ccc/symbol_database.h>
#include <ccc/symbol_file.h>
#include "common/Pcsx2Types.h"
class MemoryReader;
#include <atomic>
#include <functional>
#include <mutex>
#include <shared_mutex>
#include <thread>
struct SymbolInfo
{
@@ -76,14 +75,14 @@ public:
// 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<ccc::FunctionHash> HashFunction(const ccc::Function& function, MemoryReader& reader);
static std::optional<ccc::FunctionHash> HashFunction(const ccc::Function& function, MemoryInterface& reader);
// Delete all symbols from modules that have the "is_irx" flag set.
void ClearIrxModules();