Merge pull request #4638 from Kingcom/Debugger

Save labels separately from symbols
This commit is contained in:
Henrik Rydgård 2013-11-26 13:32:44 -08:00
commit 979a7fbdcd
10 changed files with 87 additions and 77 deletions

View File

@ -41,8 +41,6 @@ public:
virtual void runToBreakpoint() {}
virtual int getColor(unsigned int address){return 0xFFFFFFFF;}
virtual const char *getDescription(unsigned int address) {return "";}
virtual const char *findSymbolForAddress(unsigned int address) { return NULL; };
virtual bool getSymbolValue(char* symbol, u32& dest) { return false; };
virtual bool initExpression(const char* exp, PostfixExpression& dest) { return false; };
virtual bool parseExpression(PostfixExpression& exp, u32& dest) { return false; };

View File

@ -30,7 +30,7 @@ DebugInterface* DisassemblyManager::cpu;
bool isInInterval(u32 start, u32 size, u32 value)
{
return start <= value && value < start+size;
return start <= value && value <= (start+size-1);
}
void parseDisasm(const char* disasm, char* opcode, char* arguments, bool insertSymbols)
@ -58,7 +58,7 @@ void parseDisasm(const char* disasm, char* opcode, char* arguments, bool insertS
u32 branchTarget;
sscanf(disasm+3,"%08x",&branchTarget);
const char* addressSymbol = DisassemblyManager::getCpu()->findSymbolForAddress(branchTarget);
const char* addressSymbol = symbolMap.GetLabelName(branchTarget);
if (addressSymbol != NULL && insertSymbols)
{
arguments += sprintf(arguments,"%s",addressSymbol);
@ -305,7 +305,7 @@ void DisassemblyFunction::recheck()
int DisassemblyFunction::getNumLines()
{
return lineAddresses.size();
return (int) lineAddresses.size();
}
int DisassemblyFunction::getLineNum(u32 address, bool findStart)
@ -416,6 +416,15 @@ void DisassemblyFunction::generateBranchLines()
}
}
void DisassemblyFunction::addOpcodeSequence(u32 start, u32 end)
{
DisassemblyOpcode* opcode = new DisassemblyOpcode(start,(end-start)/4);
entries[start] = opcode;
for (u32 pos = start; pos < end; pos += 4)
{
lineAddresses.push_back(pos);
}
}
void DisassemblyFunction::load()
{
@ -440,6 +449,7 @@ void DisassemblyFunction::load()
u32 funcPos = address;
u32 funcEnd = address+size;
u32 opcodeSequenceStart = funcPos;
while (funcPos < funcEnd)
{
MIPSAnalyst::MipsOpcodeInfo opInfo = MIPSAnalyst::GetOpcodeInfo(cpu,funcPos);
@ -449,11 +459,6 @@ void DisassemblyFunction::load()
// skip branches and their delay slots
if (opInfo.isBranch)
{
DisassemblyOpcode* opcode = new DisassemblyOpcode(opAddress,2);
entries[opAddress] = opcode;
lineAddresses.push_back(opAddress);
lineAddresses.push_back(opAddress+4);
funcPos += 4;
continue;
}
@ -517,21 +522,26 @@ void DisassemblyFunction::load()
if (macro != NULL)
{
if (opcodeSequenceStart != opAddress)
addOpcodeSequence(opcodeSequenceStart,opAddress);
entries[opAddress] = macro;
for (int i = 0; i < macro->getNumLines(); i++)
{
lineAddresses.push_back(macro->getLineAddress(i));
}
opcodeSequenceStart = funcPos;
continue;
}
}
}
// just a normal opcode
DisassemblyOpcode* opcode = new DisassemblyOpcode(opAddress,1);
entries[opAddress] = opcode;
lineAddresses.push_back(opAddress);
}
if (opcodeSequenceStart != funcPos)
addOpcodeSequence(opcodeSequenceStart,funcPos);
}
void DisassemblyFunction::clear()
@ -615,7 +625,7 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo& dest, bool
case MACRO_LI:
dest.name = name;
addressSymbol = DisassemblyManager::getCpu()->findSymbolForAddress(immediate);
addressSymbol = symbolMap.GetLabelName(immediate);
if (addressSymbol != NULL && insertSymbols)
{
sprintf(buffer,"%s,%s",DisassemblyManager::getCpu()->GetRegName(0,rt),addressSymbol);
@ -631,7 +641,7 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo& dest, bool
case MACRO_MEMORYIMM:
dest.name = name;
addressSymbol = DisassemblyManager::getCpu()->findSymbolForAddress(immediate);
addressSymbol = symbolMap.GetLabelName(immediate);
if (addressSymbol != NULL && insertSymbols)
{
sprintf(buffer,"%s,%s",DisassemblyManager::getCpu()->GetRegName(0,rt),addressSymbol);

View File

@ -74,6 +74,7 @@ private:
void generateBranchLines();
void load();
void clear();
void addOpcodeSequence(u32 start, u32 end);
u32 address;
u32 size;

View File

@ -108,6 +108,8 @@ void SymbolMap::Clear() {
void SymbolMap::AddSymbol(const char *symbolname, unsigned int vaddress, size_t size, SymbolType st)
{
lock_guard guard(lock_);
symbolname = AddLabel(symbolname,vaddress);
MapEntry e;
strncpy(e.name, symbolname, 127);
e.name[127] = '\0';
@ -120,6 +122,7 @@ void SymbolMap::AddSymbol(const char *symbolname, unsigned int vaddress, size_t
uniqueEntries.insert((const MapEntryUniqueInfo)e);
entryRanges[e.vaddress + e.size] = e.vaddress;
}
}
void SymbolMap::RemoveSymbolNum(int symbolnum){
@ -250,7 +253,13 @@ bool SymbolMap::LoadNocashSym(const char *filename)
*seperator = 0;
sscanf(seperator+1,"%08X",&size);
}
AddSymbol(value,address,size,ST_FUNCTION);
if (size != 1)
{
AddSymbol(value,address,size,ST_FUNCTION);
} else {
AddLabel(value,address);
}
}
}
@ -329,44 +338,45 @@ u32 SymbolMap::GetNextSymbolAddress(u32 address)
return containingEntry->second;
}
const char* SymbolMap::getDirectSymbol(u32 address)
const char* SymbolMap::AddLabel(const char* name, u32 address)
{
lock_guard guard(lock_);
SymbolInfo info;
if (GetSymbolInfo(&info,address) == false) return NULL;
if (info.address != address) return NULL; // has to be the START of the function
// keep a label if it already exists
auto it = labels.find(address);
if (it != labels.end())
return it->second.name;
// now we need the name... which we can't just get from GetSymbolInfo because of the
// unique entries. But, there are so many less instances where there actually IS a
// label that the speed up is still massive
for (auto it = entries.begin(), end = entries.end(); it != end; ++it)
{
const MapEntry &entry = *it;
unsigned int addr = entry.vaddress;
if (addr == address) return entry.name;
}
return NULL;
Label label;
strcpy(label.name,name);
label.name[127] = 0;
labels[address] = label;
return name;
}
bool SymbolMap::getSymbolValue(char* symbol, u32& dest)
const char* SymbolMap::GetLabelName(u32 address)
{
lock_guard guard(lock_);
for (auto it = entries.begin(), end = entries.end(); it != end; ++it)
auto it = labels.find(address);
if (it == labels.end())
return NULL;
return it->second.name;
}
bool SymbolMap::GetLabelValue(const char* name, u32& dest)
{
for (auto it = labels.begin(); it != labels.end(); it++)
{
const MapEntry &entry = *it;
#ifdef _WIN32
if (_stricmp(entry.name,symbol) == 0)
#else
if (strcasecmp(entry.name,symbol) == 0)
#endif
if (strcasecmp(name,it->second.name) == 0)
{
dest = entry.vaddress;
dest = it->first;
return true;
}
}
return false;
}
static char descriptionTemp[256];
const char *SymbolMap::GetDescription(unsigned int address) const

View File

@ -69,12 +69,13 @@ public:
void IncreaseRunCount(int num);
unsigned int GetRunCount(int num) const;
void SortSymbols();
const char* getDirectSymbol(u32 address);
bool getSymbolValue(char* symbol, u32& dest);
void UseFuncSignaturesFile(const char *filename, u32 maxAddress);
void CompileFuncSignaturesFile(const char *filename) const;
const char* AddLabel(const char* name, u32 address);
const char* GetLabelName(u32 address);
bool GetLabelValue(const char* name, u32& dest);
private:
struct MapEntryUniqueInfo {
u32 address;
@ -87,6 +88,11 @@ private:
}
};
struct Label
{
char name[128];
};
struct MapEntry : public MapEntryUniqueInfo {
char name[128];
u32 unknown;
@ -99,7 +105,8 @@ private:
// TODO
}
};
std::map<u32,Label> labels;
std::set<MapEntryUniqueInfo> uniqueEntries;
std::vector<MapEntry> entries;
std::map<u32, u32> entryRanges;

View File

@ -109,7 +109,7 @@ public:
virtual bool parseSymbol(char* str, uint32& symbolValue)
{
return cpu->getSymbolValue(str,symbolValue);
return symbolMap.GetLabelValue(str,symbolValue);
}
virtual uint32 getReferenceValue(uint32 referenceIndex)
@ -230,16 +230,6 @@ const char *MIPSDebugInterface::getDescription(unsigned int address)
return symbolMap.GetDescription(address);
}
const char *MIPSDebugInterface::findSymbolForAddress(unsigned int address)
{
return symbolMap.getDirectSymbol(address);
}
bool MIPSDebugInterface::getSymbolValue(char* symbol, u32& dest)
{
return symbolMap.getSymbolValue(symbol,dest);
}
bool MIPSDebugInterface::initExpression(const char* exp, PostfixExpression& dest)
{
MipsExpressionFunctions funcs(this);

View File

@ -40,8 +40,6 @@ public:
virtual void runToBreakpoint();
virtual int getColor(unsigned int address);
virtual const char *getDescription(unsigned int address);
virtual const char *findSymbolForAddress(unsigned int address);
virtual bool getSymbolValue(char* symbol, u32& dest);
virtual bool initExpression(const char* exp, PostfixExpression& dest);
virtual bool parseExpression(PostfixExpression& exp, u32& dest);

View File

@ -167,7 +167,6 @@ CtrlDisAsmView::CtrlDisAsmView(HWND _wnd)
boldfont = CreateFont(rowHeight-2,charWidth,0,0,FW_DEMIBOLD,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,
L"Lucida Console");
curAddress=0;
instructionSize=4;
showHex=false;
hasFocus = false;
dontRedraw = false;
@ -206,7 +205,7 @@ bool CtrlDisAsmView::getDisasmAddressText(u32 address, char* dest, bool abbrevia
{
if (displaySymbols)
{
const char* addressSymbol = debugger->findSymbolForAddress(address);
const char* addressSymbol = symbolMap.GetLabelName(address);
if (addressSymbol != NULL)
{
for (int k = 0; addressSymbol[k] != 0; k++)
@ -655,11 +654,11 @@ void CtrlDisAsmView::onKeyDown(WPARAM wParam, LPARAM lParam)
toggleBreakpoint(true);
break;
case VK_UP:
windowStart -= instructionSize;
scrollWindow(-1);
scanFunctions();
break;
case VK_DOWN:
windowStart += instructionSize;
scrollWindow(1);
scanFunctions();
break;
case VK_NEXT:
@ -819,10 +818,10 @@ void CtrlDisAsmView::onMouseDown(WPARAM wParam, LPARAM lParam, int button)
void CtrlDisAsmView::copyInstructions(u32 startAddr, u32 endAddr, bool withDisasm)
{
int count = (endAddr - startAddr) / instructionSize;
if (withDisasm == false)
{
int instructionSize = debugger->getInstructionSize(0);
int count = (endAddr - startAddr) / instructionSize;
int space = count * 32;
char *temp = new char[space];
@ -1023,7 +1022,7 @@ void CtrlDisAsmView::updateStatusBarText()
// TODO: Could also be a float...
{
u32 data = Memory::Read_U32(line.info.dataAddress);
const char* addressSymbol = debugger->findSymbolForAddress(data);
const char* addressSymbol = symbolMap.GetLabelName(data);
if (addressSymbol)
{
sprintf(text,"[%08X] = %s (%08X)",line.info.dataAddress,addressSymbol,data);
@ -1041,7 +1040,7 @@ void CtrlDisAsmView::updateStatusBarText()
if (line.info.isBranch)
{
const char* addressSymbol = debugger->findSymbolForAddress(line.info.branchTarget);
const char* addressSymbol = symbolMap.GetLabelName(line.info.branchTarget);
if (addressSymbol == NULL)
{
sprintf(text,"%08X",line.info.branchTarget);
@ -1153,11 +1152,11 @@ std::string CtrlDisAsmView::disassembleRange(u32 start, u32 size)
// gather all branch targets without labels
std::set<u32> branchAddresses;
for (u32 i = 0; i < size; i += instructionSize)
for (u32 i = 0; i < size; i += debugger->getInstructionSize(0))
{
MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(debugger,start+i);
if (info.isBranch && debugger->findSymbolForAddress(info.branchTarget) == NULL)
if (info.isBranch && symbolMap.GetLabelName(info.branchTarget) == NULL)
{
if (branchAddresses.find(info.branchTarget) == branchAddresses.end())
{
@ -1189,7 +1188,7 @@ std::string CtrlDisAsmView::disassembleRange(u32 start, u32 size)
}
if (line.info.isBranch && !line.info.isBranchToRegister
&& debugger->findSymbolForAddress(line.info.branchTarget) == NULL
&& symbolMap.GetLabelName(line.info.branchTarget) == NULL
&& branchAddresses.find(line.info.branchTarget) != branchAddresses.end())
{
sprintf(buffer,"pos_%08X",line.info.branchTarget);

View File

@ -50,7 +50,6 @@ class CtrlDisAsmView
u32 windowStart;
int visibleRows;
int instructionSize;
bool whiteBackground;
bool displaySymbols;
@ -110,7 +109,6 @@ public:
{
debugger=deb;
curAddress=debugger->getPC();
instructionSize=debugger->getInstructionSize(0);
manager.setCpu(deb);
}
DebugInterface *getDebugger()
@ -123,13 +121,12 @@ public:
void gotoAddr(unsigned int addr)
{
addr = manager.getStartAddress(addr);
u32 windowEnd = windowStart+visibleRows*instructionSize;
u32 newAddress = addr&(~(instructionSize-1));
u32 windowEnd = manager.getNthNextAddress(windowStart,visibleRows);
u32 newAddress = manager.getStartAddress(addr);
if (newAddress < windowStart || newAddress >= windowEnd)
{
windowStart = newAddress-visibleRows/2*instructionSize;
windowStart = manager.getNthPreviousAddress(newAddress,visibleRows/2);
}
setCurAddress(newAddress);
@ -138,7 +135,7 @@ public:
}
void gotoPC()
{
gotoAddr(debugger->getPC()&(~(instructionSize-1)));
gotoAddr(debugger->getPC());
}
u32 getSelection()
{

View File

@ -457,7 +457,7 @@ void CtrlBreakpointList::GetColumnText(wchar_t* dest, int row, int col)
else
wsprintf(dest,L"0x%08X",mc.end-mc.start);
} else {
const char* sym = cpu->findSymbolForAddress(displayedBreakPoints_[index].addr);
const char* sym = symbolMap.GetLabelName(displayedBreakPoints_[index].addr);
if (sym != NULL)
{
std::wstring s = ConvertUTF8ToWString(sym);
@ -625,7 +625,7 @@ void CtrlStackTraceView::GetColumnText(wchar_t* dest, int row, int col)
break;
case SF_ENTRYNAME:
{
const char* sym = cpu->findSymbolForAddress(frames[row].entry);
const char* sym = symbolMap.GetLabelName(frames[row].entry);
if (sym != NULL) {
wcscpy(dest, ConvertUTF8ToWString(sym).c_str());
} else {