u32 SymbolMap::GetDataStart(u32 address) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); auto it = activeData.upper_bound(address); if (it == activeData.end()) { // check last element auto rit = activeData.rbegin(); if (rit != activeData.rend()) { 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 INVALID_ADDRESS; } if (it != activeData.begin()) { it--; u32 start = it->first; u32 size = it->second.size; if (start <= address && start+size > address) return start; } return INVALID_ADDRESS; }
std::vector<SymbolEntry> SymbolMap::GetAllSymbols(SymbolType symmask) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::vector<SymbolEntry> result; if (symmask & ST_FUNCTION) { std::lock_guard<std::recursive_mutex> guard(lock_); for (auto it = activeFunctions.begin(); it != activeFunctions.end(); it++) { SymbolEntry entry; entry.address = it->first; entry.size = GetFunctionSize(entry.address); const char* name = GetLabelName(entry.address); if (name != NULL) entry.name = name; result.push_back(entry); } } if (symmask & ST_DATA) { std::lock_guard<std::recursive_mutex> guard(lock_); for (auto it = activeData.begin(); it != activeData.end(); it++) { SymbolEntry entry; entry.address = it->first; entry.size = GetDataSize(entry.address); const char* name = GetLabelName(entry.address); if (name != NULL) entry.name = name; result.push_back(entry); } } return result; }
bool SymbolMap::RemoveFunction(u32 startAddress, bool removeName) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); auto it = activeFunctions.find(startAddress); if (it == activeFunctions.end()) return false; auto symbolKey = std::make_pair(it->second.module, it->second.start); auto it2 = functions.find(symbolKey); if (it2 != functions.end()) { functions.erase(it2); } activeFunctions.erase(it); if (removeName) { auto labelIt = activeLabels.find(startAddress); if (labelIt != activeLabels.end()) { symbolKey = std::make_pair(labelIt->second.module, labelIt->second.addr); auto labelIt2 = labels.find(symbolKey); if (labelIt2 != labels.end()) { labels.erase(labelIt2); } activeLabels.erase(labelIt); } } return true; }
void SymbolMap::FillSymbolListBox(HWND listbox,SymbolType symType) { if (activeNeedUpdate_) UpdateActiveSymbols(); wchar_t temp[256]; std::lock_guard<std::recursive_mutex> guard(lock_); SendMessage(listbox, WM_SETREDRAW, FALSE, 0); ListBox_ResetContent(listbox); switch (symType) { case ST_FUNCTION: { SendMessage(listbox, LB_INITSTORAGE, (WPARAM)activeFunctions.size(), (LPARAM)activeFunctions.size() * 30); for (auto it = activeFunctions.begin(), end = activeFunctions.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 = ListBox_AddString(listbox,temp); ListBox_SetItemData(listbox,index,it->first); } } break; case ST_DATA: { int count = ARRAYSIZE(defaultSymbols)+(int)activeData.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 = activeData.begin(), end = activeData.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; } SendMessage(listbox, WM_SETREDRAW, TRUE, 0); RedrawWindow(listbox, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); }
u32 SymbolMap::GetDataSize(u32 startAddress) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); auto it = activeData.find(startAddress); if (it == activeData.end()) return INVALID_ADDRESS; return it->second.size; }
u32 SymbolMap::GetDataModuleAddress(u32 startAddress) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); auto it = activeData.find(startAddress); if (it == activeData.end()) return INVALID_ADDRESS; return GetModuleAbsoluteAddr(0, it->second.module); }
DataType SymbolMap::GetDataType(u32 startAddress) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); auto it = activeData.find(startAddress); if (it == activeData.end()) return DATATYPE_NONE; return it->second.type; }
u32 SymbolMap::FindPossibleFunctionAtAfter(u32 address) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); auto it = activeFunctions.lower_bound(address); if (it == activeFunctions.end()) { return (u32)-1; } return it->first; }
SymbolType SymbolMap::GetSymbolType(u32 address) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); if (activeFunctions.find(address) != activeFunctions.end()) return ST_FUNCTION; if (activeData.find(address) != activeData.end()) return ST_DATA; return ST_NONE; }
const char *SymbolMap::GetLabelName(u32 address) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); auto it = activeLabels.find(address); if (it == activeLabels.end()) return NULL; return it->second.name; }
void SymbolMap::GetLabels(std::vector<LabelDefinition> &dest) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); for (auto it = activeLabels.begin(); it != activeLabels.end(); it++) { LabelDefinition entry; entry.value = it->first; entry.name = ConvertUTF8ToWString(it->second.name); dest.push_back(entry); } }
bool SymbolMap::GetLabelValue(const char* name, u32& dest) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); for (auto it = activeLabels.begin(); it != activeLabels.end(); it++) { if (strcasecmp(name, it->second.name) == 0) { dest = it->first; return true; } } return false; }
void SymbolMap::AddModule(const char *name, u32 address, u32 size) { lock_guard guard(lock_); for (auto it = modules.begin(), end = modules.end(); it != end; ++it) { if (!strcmp(it->name, name)) { // Just reactivate that one. it->start = address; it->size = size; activeModuleEnds.insert(std::make_pair(it->start + it->size, *it)); UpdateActiveSymbols(); return; } } ModuleEntry mod; strncpy(mod.name, name, ARRAY_SIZE(mod.name)); mod.start = address; mod.size = size; mod.index = (int)modules.size() + 1; modules.push_back(mod); activeModuleEnds.insert(std::make_pair(mod.start + mod.size, mod)); UpdateActiveSymbols(); }
void SymbolMap::SetLabelName(const char* name, u32 address) { lock_guard guard(lock_); auto labelInfo = activeLabels.find(address); if (labelInfo == activeLabels.end()) { AddLabel(name, address); } else { auto symbolKey = std::make_pair(labelInfo->second.module, labelInfo->second.addr); auto label = labels.find(symbolKey); if (label != labels.end()) { strcpy(label->second.name,name); label->second.name[127] = 0; UpdateActiveSymbols(); } } }
int SymbolMap::GetFunctionNum(u32 address) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); u32 start = GetFunctionStart(address); if (start == INVALID_ADDRESS) return INVALID_ADDRESS; auto it = activeFunctions.find(start); if (it == activeFunctions.end()) return INVALID_ADDRESS; return it->second.index; }
bool SymbolMap::SetFunctionSize(u32 startAddress, u32 newSize) { lock_guard guard(lock_); auto funcInfo = activeFunctions.find(startAddress); if (funcInfo != activeFunctions.end()) { auto symbolKey = std::make_pair(funcInfo->second.module, funcInfo->second.start); auto func = functions.find(symbolKey); if (func != functions.end()) { func->second.size = newSize; UpdateActiveSymbols(); } } // TODO: check for overlaps return true; }
u32 SymbolMap::GetNextSymbolAddress(u32 address, SymbolType symmask) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); const auto functionEntry = symmask & ST_FUNCTION ? activeFunctions.upper_bound(address) : activeFunctions.end(); const auto dataEntry = symmask & ST_DATA ? activeData.upper_bound(address) : activeData.end(); if (functionEntry == activeFunctions.end() && dataEntry == activeData.end()) return INVALID_ADDRESS; u32 funcAddress = (functionEntry != activeFunctions.end()) ? functionEntry->first : 0xFFFFFFFF; u32 dataAddress = (dataEntry != activeData.end()) ? dataEntry->first : 0xFFFFFFFF; if (funcAddress <= dataAddress) return funcAddress; else return dataAddress; }
bool SymbolMap::SetFunctionSize(u32 startAddress, u32 newSize) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); auto funcInfo = activeFunctions.find(startAddress); if (funcInfo != activeFunctions.end()) { auto symbolKey = std::make_pair(funcInfo->second.module, funcInfo->second.start); auto func = functions.find(symbolKey); if (func != functions.end()) { func->second.size = newSize; activeFunctions.erase(funcInfo); activeFunctions.insert(std::make_pair(startAddress, func->second)); } } // TODO: check for overlaps return true; }
void SymbolMap::SetLabelName(const char* name, u32 address) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); auto labelInfo = activeLabels.find(address); if (labelInfo == activeLabels.end()) { AddLabel(name, address); } else { auto symbolKey = std::make_pair(labelInfo->second.module, labelInfo->second.addr); auto label = labels.find(symbolKey); if (label != labels.end()) { truncate_cpy(label->second.name, name); label->second.name[127] = 0; // Refresh the active item if it exists. auto active = activeLabels.find(address); if (active != activeLabels.end() && active->second.module == label->second.module) { activeLabels.erase(active); activeLabels.insert(std::make_pair(address, label->second)); } } } }
void SymbolMap::UnloadModule(u32 address, u32 size) { lock_guard guard(lock_); activeModuleEnds.erase(address + size); UpdateActiveSymbols(); }