diff --git a/Core/Debugger/DisassemblyManager.cpp b/Core/Debugger/DisassemblyManager.cpp index 882239bbc..4902f16b2 100644 --- a/Core/Debugger/DisassemblyManager.cpp +++ b/Core/Debugger/DisassemblyManager.cpp @@ -34,6 +34,13 @@ bool isInInterval(u32 start, u32 size, u32 value) return start <= value && value <= (start+size-1); } + +static u32 computeHash(u32 address, u32 size) +{ + return XXH32(Memory::GetPointer(address),size,0xBACD7814); +} + + void parseDisasm(const char* disasm, char* opcode, char* arguments, bool insertSymbols) { // copy opcode @@ -222,7 +229,10 @@ void DisassemblyManager::getLine(u32 address, bool insertSymbols, DisassemblyLin if (it == entries.end()) { - dest.totalSize = 4; + if (address % 4) + dest.totalSize = ((address+3) & ~3)-address; + else + dest.totalSize = 4; dest.name = "ERROR"; dest.params = "Disassembly failure"; return; @@ -230,12 +240,13 @@ void DisassemblyManager::getLine(u32 address, bool insertSymbols, DisassemblyLin } DisassemblyEntry* entry = it->second; - - dest.info = MIPSAnalyst::GetOpcodeInfo(cpu,address); if (entry->disassemble(address,dest,insertSymbols)) return; - - dest.totalSize = 4; + + if (address % 4) + dest.totalSize = ((address+3) & ~3)-address; + else + dest.totalSize = 4; dest.name = "ERROR"; dest.params = "Disassembly failure"; } @@ -321,18 +332,13 @@ void DisassemblyManager::clear() DisassemblyFunction::DisassemblyFunction(u32 _address, u32 _size): address(_address), size(_size) { - hash = computeHash(); + hash = computeHash(address,size); load(); } -u32 DisassemblyFunction::computeHash() -{ - return XXH32(Memory::GetPointer(address),size,0xBACD7814); -} - void DisassemblyFunction::recheck() { - u32 newHash = computeHash(); + u32 newHash = computeHash(address,size); if (hash != newHash) { hash = newHash; @@ -377,9 +383,21 @@ bool DisassemblyFunction::disassemble(u32 address, DisassemblyLineInfo& dest, bo void DisassemblyFunction::getBranchLines(u32 start, u32 size, std::vector& dest) { + u32 end = start+size; + for (int i = 0; i < lines.size(); i++) { - dest.push_back(lines[i]); + BranchLine& line = lines[i]; + + u32 first = line.first; + u32 second = line.second; + + // skip branches that are entirely before or entirely after the window + if ((first < start && second < start) || + (first > end && second > end)) + continue; + + dest.push_back(line); } } @@ -634,13 +652,17 @@ bool DisassemblyOpcode::disassemble(u32 address, DisassemblyLineInfo& dest, bool dest.name = opcode; dest.params = arguments; dest.totalSize = 4; + dest.info = MIPSAnalyst::GetOpcodeInfo(DisassemblyManager::getCpu(),address); return true; } void DisassemblyOpcode::getBranchLines(u32 start, u32 size, std::vector& dest) { if (start < address) + { + size = start+size-address; start = address; + } if (start+size > address+num*4) size = address+num*4-start; @@ -693,7 +715,8 @@ void DisassemblyMacro::setMacroMemory(std::string _name, u32 _immediate, u8 _rt, bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo& dest, bool insertSymbols) { char buffer[64]; - dest.type = DISTYPE_OTHER; + dest.type = DISTYPE_MACRO; + dest.info = MIPSAnalyst::GetOpcodeInfo(DisassemblyManager::getCpu(),address); const char* addressSymbol; switch (type) @@ -743,6 +766,22 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo& dest, bool } +DisassemblyData::DisassemblyData(u32 _address, u32 _size, DataType _type): address(_address), size(_size), type(_type) +{ + hash = computeHash(address,size); + createLines(); +} + +void DisassemblyData::recheck() +{ + u32 newHash = computeHash(address,size); + if (newHash != hash) + { + hash = newHash; + createLines(); + } +} + bool DisassemblyData::disassemble(u32 address, DisassemblyLineInfo& dest, bool insertSymbols) { dest.type = DISTYPE_DATA; @@ -766,6 +805,9 @@ bool DisassemblyData::disassemble(u32 address, DisassemblyLineInfo& dest, bool i } auto it = lines.find(address); + if (it == lines.end()) + return false; + dest.params = it->second.text; dest.totalSize = it->second.size; return true; diff --git a/Core/Debugger/DisassemblyManager.h b/Core/Debugger/DisassemblyManager.h index 84ee49acc..ae1847dcd 100644 --- a/Core/Debugger/DisassemblyManager.h +++ b/Core/Debugger/DisassemblyManager.h @@ -19,7 +19,7 @@ #include "Globals.h" #include "Core/MIPS/MIPSAnalyst.h" -enum DisassemblyLineType { DISTYPE_OPCODE, DISTYPE_DATA, DISTYPE_OTHER }; +enum DisassemblyLineType { DISTYPE_OPCODE, DISTYPE_MACRO, DISTYPE_DATA, DISTYPE_OTHER }; struct DisassemblyLineInfo { @@ -70,7 +70,6 @@ public: virtual bool disassemble(u32 address, DisassemblyLineInfo& dest, bool insertSymbols); virtual void getBranchLines(u32 start, u32 size, std::vector& dest); private: - u32 computeHash(); void generateBranchLines(); void load(); void clear(); @@ -133,10 +132,10 @@ private: class DisassemblyData: public DisassemblyEntry { public: - DisassemblyData(u32 _address, u32 _size, DataType _type): address(_address), size(_size), type(_type) { createLines(); }; + DisassemblyData(u32 _address, u32 _size, DataType _type); virtual ~DisassemblyData() { }; - virtual void recheck() { createLines(); }; + virtual void recheck(); virtual int getNumLines() { return (int)lines.size(); }; virtual int getLineNum(u32 address, bool findStart); virtual u32 getLineAddress(int line) { return lineAddresses[line]; }; @@ -154,6 +153,7 @@ private: u32 address; u32 size; + u32 hash; DataType type; std::map lines; std::vector lineAddresses; diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 3b1b655c9..301b84ece 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -566,14 +566,22 @@ void CtrlDisAsmView::followBranch() DisassemblyLineInfo line; manager.getLine(curAddress,true,line); - if (line.info.isBranch) + if (line.type == DISTYPE_OPCODE || line.type == DISTYPE_MACRO) { - jumpStack.push_back(curAddress); - gotoAddr(line.info.branchTarget); - } else if (line.info.hasRelevantAddress) + if (line.info.isBranch) + { + jumpStack.push_back(curAddress); + gotoAddr(line.info.branchTarget); + } else if (line.info.hasRelevantAddress) + { + // well, not exactly a branch, but we can do something anyway + SendMessage(GetParent(wnd),WM_DEB_GOTOHEXEDIT,line.info.releventAddress,0); + SetFocus(wnd); + } + } else if (line.type == DISTYPE_DATA) { - // well, not exactly a branch, but we can do something anyway - SendMessage(GetParent(wnd),WM_DEB_GOTOHEXEDIT,line.info.releventAddress,0); + // jump to the start of the current line + SendMessage(GetParent(wnd),WM_DEB_GOTOHEXEDIT,curAddress,0); SetFocus(wnd); } } @@ -1012,7 +1020,7 @@ void CtrlDisAsmView::updateStatusBarText() manager.getLine(curAddress,true,line); text[0] = 0; - if (line.type == DISTYPE_OPCODE) + if (line.type == DISTYPE_OPCODE || line.type == DISTYPE_MACRO) { if (line.info.isDataAccess) {