2019-04-28 22:19:52 -04:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "LabelManager.h"
|
|
|
|
#include "Debugger.h"
|
2019-07-30 22:34:52 -04:00
|
|
|
#include "DebugUtilities.h"
|
2019-04-28 22:19:52 -04:00
|
|
|
|
|
|
|
LabelManager::LabelManager(Debugger *debugger)
|
|
|
|
{
|
|
|
|
_debugger = debugger;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LabelManager::ClearLabels()
|
|
|
|
{
|
|
|
|
_codeComments.clear();
|
|
|
|
_codeLabels.clear();
|
|
|
|
_codeLabelReverseLookup.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LabelManager::SetLabel(uint32_t address, SnesMemoryType memType, string label, string comment)
|
|
|
|
{
|
|
|
|
uint64_t key = GetLabelKey(address, memType);
|
|
|
|
|
|
|
|
auto existingLabel = _codeLabels.find(key);
|
|
|
|
if(existingLabel != _codeLabels.end()) {
|
|
|
|
_codeLabelReverseLookup.erase(existingLabel->second);
|
|
|
|
}
|
|
|
|
|
|
|
|
_codeLabels.erase(key);
|
|
|
|
if(!label.empty()) {
|
|
|
|
if(label.size() > 400) {
|
|
|
|
//Restrict labels to 400 bytes
|
|
|
|
label = label.substr(0, 400);
|
|
|
|
}
|
|
|
|
_codeLabels.emplace(key, label);
|
|
|
|
_codeLabelReverseLookup.emplace(label, key);
|
|
|
|
}
|
|
|
|
|
|
|
|
_codeComments.erase(key);
|
|
|
|
if(!comment.empty()) {
|
|
|
|
_codeComments.emplace(key, comment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-05 19:19:38 -04:00
|
|
|
int64_t LabelManager::GetLabelKey(uint32_t absoluteAddr, SnesMemoryType memType)
|
2019-04-28 22:19:52 -04:00
|
|
|
{
|
|
|
|
switch(memType) {
|
2019-07-05 19:19:38 -04:00
|
|
|
case SnesMemoryType::PrgRom: return absoluteAddr | ((uint64_t)1 << 32);
|
|
|
|
case SnesMemoryType::WorkRam: return absoluteAddr | ((uint64_t)2 << 32);
|
|
|
|
case SnesMemoryType::SaveRam: return absoluteAddr | ((uint64_t)3 << 32);
|
|
|
|
case SnesMemoryType::Register: return absoluteAddr | ((uint64_t)4 << 32);
|
|
|
|
case SnesMemoryType::SpcRam: return absoluteAddr | ((uint64_t)5 << 32);
|
|
|
|
case SnesMemoryType::SpcRom: return absoluteAddr | ((uint64_t)6 << 32);
|
2019-07-25 22:22:09 -04:00
|
|
|
case SnesMemoryType::Sa1InternalRam: return absoluteAddr | ((uint64_t)7 << 32);
|
2019-07-30 22:34:52 -04:00
|
|
|
case SnesMemoryType::GsuWorkRam: return absoluteAddr | ((uint64_t)8 << 32);
|
2019-07-05 19:19:38 -04:00
|
|
|
default: return -1;
|
2019-04-28 22:19:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SnesMemoryType LabelManager::GetKeyMemoryType(uint64_t key)
|
|
|
|
{
|
2019-05-03 14:16:04 -04:00
|
|
|
switch(key & ~(uint64_t)0xFFFFFFFF) {
|
2019-04-28 22:19:52 -04:00
|
|
|
case ((uint64_t)1 << 32): return SnesMemoryType::PrgRom; break;
|
|
|
|
case ((uint64_t)2 << 32): return SnesMemoryType::WorkRam; break;
|
|
|
|
case ((uint64_t)3 << 32): return SnesMemoryType::SaveRam; break;
|
|
|
|
case ((uint64_t)4 << 32): return SnesMemoryType::Register; break;
|
|
|
|
case ((uint64_t)5 << 32): return SnesMemoryType::SpcRam; break;
|
|
|
|
case ((uint64_t)6 << 32): return SnesMemoryType::SpcRom; break;
|
2019-07-25 22:22:09 -04:00
|
|
|
case ((uint64_t)7 << 32): return SnesMemoryType::Sa1InternalRam; break;
|
2019-07-30 22:34:52 -04:00
|
|
|
case ((uint64_t)8 << 32): return SnesMemoryType::GsuWorkRam; break;
|
2019-04-28 22:19:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
throw std::runtime_error("Invalid label key");
|
|
|
|
}
|
|
|
|
|
|
|
|
string LabelManager::GetLabel(AddressInfo address)
|
|
|
|
{
|
2019-07-30 22:34:52 -04:00
|
|
|
if(address.Type <= DebugUtilities::GetLastCpuMemoryType()) {
|
2019-04-28 22:19:52 -04:00
|
|
|
address = _debugger->GetAbsoluteAddress(address);
|
|
|
|
}
|
|
|
|
|
2019-07-05 19:19:38 -04:00
|
|
|
if(address.Address >= 0) {
|
|
|
|
int64_t key = GetLabelKey(address.Address, address.Type);
|
|
|
|
if(key >= 0) {
|
|
|
|
auto result = _codeLabels.find(key);
|
|
|
|
if(result != _codeLabels.end()) {
|
|
|
|
return result->second;
|
|
|
|
}
|
2019-04-28 22:19:52 -04:00
|
|
|
}
|
|
|
|
}
|
2019-07-05 19:19:38 -04:00
|
|
|
|
2019-04-28 22:19:52 -04:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
string LabelManager::GetComment(AddressInfo absAddress)
|
|
|
|
{
|
|
|
|
uint64_t key = GetLabelKey(absAddress.Address, absAddress.Type);
|
|
|
|
|
|
|
|
if(key >= 0) {
|
|
|
|
auto result = _codeComments.find(key);
|
|
|
|
if(result != _codeComments.end()) {
|
|
|
|
return result->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
void LabelManager::GetLabelAndComment(AddressInfo address, string &label, string &comment)
|
|
|
|
{
|
2019-07-30 22:34:52 -04:00
|
|
|
if(address.Type <= DebugUtilities::GetLastCpuMemoryType()) {
|
2019-04-28 22:19:52 -04:00
|
|
|
address = _debugger->GetAbsoluteAddress(address);
|
|
|
|
}
|
|
|
|
|
2019-07-05 19:19:38 -04:00
|
|
|
if(address.Address >= 0) {
|
|
|
|
int64_t key = GetLabelKey(address.Address, address.Type);
|
|
|
|
|
|
|
|
if(key >= 0) {
|
|
|
|
auto result = _codeLabels.find(key);
|
|
|
|
if(result != _codeLabels.end()) {
|
|
|
|
label = result->second;
|
|
|
|
} else {
|
|
|
|
label.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto commentResult = _codeComments.find(key);
|
|
|
|
if(commentResult != _codeComments.end()) {
|
|
|
|
comment = commentResult->second;
|
|
|
|
} else {
|
|
|
|
comment.clear();
|
|
|
|
}
|
2019-04-28 22:19:52 -04:00
|
|
|
}
|
2019-07-05 19:19:38 -04:00
|
|
|
} else {
|
|
|
|
label.clear();
|
|
|
|
comment.clear();
|
2019-04-28 22:19:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LabelManager::ContainsLabel(string &label)
|
|
|
|
{
|
|
|
|
return _codeLabelReverseLookup.find(label) != _codeLabelReverseLookup.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t LabelManager::GetLabelRelativeAddress(string &label)
|
|
|
|
{
|
|
|
|
auto result = _codeLabelReverseLookup.find(label);
|
|
|
|
if(result != _codeLabelReverseLookup.end()) {
|
|
|
|
uint64_t key = result->second;
|
|
|
|
SnesMemoryType type = GetKeyMemoryType(key);
|
|
|
|
AddressInfo addr { (int32_t)(key & 0xFFFFFFFF), type };
|
|
|
|
return _debugger->GetRelativeAddress(addr).Address;
|
|
|
|
}
|
|
|
|
//Label doesn't exist
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LabelManager::HasLabelOrComment(AddressInfo address)
|
|
|
|
{
|
2019-07-30 22:34:52 -04:00
|
|
|
if(address.Type <= DebugUtilities::GetLastCpuMemoryType()) {
|
2019-04-28 22:19:52 -04:00
|
|
|
address = _debugger->GetAbsoluteAddress(address);
|
|
|
|
}
|
|
|
|
|
2019-07-05 19:19:38 -04:00
|
|
|
if(address.Address >= 0) {
|
|
|
|
uint64_t key = GetLabelKey(address.Address, address.Type);
|
|
|
|
if(key >= 0) {
|
|
|
|
return
|
|
|
|
_codeLabels.find(key) != _codeLabels.end() ||
|
|
|
|
_codeComments.find(key) != _codeComments.end();
|
|
|
|
}
|
2019-04-28 22:19:52 -04:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|