commit
5fdf171967
|
@ -11,6 +11,8 @@
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/SymbolDB.h"
|
#include "Common/SymbolDB.h"
|
||||||
|
|
||||||
|
namespace Common
|
||||||
|
{
|
||||||
static std::string GetStrippedFunctionName(const std::string& symbol_name)
|
static std::string GetStrippedFunctionName(const std::string& symbol_name)
|
||||||
{
|
{
|
||||||
std::string name = symbol_name.substr(0, symbol_name.find('('));
|
std::string name = symbol_name.substr(0, symbol_name.find('('));
|
||||||
|
@ -20,6 +22,10 @@ static std::string GetStrippedFunctionName(const std::string& symbol_name)
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SymbolDB::SymbolDB() = default;
|
||||||
|
|
||||||
|
SymbolDB::~SymbolDB() = default;
|
||||||
|
|
||||||
void Symbol::Rename(const std::string& symbol_name)
|
void Symbol::Rename(const std::string& symbol_name)
|
||||||
{
|
{
|
||||||
this->name = symbol_name;
|
this->name = symbol_name;
|
||||||
|
@ -28,25 +34,25 @@ void Symbol::Rename(const std::string& symbol_name)
|
||||||
|
|
||||||
void SymbolDB::List()
|
void SymbolDB::List()
|
||||||
{
|
{
|
||||||
for (const auto& func : functions)
|
for (const auto& func : m_functions)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(OSHLE, "%s @ %08x: %i bytes (hash %08x) : %i calls", func.second.name.c_str(),
|
DEBUG_LOG(OSHLE, "%s @ %08x: %i bytes (hash %08x) : %i calls", func.second.name.c_str(),
|
||||||
func.second.address, func.second.size, func.second.hash, func.second.numCalls);
|
func.second.address, func.second.size, func.second.hash, func.second.num_calls);
|
||||||
}
|
}
|
||||||
INFO_LOG(OSHLE, "%zu functions known in this program above.", functions.size());
|
INFO_LOG(OSHLE, "%zu functions known in this program above.", m_functions.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolDB::Clear(const char* prefix)
|
void SymbolDB::Clear(const char* prefix)
|
||||||
{
|
{
|
||||||
// TODO: honor prefix
|
// TODO: honor prefix
|
||||||
functions.clear();
|
m_functions.clear();
|
||||||
checksumToFunction.clear();
|
m_checksum_to_function.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolDB::Index()
|
void SymbolDB::Index()
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto& func : functions)
|
for (auto& func : m_functions)
|
||||||
{
|
{
|
||||||
func.second.index = i++;
|
func.second.index = i++;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +60,7 @@ void SymbolDB::Index()
|
||||||
|
|
||||||
Symbol* SymbolDB::GetSymbolFromName(const std::string& name)
|
Symbol* SymbolDB::GetSymbolFromName(const std::string& name)
|
||||||
{
|
{
|
||||||
for (auto& func : functions)
|
for (auto& func : m_functions)
|
||||||
{
|
{
|
||||||
if (func.second.function_name == name)
|
if (func.second.function_name == name)
|
||||||
return &func.second;
|
return &func.second;
|
||||||
|
@ -67,7 +73,7 @@ std::vector<Symbol*> SymbolDB::GetSymbolsFromName(const std::string& name)
|
||||||
{
|
{
|
||||||
std::vector<Symbol*> symbols;
|
std::vector<Symbol*> symbols;
|
||||||
|
|
||||||
for (auto& func : functions)
|
for (auto& func : m_functions)
|
||||||
{
|
{
|
||||||
if (func.second.function_name == name)
|
if (func.second.function_name == name)
|
||||||
symbols.push_back(&func.second);
|
symbols.push_back(&func.second);
|
||||||
|
@ -78,18 +84,18 @@ std::vector<Symbol*> SymbolDB::GetSymbolsFromName(const std::string& name)
|
||||||
|
|
||||||
Symbol* SymbolDB::GetSymbolFromHash(u32 hash)
|
Symbol* SymbolDB::GetSymbolFromHash(u32 hash)
|
||||||
{
|
{
|
||||||
XFuncPtrMap::iterator iter = checksumToFunction.find(hash);
|
auto iter = m_checksum_to_function.find(hash);
|
||||||
if (iter != checksumToFunction.end())
|
if (iter == m_checksum_to_function.end())
|
||||||
return *iter->second.begin();
|
|
||||||
else
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
return *iter->second.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Symbol*> SymbolDB::GetSymbolsFromHash(u32 hash)
|
std::vector<Symbol*> SymbolDB::GetSymbolsFromHash(u32 hash)
|
||||||
{
|
{
|
||||||
const auto iter = checksumToFunction.find(hash);
|
const auto iter = m_checksum_to_function.find(hash);
|
||||||
|
|
||||||
if (iter == checksumToFunction.cend())
|
if (iter == m_checksum_to_function.cend())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return {iter->second.cbegin(), iter->second.cend()};
|
return {iter->second.cbegin(), iter->second.cend()};
|
||||||
|
@ -97,5 +103,6 @@ std::vector<Symbol*> SymbolDB::GetSymbolsFromHash(u32 hash)
|
||||||
|
|
||||||
void SymbolDB::AddCompleteSymbol(const Symbol& symbol)
|
void SymbolDB::AddCompleteSymbol(const Symbol& symbol)
|
||||||
{
|
{
|
||||||
functions.emplace(symbol.address, symbol);
|
m_functions.emplace(symbol.address, symbol);
|
||||||
}
|
}
|
||||||
|
} // namespace Common
|
||||||
|
|
|
@ -15,11 +15,13 @@
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
namespace Common
|
||||||
|
{
|
||||||
struct SCall
|
struct SCall
|
||||||
{
|
{
|
||||||
SCall(u32 a, u32 b) : function(a), callAddress(b) {}
|
SCall(u32 a, u32 b) : function(a), call_address(b) {}
|
||||||
u32 function;
|
u32 function;
|
||||||
u32 callAddress;
|
u32 call_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Symbol
|
struct Symbol
|
||||||
|
@ -40,7 +42,7 @@ struct Symbol
|
||||||
u32 address = 0;
|
u32 address = 0;
|
||||||
u32 flags = 0;
|
u32 flags = 0;
|
||||||
u32 size = 0;
|
u32 size = 0;
|
||||||
int numCalls = 0;
|
int num_calls = 0;
|
||||||
Type type = Type::Function;
|
Type type = Type::Function;
|
||||||
int index = 0; // only used for coloring the disasm view
|
int index = 0; // only used for coloring the disasm view
|
||||||
bool analyzed = false;
|
bool analyzed = false;
|
||||||
|
@ -59,18 +61,14 @@ enum
|
||||||
class SymbolDB
|
class SymbolDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::map<u32, Symbol> XFuncMap;
|
using XFuncMap = std::map<u32, Symbol>;
|
||||||
typedef std::map<u32, std::set<Symbol*>> XFuncPtrMap;
|
using XFuncPtrMap = std::map<u32, std::set<Symbol*>>;
|
||||||
|
|
||||||
protected:
|
SymbolDB();
|
||||||
XFuncMap functions;
|
virtual ~SymbolDB();
|
||||||
XFuncPtrMap checksumToFunction;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SymbolDB() {}
|
|
||||||
virtual ~SymbolDB() {}
|
|
||||||
virtual Symbol* GetSymbolFromAddr(u32 addr) { return nullptr; }
|
virtual Symbol* GetSymbolFromAddr(u32 addr) { return nullptr; }
|
||||||
virtual Symbol* AddFunction(u32 startAddr) { return nullptr; }
|
virtual Symbol* AddFunction(u32 start_addr) { return nullptr; }
|
||||||
void AddCompleteSymbol(const Symbol& symbol);
|
void AddCompleteSymbol(const Symbol& symbol);
|
||||||
|
|
||||||
Symbol* GetSymbolFromName(const std::string& name);
|
Symbol* GetSymbolFromName(const std::string& name);
|
||||||
|
@ -78,9 +76,14 @@ public:
|
||||||
Symbol* GetSymbolFromHash(u32 hash);
|
Symbol* GetSymbolFromHash(u32 hash);
|
||||||
std::vector<Symbol*> GetSymbolsFromHash(u32 hash);
|
std::vector<Symbol*> GetSymbolsFromHash(u32 hash);
|
||||||
|
|
||||||
const XFuncMap& Symbols() const { return functions; }
|
const XFuncMap& Symbols() const { return m_functions; }
|
||||||
XFuncMap& AccessSymbols() { return functions; }
|
XFuncMap& AccessSymbols() { return m_functions; }
|
||||||
void Clear(const char* prefix = "");
|
void Clear(const char* prefix = "");
|
||||||
void List();
|
void List();
|
||||||
void Index();
|
void Index();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
XFuncMap m_functions;
|
||||||
|
XFuncPtrMap m_checksum_to_function;
|
||||||
};
|
};
|
||||||
|
} // namespace Common
|
||||||
|
|
|
@ -204,14 +204,14 @@ bool ElfReader::LoadSymbols() const
|
||||||
if (bRelocate)
|
if (bRelocate)
|
||||||
value += sectionAddrs[sectionIndex];
|
value += sectionAddrs[sectionIndex];
|
||||||
|
|
||||||
auto symtype = Symbol::Type::Data;
|
auto symtype = Common::Symbol::Type::Data;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case STT_OBJECT:
|
case STT_OBJECT:
|
||||||
symtype = Symbol::Type::Data;
|
symtype = Common::Symbol::Type::Data;
|
||||||
break;
|
break;
|
||||||
case STT_FUNC:
|
case STT_FUNC:
|
||||||
symtype = Symbol::Type::Function;
|
symtype = Common::Symbol::Type::Function;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -29,7 +29,7 @@ void AddAutoBreakpoints()
|
||||||
|
|
||||||
for (const char* bp : bps)
|
for (const char* bp : bps)
|
||||||
{
|
{
|
||||||
Symbol* symbol = g_symbolDB.GetSymbolFromName(bp);
|
Common::Symbol* symbol = g_symbolDB.GetSymbolFromName(bp);
|
||||||
if (symbol)
|
if (symbol)
|
||||||
PowerPC::breakpoints.Add(symbol->address, false);
|
PowerPC::breakpoints.Add(symbol->address, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,10 +310,10 @@ int PPCDebugInterface::GetColor(unsigned int address)
|
||||||
0xd0FFd0, // light green
|
0xd0FFd0, // light green
|
||||||
0xFFFFd0, // light yellow
|
0xFFFFd0, // light yellow
|
||||||
};
|
};
|
||||||
Symbol* symbol = g_symbolDB.GetSymbolFromAddr(address);
|
Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(address);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return 0xFFFFFF;
|
return 0xFFFFFF;
|
||||||
if (symbol->type != Symbol::Type::Function)
|
if (symbol->type != Common::Symbol::Type::Function)
|
||||||
return 0xEEEEFF;
|
return 0xEEEEFF;
|
||||||
return colors[symbol->index % 6];
|
return colors[symbol->index % 6];
|
||||||
}
|
}
|
||||||
|
|
|
@ -376,7 +376,7 @@ void RSOView::Apply(PPCSymbolDB* symbol_db) const
|
||||||
u32 address = GetExportAddress(rso_export);
|
u32 address = GetExportAddress(rso_export);
|
||||||
if (address != 0)
|
if (address != 0)
|
||||||
{
|
{
|
||||||
Symbol* symbol = symbol_db->AddFunction(address);
|
Common::Symbol* symbol = symbol_db->AddFunction(address);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
symbol = symbol_db->GetSymbolFromAddr(address);
|
symbol = symbol_db->GetSymbolFromAddr(address);
|
||||||
|
|
||||||
|
@ -389,7 +389,7 @@ void RSOView::Apply(PPCSymbolDB* symbol_db) const
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Data symbol
|
// Data symbol
|
||||||
symbol_db->AddKnownSymbol(address, 0, export_name, Symbol::Type::Data);
|
symbol_db->AddKnownSymbol(address, 0, export_name, Common::Symbol::Type::Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,10 +277,10 @@ int DSPDebugInterface::GetColor(unsigned int address)
|
||||||
if (addr == -1)
|
if (addr == -1)
|
||||||
return 0xFFFFFF;
|
return 0xFFFFFF;
|
||||||
|
|
||||||
Symbol* symbol = Symbols::g_dsp_symbol_db.GetSymbolFromAddr(addr);
|
Common::Symbol* symbol = Symbols::g_dsp_symbol_db.GetSymbolFromAddr(addr);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return 0xFFFFFF;
|
return 0xFFFFFF;
|
||||||
if (symbol->type != Symbol::Type::Function)
|
if (symbol->type != Common::Symbol::Type::Function)
|
||||||
return 0xEEEEFF;
|
return 0xEEEEFF;
|
||||||
return colors[symbol->index % 6];
|
return colors[symbol->index % 6];
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,22 +59,19 @@ const char* GetLineText(int line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* DSPSymbolDB::GetSymbolFromAddr(u32 addr)
|
Common::Symbol* DSPSymbolDB::GetSymbolFromAddr(u32 addr)
|
||||||
{
|
{
|
||||||
XFuncMap::iterator it = functions.find(addr);
|
auto it = m_functions.find(addr);
|
||||||
|
|
||||||
if (it != functions.end())
|
if (it != m_functions.end())
|
||||||
{
|
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
|
||||||
else
|
for (auto& func : m_functions)
|
||||||
{
|
|
||||||
for (auto& func : functions)
|
|
||||||
{
|
{
|
||||||
if (addr >= func.second.address && addr < func.second.address + func.second.size)
|
if (addr >= func.second.address && addr < func.second.address + func.second.size)
|
||||||
return &func.second;
|
return &func.second;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,12 @@ namespace DSP
|
||||||
{
|
{
|
||||||
namespace Symbols
|
namespace Symbols
|
||||||
{
|
{
|
||||||
class DSPSymbolDB : public SymbolDB
|
class DSPSymbolDB : public Common::SymbolDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DSPSymbolDB() {}
|
DSPSymbolDB() {}
|
||||||
~DSPSymbolDB() {}
|
~DSPSymbolDB() {}
|
||||||
Symbol* GetSymbolFromAddr(u32 addr) override;
|
Common::Symbol* GetSymbolFromAddr(u32 addr) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern DSPSymbolDB g_dsp_symbol_db;
|
extern DSPSymbolDB g_dsp_symbol_db;
|
||||||
|
|
|
@ -133,7 +133,7 @@ void JitBaseBlockCache::FinalizeBlock(JitBlock& block, bool block_link,
|
||||||
LinkBlock(block);
|
LinkBlock(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* symbol = nullptr;
|
Common::Symbol* symbol = nullptr;
|
||||||
if (JitRegister::IsEnabled() &&
|
if (JitRegister::IsEnabled() &&
|
||||||
(symbol = g_symbolDB.GetSymbolFromAddr(block.effectiveAddress)) != nullptr)
|
(symbol = g_symbolDB.GetSymbolFromAddr(block.effectiveAddress)) != nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,7 +73,7 @@ static u32 EvaluateBranchTarget(UGeckoInstruction instr, u32 pc)
|
||||||
// Also collect which internal branch goes the farthest.
|
// Also collect which internal branch goes the farthest.
|
||||||
// If any one goes farther than the blr or rfi, assume that there is more than
|
// If any one goes farther than the blr or rfi, assume that there is more than
|
||||||
// one blr or rfi, and keep scanning.
|
// one blr or rfi, and keep scanning.
|
||||||
bool AnalyzeFunction(u32 startAddr, Symbol& func, u32 max_size)
|
bool AnalyzeFunction(u32 startAddr, Common::Symbol& func, u32 max_size)
|
||||||
{
|
{
|
||||||
if (func.name.empty())
|
if (func.name.empty())
|
||||||
func.Rename(StringFromFormat("zz_%08x_", startAddr));
|
func.Rename(StringFromFormat("zz_%08x_", startAddr));
|
||||||
|
@ -83,7 +83,7 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, u32 max_size)
|
||||||
func.calls.clear();
|
func.calls.clear();
|
||||||
func.callers.clear();
|
func.callers.clear();
|
||||||
func.size = 0;
|
func.size = 0;
|
||||||
func.flags = FFLAG_LEAF;
|
func.flags = Common::FFLAG_LEAF;
|
||||||
|
|
||||||
u32 farthestInternalBranchTarget = startAddr;
|
u32 farthestInternalBranchTarget = startAddr;
|
||||||
int numInternalBranches = 0;
|
int numInternalBranches = 0;
|
||||||
|
@ -100,7 +100,7 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, u32 max_size)
|
||||||
func.size -= 4;
|
func.size -= 4;
|
||||||
func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr - 4);
|
func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr - 4);
|
||||||
if (numInternalBranches == 0)
|
if (numInternalBranches == 0)
|
||||||
func.flags |= FFLAG_STRAIGHT;
|
func.flags |= Common::FFLAG_STRAIGHT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const PowerPC::TryReadInstResult read_result = PowerPC::TryReadInstruction(addr);
|
const PowerPC::TryReadInstResult read_result = PowerPC::TryReadInstruction(addr);
|
||||||
|
@ -122,18 +122,18 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, u32 max_size)
|
||||||
func.analyzed = true;
|
func.analyzed = true;
|
||||||
func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr);
|
func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr);
|
||||||
if (numInternalBranches == 0)
|
if (numInternalBranches == 0)
|
||||||
func.flags |= FFLAG_STRAIGHT;
|
func.flags |= Common::FFLAG_STRAIGHT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (instr.hex == 0x4e800021 || instr.hex == 0x4e800420 || instr.hex == 0x4e800421)
|
else if (instr.hex == 0x4e800021 || instr.hex == 0x4e800420 || instr.hex == 0x4e800421)
|
||||||
{
|
{
|
||||||
func.flags &= ~FFLAG_LEAF;
|
func.flags &= ~Common::FFLAG_LEAF;
|
||||||
func.flags |= FFLAG_EVIL;
|
func.flags |= Common::FFLAG_EVIL;
|
||||||
}
|
}
|
||||||
else if (instr.hex == 0x4c000064)
|
else if (instr.hex == 0x4c000064)
|
||||||
{
|
{
|
||||||
func.flags &= ~FFLAG_LEAF;
|
func.flags &= ~Common::FFLAG_LEAF;
|
||||||
func.flags |= FFLAG_RFI;
|
func.flags |= Common::FFLAG_RFI;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -146,7 +146,7 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, u32 max_size)
|
||||||
{
|
{
|
||||||
// Found a function call
|
// Found a function call
|
||||||
func.calls.emplace_back(target, addr);
|
func.calls.emplace_back(target, addr);
|
||||||
func.flags &= ~FFLAG_LEAF;
|
func.flags &= ~Common::FFLAG_LEAF;
|
||||||
}
|
}
|
||||||
else if (instr.OPCD == 16)
|
else if (instr.OPCD == 16)
|
||||||
{
|
{
|
||||||
|
@ -166,7 +166,7 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, u32 max_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReanalyzeFunction(u32 start_addr, Symbol& func, u32 max_size)
|
bool ReanalyzeFunction(u32 start_addr, Common::Symbol& func, u32 max_size)
|
||||||
{
|
{
|
||||||
ASSERT_MSG(SYMBOLS, func.analyzed, "The function wasn't previously analyzed!");
|
ASSERT_MSG(SYMBOLS, func.analyzed, "The function wasn't previously analyzed!");
|
||||||
|
|
||||||
|
@ -176,17 +176,17 @@ bool ReanalyzeFunction(u32 start_addr, Symbol& func, u32 max_size)
|
||||||
|
|
||||||
// Second pass analysis, done after the first pass is done for all functions
|
// Second pass analysis, done after the first pass is done for all functions
|
||||||
// so we have more information to work with
|
// so we have more information to work with
|
||||||
static void AnalyzeFunction2(Symbol* func)
|
static void AnalyzeFunction2(Common::Symbol* func)
|
||||||
{
|
{
|
||||||
u32 flags = func->flags;
|
u32 flags = func->flags;
|
||||||
|
|
||||||
bool nonleafcall = std::any_of(func->calls.begin(), func->calls.end(), [](const auto& call) {
|
bool nonleafcall = std::any_of(func->calls.begin(), func->calls.end(), [](const auto& call) {
|
||||||
const Symbol* called_func = g_symbolDB.GetSymbolFromAddr(call.function);
|
const Common::Symbol* called_func = g_symbolDB.GetSymbolFromAddr(call.function);
|
||||||
return called_func && (called_func->flags & FFLAG_LEAF) == 0;
|
return called_func && (called_func->flags & Common::FFLAG_LEAF) == 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (nonleafcall && !(flags & FFLAG_EVIL) && !(flags & FFLAG_RFI))
|
if (nonleafcall && !(flags & Common::FFLAG_EVIL) && !(flags & Common::FFLAG_RFI))
|
||||||
flags |= FFLAG_ONLYCALLSNICELEAFS;
|
flags |= Common::FFLAG_ONLYCALLSNICELEAFS;
|
||||||
|
|
||||||
func->flags = flags;
|
func->flags = flags;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +254,7 @@ static bool CanSwapAdjacentOps(const CodeOp& a, const CodeOp& b)
|
||||||
// called by another function. Therefore, let's scan the
|
// called by another function. Therefore, let's scan the
|
||||||
// entire space for bl operations and find what functions
|
// entire space for bl operations and find what functions
|
||||||
// get called.
|
// get called.
|
||||||
static void FindFunctionsFromBranches(u32 startAddr, u32 endAddr, SymbolDB* func_db)
|
static void FindFunctionsFromBranches(u32 startAddr, u32 endAddr, Common::SymbolDB* func_db)
|
||||||
{
|
{
|
||||||
for (u32 addr = startAddr; addr < endAddr; addr += 4)
|
for (u32 addr = startAddr; addr < endAddr; addr += 4)
|
||||||
{
|
{
|
||||||
|
@ -312,7 +312,7 @@ static void FindFunctionsFromHandlers(PPCSymbolDB* func_db)
|
||||||
if (read_result.valid && PPCTables::IsValidInstruction(read_result.hex))
|
if (read_result.valid && PPCTables::IsValidInstruction(read_result.hex))
|
||||||
{
|
{
|
||||||
// Check if this function is already mapped
|
// Check if this function is already mapped
|
||||||
Symbol* f = func_db->AddFunction(entry.first);
|
Common::Symbol* f = func_db->AddFunction(entry.first);
|
||||||
if (!f)
|
if (!f)
|
||||||
continue;
|
continue;
|
||||||
f->Rename(entry.second);
|
f->Rename(entry.second);
|
||||||
|
@ -344,7 +344,7 @@ static void FindFunctionsAfterReturnInstruction(PPCSymbolDB* func_db)
|
||||||
if (read_result.valid && PPCTables::IsValidInstruction(read_result.hex))
|
if (read_result.valid && PPCTables::IsValidInstruction(read_result.hex))
|
||||||
{
|
{
|
||||||
// check if this function is already mapped
|
// check if this function is already mapped
|
||||||
Symbol* f = func_db->AddFunction(location);
|
Common::Symbol* f = func_db->AddFunction(location);
|
||||||
if (!f)
|
if (!f)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
|
@ -377,20 +377,20 @@ void FindFunctions(u32 startAddr, u32 endAddr, PPCSymbolDB* func_db)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
AnalyzeFunction2(&(func.second));
|
AnalyzeFunction2(&(func.second));
|
||||||
Symbol& f = func.second;
|
Common::Symbol& f = func.second;
|
||||||
if (f.name.substr(0, 3) == "zzz")
|
if (f.name.substr(0, 3) == "zzz")
|
||||||
{
|
{
|
||||||
if (f.flags & FFLAG_LEAF)
|
if (f.flags & Common::FFLAG_LEAF)
|
||||||
f.Rename(f.name + "_leaf");
|
f.Rename(f.name + "_leaf");
|
||||||
if (f.flags & FFLAG_STRAIGHT)
|
if (f.flags & Common::FFLAG_STRAIGHT)
|
||||||
f.Rename(f.name + "_straight");
|
f.Rename(f.name + "_straight");
|
||||||
}
|
}
|
||||||
if (f.flags & FFLAG_LEAF)
|
if (f.flags & Common::FFLAG_LEAF)
|
||||||
{
|
{
|
||||||
numLeafs++;
|
numLeafs++;
|
||||||
leafSize += f.size;
|
leafSize += f.size;
|
||||||
}
|
}
|
||||||
else if (f.flags & FFLAG_ONLYCALLSNICELEAFS)
|
else if (f.flags & Common::FFLAG_ONLYCALLSNICELEAFS)
|
||||||
{
|
{
|
||||||
numNice++;
|
numNice++;
|
||||||
niceSize += f.size;
|
niceSize += f.size;
|
||||||
|
@ -401,11 +401,11 @@ void FindFunctions(u32 startAddr, u32 endAddr, PPCSymbolDB* func_db)
|
||||||
unniceSize += f.size;
|
unniceSize += f.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f.flags & FFLAG_TIMERINSTRUCTIONS)
|
if (f.flags & Common::FFLAG_TIMERINSTRUCTIONS)
|
||||||
numTimer++;
|
numTimer++;
|
||||||
if (f.flags & FFLAG_RFI)
|
if (f.flags & Common::FFLAG_RFI)
|
||||||
numRFI++;
|
numRFI++;
|
||||||
if ((f.flags & FFLAG_STRAIGHT) && (f.flags & FFLAG_LEAF))
|
if ((f.flags & Common::FFLAG_STRAIGHT) && (f.flags & Common::FFLAG_LEAF))
|
||||||
numStraightLeaf++;
|
numStraightLeaf++;
|
||||||
}
|
}
|
||||||
if (numLeafs == 0)
|
if (numLeafs == 0)
|
||||||
|
|
|
@ -14,7 +14,11 @@
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
|
|
||||||
class PPCSymbolDB;
|
class PPCSymbolDB;
|
||||||
|
|
||||||
|
namespace Common
|
||||||
|
{
|
||||||
struct Symbol;
|
struct Symbol;
|
||||||
|
}
|
||||||
|
|
||||||
namespace PPCAnalyst
|
namespace PPCAnalyst
|
||||||
{
|
{
|
||||||
|
@ -216,7 +220,7 @@ private:
|
||||||
|
|
||||||
void LogFunctionCall(u32 addr);
|
void LogFunctionCall(u32 addr);
|
||||||
void FindFunctions(u32 startAddr, u32 endAddr, PPCSymbolDB* func_db);
|
void FindFunctions(u32 startAddr, u32 endAddr, PPCSymbolDB* func_db);
|
||||||
bool AnalyzeFunction(u32 startAddr, Symbol& func, u32 max_size = 0);
|
bool AnalyzeFunction(u32 startAddr, Common::Symbol& func, u32 max_size = 0);
|
||||||
bool ReanalyzeFunction(u32 start_addr, Symbol& func, u32 max_size = 0);
|
bool ReanalyzeFunction(u32 start_addr, Common::Symbol& func, u32 max_size = 0);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -28,31 +28,31 @@ PPCSymbolDB::PPCSymbolDB() : debugger{&PowerPC::debug_interface}
|
||||||
PPCSymbolDB::~PPCSymbolDB() = default;
|
PPCSymbolDB::~PPCSymbolDB() = default;
|
||||||
|
|
||||||
// Adds the function to the list, unless it's already there
|
// Adds the function to the list, unless it's already there
|
||||||
Symbol* PPCSymbolDB::AddFunction(u32 start_addr)
|
Common::Symbol* PPCSymbolDB::AddFunction(u32 start_addr)
|
||||||
{
|
{
|
||||||
// It's already in the list
|
// It's already in the list
|
||||||
if (functions.find(start_addr) != functions.end())
|
if (m_functions.find(start_addr) != m_functions.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Symbol symbol;
|
Common::Symbol symbol;
|
||||||
if (!PPCAnalyst::AnalyzeFunction(start_addr, symbol))
|
if (!PPCAnalyst::AnalyzeFunction(start_addr, symbol))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
functions[start_addr] = std::move(symbol);
|
m_functions[start_addr] = std::move(symbol);
|
||||||
Symbol* ptr = &functions[start_addr];
|
Common::Symbol* ptr = &m_functions[start_addr];
|
||||||
ptr->type = Symbol::Type::Function;
|
ptr->type = Common::Symbol::Type::Function;
|
||||||
checksumToFunction[ptr->hash].insert(ptr);
|
m_checksum_to_function[ptr->hash].insert(ptr);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCSymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const std::string& name,
|
void PPCSymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const std::string& name,
|
||||||
Symbol::Type type)
|
Common::Symbol::Type type)
|
||||||
{
|
{
|
||||||
auto iter = functions.find(startAddr);
|
auto iter = m_functions.find(startAddr);
|
||||||
if (iter != functions.end())
|
if (iter != m_functions.end())
|
||||||
{
|
{
|
||||||
// already got it, let's just update name, checksum & size to be sure.
|
// already got it, let's just update name, checksum & size to be sure.
|
||||||
Symbol* tempfunc = &iter->second;
|
Common::Symbol* tempfunc = &iter->second;
|
||||||
tempfunc->Rename(name);
|
tempfunc->Rename(name);
|
||||||
tempfunc->hash = HashSignatureDB::ComputeCodeChecksum(startAddr, startAddr + size - 4);
|
tempfunc->hash = HashSignatureDB::ComputeCodeChecksum(startAddr, startAddr + size - 4);
|
||||||
tempfunc->type = type;
|
tempfunc->type = type;
|
||||||
|
@ -61,11 +61,11 @@ void PPCSymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const std::string& nam
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// new symbol. run analyze.
|
// new symbol. run analyze.
|
||||||
Symbol tf;
|
Common::Symbol tf;
|
||||||
tf.Rename(name);
|
tf.Rename(name);
|
||||||
tf.type = type;
|
tf.type = type;
|
||||||
tf.address = startAddr;
|
tf.address = startAddr;
|
||||||
if (tf.type == Symbol::Type::Function)
|
if (tf.type == Common::Symbol::Type::Function)
|
||||||
{
|
{
|
||||||
PPCAnalyst::AnalyzeFunction(startAddr, tf, size);
|
PPCAnalyst::AnalyzeFunction(startAddr, tf, size);
|
||||||
// Do not truncate symbol when a size is expected
|
// Do not truncate symbol when a size is expected
|
||||||
|
@ -75,20 +75,20 @@ void PPCSymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const std::string& nam
|
||||||
name.c_str(), size, tf.size);
|
name.c_str(), size, tf.size);
|
||||||
tf.size = size;
|
tf.size = size;
|
||||||
}
|
}
|
||||||
checksumToFunction[tf.hash].insert(&functions[startAddr]);
|
m_checksum_to_function[tf.hash].insert(&m_functions[startAddr]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tf.size = size;
|
tf.size = size;
|
||||||
}
|
}
|
||||||
functions[startAddr] = tf;
|
m_functions[startAddr] = tf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* PPCSymbolDB::GetSymbolFromAddr(u32 addr)
|
Common::Symbol* PPCSymbolDB::GetSymbolFromAddr(u32 addr)
|
||||||
{
|
{
|
||||||
auto it = functions.lower_bound(addr);
|
auto it = m_functions.lower_bound(addr);
|
||||||
if (it == functions.end())
|
if (it == m_functions.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// If the address is exactly the start address of a symbol, we're done.
|
// If the address is exactly the start address of a symbol, we're done.
|
||||||
|
@ -96,7 +96,7 @@ Symbol* PPCSymbolDB::GetSymbolFromAddr(u32 addr)
|
||||||
return &it->second;
|
return &it->second;
|
||||||
|
|
||||||
// Otherwise, check whether the address is within the bounds of a symbol.
|
// Otherwise, check whether the address is within the bounds of a symbol.
|
||||||
if (it != functions.begin())
|
if (it != m_functions.begin())
|
||||||
--it;
|
--it;
|
||||||
if (addr >= it->second.address && addr < it->second.address + it->second.size)
|
if (addr >= it->second.address && addr < it->second.address + it->second.size)
|
||||||
return &it->second;
|
return &it->second;
|
||||||
|
@ -106,7 +106,7 @@ Symbol* PPCSymbolDB::GetSymbolFromAddr(u32 addr)
|
||||||
|
|
||||||
std::string PPCSymbolDB::GetDescription(u32 addr)
|
std::string PPCSymbolDB::GetDescription(u32 addr)
|
||||||
{
|
{
|
||||||
Symbol* symbol = GetSymbolFromAddr(addr);
|
Common::Symbol* symbol = GetSymbolFromAddr(addr);
|
||||||
if (symbol)
|
if (symbol)
|
||||||
return symbol->name;
|
return symbol->name;
|
||||||
else
|
else
|
||||||
|
@ -115,23 +115,23 @@ std::string PPCSymbolDB::GetDescription(u32 addr)
|
||||||
|
|
||||||
void PPCSymbolDB::FillInCallers()
|
void PPCSymbolDB::FillInCallers()
|
||||||
{
|
{
|
||||||
for (auto& p : functions)
|
for (auto& p : m_functions)
|
||||||
{
|
{
|
||||||
p.second.callers.clear();
|
p.second.callers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& entry : functions)
|
for (auto& entry : m_functions)
|
||||||
{
|
{
|
||||||
Symbol& f = entry.second;
|
Common::Symbol& f = entry.second;
|
||||||
for (const SCall& call : f.calls)
|
for (const Common::SCall& call : f.calls)
|
||||||
{
|
{
|
||||||
const SCall new_call(entry.first, call.callAddress);
|
const Common::SCall new_call(entry.first, call.call_address);
|
||||||
const u32 function_address = call.function;
|
const u32 function_address = call.function;
|
||||||
|
|
||||||
auto func_iter = functions.find(function_address);
|
auto func_iter = m_functions.find(function_address);
|
||||||
if (func_iter != functions.end())
|
if (func_iter != m_functions.end())
|
||||||
{
|
{
|
||||||
Symbol& called_function = func_iter->second;
|
Common::Symbol& called_function = func_iter->second;
|
||||||
called_function.callers.push_back(new_call);
|
called_function.callers.push_back(new_call);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -146,51 +146,51 @@ void PPCSymbolDB::FillInCallers()
|
||||||
|
|
||||||
void PPCSymbolDB::PrintCalls(u32 funcAddr) const
|
void PPCSymbolDB::PrintCalls(u32 funcAddr) const
|
||||||
{
|
{
|
||||||
const auto iter = functions.find(funcAddr);
|
const auto iter = m_functions.find(funcAddr);
|
||||||
if (iter == functions.end())
|
if (iter == m_functions.end())
|
||||||
{
|
{
|
||||||
WARN_LOG(SYMBOLS, "Symbol does not exist");
|
WARN_LOG(SYMBOLS, "Symbol does not exist");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Symbol& f = iter->second;
|
const Common::Symbol& f = iter->second;
|
||||||
DEBUG_LOG(SYMBOLS, "The function %s at %08x calls:", f.name.c_str(), f.address);
|
DEBUG_LOG(SYMBOLS, "The function %s at %08x calls:", f.name.c_str(), f.address);
|
||||||
for (const SCall& call : f.calls)
|
for (const Common::SCall& call : f.calls)
|
||||||
{
|
{
|
||||||
const auto n = functions.find(call.function);
|
const auto n = m_functions.find(call.function);
|
||||||
if (n != functions.end())
|
if (n != m_functions.end())
|
||||||
{
|
{
|
||||||
DEBUG_LOG(SYMBOLS, "* %08x : %s", call.callAddress, n->second.name.c_str());
|
DEBUG_LOG(SYMBOLS, "* %08x : %s", call.call_address, n->second.name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCSymbolDB::PrintCallers(u32 funcAddr) const
|
void PPCSymbolDB::PrintCallers(u32 funcAddr) const
|
||||||
{
|
{
|
||||||
const auto iter = functions.find(funcAddr);
|
const auto iter = m_functions.find(funcAddr);
|
||||||
if (iter == functions.end())
|
if (iter == m_functions.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Symbol& f = iter->second;
|
const Common::Symbol& f = iter->second;
|
||||||
DEBUG_LOG(SYMBOLS, "The function %s at %08x is called by:", f.name.c_str(), f.address);
|
DEBUG_LOG(SYMBOLS, "The function %s at %08x is called by:", f.name.c_str(), f.address);
|
||||||
for (const SCall& caller : f.callers)
|
for (const Common::SCall& caller : f.callers)
|
||||||
{
|
{
|
||||||
const auto n = functions.find(caller.function);
|
const auto n = m_functions.find(caller.function);
|
||||||
if (n != functions.end())
|
if (n != m_functions.end())
|
||||||
{
|
{
|
||||||
DEBUG_LOG(SYMBOLS, "* %08x : %s", caller.callAddress, n->second.name.c_str());
|
DEBUG_LOG(SYMBOLS, "* %08x : %s", caller.call_address, n->second.name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCSymbolDB::LogFunctionCall(u32 addr)
|
void PPCSymbolDB::LogFunctionCall(u32 addr)
|
||||||
{
|
{
|
||||||
auto iter = functions.find(addr);
|
auto iter = m_functions.find(addr);
|
||||||
if (iter == functions.end())
|
if (iter == m_functions.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Symbol& f = iter->second;
|
Common::Symbol& f = iter->second;
|
||||||
f.numCalls++;
|
f.num_calls++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The use case for handling bad map files is when you have a game with a map file on the disc,
|
// The use case for handling bad map files is when you have a game with a map file on the disc,
|
||||||
|
@ -400,9 +400,9 @@ bool PPCSymbolDB::LoadMap(const std::string& filename, bool bad)
|
||||||
{
|
{
|
||||||
++good_count;
|
++good_count;
|
||||||
if (section_name == ".text" || section_name == ".init")
|
if (section_name == ".text" || section_name == ".init")
|
||||||
AddKnownSymbol(vaddress, size, name, Symbol::Type::Function);
|
AddKnownSymbol(vaddress, size, name, Common::Symbol::Type::Function);
|
||||||
else
|
else
|
||||||
AddKnownSymbol(vaddress, size, name, Symbol::Type::Data);
|
AddKnownSymbol(vaddress, size, name, Common::Symbol::Type::Data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -423,13 +423,13 @@ bool PPCSymbolDB::SaveSymbolMap(const std::string& filename) const
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::vector<const Symbol*> function_symbols;
|
std::vector<const Common::Symbol*> function_symbols;
|
||||||
std::vector<const Symbol*> data_symbols;
|
std::vector<const Common::Symbol*> data_symbols;
|
||||||
|
|
||||||
for (const auto& function : functions)
|
for (const auto& function : m_functions)
|
||||||
{
|
{
|
||||||
const Symbol& symbol = function.second;
|
const Common::Symbol& symbol = function.second;
|
||||||
if (symbol.type == Symbol::Type::Function)
|
if (symbol.type == Common::Symbol::Type::Function)
|
||||||
function_symbols.push_back(&symbol);
|
function_symbols.push_back(&symbol);
|
||||||
else
|
else
|
||||||
data_symbols.push_back(&symbol);
|
data_symbols.push_back(&symbol);
|
||||||
|
@ -472,9 +472,9 @@ bool PPCSymbolDB::SaveCodeMap(const std::string& filename) const
|
||||||
fprintf(f.GetHandle(), ".text\n");
|
fprintf(f.GetHandle(), ".text\n");
|
||||||
|
|
||||||
u32 next_address = 0;
|
u32 next_address = 0;
|
||||||
for (const auto& function : functions)
|
for (const auto& function : m_functions)
|
||||||
{
|
{
|
||||||
const Symbol& symbol = function.second;
|
const Common::Symbol& symbol = function.second;
|
||||||
|
|
||||||
// Skip functions which are inside bigger functions
|
// Skip functions which are inside bigger functions
|
||||||
if (symbol.address + symbol.size <= next_address)
|
if (symbol.address + symbol.size <= next_address)
|
||||||
|
|
|
@ -14,17 +14,17 @@
|
||||||
#include "Core/Debugger/PPCDebugInterface.h"
|
#include "Core/Debugger/PPCDebugInterface.h"
|
||||||
|
|
||||||
// This has functionality overlapping Debugger_Symbolmap. Should merge that stuff in here later.
|
// This has functionality overlapping Debugger_Symbolmap. Should merge that stuff in here later.
|
||||||
class PPCSymbolDB : public SymbolDB
|
class PPCSymbolDB : public Common::SymbolDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PPCSymbolDB();
|
PPCSymbolDB();
|
||||||
~PPCSymbolDB() override;
|
~PPCSymbolDB() override;
|
||||||
|
|
||||||
Symbol* AddFunction(u32 start_addr) override;
|
Common::Symbol* AddFunction(u32 start_addr) override;
|
||||||
void AddKnownSymbol(u32 startAddr, u32 size, const std::string& name,
|
void AddKnownSymbol(u32 startAddr, u32 size, const std::string& name,
|
||||||
Symbol::Type type = Symbol::Type::Function);
|
Common::Symbol::Type type = Common::Symbol::Type::Function);
|
||||||
|
|
||||||
Symbol* GetSymbolFromAddr(u32 addr) override;
|
Common::Symbol* GetSymbolFromAddr(u32 addr) override;
|
||||||
|
|
||||||
std::string GetDescription(u32 addr);
|
std::string GetDescription(u32 addr);
|
||||||
|
|
||||||
|
|
|
@ -280,7 +280,7 @@ void CodeViewWidget::OnCopyFunction()
|
||||||
{
|
{
|
||||||
const u32 address = GetContextAddress();
|
const u32 address = GetContextAddress();
|
||||||
|
|
||||||
const Symbol* symbol = g_symbolDB.GetSymbolFromAddr(address);
|
const Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(address);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ void CodeViewWidget::OnRenameSymbol()
|
||||||
{
|
{
|
||||||
const u32 addr = GetContextAddress();
|
const u32 addr = GetContextAddress();
|
||||||
|
|
||||||
Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
||||||
|
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
@ -396,7 +396,7 @@ void CodeViewWidget::OnSetSymbolSize()
|
||||||
{
|
{
|
||||||
const u32 addr = GetContextAddress();
|
const u32 addr = GetContextAddress();
|
||||||
|
|
||||||
Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
||||||
|
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
@ -419,7 +419,7 @@ void CodeViewWidget::OnSetSymbolEndAddress()
|
||||||
{
|
{
|
||||||
const u32 addr = GetContextAddress();
|
const u32 addr = GetContextAddress();
|
||||||
|
|
||||||
Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
||||||
|
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -202,7 +202,7 @@ void CodeWidget::OnSelectSymbol()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const u32 address = items[0]->data(Qt::UserRole).toUInt();
|
const u32 address = items[0]->data(Qt::UserRole).toUInt();
|
||||||
const Symbol* symbol = g_symbolDB.GetSymbolFromAddr(address);
|
const Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(address);
|
||||||
|
|
||||||
m_code_view->SetAddress(address, CodeViewWidget::SetAddressUpdate::WithUpdate);
|
m_code_view->SetAddress(address, CodeViewWidget::SetAddressUpdate::WithUpdate);
|
||||||
UpdateCallstack();
|
UpdateCallstack();
|
||||||
|
@ -252,7 +252,7 @@ void CodeWidget::SetAddress(u32 address, CodeViewWidget::SetAddressUpdate update
|
||||||
|
|
||||||
void CodeWidget::Update()
|
void CodeWidget::Update()
|
||||||
{
|
{
|
||||||
const Symbol* symbol = g_symbolDB.GetSymbolFromAddr(m_code_view->GetAddress());
|
const Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(m_code_view->GetAddress());
|
||||||
|
|
||||||
UpdateCallstack();
|
UpdateCallstack();
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ void CodeWidget::UpdateSymbols()
|
||||||
item->setSelected(true);
|
item->setSelected(true);
|
||||||
|
|
||||||
// Disable non-function symbols as you can't do anything with them.
|
// Disable non-function symbols as you can't do anything with them.
|
||||||
if (symbol.second.type != Symbol::Type::Function)
|
if (symbol.second.type != Common::Symbol::Type::Function)
|
||||||
item->setFlags(Qt::NoItemFlags);
|
item->setFlags(Qt::NoItemFlags);
|
||||||
|
|
||||||
item->setData(Qt::UserRole, symbol.second.address);
|
item->setData(Qt::UserRole, symbol.second.address);
|
||||||
|
@ -321,14 +321,14 @@ void CodeWidget::UpdateSymbols()
|
||||||
m_symbols_list->sortItems();
|
m_symbols_list->sortItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeWidget::UpdateFunctionCalls(const Symbol* symbol)
|
void CodeWidget::UpdateFunctionCalls(const Common::Symbol* symbol)
|
||||||
{
|
{
|
||||||
m_function_calls_list->clear();
|
m_function_calls_list->clear();
|
||||||
|
|
||||||
for (const auto& call : symbol->calls)
|
for (const auto& call : symbol->calls)
|
||||||
{
|
{
|
||||||
const u32 addr = call.function;
|
const u32 addr = call.function;
|
||||||
const Symbol* call_symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
const Common::Symbol* call_symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
||||||
|
|
||||||
if (call_symbol)
|
if (call_symbol)
|
||||||
{
|
{
|
||||||
|
@ -341,14 +341,14 @@ void CodeWidget::UpdateFunctionCalls(const Symbol* symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeWidget::UpdateFunctionCallers(const Symbol* symbol)
|
void CodeWidget::UpdateFunctionCallers(const Common::Symbol* symbol)
|
||||||
{
|
{
|
||||||
m_function_callers_list->clear();
|
m_function_callers_list->clear();
|
||||||
|
|
||||||
for (const auto& caller : symbol->callers)
|
for (const auto& caller : symbol->callers)
|
||||||
{
|
{
|
||||||
const u32 addr = caller.callAddress;
|
const u32 addr = caller.call_address;
|
||||||
const Symbol* caller_symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
const Common::Symbol* caller_symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
||||||
|
|
||||||
if (caller_symbol)
|
if (caller_symbol)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,11 @@ class QLineEdit;
|
||||||
class QSplitter;
|
class QSplitter;
|
||||||
class QListWidget;
|
class QListWidget;
|
||||||
class QTableWidget;
|
class QTableWidget;
|
||||||
|
|
||||||
|
namespace Common
|
||||||
|
{
|
||||||
struct Symbol;
|
struct Symbol;
|
||||||
|
}
|
||||||
|
|
||||||
class CodeWidget : public QDockWidget
|
class CodeWidget : public QDockWidget
|
||||||
{
|
{
|
||||||
|
@ -45,8 +49,8 @@ private:
|
||||||
void CreateWidgets();
|
void CreateWidgets();
|
||||||
void ConnectWidgets();
|
void ConnectWidgets();
|
||||||
void UpdateCallstack();
|
void UpdateCallstack();
|
||||||
void UpdateFunctionCalls(const Symbol* symbol);
|
void UpdateFunctionCalls(const Common::Symbol* symbol);
|
||||||
void UpdateFunctionCallers(const Symbol* symbol);
|
void UpdateFunctionCallers(const Common::Symbol* symbol);
|
||||||
|
|
||||||
void OnSearchAddress();
|
void OnSearchAddress();
|
||||||
void OnSearchSymbols();
|
void OnSearchSymbols();
|
||||||
|
|
|
@ -45,7 +45,7 @@ void CBreakPointView::Repopulate()
|
||||||
int item = InsertItem(0, breakpoint_enabled_str);
|
int item = InsertItem(0, breakpoint_enabled_str);
|
||||||
SetItem(item, 1, StrToWxStr("BP"));
|
SetItem(item, 1, StrToWxStr("BP"));
|
||||||
|
|
||||||
Symbol* symbol = g_symbolDB.GetSymbolFromAddr(rBP.address);
|
Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(rBP.address);
|
||||||
if (symbol)
|
if (symbol)
|
||||||
{
|
{
|
||||||
wxString symbol_description = StrToWxStr(g_symbolDB.GetDescription(rBP.address));
|
wxString symbol_description = StrToWxStr(g_symbolDB.GetDescription(rBP.address));
|
||||||
|
@ -67,7 +67,7 @@ void CBreakPointView::Repopulate()
|
||||||
int item = InsertItem(0, memcheck_on_str);
|
int item = InsertItem(0, memcheck_on_str);
|
||||||
SetItem(item, 1, StrToWxStr("MBP"));
|
SetItem(item, 1, StrToWxStr("MBP"));
|
||||||
|
|
||||||
Symbol* symbol = g_symbolDB.GetSymbolFromAddr(rMemCheck.start_address);
|
Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(rMemCheck.start_address);
|
||||||
if (symbol)
|
if (symbol)
|
||||||
{
|
{
|
||||||
wxString memcheck_start_addr = StrToWxStr(g_symbolDB.GetDescription(rMemCheck.start_address));
|
wxString memcheck_start_addr = StrToWxStr(g_symbolDB.GetDescription(rMemCheck.start_address));
|
||||||
|
|
|
@ -57,7 +57,7 @@ enum
|
||||||
IDM_ADDFUNCTION,
|
IDM_ADDFUNCTION,
|
||||||
};
|
};
|
||||||
|
|
||||||
CCodeView::CCodeView(DebugInterface* debuginterface, SymbolDB* symboldb, wxWindow* parent,
|
CCodeView::CCodeView(DebugInterface* debuginterface, Common::SymbolDB* symboldb, wxWindow* parent,
|
||||||
wxWindowID Id)
|
wxWindowID Id)
|
||||||
: wxControl(parent, Id), m_debugger(debuginterface), m_symbol_db(symboldb), m_plain(false),
|
: wxControl(parent, Id), m_debugger(debuginterface), m_symbol_db(symboldb), m_plain(false),
|
||||||
m_curAddress(debuginterface->GetPC()), m_align(debuginterface->GetInstructionSize(0)),
|
m_curAddress(debuginterface->GetPC()), m_align(debuginterface->GetInstructionSize(0)),
|
||||||
|
@ -243,7 +243,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||||
|
|
||||||
case IDM_COPYFUNCTION:
|
case IDM_COPYFUNCTION:
|
||||||
{
|
{
|
||||||
Symbol* symbol = m_symbol_db->GetSymbolFromAddr(m_selection);
|
Common::Symbol* symbol = m_symbol_db->GetSymbolFromAddr(m_selection);
|
||||||
if (symbol)
|
if (symbol)
|
||||||
{
|
{
|
||||||
std::string text;
|
std::string text;
|
||||||
|
@ -335,7 +335,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||||
|
|
||||||
case IDM_RENAMESYMBOL:
|
case IDM_RENAMESYMBOL:
|
||||||
{
|
{
|
||||||
Symbol* symbol = m_symbol_db->GetSymbolFromAddr(m_selection);
|
Common::Symbol* symbol = m_symbol_db->GetSymbolFromAddr(m_selection);
|
||||||
if (symbol)
|
if (symbol)
|
||||||
{
|
{
|
||||||
wxTextEntryDialog input_symbol(this, _("Rename symbol:"), wxGetTextFromUserPromptStr,
|
wxTextEntryDialog input_symbol(this, _("Rename symbol:"), wxGetTextFromUserPromptStr,
|
||||||
|
@ -352,7 +352,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||||
|
|
||||||
case IDM_SETSYMBOLSIZE:
|
case IDM_SETSYMBOLSIZE:
|
||||||
{
|
{
|
||||||
Symbol* symbol = m_symbol_db->GetSymbolFromAddr(m_selection);
|
Common::Symbol* symbol = m_symbol_db->GetSymbolFromAddr(m_selection);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||||
|
|
||||||
case IDM_SETSYMBOLEND:
|
case IDM_SETSYMBOLEND:
|
||||||
{
|
{
|
||||||
Symbol* symbol = m_symbol_db->GetSymbolFromAddr(m_selection);
|
Common::Symbol* symbol = m_symbol_db->GetSymbolFromAddr(m_selection);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -18,13 +18,17 @@
|
||||||
wxDECLARE_EVENT(wxEVT_CODEVIEW_CHANGE, wxCommandEvent);
|
wxDECLARE_EVENT(wxEVT_CODEVIEW_CHANGE, wxCommandEvent);
|
||||||
|
|
||||||
class DebugInterface;
|
class DebugInterface;
|
||||||
class SymbolDB;
|
|
||||||
class wxPaintDC;
|
class wxPaintDC;
|
||||||
|
|
||||||
|
namespace Common
|
||||||
|
{
|
||||||
|
class SymbolDB;
|
||||||
|
}
|
||||||
|
|
||||||
class CCodeView : public wxControl
|
class CCodeView : public wxControl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CCodeView(DebugInterface* debuginterface, SymbolDB* symbol_db, wxWindow* parent,
|
CCodeView(DebugInterface* debuginterface, Common::SymbolDB* symbol_db, wxWindow* parent,
|
||||||
wxWindowID Id = wxID_ANY);
|
wxWindowID Id = wxID_ANY);
|
||||||
|
|
||||||
void ToggleBreakpoint(u32 address);
|
void ToggleBreakpoint(u32 address);
|
||||||
|
@ -58,7 +62,7 @@ private:
|
||||||
static constexpr int LEFT_COL_WIDTH = 16;
|
static constexpr int LEFT_COL_WIDTH = 16;
|
||||||
|
|
||||||
DebugInterface* m_debugger;
|
DebugInterface* m_debugger;
|
||||||
SymbolDB* m_symbol_db;
|
Common::SymbolDB* m_symbol_db;
|
||||||
|
|
||||||
bool m_plain;
|
bool m_plain;
|
||||||
|
|
||||||
|
|
|
@ -434,14 +434,14 @@ void CCodeWindow::UpdateLists()
|
||||||
{
|
{
|
||||||
callers->Clear();
|
callers->Clear();
|
||||||
u32 addr = codeview->GetSelection();
|
u32 addr = codeview->GetSelection();
|
||||||
Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto& call : symbol->callers)
|
for (auto& call : symbol->callers)
|
||||||
{
|
{
|
||||||
u32 caller_addr = call.callAddress;
|
u32 caller_addr = call.call_address;
|
||||||
Symbol* caller_symbol = g_symbolDB.GetSymbolFromAddr(caller_addr);
|
Common::Symbol* caller_symbol = g_symbolDB.GetSymbolFromAddr(caller_addr);
|
||||||
if (caller_symbol)
|
if (caller_symbol)
|
||||||
{
|
{
|
||||||
int idx = callers->Append(StrToWxStr(
|
int idx = callers->Append(StrToWxStr(
|
||||||
|
@ -454,7 +454,7 @@ void CCodeWindow::UpdateLists()
|
||||||
for (auto& call : symbol->calls)
|
for (auto& call : symbol->calls)
|
||||||
{
|
{
|
||||||
u32 call_addr = call.function;
|
u32 call_addr = call.function;
|
||||||
Symbol* call_symbol = g_symbolDB.GetSymbolFromAddr(call_addr);
|
Common::Symbol* call_symbol = g_symbolDB.GetSymbolFromAddr(call_addr);
|
||||||
if (call_symbol)
|
if (call_symbol)
|
||||||
{
|
{
|
||||||
int idx = calls->Append(StrToWxStr(
|
int idx = calls->Append(StrToWxStr(
|
||||||
|
|
|
@ -335,7 +335,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
std::istringstream ss(line);
|
std::istringstream ss(line);
|
||||||
ss >> std::hex >> address >> std::dec >> type >> name;
|
ss >> std::hex >> address >> std::dec >> type >> name;
|
||||||
|
|
||||||
Symbol* symbol = g_symbolDB.GetSymbolFromAddr(address);
|
Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(address);
|
||||||
if (symbol)
|
if (symbol)
|
||||||
symbol->Rename(line.substr(12));
|
symbol->Rename(line.substr(12));
|
||||||
}
|
}
|
||||||
|
@ -474,10 +474,10 @@ void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
|
||||||
int index = symbols->GetSelection();
|
int index = symbols->GetSelection();
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
Symbol* pSymbol = static_cast<Symbol*>(symbols->GetClientData(index));
|
auto* pSymbol = static_cast<Common::Symbol*>(symbols->GetClientData(index));
|
||||||
if (pSymbol != nullptr)
|
if (pSymbol != nullptr)
|
||||||
{
|
{
|
||||||
if (pSymbol->type == Symbol::Type::Data)
|
if (pSymbol->type == Common::Symbol::Type::Data)
|
||||||
{
|
{
|
||||||
CMemoryWindow* memory = GetPanel<CMemoryWindow>();
|
CMemoryWindow* memory = GetPanel<CMemoryWindow>();
|
||||||
if (memory)
|
if (memory)
|
||||||
|
|
|
@ -223,10 +223,10 @@ void DSPDebuggerLLE::OnSymbolListChange(wxCommandEvent& event)
|
||||||
int index = m_SymbolList->GetSelection();
|
int index = m_SymbolList->GetSelection();
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
Symbol* pSymbol = static_cast<Symbol*>(m_SymbolList->GetClientData(index));
|
auto* pSymbol = static_cast<Common::Symbol*>(m_SymbolList->GetClientData(index));
|
||||||
if (pSymbol != nullptr)
|
if (pSymbol != nullptr)
|
||||||
{
|
{
|
||||||
if (pSymbol->type == Symbol::Type::Function)
|
if (pSymbol->type == Common::Symbol::Type::Function)
|
||||||
{
|
{
|
||||||
JumpToAddress(pSymbol->address);
|
JumpToAddress(pSymbol->address);
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ wxString CMemoryView::ReadMemoryAsString(u32 address) const
|
||||||
str += ' ';
|
str += ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* sym = g_symbolDB.GetSymbolFromAddr(mem_data);
|
Common::Symbol* sym = g_symbolDB.GetSymbolFromAddr(mem_data);
|
||||||
if (sym)
|
if (sym)
|
||||||
{
|
{
|
||||||
str += StringFromFormat(" # -> %s", sym->name.c_str());
|
str += StringFromFormat(" # -> %s", sym->name.c_str());
|
||||||
|
|
Loading…
Reference in New Issue