#include "pch.h" #include "Debugger/LabelManager.h" #include "Debugger/Debugger.h" #include "Debugger/DebugUtilities.h" #include "Debugger/DebugBreakHelper.h" LabelManager::LabelManager(Debugger *debugger) { _debugger = debugger; } void LabelManager::ClearLabels() { DebugBreakHelper helper(_debugger); _codeLabels.clear(); _codeLabelReverseLookup.clear(); } void LabelManager::SetLabel(uint32_t address, MemoryType memType, string label, string comment) { DebugBreakHelper helper(_debugger); uint64_t key = GetLabelKey(address, memType); auto existingLabel = _codeLabels.find(key); if(existingLabel != _codeLabels.end()) { _codeLabelReverseLookup.erase(existingLabel->second.Label); } _codeLabels.erase(key); if(!label.empty() || !comment.empty()) { if(label.size() > 400) { //Restrict labels to 400 bytes label = label.substr(0, 400); } LabelInfo labelInfo; labelInfo.Label = label; labelInfo.Comment = comment; _codeLabels.emplace(key, labelInfo); _codeLabelReverseLookup.emplace(label, key); } } int64_t LabelManager::GetLabelKey(uint32_t absoluteAddr, MemoryType memType) { return absoluteAddr | ((uint64_t)memType << 32); } MemoryType LabelManager::GetKeyMemoryType(uint64_t key) { return (MemoryType)(key >> 32); } string LabelManager::GetLabel(AddressInfo address, bool checkRegisterLabels) { string label; if(DebugUtilities::IsRelativeMemory(address.Type)) { if(checkRegisterLabels && InternalGetLabel(address, label)) { //Labels for registers return label; } address = _debugger->GetAbsoluteAddress(address); } if(address.Address >= 0) { InternalGetLabel(address, label); } return label; } bool LabelManager::InternalGetLabel(AddressInfo address, string &label) { int64_t key = GetLabelKey(address.Address, address.Type); if(key >= 0) { auto result = _codeLabels.find(key); if(result != _codeLabels.end()) { label = result->second.Label; return true; } } return false; } string LabelManager::GetComment(AddressInfo absAddress) { uint64_t key = GetLabelKey(absAddress.Address, absAddress.Type); if(key >= 0) { auto result = _codeLabels.find(key); if(result != _codeLabels.end()) { return result->second.Comment; } } return ""; } bool LabelManager::GetLabelAndComment(AddressInfo address, LabelInfo &labelInfo) { if(DebugUtilities::IsRelativeMemory(address.Type)) { address = _debugger->GetAbsoluteAddress(address); } if(address.Address >= 0) { int64_t key = GetLabelKey(address.Address, address.Type); if(key >= 0) { auto result = _codeLabels.find(key); if(result != _codeLabels.end()) { labelInfo = result->second; return true; } } } return false; } bool LabelManager::ContainsLabel(string &label) { return _codeLabelReverseLookup.find(label) != _codeLabelReverseLookup.end(); } AddressInfo LabelManager::GetLabelAbsoluteAddress(string& label) { AddressInfo addr = { -1, MemoryType::None }; auto result = _codeLabelReverseLookup.find(label); if(result != _codeLabelReverseLookup.end()) { uint64_t key = result->second; addr.Type = GetKeyMemoryType(key); addr.Address = (int32_t)(key & 0xFFFFFFFF); } return addr; } int32_t LabelManager::GetLabelRelativeAddress(string &label, CpuType cpuType) { auto result = _codeLabelReverseLookup.find(label); if(result == _codeLabelReverseLookup.end()) { //Label doesn't exist, try to find a matching multi-byte label result = _codeLabelReverseLookup.find(label + "+0"); } if(result != _codeLabelReverseLookup.end()) { uint64_t key = result->second; MemoryType type = GetKeyMemoryType(key); AddressInfo addr { (int32_t)(key & 0xFFFFFFFF), type }; if(DebugUtilities::IsRelativeMemory(type)) { return addr.Address; } return _debugger->GetRelativeAddress(addr, cpuType).Address; } //Label doesn't exist return -2; } bool LabelManager::HasLabelOrComment(AddressInfo address) { if(DebugUtilities::IsRelativeMemory(address.Type)) { address = _debugger->GetAbsoluteAddress(address); } if(address.Address >= 0) { uint64_t key = GetLabelKey(address.Address, address.Type); if(key >= 0) { return _codeLabels.find(key) != _codeLabels.end(); } } return false; }