From 5844d0107ba0874947d529b5dd587f021ea8fef0 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Wed, 27 Nov 2013 13:33:30 +0100 Subject: [PATCH] Rewrite SymbolTable --- Core/Debugger/DisassemblyManager.cpp | 4 +- Core/Debugger/SymbolMap.cpp | 916 +++++++++++++------------- Core/Debugger/SymbolMap.h | 97 ++- Core/ELF/ElfReader.cpp | 8 +- Core/HLE/sceKernelModule.cpp | 2 +- Core/MIPS/MIPSAnalyst.cpp | 4 +- Core/MIPS/MIPSDebugInterface.cpp | 4 +- Windows/Debugger/CtrlDisAsmView.cpp | 50 +- Windows/Debugger/CtrlRegisterList.cpp | 18 - Windows/Debugger/Debugger_Disasm.cpp | 40 +- Windows/WindowsHost.cpp | 5 - Windows/WindowsHost.h | 2 - Windows/resource.h | 2 - 13 files changed, 527 insertions(+), 625 deletions(-) diff --git a/Core/Debugger/DisassemblyManager.cpp b/Core/Debugger/DisassemblyManager.cpp index a293db71c0..7229219d50 100644 --- a/Core/Debugger/DisassemblyManager.cpp +++ b/Core/Debugger/DisassemblyManager.cpp @@ -139,13 +139,13 @@ void DisassemblyManager::analyze(u32 address, u32 size = 1024) } SymbolInfo info; - if (symbolMap.GetSymbolInfo(&info,address) && info.size >= 4) + if (symbolMap.GetSymbolInfo(&info,address) && info.type == ST_FUNCTION) { DisassemblyFunction* function = new DisassemblyFunction(info.address,info.size); entries[info.address] = function; address = info.address+info.size; } else { - u32 next = symbolMap.GetNextSymbolAddress(address+1); + u32 next = symbolMap.GetNextSymbolAddress(address+1,ST_FUNCTION); // let's just assume anything otuside a function is a normal opcode DisassemblyOpcode* opcode = new DisassemblyOpcode(address,(next-address)/4); diff --git a/Core/Debugger/SymbolMap.cpp b/Core/Debugger/SymbolMap.cpp index d80ce61310..eb8179848c 100644 --- a/Core/Debugger/SymbolMap.cpp +++ b/Core/Debugger/SymbolMap.cpp @@ -31,108 +31,18 @@ SymbolMap symbolMap; -//need improvement -static u32 hasher(u32 last, u32 value) -{ - return __rotl(last,3) ^ value; -} - -//#define BWLINKS - -// TODO: This should ignore immediates of many instructions, in order to be less sensitive. If it did, -// this could work okay. -static u32 ComputeHash(u32 start, u32 size) -{ - u32 hash=0; - for (unsigned int i=start; i> 26) { - case 18: - { - if (LK) { - u32 addr; - if(AA) - addr = SignExt26(LI << 2); - else - addr = ptr + SignExt26(LI << 2); - - int funNum = GetSymbolNum(addr); - if (funNum >= 0) - entries[funNum].backwardLinks.push_back(ptr); - } - break; - } - default: - ; - } - - ptr += 4; - } - } -#endif + AssignFunctionIndices(); } void SymbolMap::Clear() { lock_guard guard(lock_); -#ifdef BWLINKS - for (int i=0; isecond; + fprintf(f,"%08x %08x %08x %i %s\n",it->first,e.size,it->first,ST_FUNCTION,GetLabelName(it->first)); + } + + for (auto it = data.begin(), end = data.end(); it != end; ++it) + { + const DataEntry& e = it->second; + fprintf(f,"%08x %08x %08x %i %s\n",it->first,e.size,it->first,ST_DATA,GetLabelName(it->first)); } fclose(f); } @@ -244,7 +169,25 @@ bool SymbolMap::LoadNocashSym(const char *filename) if (value[0] == '.') // data directives { - continue; // not supported yet + char* s = strchr(value,':'); + if (s != NULL) + { + *s = 0; + + u32 size = 0; + if (sscanf(s+1,"%04X",&size) != 1) continue; + + if (strcasecmp(value,".byt") == 0) + { + AddData(address,size,DATATYPE_BYTE); + } else if (strcasecmp(value,".wrd") == 0) + { + AddData(address,size,DATATYPE_HALFWORD); + } else if (strcasecmp(value,".dbl") == 0) + { + AddData(address,size,DATATYPE_WORD); + } + } } else { // labels int size = 1; char* seperator = strchr(value,','); @@ -256,7 +199,7 @@ bool SymbolMap::LoadNocashSym(const char *filename) if (size != 1) { - AddSymbol(value,address,size,ST_FUNCTION); + AddFunction(value,address,size); } else { AddLabel(value,address); } @@ -267,93 +210,258 @@ bool SymbolMap::LoadNocashSym(const char *filename) return true; } -int SymbolMap::GetSymbolNum(unsigned int address, SymbolType symmask) const + + +SymbolType SymbolMap::GetSymbolType(u32 address) const { - lock_guard guard(lock_); - for (size_t i = 0, n = entries.size(); i < n; i++) - { - const MapEntry &entry = entries[i]; - unsigned int addr = entry.vaddress; - if (address >= addr) - { - if (address < addr + entry.size) - { - if (entries[i].type & symmask) - return (int) i; - else - return -1; - } - } - else - break; - } - return -1; + if (functions.find(address) != functions.end()) + return ST_FUNCTION; + + if (data.find(address) != data.end()) + return ST_DATA; + + return ST_NONE; } bool SymbolMap::GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask) const { - lock_guard guard(lock_); - // entryRanges is indexed by end. The first entry after address should contain address. - // Otherwise, we have no entry that contains it, unless things overlap (which they shouldn't.) - const auto containingEntry = entryRanges.upper_bound(address); - if (containingEntry == entryRanges.end()) - return false; + u32 functionAddress = -1; + u32 dataAddress = -1; - // The next most common case is a single symbol by start address. - // So we optimize for that by looking in our uniqueEntry set. - u32 start_address = containingEntry->second; - if (start_address <= address) + if (symmask & ST_FUNCTION) + functionAddress = GetFunctionStart(address); + + if (symmask & ST_DATA) + dataAddress = GetDataStart(address); + + if (functionAddress == -1 || dataAddress == -1) { - const MapEntryUniqueInfo searchKey = {start_address, start_address}; - const auto entry = uniqueEntries.find(searchKey); - // In case there were duplicates at some point, double check the end address. - if (entry != uniqueEntries.end() && entry->vaddress + entry->size > address && (entry->type & symmask) != 0) + if (functionAddress != -1) { - info->address = entry->vaddress; - info->size = entry->size; + if (info != NULL) + { + info->type = ST_FUNCTION; + info->address = functionAddress; + info->size = GetFunctionSize(functionAddress); + } + return true; } + + if (dataAddress != -1) + { + if (info != NULL) + { + info->type = ST_DATA; + info->address = dataAddress; + info->size = GetDataSize(functionAddress); + } + + return true; + } + + return false; } - // Fall back to a slower scan. - int n = GetSymbolNum(address, symmask); - if (n != -1) + // if both exist, return the function + if (info != NULL) { - info->address = GetSymbolAddr(n); - info->size = GetSymbolSize(n); - return true; + info->type = ST_FUNCTION; + info->address = functionAddress; + info->size = GetFunctionSize(functionAddress); } - return false; + return true; } -u32 SymbolMap::GetNextSymbolAddress(u32 address) +u32 SymbolMap::GetNextSymbolAddress(u32 address, SymbolType symmask) +{ + const auto functionEntry = symmask & ST_FUNCTION ? functions.upper_bound(address) : functions.end(); + const auto dataEntry = symmask & ST_DATA ? data.upper_bound(address) : data.end(); + + if (functionEntry == functions.end() && dataEntry == data.end()) + return -1; + + u32 funcAddress = (functionEntry != functions.end()) ? functionEntry->first : 0xFFFFFFFF; + u32 dataAddress = (dataEntry != data.end()) ? dataEntry->first : 0xFFFFFFFF; + + if (funcAddress <= dataAddress) + return funcAddress; + else + return dataAddress; +} + + +static char descriptionTemp[256]; + +const char *SymbolMap::GetDescription(unsigned int address) const +{ + const char* labelName = NULL; + + u32 funcStart = GetFunctionStart(address); + if (funcStart != -1) + { + labelName = GetLabelName(funcStart); + } else { + u32 dataStart = GetDataStart(address); + if (dataStart != -1) + labelName = GetLabelName(dataStart); + } + + if (labelName != NULL) + return labelName; + + sprintf(descriptionTemp, "(%08x)", address); + return descriptionTemp; +} + + + + +void SymbolMap::AddFunction(const char* name, u32 address, u32 size) { lock_guard guard(lock_); - const auto containingEntry = entryRanges.upper_bound(address); - if (containingEntry == entryRanges.end()) - return -1; + FunctionEntry func; + func.size = size; + func.index = (int)functions.size(); + functions[address] = func; - return containingEntry->second; + if (GetLabelName(address) == NULL) + AddLabel(name,address); } -const char* SymbolMap::AddLabel(const char* name, u32 address) +u32 SymbolMap::GetFunctionStart(u32 address) const +{ + auto it = functions.upper_bound(address); + if (it == functions.end()) + { + // check last element + auto rit = functions.rbegin(); + + if (rit != functions.rend()) + { + u32 start = rit->first; + u32 size = rit->second.size; + if (start <= address && start+size > address) + return start; + } + + // otherwise there's no function that contains this address + return -1; + } + + if (it != functions.begin()) + { + it--; + + u32 start = it->first; + u32 size = it->second.size; + if (start <= address && start+size > address) + return start; + } + + return -1; +} + +u32 SymbolMap::GetFunctionSize(u32 startAddress) const +{ + auto it = functions.find(startAddress); + if (it == functions.end()) + return -1; + + return it->second.size; +} + +int SymbolMap::GetFunctionNum(u32 address) const +{ + u32 start = GetFunctionStart(address); + if (start == -1) + return -1; + + auto it = functions.find(start); + if (it == functions.end()) + return -1; + + return it->second.index; +} + +void SymbolMap::AssignFunctionIndices() +{ + int index = 0; + for (auto it = functions.begin(); it != functions.end(); it++) + { + it->second.index = index++; + } +} + +bool SymbolMap::SetFunctionSize(u32 startAddress, u32 newSize) +{ + lock_guard guard(lock_); + + auto it = functions.find(startAddress); + if (it == functions.end()) + return false; + + it->second.size = newSize; + + // TODO: check for overlaps + return true; +} + +bool SymbolMap::RemoveFunction(u32 startAddress, bool removeName) +{ + lock_guard guard(lock_); + + auto it = functions.find(startAddress); + if (it == functions.end()) + return false; + + functions.erase(it); + if (removeName) + { + auto labelIt = labels.find(startAddress); + if (labelIt != labels.end()) + labels.erase(labelIt); + } + + return true; +} + + + + +void SymbolMap::AddLabel(const char* name, u32 address) { // keep a label if it already exists auto it = labels.find(address); - if (it != labels.end()) - return it->second.name; + if (it == labels.end()) + { + LabelEntry label; + strcpy(label.name,name); + label.name[127] = 0; - Label label; - strcpy(label.name,name); - label.name[127] = 0; - - labels[address] = label; - return name; + labels[address] = label; + } } -const char* SymbolMap::GetLabelName(u32 address) +void SymbolMap::SetLabelName(const char* name, u32 address) +{ + auto it = labels.find(address); + if (it == labels.end()) + { + LabelEntry label; + strcpy(label.name,name); + label.name[127] = 0; + + labels[address] = label; + } else { + strcpy(it->second.name,name); + it->second.name[127] = 0; + } +} + +const char* SymbolMap::GetLabelName(u32 address) const { auto it = labels.find(address); if (it == labels.end()) @@ -377,345 +485,209 @@ bool SymbolMap::GetLabelValue(const char* name, u32& dest) } -static char descriptionTemp[256]; -const char *SymbolMap::GetDescription(unsigned int address) const + +void SymbolMap::AddData(u32 address, u32 size, DataType type) { - int fun = SymbolMap::GetSymbolNum(address); - //if (address == entries[fun].vaddress) - //{ - if (fun!=-1) - return entries[fun].name; - else - { - sprintf(descriptionTemp, "(%08x)", address); - return descriptionTemp; - } - //} - //else - // return ""; + DataEntry entry; + entry.size = size; + entry.type = type; + data[address] = entry; } -#ifdef _WIN32 - -static const int defaultSymbolsAddresses[] = { - 0x08800000, 0x08804000, 0x04000000, 0x88000000, 0x00010000 -}; - -static const char* defaultSymbolsNames[] = { - "User memory", "Default load address", "VRAM","Kernel memory","Scratchpad" -}; - -static const int defaultSymbolsAmount = sizeof(defaultSymbolsAddresses)/sizeof(const int); - -void SymbolMap::FillSymbolListBox(HWND listbox,SymbolType symmask) const +u32 SymbolMap::GetDataStart(u32 address) const { - BOOL visible = ShowWindow(listbox,SW_HIDE); - ListBox_ResetContent(listbox); - - if (symmask & ST_DATA) + auto it = data.upper_bound(address); + if (it == data.end()) { - for (int i = 0; i < defaultSymbolsAmount; i++) + // check last element + auto rit = data.rbegin(); + + if (rit != data.rend()) { - wchar_t temp[256]; - wsprintf(temp, L"0x%08X (%S)", defaultSymbolsAddresses[i], defaultSymbolsNames[i]); - int index = ListBox_AddString(listbox,temp); - ListBox_SetItemData(listbox,index,defaultSymbolsAddresses[i]); + u32 start = rit->first; + u32 size = rit->second.size; + if (start <= address && start+size > address) + return start; } + + // otherwise there's no data that contains this address + return -1; } - lock_guard guard(lock_); - - SendMessage(listbox, WM_SETREDRAW, FALSE, 0); - SendMessage(listbox, LB_INITSTORAGE, (WPARAM)entries.size(), (LPARAM)entries.size() * 30); - for (auto it = entries.begin(), end = entries.end(); it != end; ++it) + if (it != data.begin()) { - const MapEntry &entry = *it; - if (entry.type & symmask) - { - wchar_t temp[256]; - if (entry.type & ST_FUNCTION || !(entry.type & ST_DATA)) - { - wsprintf(temp, L"%S", entry.name); - } else { - wsprintf(temp, L"0x%08X (%S)", entry.vaddress, entry.name); - } - - int index = ListBox_AddString(listbox,temp); - ListBox_SetItemData(listbox,index,entry.vaddress); - } - } - SendMessage(listbox, WM_SETREDRAW, TRUE, 0); - RedrawWindow(listbox, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); - - if (visible) - ShowWindow(listbox,SW_SHOW); -} - -void SymbolMap::FillSymbolComboBox(HWND listbox,SymbolType symmask) const -{ - ShowWindow(listbox,SW_HIDE); - ComboBox_ResetContent(listbox); - - //int style = GetWindowLong(listbox,GWL_STYLE); - - ComboBox_AddString(listbox, L"(0x02000000)"); - ComboBox_SetItemData(listbox, 0, 0x02000000); - - //ListBox_AddString(listbox, L"(0x80002000)"); - //ListBox_SetItemData(listbox, 1, 0x80002000); - - lock_guard guard(lock_); - - SendMessage(listbox, WM_SETREDRAW, FALSE, 0); - SendMessage(listbox, CB_INITSTORAGE, (WPARAM)entries.size(), (LPARAM)entries.size() * 30 * sizeof(wchar_t)); - for (size_t i = 0, end = entries.size(); i < end; ++i) - { - const MapEntry &entry = entries[i]; - if (entry.type & symmask) - { - wchar_t temp[256]; - wsprintf(temp, L"%S (%d)", entry.name, entry.size); - int index = ComboBox_AddString(listbox,temp); - ComboBox_SetItemData(listbox,index,entry.vaddress); - } - } - SendMessage(listbox, WM_SETREDRAW, TRUE, 0); - RedrawWindow(listbox, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); - ShowWindow(listbox,SW_SHOW); -} - -void SymbolMap::FillListBoxBLinks(HWND listbox, int num) const -{ - ListBox_ResetContent(listbox); - - lock_guard guard(lock_); - - int style = GetWindowLong(listbox,GWL_STYLE); - - const MapEntry &e = entries[num]; -#ifdef BWLINKS - for (int i=0; i::iterator it = uniqueEntries.find((const MapEntryUniqueInfo) e); - if (it != uniqueEntries.end()){ - MapEntryUniqueInfo temp = *it; - temp.size = newSize; - uniqueEntries.erase(it); - uniqueEntries.insert(temp); + u32 start = it->first; + u32 size = it->second.size; + if (start <= address && start+size > address) + return start; } - entryRanges.erase(e.vaddress + e.size); - entryRanges.insert(std::pair(e.vaddress+newSize,e.vaddress)); - e.size = newSize; -} - -u32 SymbolMap::GetSymbolAddr(int i) const -{ - return entries[i].vaddress; -} - -u32 SymbolMap::GetSymbolSize(int i) const -{ - return entries[i].size; -} - -int SymbolMap::FindSymbol(const char *name) const -{ - lock_guard guard(lock_); - for (size_t i = 0; i < entries.size(); i++) - if (strcmp(entries[i].name,name)==0) - return (int) i; return -1; } -u32 SymbolMap::GetAddress(int num) const +u32 SymbolMap::GetDataSize(u32 startAddress) const { - return entries[num].vaddress; + auto it = data.find(startAddress); + if (it == data.end()) + return -1; + + return it->second.size; } -void SymbolMap::IncreaseRunCount(int num) +DataType SymbolMap::GetDataType(u32 startAddress) const { - entries[num].runCount++; -} + auto it = data.find(startAddress); + if (it == data.end()) + return DATATYPE_NONE; -unsigned int SymbolMap::GetRunCount(int num) const -{ - if (num>=0) - return entries[num].runCount; - else - return 0; -} - -// Load an elf with symbols, use SymbolMap::compilefuncsignaturesfile -// to make a symbol map, load a dol or somethin without symbols, then apply -// the map with SymbolMap::usefuncsignaturesfile. - -void SymbolMap::CompileFuncSignaturesFile(const char *filename) const -{ - // Store name,length,first instruction,hash into file - FILE *f = File::OpenCFile(filename, "w"); - fprintf(f,"00000000\n"); - int count=0; - for (auto it = entries.begin(), end = entries.end(); it != end; ++it) - { - const MapEntry &entry = *it; - int size = entry.size; - if (size >= 16 && entry.type == ST_FUNCTION) - { - u32 inst = Memory::Read_Instruction(entry.vaddress).encoding; //try to make a bigger number of different vals sometime - if (inst != 0) - { - char temp[64]; - strncpy(temp,entry.name,63); - fprintf(f, "%08x\t%08x\t%08x\t%s\n", inst, size, ComputeHash(entry.vaddress,size), temp); - count++; - } - } - } - fseek(f,0,SEEK_SET); - fprintf(f,"%08x",count); - fclose(f); + return it->second.type; } -struct Sig + +#ifdef _WIN32 + +struct DefaultSymbol { - u32 inst; - u32 size; - u32 hash; - char name[64]; - Sig(){} - Sig(u32 _inst, u32 _size, u32 _hash, char *_name) : inst(_inst), size(_size), hash(_hash) - { - strncpy(name,_name,63); - } - bool operator <(const Sig &other) const { - return inst < other.inst; - } + u32 address; + const char* name; }; -std::vector sigs; +static const DefaultSymbol defaultSymbols[]= { + { 0x08800000, "User memory" }, + { 0x08804000, "Default load address" }, + { 0x04000000, "VRAM" }, + { 0x88000000, "Kernel memory" }, + { 0x00010000, "Scratchpad" }, +}; -typedef std::map Sigmap; -Sigmap sigmap; - -void SymbolMap::UseFuncSignaturesFile(const char *filename, u32 maxAddress) +void SymbolMap::FillSymbolListBox(HWND listbox,SymbolType symType) const { - sigs.clear(); - // symbolMap.Clear(); - //#1: Read the signature file and put them in a fast data structure - FILE *f = File::OpenCFile(filename, "r"); - int count; - if (fscanf(f, "%08x\n", &count) != 1) - count = 0; - char name[256]; - for (int a=0; asecond; - while (true) + for (auto it = functions.begin(), end = functions.end(); it != end; ++it) { - if (sig->inst != inst) - break; - - u32 hash = ComputeHash(addr,sig->size); - if (hash==sig->hash) - { - //MATCH!!!! - MapEntry e; - e.address=addr; - e.size= sig->size; - e.vaddress = addr; - e.type=ST_FUNCTION; - strcpy(e.name,sig->name); - addr+=sig->size-4; //don't need to check function interior - entries.push_back(e); - uniqueEntries.insert((const MapEntryUniqueInfo)e); - entryRanges[e.vaddress + e.size] = e.vaddress; - break; - } - sig++; + const FunctionEntry& entry = it->second; + const char* name = GetLabelName(it->first); + + if (name != NULL) + wsprintf(temp, L"%S", name); + else + wsprintf(temp, L"0x%08X", it->first); + + int index = ListBox_AddString(listbox,temp); + ListBox_SetItemData(listbox,index,it->first); } } + break; + + case ST_DATA: + { + int count = ARRAYSIZE(defaultSymbols)+(int)data.size(); + SendMessage(listbox, LB_INITSTORAGE, (WPARAM)count, (LPARAM)count * 30); + + for (int i = 0; i < ARRAYSIZE(defaultSymbols); i++) + { + wsprintf(temp, L"0x%08X (%S)", defaultSymbols[i].address, defaultSymbols[i].name); + int index = ListBox_AddString(listbox,temp); + ListBox_SetItemData(listbox,index,defaultSymbols[i].address); + } + + for (auto it = data.begin(), end = data.end(); it != end; ++it) + { + const DataEntry& entry = it->second; + const char* name = GetLabelName(it->first); + + if (name != NULL) + wsprintf(temp, L"%S", name); + else + wsprintf(temp, L"0x%08X", it->first); + + int index = ListBox_AddString(listbox,temp); + ListBox_SetItemData(listbox,index,it->first); + } + } + break; } - //ensure code coloring even if symbols were loaded before - SymbolMap::SortSymbols(); + + SendMessage(listbox, WM_SETREDRAW, TRUE, 0); + RedrawWindow(listbox, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); } + +void SymbolMap::FillSymbolComboBox(HWND comboxBox, SymbolType symType) const +{ + wchar_t temp[256]; + lock_guard guard(lock_); + + SendMessage(comboxBox, WM_SETREDRAW, FALSE, 0); + ComboBox_ResetContent(comboxBox); + + switch (symType) + { + case ST_FUNCTION: + { + SendMessage(comboxBox, CB_INITSTORAGE, (WPARAM)functions.size(), (LPARAM)functions.size() * 30); + + for (auto it = functions.begin(), end = functions.end(); it != end; ++it) + { + const FunctionEntry& entry = it->second; + const char* name = GetLabelName(it->first); + + if (name != NULL) + wsprintf(temp, L"%S", name); + else + wsprintf(temp, L"0x%08X", it->first); + + int index = ComboBox_AddString(comboxBox,temp); + ComboBox_SetItemData(comboxBox,index,it->first); + } + } + break; + + case ST_DATA: + { + int count = ARRAYSIZE(defaultSymbols)+(int)data.size(); + SendMessage(comboxBox, CB_INITSTORAGE, (WPARAM)count, (LPARAM)count * 30); + + for (int i = 0; i < ARRAYSIZE(defaultSymbols); i++) + { + wsprintf(temp, L"0x%08X (%S)", defaultSymbols[i].address, defaultSymbols[i].name); + int index = ComboBox_AddString(comboxBox,temp); + ComboBox_SetItemData(comboxBox,index,defaultSymbols[i].address); + } + + for (auto it = data.begin(), end = data.end(); it != end; ++it) + { + const DataEntry& entry = it->second; + const char* name = GetLabelName(it->first); + + if (name != NULL) + wsprintf(temp, L"%S", name); + else + wsprintf(temp, L"0x%08X", it->first); + + int index = ComboBox_AddString(comboxBox,temp); + ComboBox_SetItemData(comboxBox,index,it->first); + } + } + break; + } + + SendMessage(comboxBox, WM_SETREDRAW, TRUE, 0); + RedrawWindow(comboxBox, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); +} + +#endif diff --git a/Core/Debugger/SymbolMap.h b/Core/Debugger/SymbolMap.h index 6260932576..80efc2d297 100644 --- a/Core/Debugger/SymbolMap.h +++ b/Core/Debugger/SymbolMap.h @@ -24,15 +24,20 @@ #include enum SymbolType { + ST_NONE=0, ST_FUNCTION=1, - ST_DATA=2 + ST_DATA=2, + ST_ALL=3 }; struct SymbolInfo { + SymbolType type; u32 address; u32 size; }; +enum DataType { DATATYPE_NONE, DATATYPE_BYTE, DATATYPE_HALFWORD, DATATYPE_WORD }; + #ifdef _WIN32 struct HWND__; typedef struct HWND__ *HWND; @@ -41,75 +46,63 @@ typedef struct HWND__ *HWND; class SymbolMap { public: SymbolMap() {} + void Clear(); + void SortSymbols(); + bool LoadSymbolMap(const char *filename); void SaveSymbolMap(const char *filename) const; bool LoadNocashSym(const char *ilename); - void AddSymbol(const char *symbolname, unsigned int vaddress, size_t size, SymbolType symbol); - void RemoveSymbolNum(int symbolnum); - void Clear(); - void AnalyzeBackwards(); - int GetSymbolNum(unsigned int address, SymbolType symmask=ST_FUNCTION) const; + + SymbolType GetSymbolType(u32 address) const; bool GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask = ST_FUNCTION) const; - u32 GetNextSymbolAddress(u32 address); + u32 GetNextSymbolAddress(u32 address, SymbolType symmask); const char *GetDescription(unsigned int address) const; + #ifdef _WIN32 - void FillSymbolListBox(HWND listbox, SymbolType symmask=ST_FUNCTION) const; - void FillSymbolComboBox(HWND listbox,SymbolType symmask=ST_FUNCTION) const; - void FillListBoxBLinks(HWND listbox, int num) const; + void FillSymbolListBox(HWND listbox, SymbolType symType) const; + void FillSymbolComboBox(HWND listbox,SymbolType symType) const; #endif - int GetNumSymbols() const; - const char *GetSymbolName(int i) const; - void SetSymbolName(int i, const char *newname); - void SetSymbolSize(int i, int newSize); - u32 GetSymbolSize(int i) const; - u32 GetSymbolAddr(int i) const; - SymbolType GetSymbolType(int i) const; - int FindSymbol(const char *name) const; - u32 GetAddress(int num) const; - void IncreaseRunCount(int num); - unsigned int GetRunCount(int num) const; - void SortSymbols(); - void UseFuncSignaturesFile(const char *filename, u32 maxAddress); - void CompileFuncSignaturesFile(const char *filename) const; + void AddFunction(const char* name, u32 address, u32 size); + u32 GetFunctionStart(u32 address) const; + int GetFunctionNum(u32 address) const; + u32 GetFunctionSize(u32 startAddress) const; + bool SetFunctionSize(u32 startAddress, u32 newSize); + bool RemoveFunction(u32 startAddress, bool removeName); - const char* AddLabel(const char* name, u32 address); - const char* GetLabelName(u32 address); + void AddLabel(const char* name, u32 address); + void SetLabelName(const char* name, u32 address); + const char* GetLabelName(u32 address) const; bool GetLabelValue(const char* name, u32& dest); -private: - struct MapEntryUniqueInfo { - u32 address; - u32 vaddress; - u32 size; - SymbolType type; - bool operator < (const MapEntryUniqueInfo &other) const { - return vaddress < other.vaddress; - } + void AddData(u32 address, u32 size, DataType type); + u32 GetDataStart(u32 address) const; + u32 GetDataSize(u32 startAddress) const; + DataType GetDataType(u32 startAddress) const; +private: + void AssignFunctionIndices(); + + struct FunctionEntry + { + u32 size; + int index; }; - struct Label + struct LabelEntry { char name[128]; }; - struct MapEntry : public MapEntryUniqueInfo { - char name[128]; - u32 unknown; - u32 runCount; - -#ifdef BWLINKS - std::vector backwardLinks; -#endif - void UndecorateName() { - // TODO - } + struct DataEntry + { + DataType type; + u32 size; }; - - std::map labels; - std::set uniqueEntries; - std::vector entries; - std::map entryRanges; + + std::map functions; + std::map labels; + std::map data; + mutable recursive_mutex lock_; }; diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index 6e47053b9a..0f2a29f9be 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -592,18 +592,18 @@ bool ElfReader::LoadSymbols() if (bRelocate) value += sectionAddrs[sectionIndex]; - SymbolType symtype = ST_DATA; switch (type) { case STT_OBJECT: - symtype = ST_DATA; break; + symbolMap.AddData(value,size,DATATYPE_BYTE); + break; case STT_FUNC: - symtype = ST_FUNCTION; break; + symbolMap.AddFunction(name,value,size); + break; default: continue; } - symbolMap.AddSymbol(name, value, size, symtype); hasSymbols = true; //... } diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index e023c81050..80dc46cc33 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -257,7 +257,7 @@ public: // Add the symbol to the symbol map for debugging. char temp[256]; sprintf(temp,"zz_%s", GetFuncName(func.moduleName, func.nid)); - symbolMap.AddSymbol(temp, func.stubAddr, 8, ST_FUNCTION); + symbolMap.AddFunction(temp,func.stubAddr,8); // Keep track and actually hook it up if possible. importedFuncs.push_back(func); diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index ff7d0f9121..6af55b0af3 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -248,7 +248,7 @@ namespace MIPSAnalyst { u32 addr; for (addr = startAddr; addr <= endAddr; addr+=4) { SymbolInfo syminfo; - if (symbolMap.GetSymbolInfo(&syminfo, addr, ST_FUNCTION) && syminfo.size >= 4) { + if (symbolMap.GetSymbolInfo(&syminfo, addr, ST_FUNCTION)) { addr = syminfo.address + syminfo.size; continue; } @@ -302,7 +302,7 @@ namespace MIPSAnalyst { (*iter).size = ((*iter).end-(*iter).start+4); char temp[256]; sprintf(temp,"z_un_%08x",(*iter).start); - symbolMap.AddSymbol(std::string(temp).c_str(), (*iter).start,(*iter).end-(*iter).start+4,ST_FUNCTION); + symbolMap.AddFunction(temp,(*iter).start,(*iter).end-(*iter).start+4); } HashFunctions(); } diff --git a/Core/MIPS/MIPSDebugInterface.cpp b/Core/MIPS/MIPSDebugInterface.cpp index 4e8f5a7fda..0819eebc82 100644 --- a/Core/MIPS/MIPSDebugInterface.cpp +++ b/Core/MIPS/MIPSDebugInterface.cpp @@ -221,8 +221,8 @@ void MIPSDebugInterface::toggleBreakpoint(unsigned int address) int MIPSDebugInterface::getColor(unsigned int address) { int colors[6] = {0xe0FFFF,0xFFe0e0,0xe8e8FF,0xFFe0FF,0xe0FFe0,0xFFFFe0}; - int n=symbolMap.GetSymbolNum(address); - if (n==-1 || symbolMap.GetSymbolSize(n) < 4) return 0xFFFFFF; + int n=symbolMap.GetFunctionNum(address); + if (n==-1) return 0xFFFFFF; return colors[n%6]; } const char *MIPSDebugInterface::getDescription(unsigned int address) diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 0f8d10d80d..78d6b40f51 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -497,10 +497,10 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) } if (line.params.size() != 0) - TextOutA(hdc,pixelPositions.argumentsStart,rowY1+2,line.params.c_str(),line.params.size()); + TextOutA(hdc,pixelPositions.argumentsStart,rowY1+2,line.params.c_str(),(int)line.params.size()); SelectObject(hdc,boldfont); - TextOutA(hdc,pixelPositions.opcodeStart,rowY1+2,line.name.c_str(),line.name.size()); + TextOutA(hdc,pixelPositions.opcodeStart,rowY1+2,line.name.c_str(),(int)line.name.size()); SelectObject(hdc,font); address += line.totalSize; @@ -899,17 +899,17 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) break; case ID_DISASM_RENAMEFUNCTION: { - int sym = symbolMap.GetSymbolNum(curAddress); - if (sym != -1) + u32 funcBegin = symbolMap.GetFunctionStart(curAddress); + if (funcBegin != -1) { char name[256]; std::string newname; - strncpy_s(name, symbolMap.GetSymbolName(sym),_TRUNCATE); + strncpy_s(name, symbolMap.GetLabelName(funcBegin),_TRUNCATE); if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), L"New function name", name, newname)) { - symbolMap.SetSymbolName(sym, newname.c_str()); - redraw(); + symbolMap.SetLabelName(newname.c_str(),funcBegin); SendMessage(GetParent(wnd),WM_DEB_MAPLOADED,0,0); + redraw(); } } else @@ -921,17 +921,17 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) case ID_DISASM_REMOVEFUNCTION: { char statusBarTextBuff[256]; - int sym = symbolMap.GetSymbolNum(curAddress); - if (sym != -1) + u32 funcBegin = symbolMap.GetFunctionStart(curAddress); + if (funcBegin != -1) { - u32 funcBegin = symbolMap.GetAddress(sym); - int prev = symbolMap.GetSymbolNum(funcBegin - 1); - if (prev != -1) + u32 prevBegin = symbolMap.GetFunctionStart(funcBegin-1); + if (prevBegin != -1) { - int expandedSize = symbolMap.GetSymbolSize(prev) + symbolMap.GetSymbolSize(sym); - symbolMap.SetSymbolSize(prev, expandedSize); + u32 expandedSize = symbolMap.GetFunctionSize(prevBegin)+symbolMap.GetFunctionSize(funcBegin); + symbolMap.SetFunctionSize(prevBegin,expandedSize); } - symbolMap.RemoveSymbolNum(sym); + + symbolMap.RemoveFunction(funcBegin,true); SendMessage(GetParent(wnd), WM_DEB_MAPLOADED, 0, 0); } else @@ -945,10 +945,10 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) case ID_DISASM_ADDFUNCTION: { char statusBarTextBuff[256]; - int sym = symbolMap.GetSymbolNum(curAddress); - if (sym != -1) + u32 prevBegin = symbolMap.GetFunctionStart(curAddress); + if (prevBegin != -1) { - if (symbolMap.GetAddress(sym) == curAddress) + if (prevBegin == curAddress) { snprintf(statusBarTextBuff,256, "WARNING: There's already a function entry point at this adress"); SendMessage(GetParent(wnd), WM_DEB_SETSTATUSBARTEXT, 0, (LPARAM) statusBarTextBuff); @@ -956,14 +956,14 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) else { char symname[128]; - int prevSize = symbolMap.GetSymbolSize(sym); - u32 prevAddr = symbolMap.GetSymbolAddr(sym); - int newSize = curAddress - prevAddr; - symbolMap.SetSymbolSize(sym, newSize); - newSize = prevSize - newSize; + u32 prevSize = symbolMap.GetFunctionSize(prevBegin); + u32 newSize = curAddress-prevBegin; + symbolMap.SetFunctionSize(prevBegin,newSize); + + newSize = prevSize-newSize; snprintf(symname,128,"u_un_%08X",curAddress); - symbolMap.AddSymbol(symname, curAddress, newSize, ST_FUNCTION); - symbolMap.SortSymbols(); + symbolMap.AddFunction(symname,curAddress,newSize); + SendMessage(GetParent(wnd), WM_DEB_MAPLOADED, 0, 0); } } diff --git a/Windows/Debugger/CtrlRegisterList.cpp b/Windows/Debugger/CtrlRegisterList.cpp index b274127f7c..02d006788d 100644 --- a/Windows/Debugger/CtrlRegisterList.cpp +++ b/Windows/Debugger/CtrlRegisterList.cpp @@ -300,24 +300,6 @@ void CtrlRegisterList::onPaint(WPARAM wParam, LPARAM lParam) SetTextColor(hdc,0x004000); TextOutA(hdc,77,rowY1,temp,(int)strlen(temp)); } - - /* - } - SetTextColor(hdc,0x007000); - - TextOut(hdc,70,rowY1,dis,strlen(dis)); - if (desc[0]==0) - strcpy(desc,debugger->getDescription(address)); - SetTextColor(hdc,0x0000FF); - //char temp[256]; - //UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE); - if (strlen(desc)) - TextOut(hdc,280,rowY1,desc,strlen(desc)); - if (debugger->isBreakpoint(address)) - { - DrawIconEx(hdc,2,rowY1,breakPoint,32,32,0,0,DI_NORMAL); - } - }*/ } SelectObject(hdc,oldFont); diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index cdea3fce0d..994d6adbd9 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -513,35 +513,6 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) case IDC_MEMCHECK: SendMessage(m_hDlg,WM_COMMAND,ID_DEBUG_ADDBREAKPOINT,0); break; - case IDC_UPDATECALLSTACK: - { - HWND hDlg = m_hDlg; - HWND list = GetDlgItem(hDlg,IDC_CALLSTACK); - ComboBox_ResetContent(list); - - u32 pc = currentMIPS->pc; - u32 ra = currentMIPS->r[MIPS_REG_RA]; - DWORD addr = Memory::ReadUnchecked_U32(pc); - int count=1; - ComboBox_SetItemData(list, ComboBox_AddString(list, ConvertUTF8ToWString(symbolMap.GetDescription(pc)).c_str()), pc); - if (symbolMap.GetDescription(pc) != symbolMap.GetDescription(ra)) - { - ComboBox_SetItemData(list, ComboBox_AddString(list, ConvertUTF8ToWString(symbolMap.GetDescription(ra)).c_str()), ra); - count++; - } - //walk the stack chain - while (addr != 0xFFFFFFFF && addr!=0 && count++<20) - { - DWORD fun = Memory::ReadUnchecked_U32(addr+4); - const wchar_t *str = ConvertUTF8ToWString(symbolMap.GetDescription(fun)).c_str(); - if (wcslen(str) == 0) - str = L"(unknown)"; - ComboBox_SetItemData(list, ComboBox_AddString(list,str), fun); - addr = Memory::ReadUnchecked_U32(addr); - } - ComboBox_SetCurSel(list,0); - } - break; case IDC_GOTOPC: { @@ -557,18 +528,10 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) } break; - case IDC_BACKWARDLINKS: - { - HWND box = GetDlgItem(m_hDlg, IDC_FUNCTIONLIST); - int funcnum = symbolMap.GetSymbolNum(ListBox_GetItemData(box,ListBox_GetCurSel(box))); - if (funcnum!=-1) - symbolMap.FillListBoxBLinks(box,funcnum); - break; - } - case IDC_ALLFUNCTIONS: { symbolMap.FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION); + symbolMap.FillSymbolComboBox(GetDlgItem(m_hDlg, IDC_GOTOINT),ST_FUNCTION); break; } default: @@ -817,6 +780,7 @@ void CDisasm::SetDebugMode(bool _bDebug, bool switchPC) void CDisasm::NotifyMapLoaded() { symbolMap.FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION); + symbolMap.FillSymbolComboBox(GetDlgItem(m_hDlg, IDC_GOTOINT),ST_FUNCTION); CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); ptr->clearFunctions(); ptr->redraw(); diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 09da666360..4dd493e34b 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -250,11 +250,6 @@ void WindowsHost::SaveSymbolMap() symbolMap.SaveSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart.c_str(),".map").c_str()); } -void WindowsHost::AddSymbol(std::string name, u32 addr, u32 size, int type=0) -{ - symbolMap.AddSymbol(name.c_str(), addr, size, (SymbolType)type); -} - bool WindowsHost::IsDebuggingEnabled() { #ifdef _DEBUG diff --git a/Windows/WindowsHost.h b/Windows/WindowsHost.h index dc235f8edf..2368886817 100644 --- a/Windows/WindowsHost.h +++ b/Windows/WindowsHost.h @@ -40,8 +40,6 @@ public: virtual void UpdateScreen(); void SetDebugMode(bool mode); - void AddSymbol(std::string name, u32 addr, u32 size, int type); - bool InitGL(std::string *error_message); void PollControllers(InputState &input_state); void ShutdownGL(); diff --git a/Windows/resource.h b/Windows/resource.h index cce8701c05..83146d83c0 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -12,7 +12,6 @@ #define IDC_STEPOVER 108 #define IDC_TABDATATYPE 109 #define IDC_CALLSTACK 110 -#define IDC_UPDATECALLSTACK 111 #define ID_MEMVIEW_GOTOINDISASM 112 #define ID_DISASM_DYNARECRESULTS 113 #define IDI_PPSSPP 115 @@ -105,7 +104,6 @@ #define IDC_GOTOLR 1070 #define IDC_GOTOINT 1071 #define IDC_MEMSORT 1073 -#define IDC_BACKWARDLINKS 1074 #define IDC_ALLFUNCTIONS 1075 #define IDC_RESULTS 1093 #define IDC_SYMBOLS 1097