mirror of https://github.com/PCSX2/pcsx2.git
DebugTools: Simplify the symbol map
This commit is contained in:
parent
78bc0a52ea
commit
85539c7bb9
|
@ -574,7 +574,7 @@ void CpuWidget::onFuncListContextMenu(QPoint pos)
|
|||
// Resolve the function name by fetching the symbolmap and filtering the address
|
||||
|
||||
const QListWidgetItem* selectedItem = m_ui.listFunctions->selectedItems().first();
|
||||
const QString functionName = QString(m_cpu.GetSymbolMap().GetLabelString(selectedItem->data(256).toUInt()).c_str());
|
||||
const QString functionName = QString(m_cpu.GetSymbolMap().GetLabelName(selectedItem->data(256).toUInt()).c_str());
|
||||
QApplication::clipboard()->setText(functionName);
|
||||
});
|
||||
m_funclistContextMenu->addAction(copyName);
|
||||
|
|
|
@ -219,7 +219,6 @@ void DisassemblyWidget::contextAddFunction()
|
|||
newSize = prevSize - newSize;
|
||||
m_cpu->GetSymbolMap().AddFunction(funcName.toLocal8Bit().constData(), curAddress, newSize);
|
||||
m_cpu->GetSymbolMap().SortSymbols();
|
||||
m_cpu->GetSymbolMap().UpdateActiveSymbols();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -232,7 +231,6 @@ void DisassemblyWidget::contextAddFunction()
|
|||
|
||||
m_cpu->GetSymbolMap().AddFunction(funcName.toLocal8Bit().constData(), m_selectedAddressStart, m_selectedAddressEnd + 4 - m_selectedAddressStart);
|
||||
m_cpu->GetSymbolMap().SortSymbols();
|
||||
m_cpu->GetSymbolMap().UpdateActiveSymbols();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,9 +248,8 @@ void DisassemblyWidget::contextRemoveFunction()
|
|||
m_cpu->GetSymbolMap().SetFunctionSize(previousFuncAddr, expandedSize);
|
||||
}
|
||||
|
||||
m_cpu->GetSymbolMap().RemoveFunction(curFuncAddr, true);
|
||||
m_cpu->GetSymbolMap().RemoveFunction(curFuncAddr);
|
||||
m_cpu->GetSymbolMap().SortSymbols();
|
||||
m_cpu->GetSymbolMap().UpdateActiveSymbols();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +259,7 @@ void DisassemblyWidget::contextRenameFunction()
|
|||
if (curFuncAddress != SymbolMap::INVALID_ADDRESS)
|
||||
{
|
||||
bool ok;
|
||||
QString funcName = QInputDialog::getText(this, tr("Rename Function"), tr("Function name"), QLineEdit::Normal, m_cpu->GetSymbolMap().GetLabelString(curFuncAddress).c_str(), &ok);
|
||||
QString funcName = QInputDialog::getText(this, tr("Rename Function"), tr("Function name"), QLineEdit::Normal, m_cpu->GetSymbolMap().GetLabelName(curFuncAddress).c_str(), &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
|
@ -274,7 +271,6 @@ void DisassemblyWidget::contextRenameFunction()
|
|||
{
|
||||
m_cpu->GetSymbolMap().SetLabelName(funcName.toLocal8Bit().constData(), curFuncAddress);
|
||||
m_cpu->GetSymbolMap().SortSymbols();
|
||||
m_cpu->GetSymbolMap().UpdateActiveSymbols();
|
||||
this->repaint();
|
||||
}
|
||||
}
|
||||
|
@ -713,7 +709,7 @@ inline QString DisassemblyWidget::DisassemblyStringFromAddress(u32 address, QFon
|
|||
const bool isConditionalMet = line.info.conditionMet;
|
||||
const bool isCurrentPC = m_cpu->getPC() == address;
|
||||
|
||||
const std::string addressSymbol = m_cpu->GetSymbolMap().GetLabelString(address);
|
||||
const std::string addressSymbol = m_cpu->GetSymbolMap().GetLabelName(address);
|
||||
|
||||
const auto demangler = demangler::CDemangler::createGcc();
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
|
|||
case BreakpointColumns::OFFSET:
|
||||
return QtUtils::FilledQStringFromValue(bp->addr, 16);
|
||||
case BreakpointColumns::SIZE_LABEL:
|
||||
return m_cpu.GetSymbolMap().GetLabelString(bp->addr).c_str();
|
||||
return m_cpu.GetSymbolMap().GetLabelName(bp->addr).c_str();
|
||||
case BreakpointColumns::OPCODE:
|
||||
// Note: Fix up the disassemblymanager so we can use it here, instead of calling a function through the disassemblyview (yuck)
|
||||
return m_cpu.disasm(bp->addr, true).c_str();
|
||||
|
@ -111,7 +111,7 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
|
|||
case BreakpointColumns::OFFSET:
|
||||
return bp->addr;
|
||||
case BreakpointColumns::SIZE_LABEL:
|
||||
return m_cpu.GetSymbolMap().GetLabelString(bp->addr).c_str();
|
||||
return m_cpu.GetSymbolMap().GetLabelName(bp->addr).c_str();
|
||||
case BreakpointColumns::OPCODE:
|
||||
// Note: Fix up the disassemblymanager so we can use it here, instead of calling a function through the disassemblyview (yuck)
|
||||
return m_cpu.disasm(bp->addr, true).c_str();
|
||||
|
@ -157,7 +157,7 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
|
|||
case BreakpointColumns::OFFSET:
|
||||
return QtUtils::FilledQStringFromValue(bp->addr, 16);
|
||||
case BreakpointColumns::SIZE_LABEL:
|
||||
return m_cpu.GetSymbolMap().GetLabelString(bp->addr).c_str();
|
||||
return m_cpu.GetSymbolMap().GetLabelName(bp->addr).c_str();
|
||||
case BreakpointColumns::OPCODE:
|
||||
// Note: Fix up the disassemblymanager so we can use it here, instead of calling a function through the disassemblyview (yuck)
|
||||
return m_cpu.disasm(bp->addr, true).c_str();
|
||||
|
|
|
@ -47,7 +47,7 @@ QVariant StackModel::data(const QModelIndex& index, int role) const
|
|||
case StackModel::ENTRY:
|
||||
return QtUtils::FilledQStringFromValue(stackFrame.entry, 16);
|
||||
case StackModel::ENTRY_LABEL:
|
||||
return m_cpu.GetSymbolMap().GetLabelString(stackFrame.entry).c_str();
|
||||
return m_cpu.GetSymbolMap().GetLabelName(stackFrame.entry).c_str();
|
||||
case StackModel::PC:
|
||||
return QtUtils::FilledQStringFromValue(stackFrame.pc, 16);
|
||||
case StackModel::PC_OPCODE:
|
||||
|
@ -66,7 +66,7 @@ QVariant StackModel::data(const QModelIndex& index, int role) const
|
|||
case StackModel::ENTRY:
|
||||
return stackFrame.entry;
|
||||
case StackModel::ENTRY_LABEL:
|
||||
return m_cpu.GetSymbolMap().GetLabelString(stackFrame.entry).c_str();
|
||||
return m_cpu.GetSymbolMap().GetLabelName(stackFrame.entry).c_str();
|
||||
case StackModel::PC:
|
||||
return stackFrame.pc;
|
||||
case StackModel::PC_OPCODE:
|
||||
|
|
|
@ -305,7 +305,7 @@ void CDVDsys_SetFile(CDVD_SourceType srctype, std::string newfile)
|
|||
symName = m_SourceFilename[enum_cast(srctype)].substr(0, n) + ".sym";
|
||||
|
||||
R5900SymbolMap.LoadNocashSym(symName.c_str());
|
||||
R5900SymbolMap.UpdateActiveSymbols();
|
||||
R5900SymbolMap.SortSymbols();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ static void parseDisasm(SymbolMap& map, const char* disasm, char* opcode, char*
|
|||
u32 branchTarget;
|
||||
sscanf(disasm+3,"0x%08x",&branchTarget);
|
||||
|
||||
const std::string addressSymbol = map.GetLabelString(branchTarget);
|
||||
const std::string addressSymbol = map.GetLabelName(branchTarget);
|
||||
if (!addressSymbol.empty() && insertSymbols)
|
||||
{
|
||||
arguments += std::snprintf(arguments, arguments_size, "%s",addressSymbol.c_str());
|
||||
|
@ -777,7 +777,7 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo& dest, bool
|
|||
case MACRO_LI:
|
||||
dest.name = name;
|
||||
|
||||
addressSymbol = cpu->GetSymbolMap().GetLabelString(immediate);
|
||||
addressSymbol = cpu->GetSymbolMap().GetLabelName(immediate);
|
||||
if (!addressSymbol.empty() && insertSymbols)
|
||||
{
|
||||
std::snprintf(buffer,std::size(buffer),"%s,%s",cpu->getRegisterName(0,rt),addressSymbol.c_str());
|
||||
|
@ -793,7 +793,7 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo& dest, bool
|
|||
case MACRO_MEMORYIMM:
|
||||
dest.name = name;
|
||||
|
||||
addressSymbol = cpu->GetSymbolMap().GetLabelString(immediate);
|
||||
addressSymbol = cpu->GetSymbolMap().GetLabelName(immediate);
|
||||
if (!addressSymbol.empty() && insertSymbols)
|
||||
{
|
||||
std::snprintf(buffer,std::size(buffer),"%s,%s",cpu->getRegisterName(0,rt),addressSymbol.c_str());
|
||||
|
@ -988,7 +988,7 @@ void DisassemblyData::createLines()
|
|||
case DATATYPE_WORD:
|
||||
{
|
||||
value = memRead32(pos);
|
||||
const std::string label = cpu->GetSymbolMap().GetLabelString(value);
|
||||
const std::string label = cpu->GetSymbolMap().GetLabelName(value);
|
||||
if (!label.empty())
|
||||
std::snprintf(buffer,std::size(buffer),"%s",label.c_str());
|
||||
else
|
||||
|
|
|
@ -26,35 +26,34 @@ SymbolMap R3000SymbolMap;
|
|||
#define strcasecmp stricmp
|
||||
#endif
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof((x))/sizeof(*(x)))
|
||||
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof(*(x)))
|
||||
|
||||
void SymbolMap::SortSymbols() {
|
||||
void SymbolMap::SortSymbols()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
AssignFunctionIndices();
|
||||
}
|
||||
|
||||
void SymbolMap::Clear() {
|
||||
void SymbolMap::Clear()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
functions.clear();
|
||||
labels.clear();
|
||||
data.clear();
|
||||
activeFunctions.clear();
|
||||
activeLabels.clear();
|
||||
activeData.clear();
|
||||
activeModuleEnds.clear();
|
||||
modules.clear();
|
||||
}
|
||||
|
||||
|
||||
bool SymbolMap::LoadNocashSym(const char *filename) {
|
||||
bool SymbolMap::LoadNocashSym(const std::string& filename)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
FILE *f = FileSystem::OpenCFile(filename, "r");
|
||||
FILE* f = FileSystem::OpenCFile(filename.c_str(), "r");
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
while (!feof(f)) {
|
||||
while (!feof(f))
|
||||
{
|
||||
char line[256], value[256] = {0};
|
||||
char *p = fgets(line, 256, f);
|
||||
char* p = fgets(line, 256, f);
|
||||
if (p == NULL)
|
||||
break;
|
||||
|
||||
|
@ -64,38 +63,53 @@ bool SymbolMap::LoadNocashSym(const char *filename) {
|
|||
if (address == 0 && strcmp(value, "0") == 0)
|
||||
continue;
|
||||
|
||||
if (value[0] == '.') {
|
||||
if (value[0] == '.')
|
||||
{
|
||||
// data directives
|
||||
char* s = strchr(value, ':');
|
||||
if (s != NULL) {
|
||||
if (s != NULL)
|
||||
{
|
||||
*s = 0;
|
||||
|
||||
u32 size = 0;
|
||||
if (sscanf(s + 1, "%04X", &size) != 1)
|
||||
continue;
|
||||
|
||||
if (strcasecmp(value, ".byt") == 0) {
|
||||
if (strcasecmp(value, ".byt") == 0)
|
||||
{
|
||||
AddData(address, size, DATATYPE_BYTE, 0);
|
||||
} else if (strcasecmp(value, ".wrd") == 0) {
|
||||
}
|
||||
else if (strcasecmp(value, ".wrd") == 0)
|
||||
{
|
||||
AddData(address, size, DATATYPE_HALFWORD, 0);
|
||||
} else if (strcasecmp(value, ".dbl") == 0) {
|
||||
}
|
||||
else if (strcasecmp(value, ".dbl") == 0)
|
||||
{
|
||||
AddData(address, size, DATATYPE_WORD, 0);
|
||||
} else if (strcasecmp(value, ".asc") == 0) {
|
||||
}
|
||||
else if (strcasecmp(value, ".asc") == 0)
|
||||
{
|
||||
AddData(address, size, DATATYPE_ASCII, 0);
|
||||
}
|
||||
}
|
||||
} else { // labels
|
||||
}
|
||||
else
|
||||
{ // labels
|
||||
int size = 1;
|
||||
char* seperator = strchr(value, ',');
|
||||
if (seperator != NULL) {
|
||||
if (seperator != NULL)
|
||||
{
|
||||
*seperator = 0;
|
||||
sscanf(seperator+1,"%08X",&size);
|
||||
sscanf(seperator + 1, "%08X", &size);
|
||||
}
|
||||
|
||||
if (size != 1) {
|
||||
AddFunction(value, address,size, 0);
|
||||
} else {
|
||||
AddLabel(value, address, 0);
|
||||
if (size != 1)
|
||||
{
|
||||
AddFunction(value, address, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLabel(value, address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,16 +118,18 @@ bool SymbolMap::LoadNocashSym(const char *filename) {
|
|||
return true;
|
||||
}
|
||||
|
||||
SymbolType SymbolMap::GetSymbolType(u32 address) const {
|
||||
SymbolType SymbolMap::GetSymbolType(u32 address) const
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
if (activeFunctions.find(address) != activeFunctions.end())
|
||||
if (functions.find(address) != functions.end())
|
||||
return ST_FUNCTION;
|
||||
if (activeData.find(address) != activeData.end())
|
||||
if (data.find(address) != data.end())
|
||||
return ST_DATA;
|
||||
return ST_NONE;
|
||||
}
|
||||
|
||||
bool SymbolMap::GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask) const {
|
||||
bool SymbolMap::GetSymbolInfo(SymbolInfo* info, u32 address, SymbolType symmask) const
|
||||
{
|
||||
u32 functionAddress = INVALID_ADDRESS;
|
||||
u32 dataAddress = INVALID_ADDRESS;
|
||||
|
||||
|
@ -123,9 +139,12 @@ bool SymbolMap::GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask)
|
|||
if (symmask & ST_DATA)
|
||||
dataAddress = GetDataStart(address);
|
||||
|
||||
if (functionAddress == INVALID_ADDRESS || dataAddress == INVALID_ADDRESS) {
|
||||
if (functionAddress != INVALID_ADDRESS) {
|
||||
if (info != NULL) {
|
||||
if (functionAddress == INVALID_ADDRESS || dataAddress == INVALID_ADDRESS)
|
||||
{
|
||||
if (functionAddress != INVALID_ADDRESS)
|
||||
{
|
||||
if (info != NULL)
|
||||
{
|
||||
info->type = ST_FUNCTION;
|
||||
info->address = functionAddress;
|
||||
info->size = GetFunctionSize(functionAddress);
|
||||
|
@ -134,8 +153,10 @@ bool SymbolMap::GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (dataAddress != INVALID_ADDRESS) {
|
||||
if (info != NULL) {
|
||||
if (dataAddress != INVALID_ADDRESS)
|
||||
{
|
||||
if (info != NULL)
|
||||
{
|
||||
info->type = ST_DATA;
|
||||
info->address = dataAddress;
|
||||
info->size = GetDataSize(dataAddress);
|
||||
|
@ -148,7 +169,8 @@ bool SymbolMap::GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask)
|
|||
}
|
||||
|
||||
// if both exist, return the function
|
||||
if (info != NULL) {
|
||||
if (info != NULL)
|
||||
{
|
||||
info->type = ST_FUNCTION;
|
||||
info->address = functionAddress;
|
||||
info->size = GetFunctionSize(functionAddress);
|
||||
|
@ -157,16 +179,17 @@ bool SymbolMap::GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask)
|
|||
return true;
|
||||
}
|
||||
|
||||
u32 SymbolMap::GetNextSymbolAddress(u32 address, SymbolType symmask) {
|
||||
u32 SymbolMap::GetNextSymbolAddress(u32 address, SymbolType symmask)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_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();
|
||||
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 == activeFunctions.end() && dataEntry == activeData.end())
|
||||
if (functionEntry == functions.end() && dataEntry == data.end())
|
||||
return INVALID_ADDRESS;
|
||||
|
||||
u32 funcAddress = (functionEntry != activeFunctions.end()) ? functionEntry->first : 0xFFFFFFFF;
|
||||
u32 dataAddress = (dataEntry != activeData.end()) ? dataEntry->first : 0xFFFFFFFF;
|
||||
u32 funcAddress = (functionEntry != functions.end()) ? functionEntry->first : 0xFFFFFFFF;
|
||||
u32 dataAddress = (dataEntry != data.end()) ? dataEntry->first : 0xFFFFFFFF;
|
||||
|
||||
if (funcAddress <= dataAddress)
|
||||
return funcAddress;
|
||||
|
@ -174,20 +197,24 @@ u32 SymbolMap::GetNextSymbolAddress(u32 address, SymbolType symmask) {
|
|||
return dataAddress;
|
||||
}
|
||||
|
||||
std::string SymbolMap::GetDescription(unsigned int address) const {
|
||||
std::string SymbolMap::GetDescription(unsigned int address) const
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
const char* labelName = NULL;
|
||||
std::string labelName;
|
||||
|
||||
u32 funcStart = GetFunctionStart(address);
|
||||
if (funcStart != INVALID_ADDRESS) {
|
||||
if (funcStart != INVALID_ADDRESS)
|
||||
{
|
||||
labelName = GetLabelName(funcStart);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 dataStart = GetDataStart(address);
|
||||
if (dataStart != INVALID_ADDRESS)
|
||||
labelName = GetLabelName(dataStart);
|
||||
}
|
||||
|
||||
if (labelName != NULL)
|
||||
if (!labelName.empty())
|
||||
return labelName;
|
||||
|
||||
char descriptionTemp[256];
|
||||
|
@ -195,31 +222,34 @@ std::string SymbolMap::GetDescription(unsigned int address) const {
|
|||
return descriptionTemp;
|
||||
}
|
||||
|
||||
std::vector<SymbolEntry> SymbolMap::GetAllSymbols(SymbolType symmask) {
|
||||
std::vector<SymbolEntry> SymbolMap::GetAllSymbols(SymbolType symmask)
|
||||
{
|
||||
std::vector<SymbolEntry> result;
|
||||
|
||||
if (symmask & ST_FUNCTION) {
|
||||
if (symmask & ST_FUNCTION)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
for (auto it = activeFunctions.begin(); it != activeFunctions.end(); it++) {
|
||||
for (auto it = functions.begin(); it != functions.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;
|
||||
entry.name = GetLabelName(entry.address);
|
||||
|
||||
result.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (symmask & ST_DATA) {
|
||||
if (symmask & ST_DATA)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
for (auto it = activeData.begin(); it != activeData.end(); it++) {
|
||||
for (auto it = data.begin(); it != data.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;
|
||||
entry.name = GetLabelName(entry.address);
|
||||
|
||||
result.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
@ -227,393 +257,179 @@ std::vector<SymbolEntry> SymbolMap::GetAllSymbols(SymbolType symmask) {
|
|||
return result;
|
||||
}
|
||||
|
||||
void SymbolMap::AddModule(const char *name, u32 address, u32 size) {
|
||||
void SymbolMap::AddFunction(const std::string& name, u32 address, u32 size)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_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;
|
||||
}
|
||||
}
|
||||
auto existing = functions.find(address);
|
||||
|
||||
ModuleEntry mod;
|
||||
strncpy(mod.name, name, ARRAY_SIZE(mod.name));
|
||||
mod.name[ARRAY_SIZE(mod.name) - 1] = 0;
|
||||
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::UnloadModule(u32 address, u32 size) {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
activeModuleEnds.erase(address + size);
|
||||
UpdateActiveSymbols();
|
||||
}
|
||||
|
||||
u32 SymbolMap::GetModuleRelativeAddr(u32 address, int moduleIndex) const {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
if (moduleIndex == -1) {
|
||||
moduleIndex = GetModuleIndex(address);
|
||||
}
|
||||
|
||||
for (auto it = modules.begin(), end = modules.end(); it != end; ++it) {
|
||||
if (it->index == moduleIndex) {
|
||||
return address - it->start;
|
||||
}
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
u32 SymbolMap::GetModuleAbsoluteAddr(u32 relative, int moduleIndex) const {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
for (auto it = modules.begin(), end = modules.end(); it != end; ++it) {
|
||||
if (it->index == moduleIndex) {
|
||||
return it->start + relative;
|
||||
}
|
||||
}
|
||||
return relative;
|
||||
}
|
||||
|
||||
int SymbolMap::GetModuleIndex(u32 address) const {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
auto iter = activeModuleEnds.upper_bound(address);
|
||||
if (iter == activeModuleEnds.end())
|
||||
return -1;
|
||||
return iter->second.index;
|
||||
}
|
||||
|
||||
bool SymbolMap::IsModuleActive(int moduleIndex) const {
|
||||
if (moduleIndex == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
for (auto it = activeModuleEnds.begin(), end = activeModuleEnds.end(); it != end; ++it) {
|
||||
if (it->second.index == moduleIndex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<LoadedModuleInfo> SymbolMap::getAllModules() const {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
|
||||
std::vector<LoadedModuleInfo> result;
|
||||
for (size_t i = 0; i < modules.size(); i++) {
|
||||
LoadedModuleInfo m;
|
||||
m.name = modules[i].name;
|
||||
m.address = modules[i].start;
|
||||
m.size = modules[i].size;
|
||||
|
||||
u32 key = modules[i].start + modules[i].size;
|
||||
m.active = activeModuleEnds.find(key) != activeModuleEnds.end();
|
||||
|
||||
result.push_back(m);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SymbolMap::AddFunction(const char* name, u32 address, u32 size, int moduleIndex) {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
|
||||
if (moduleIndex == -1) {
|
||||
moduleIndex = GetModuleIndex(address);
|
||||
}
|
||||
|
||||
// Is there an existing one?
|
||||
u32 relAddress = GetModuleRelativeAddr(address, moduleIndex);
|
||||
auto symbolKey = std::make_pair(moduleIndex, relAddress);
|
||||
auto existing = functions.find(symbolKey);
|
||||
if (existing == functions.end()) {
|
||||
// Fall back: maybe it's got moduleIndex = 0.
|
||||
existing = functions.find(std::make_pair(0, address));
|
||||
}
|
||||
|
||||
if (existing != functions.end()) {
|
||||
if (existing != functions.end())
|
||||
{
|
||||
existing->second.size = size;
|
||||
if (existing->second.module != moduleIndex) {
|
||||
existing->second.start = relAddress;
|
||||
existing->second.module = moduleIndex;
|
||||
}
|
||||
|
||||
// Refresh the active item if it exists.
|
||||
auto active = activeFunctions.find(address);
|
||||
if (active != activeFunctions.end() && active->second.module == moduleIndex) {
|
||||
activeFunctions.erase(active);
|
||||
activeFunctions.insert(std::make_pair(address, existing->second));
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
FunctionEntry func;
|
||||
func.start = relAddress;
|
||||
func.start = address;
|
||||
func.size = size;
|
||||
func.index = (int)functions.size();
|
||||
func.module = moduleIndex;
|
||||
functions[symbolKey] = func;
|
||||
functions[address] = func;
|
||||
|
||||
if (IsModuleActive(moduleIndex)) {
|
||||
activeFunctions.insert(std::make_pair(address, func));
|
||||
}
|
||||
functions.insert(std::make_pair(address, func));
|
||||
}
|
||||
|
||||
AddLabel(name, address, moduleIndex);
|
||||
AddLabel(name, address);
|
||||
}
|
||||
|
||||
u32 SymbolMap::GetFunctionStart(u32 address) const {
|
||||
u32 SymbolMap::GetFunctionStart(u32 address) const
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
auto it = activeFunctions.upper_bound(address);
|
||||
if (it == activeFunctions.end()) {
|
||||
auto it = functions.upper_bound(address);
|
||||
if (it == functions.end())
|
||||
{
|
||||
// check last element
|
||||
auto rit = activeFunctions.rbegin();
|
||||
if (rit != activeFunctions.rend()) {
|
||||
auto rit = functions.rbegin();
|
||||
if (rit != functions.rend())
|
||||
{
|
||||
u32 start = rit->first;
|
||||
u32 size = rit->second.size;
|
||||
if (start <= address && start+size > address)
|
||||
if (start <= address && start + size > address)
|
||||
return start;
|
||||
}
|
||||
// otherwise there's no function that contains this address
|
||||
return INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if (it != activeFunctions.begin()) {
|
||||
if (it != functions.begin())
|
||||
{
|
||||
it--;
|
||||
u32 start = it->first;
|
||||
u32 size = it->second.size;
|
||||
if (start <= address && start+size > address)
|
||||
if (start <= address && start + size > address)
|
||||
return start;
|
||||
}
|
||||
|
||||
return INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
u32 SymbolMap::GetFunctionSize(u32 startAddress) const {
|
||||
u32 SymbolMap::GetFunctionSize(u32 startAddress) const
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
auto it = activeFunctions.find(startAddress);
|
||||
if (it == activeFunctions.end())
|
||||
auto it = functions.find(startAddress);
|
||||
if (it == functions.end())
|
||||
return INVALID_ADDRESS;
|
||||
|
||||
return it->second.size;
|
||||
}
|
||||
|
||||
int SymbolMap::GetFunctionNum(u32 address) const {
|
||||
int SymbolMap::GetFunctionNum(u32 address) const
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
u32 start = GetFunctionStart(address);
|
||||
if (start == INVALID_ADDRESS)
|
||||
return INVALID_ADDRESS;
|
||||
|
||||
auto it = activeFunctions.find(start);
|
||||
if (it == activeFunctions.end())
|
||||
auto it = functions.find(start);
|
||||
if (it == functions.end())
|
||||
return INVALID_ADDRESS;
|
||||
|
||||
return it->second.index;
|
||||
}
|
||||
|
||||
void SymbolMap::AssignFunctionIndices() {
|
||||
void SymbolMap::AssignFunctionIndices()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
int index = 0;
|
||||
for (auto mod = activeModuleEnds.begin(), modend = activeModuleEnds.end(); mod != modend; ++mod) {
|
||||
int moduleIndex = mod->second.index;
|
||||
auto begin = functions.lower_bound(std::make_pair(moduleIndex, 0));
|
||||
auto end = functions.upper_bound(std::make_pair(moduleIndex, 0xFFFFFFFF));
|
||||
for (auto it = begin; it != end; ++it) {
|
||||
it->second.index = index++;
|
||||
}
|
||||
auto begin = functions.lower_bound(0);
|
||||
auto end = functions.upper_bound(0xFFFFFFFF);
|
||||
for (auto it = begin; it != end; ++it)
|
||||
{
|
||||
it->second.index = index++;
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolMap::UpdateActiveSymbols() {
|
||||
// return; (slow in debug mode)
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
std::map<int, u32> activeModuleIndexes;
|
||||
for (auto it = activeModuleEnds.begin(), end = activeModuleEnds.end(); it != end; ++it) {
|
||||
activeModuleIndexes[it->second.index] = it->second.start;
|
||||
}
|
||||
|
||||
activeFunctions.clear();
|
||||
activeLabels.clear();
|
||||
activeData.clear();
|
||||
|
||||
for (auto it = functions.begin(), end = functions.end(); it != end; ++it) {
|
||||
const auto mod = activeModuleIndexes.find(it->second.module);
|
||||
if (it->second.module <= 0) {
|
||||
activeFunctions.insert(std::make_pair(it->second.start, it->second));
|
||||
} else if (mod != activeModuleIndexes.end()) {
|
||||
activeFunctions.insert(std::make_pair(mod->second + it->second.start, it->second));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = labels.begin(), end = labels.end(); it != end; ++it) {
|
||||
const auto mod = activeModuleIndexes.find(it->second.module);
|
||||
if (it->second.module <= 0) {
|
||||
activeLabels.insert(std::make_pair(it->second.addr, it->second));
|
||||
} else if (mod != activeModuleIndexes.end()) {
|
||||
activeLabels.insert(std::make_pair(mod->second + it->second.addr, it->second));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = data.begin(), end = data.end(); it != end; ++it) {
|
||||
const auto mod = activeModuleIndexes.find(it->second.module);
|
||||
if (it->second.module <= 0) {
|
||||
activeData.insert(std::make_pair(it->second.start, it->second));
|
||||
} else if (mod != activeModuleIndexes.end()) {
|
||||
activeData.insert(std::make_pair(mod->second + it->second.start, it->second));
|
||||
}
|
||||
}
|
||||
|
||||
AssignFunctionIndices();
|
||||
}
|
||||
|
||||
bool SymbolMap::SetFunctionSize(u32 startAddress, u32 newSize) {
|
||||
bool SymbolMap::SetFunctionSize(u32 startAddress, u32 newSize)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_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();
|
||||
}
|
||||
auto funcInfo = functions.find(startAddress);
|
||||
if (funcInfo != functions.end())
|
||||
{
|
||||
funcInfo->second.size = newSize;
|
||||
}
|
||||
|
||||
// TODO: check for overlaps
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SymbolMap::RemoveFunction(u32 startAddress, bool removeName) {
|
||||
bool SymbolMap::RemoveFunction(u32 startAddress)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
|
||||
auto it = activeFunctions.find(startAddress);
|
||||
if (it == activeFunctions.end())
|
||||
auto it = functions.find(startAddress);
|
||||
if (it == functions.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);
|
||||
functions.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);
|
||||
}
|
||||
}
|
||||
labels.erase(startAddress);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SymbolMap::AddLabel(const char* name, u32 address, int moduleIndex) {
|
||||
void SymbolMap::AddLabel(const std::string& name, u32 address)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
|
||||
if (moduleIndex == -1) {
|
||||
moduleIndex = GetModuleIndex(address);
|
||||
auto existing = labels.find(address);
|
||||
|
||||
if (existing != labels.end())
|
||||
{
|
||||
// Adding a function will automatically call this.
|
||||
// We don't want to overwrite the name if it's already set because
|
||||
// label names are added before our functions
|
||||
}
|
||||
|
||||
// Is there an existing one?
|
||||
u32 relAddress = GetModuleRelativeAddr(address, moduleIndex);
|
||||
auto symbolKey = std::make_pair(moduleIndex, relAddress);
|
||||
auto existing = labels.find(symbolKey);
|
||||
if (existing == labels.end()) {
|
||||
// Fall back: maybe it's got moduleIndex = 0.
|
||||
existing = labels.find(std::make_pair(0, address));
|
||||
}
|
||||
|
||||
if (existing != labels.end()) {
|
||||
// We leave an existing label alone, rather than overwriting.
|
||||
// But we'll still upgrade it to the correct module / relative address.
|
||||
if (existing->second.module != moduleIndex) {
|
||||
existing->second.addr = relAddress;
|
||||
existing->second.module = moduleIndex;
|
||||
|
||||
// Refresh the active item if it exists.
|
||||
auto active = activeLabels.find(address);
|
||||
if (active != activeLabels.end() && active->second.module == moduleIndex) {
|
||||
activeLabels.erase(active);
|
||||
activeLabels.insert(std::make_pair(address, existing->second));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
else
|
||||
{
|
||||
LabelEntry label;
|
||||
label.addr = relAddress;
|
||||
label.module = moduleIndex;
|
||||
strncpy(label.name, name, 128);
|
||||
label.name[127] = 0;
|
||||
label.addr = address;
|
||||
label.name = name;
|
||||
|
||||
labels[symbolKey] = label;
|
||||
if (IsModuleActive(moduleIndex)) {
|
||||
activeLabels.insert(std::make_pair(address, label));
|
||||
}
|
||||
labels[address] = label;
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolMap::SetLabelName(const char* name, u32 address, bool updateImmediately) {
|
||||
void SymbolMap::SetLabelName(const std::string& name, u32 address)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
auto labelInfo = activeLabels.find(address);
|
||||
if (labelInfo == activeLabels.end()) {
|
||||
auto labelInfo = labels.find(address);
|
||||
if (labelInfo == labels.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()) {
|
||||
strncpy(label->second.name, name, ARRAY_SIZE(label->second.name));
|
||||
label->second.name[ARRAY_SIZE(label->second.name) - 1] = 0;
|
||||
|
||||
// Allow the caller to skip this as it causes extreme startup slowdown
|
||||
// when this gets called for every function identified by the function replacement code.
|
||||
if (updateImmediately) {
|
||||
UpdateActiveSymbols();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
labelInfo->second.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
const char *SymbolMap::GetLabelName(u32 address) const {
|
||||
std::string SymbolMap::GetLabelName(u32 address) const
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
auto it = activeLabels.find(address);
|
||||
if (it == activeLabels.end())
|
||||
return NULL;
|
||||
|
||||
return it->second.name;
|
||||
}
|
||||
|
||||
const char *SymbolMap::GetLabelNameRel(u32 relAddress, int moduleIndex) const {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
auto it = labels.find(std::make_pair(moduleIndex, relAddress));
|
||||
auto it = labels.find(address);
|
||||
if (it == labels.end())
|
||||
return NULL;
|
||||
return "";
|
||||
|
||||
return it->second.name;
|
||||
}
|
||||
|
||||
std::string SymbolMap::GetLabelString(u32 address) const {
|
||||
bool SymbolMap::GetLabelValue(const std::string& name, u32& dest)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
const char *label = GetLabelName(address);
|
||||
if (label == NULL)
|
||||
return "";
|
||||
return label;
|
||||
}
|
||||
|
||||
bool SymbolMap::GetLabelValue(const char* name, u32& dest) {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
for (auto it = activeLabels.begin(); it != activeLabels.end(); it++) {
|
||||
if (strcasecmp(name, it->second.name) == 0) {
|
||||
for (auto it = labels.begin(); it != labels.end(); it++)
|
||||
{
|
||||
if (name == it->second.name)
|
||||
{
|
||||
dest = it->first;
|
||||
return true;
|
||||
}
|
||||
|
@ -622,92 +438,74 @@ bool SymbolMap::GetLabelValue(const char* name, u32& dest) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void SymbolMap::AddData(u32 address, u32 size, DataType type, int moduleIndex) {
|
||||
void SymbolMap::AddData(u32 address, u32 size, DataType type, int moduleIndex)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
|
||||
if (moduleIndex == -1) {
|
||||
moduleIndex = GetModuleIndex(address);
|
||||
}
|
||||
auto existing = data.find(address);
|
||||
|
||||
// Is there an existing one?
|
||||
u32 relAddress = GetModuleRelativeAddr(address, moduleIndex);
|
||||
auto symbolKey = std::make_pair(moduleIndex, relAddress);
|
||||
auto existing = data.find(symbolKey);
|
||||
if (existing == data.end()) {
|
||||
// Fall back: maybe it's got moduleIndex = 0.
|
||||
existing = data.find(std::make_pair(0, address));
|
||||
}
|
||||
|
||||
if (existing != data.end()) {
|
||||
if (existing != data.end())
|
||||
{
|
||||
existing->second.size = size;
|
||||
existing->second.type = type;
|
||||
if (existing->second.module != moduleIndex) {
|
||||
existing->second.module = moduleIndex;
|
||||
existing->second.start = relAddress;
|
||||
}
|
||||
|
||||
// Refresh the active item if it exists.
|
||||
auto active = activeData.find(address);
|
||||
if (active != activeData.end() && active->second.module == moduleIndex) {
|
||||
activeData.erase(active);
|
||||
activeData.insert(std::make_pair(address, existing->second));
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
DataEntry entry;
|
||||
entry.start = relAddress;
|
||||
entry.start = address;
|
||||
entry.size = size;
|
||||
entry.type = type;
|
||||
entry.module = moduleIndex;
|
||||
|
||||
data[symbolKey] = entry;
|
||||
if (IsModuleActive(moduleIndex)) {
|
||||
activeData.insert(std::make_pair(address, entry));
|
||||
}
|
||||
data[address] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
u32 SymbolMap::GetDataStart(u32 address) const {
|
||||
u32 SymbolMap::GetDataStart(u32 address) const
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
auto it = activeData.upper_bound(address);
|
||||
if (it == activeData.end())
|
||||
auto it = data.upper_bound(address);
|
||||
if (it == data.end())
|
||||
{
|
||||
// check last element
|
||||
auto rit = activeData.rbegin();
|
||||
auto rit = data.rbegin();
|
||||
|
||||
if (rit != activeData.rend())
|
||||
if (rit != data.rend())
|
||||
{
|
||||
u32 start = rit->first;
|
||||
u32 size = rit->second.size;
|
||||
if (start <= address && start+size > address)
|
||||
if (start <= address && start + size > address)
|
||||
return start;
|
||||
}
|
||||
// otherwise there's no data that contains this address
|
||||
return INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if (it != activeData.begin()) {
|
||||
if (it != data.begin())
|
||||
{
|
||||
it--;
|
||||
u32 start = it->first;
|
||||
u32 size = it->second.size;
|
||||
if (start <= address && start+size > address)
|
||||
if (start <= address && start + size > address)
|
||||
return start;
|
||||
}
|
||||
|
||||
return INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
u32 SymbolMap::GetDataSize(u32 startAddress) const {
|
||||
u32 SymbolMap::GetDataSize(u32 startAddress) const
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
auto it = activeData.find(startAddress);
|
||||
if (it == activeData.end())
|
||||
auto it = data.find(startAddress);
|
||||
if (it == data.end())
|
||||
return INVALID_ADDRESS;
|
||||
return it->second.size;
|
||||
}
|
||||
|
||||
DataType SymbolMap::GetDataType(u32 startAddress) const {
|
||||
DataType SymbolMap::GetDataType(u32 startAddress) const
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||
auto it = activeData.find(startAddress);
|
||||
if (it == activeData.end())
|
||||
auto it = data.find(startAddress);
|
||||
if (it == data.end())
|
||||
return DATATYPE_NONE;
|
||||
return it->second.type;
|
||||
}
|
||||
|
|
|
@ -23,69 +23,71 @@
|
|||
|
||||
#include "common/Pcsx2Types.h"
|
||||
|
||||
enum SymbolType {
|
||||
ST_NONE = 0,
|
||||
enum SymbolType
|
||||
{
|
||||
ST_NONE = 0,
|
||||
ST_FUNCTION = 1,
|
||||
ST_DATA = 2,
|
||||
ST_ALL = 3,
|
||||
ST_DATA = 2,
|
||||
ST_ALL = 3,
|
||||
};
|
||||
|
||||
struct SymbolInfo {
|
||||
struct SymbolInfo
|
||||
{
|
||||
SymbolType type;
|
||||
u32 address;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct SymbolEntry {
|
||||
struct SymbolEntry
|
||||
{
|
||||
std::string name;
|
||||
u32 address;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct LoadedModuleInfo {
|
||||
struct LoadedModuleInfo
|
||||
{
|
||||
std::string name;
|
||||
u32 address;
|
||||
u32 size;
|
||||
bool active;
|
||||
};
|
||||
|
||||
enum DataType {
|
||||
DATATYPE_NONE, DATATYPE_BYTE, DATATYPE_HALFWORD, DATATYPE_WORD, DATATYPE_ASCII
|
||||
enum DataType
|
||||
{
|
||||
DATATYPE_NONE,
|
||||
DATATYPE_BYTE,
|
||||
DATATYPE_HALFWORD,
|
||||
DATATYPE_WORD,
|
||||
DATATYPE_ASCII
|
||||
};
|
||||
|
||||
class SymbolMap {
|
||||
class SymbolMap
|
||||
{
|
||||
public:
|
||||
SymbolMap() {}
|
||||
void Clear();
|
||||
void SortSymbols();
|
||||
|
||||
bool LoadNocashSym(const char *ilename);
|
||||
bool LoadNocashSym(const std::string& filename);
|
||||
|
||||
SymbolType GetSymbolType(u32 address) const;
|
||||
bool GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask = ST_FUNCTION) const;
|
||||
bool GetSymbolInfo(SymbolInfo* info, u32 address, SymbolType symmask = ST_FUNCTION) const;
|
||||
u32 GetNextSymbolAddress(u32 address, SymbolType symmask);
|
||||
std::string GetDescription(unsigned int address) const;
|
||||
std::vector<SymbolEntry> GetAllSymbols(SymbolType symmask);
|
||||
|
||||
void AddModule(const char *name, u32 address, u32 size);
|
||||
void UnloadModule(u32 address, u32 size);
|
||||
u32 GetModuleRelativeAddr(u32 address, int moduleIndex = -1) const;
|
||||
u32 GetModuleAbsoluteAddr(u32 relative, int moduleIndex) const;
|
||||
int GetModuleIndex(u32 address) const;
|
||||
bool IsModuleActive(int moduleIndex) const;
|
||||
std::vector<LoadedModuleInfo> getAllModules() const;
|
||||
|
||||
void AddFunction(const char* name, u32 address, u32 size, int moduleIndex = -1);
|
||||
void AddFunction(const std::string& 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);
|
||||
bool RemoveFunction(u32 startAddress);
|
||||
|
||||
void AddLabel(const char* name, u32 address, int moduleIndex = -1);
|
||||
std::string GetLabelString(u32 address) const;
|
||||
void SetLabelName(const char* name, u32 address, bool updateImmediately = true);
|
||||
bool GetLabelValue(const char* name, u32& dest);
|
||||
void AddLabel(const std::string& name, u32 address);
|
||||
std::string GetLabelName(u32 address) const;
|
||||
void SetLabelName(const std::string& name, u32 address);
|
||||
bool GetLabelValue(const std::string& name, u32& dest);
|
||||
|
||||
void AddData(u32 address, u32 size, DataType type, int moduleIndex = -1);
|
||||
u32 GetDataStart(u32 address) const;
|
||||
|
@ -94,56 +96,34 @@ public:
|
|||
|
||||
static const u32 INVALID_ADDRESS = (u32)-1;
|
||||
|
||||
void UpdateActiveSymbols();
|
||||
bool IsEmpty() const { return activeFunctions.empty() && activeLabels.empty() && activeData.empty(); };
|
||||
bool IsEmpty() const { return functions.empty() && labels.empty() && data.empty(); };
|
||||
|
||||
private:
|
||||
void AssignFunctionIndices();
|
||||
const char *GetLabelName(u32 address) const;
|
||||
const char *GetLabelNameRel(u32 relAddress, int moduleIndex) const;
|
||||
|
||||
struct FunctionEntry {
|
||||
struct FunctionEntry
|
||||
{
|
||||
u32 start;
|
||||
u32 size;
|
||||
int index;
|
||||
int module;
|
||||
};
|
||||
|
||||
struct LabelEntry {
|
||||
struct LabelEntry
|
||||
{
|
||||
u32 addr;
|
||||
int module;
|
||||
char name[128];
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct DataEntry {
|
||||
struct DataEntry
|
||||
{
|
||||
DataType type;
|
||||
u32 start;
|
||||
u32 size;
|
||||
int module;
|
||||
};
|
||||
|
||||
struct ModuleEntry {
|
||||
// Note: this index is +1, 0 matches any for backwards-compat.
|
||||
int index;
|
||||
u32 start;
|
||||
u32 size;
|
||||
char name[128];
|
||||
};
|
||||
|
||||
// These are flattened, read-only copies of the actual data in active modules only.
|
||||
std::map<u32, const FunctionEntry> activeFunctions;
|
||||
std::map<u32, const LabelEntry> activeLabels;
|
||||
std::map<u32, const DataEntry> activeData;
|
||||
|
||||
// This is indexed by the end address of the module.
|
||||
std::map<u32, const ModuleEntry> activeModuleEnds;
|
||||
|
||||
typedef std::pair<int, u32> SymbolKey;
|
||||
|
||||
// These are indexed by the module id and relative address in the module.
|
||||
std::map<SymbolKey, FunctionEntry> functions;
|
||||
std::map<SymbolKey, LabelEntry> labels;
|
||||
std::map<SymbolKey, DataEntry> data;
|
||||
std::vector<ModuleEntry> modules;
|
||||
std::map<u32, FunctionEntry> functions;
|
||||
std::map<u32, LabelEntry> labels;
|
||||
std::map<u32, DataEntry> data;
|
||||
|
||||
mutable std::recursive_mutex m_lock;
|
||||
};
|
||||
|
|
|
@ -962,8 +962,6 @@ void VMManager::HandleELFChange(bool verbose_patches_if_changed)
|
|||
|
||||
MIPSAnalyst::ScanForFunctions(
|
||||
R5900SymbolMap, s_elf_text_range.first, s_elf_text_range.first + s_elf_text_range.second, true);
|
||||
R5900SymbolMap.UpdateActiveSymbols();
|
||||
R3000SymbolMap.UpdateActiveSymbols();
|
||||
}
|
||||
|
||||
void VMManager::UpdateELFInfo(std::string elf_path)
|
||||
|
|
Loading…
Reference in New Issue