More symbol magic+bugfixes
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@300 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
241896ee4c
commit
71ea240890
|
@ -245,10 +245,10 @@ bool ElfReader::LoadSymbols()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
g_symbolDB.AddKnownSymbol(value, size, name, symtype);
|
g_symbolDB.AddKnownSymbol(value, size, name, symtype);
|
||||||
|
|
||||||
hasSymbols = true;
|
hasSymbols = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g_symbolDB.Index();
|
||||||
return hasSymbols;
|
return hasSymbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,10 +73,10 @@ u32 EvaluateBranchTarget(UGeckoInstruction instr, u32 pc)
|
||||||
//If any one goes farther than the blr, assume that there is more than
|
//If any one goes farther than the blr, assume that there is more than
|
||||||
//one blr, and keep scanning.
|
//one blr, and keep scanning.
|
||||||
|
|
||||||
bool AnalyzeFunction(u32 startAddr, Symbol &func)
|
bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size)
|
||||||
{
|
{
|
||||||
if (!func.name.size())
|
if (!func.name.size())
|
||||||
func.name = StringFromFormat("zzz_%08x ??", startAddr);
|
func.name = StringFromFormat("zz_%07x_", startAddr & 0x0FFFFFF);
|
||||||
if (func.analyzed >= 1)
|
if (func.analyzed >= 1)
|
||||||
return true; // No error, just already did it.
|
return true; // No error, just already did it.
|
||||||
|
|
||||||
|
@ -95,7 +95,15 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
UGeckoInstruction instr = (UGeckoInstruction)Memory::ReadUnchecked_U32(addr);
|
UGeckoInstruction instr = (UGeckoInstruction)Memory::ReadUnchecked_U32(addr);
|
||||||
|
if (max_size && func.size > max_size)
|
||||||
|
{
|
||||||
|
func.address = startAddr;
|
||||||
|
func.analyzed = 1;
|
||||||
|
func.hash = SignatureDB::ComputeCodeChecksum(startAddr, addr);
|
||||||
|
if (numInternalBranches == 0)
|
||||||
|
func.flags |= FFLAG_STRAIGHT;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (PPCTables::IsValidInstruction(instr))
|
if (PPCTables::IsValidInstruction(instr))
|
||||||
{
|
{
|
||||||
if (instr.hex == 0x4e800020) //4e800021 is blrl, not the end of a function
|
if (instr.hex == 0x4e800020) //4e800021 is blrl, not the end of a function
|
||||||
|
@ -119,6 +127,21 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
else if ((instr.hex & 0xFC000000) == (0x4b000000 & 0xFC000000) && !instr.LK) {
|
||||||
|
u32 target = addr + SignExt26(instr.LI << 2);
|
||||||
|
if (target < startAddr || (max_size && target > max_size+startAddr))
|
||||||
|
{
|
||||||
|
//block ends by branching away. We're done!
|
||||||
|
func.size *= 4; // into bytes
|
||||||
|
func.address = startAddr;
|
||||||
|
func.analyzed = 1;
|
||||||
|
func.hash = SignatureDB::ComputeCodeChecksum(startAddr, addr);
|
||||||
|
if (numInternalBranches == 0)
|
||||||
|
func.flags |= FFLAG_STRAIGHT;
|
||||||
|
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 &= ~FFLAG_LEAF;
|
||||||
|
@ -133,12 +156,12 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func)
|
||||||
{
|
{
|
||||||
if (instr.OPCD == 16)
|
if (instr.OPCD == 16)
|
||||||
{
|
{
|
||||||
u32 target = SignExt16(instr.BD<<2);
|
u32 target = SignExt16(instr.BD << 2);
|
||||||
|
|
||||||
if (!instr.AA)
|
if (!instr.AA)
|
||||||
target += addr;
|
target += addr;
|
||||||
|
|
||||||
if (target > farthestInternalBranchTarget)
|
if (target > farthestInternalBranchTarget && !instr.LK)
|
||||||
{
|
{
|
||||||
farthestInternalBranchTarget = target;
|
farthestInternalBranchTarget = target;
|
||||||
}
|
}
|
||||||
|
@ -628,6 +651,13 @@ void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db)
|
||||||
}
|
}
|
||||||
AnalyzeFunction2(iter->second);
|
AnalyzeFunction2(iter->second);
|
||||||
Symbol &f = iter->second;
|
Symbol &f = iter->second;
|
||||||
|
if (f.name.substr(0,3) == "zzz")
|
||||||
|
{
|
||||||
|
if (f.flags & FFLAG_LEAF)
|
||||||
|
f.name += "_leaf";
|
||||||
|
if (f.flags & FFLAG_STRAIGHT)
|
||||||
|
f.name += "_straight";
|
||||||
|
}
|
||||||
if (f.flags & FFLAG_LEAF)
|
if (f.flags & FFLAG_LEAF)
|
||||||
{
|
{
|
||||||
numLeafs++;
|
numLeafs++;
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace PPCAnalyst
|
||||||
void LogFunctionCall(u32 addr);
|
void LogFunctionCall(u32 addr);
|
||||||
|
|
||||||
void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db);
|
void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db);
|
||||||
bool AnalyzeFunction(u32 startAddr, Symbol &func);
|
bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size = 0);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,8 +36,9 @@ void SymbolDB::List()
|
||||||
LOG(HLE,"%i functions known in this program above.", functions.size());
|
LOG(HLE,"%i functions known in this program above.", functions.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolDB::Clear()
|
void SymbolDB::Clear(const char *prefix)
|
||||||
{
|
{
|
||||||
|
// TODO: honor prefix
|
||||||
functions.clear();
|
functions.clear();
|
||||||
checksumToFunction.clear();
|
checksumToFunction.clear();
|
||||||
}
|
}
|
||||||
|
@ -94,7 +95,7 @@ void SymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const char *name, int typ
|
||||||
tf.name = name;
|
tf.name = name;
|
||||||
tf.type = type;
|
tf.type = type;
|
||||||
if (tf.type == Symbol::SYMBOL_FUNCTION) {
|
if (tf.type == Symbol::SYMBOL_FUNCTION) {
|
||||||
PPCAnalyst::AnalyzeFunction(startAddr, tf);
|
PPCAnalyst::AnalyzeFunction(startAddr, tf, size);
|
||||||
checksumToFunction[tf.hash] = &(functions[startAddr]);
|
checksumToFunction[tf.hash] = &(functions[startAddr]);
|
||||||
}
|
}
|
||||||
functions[startAddr] = tf;
|
functions[startAddr] = tf;
|
||||||
|
|
|
@ -118,7 +118,7 @@ public:
|
||||||
|
|
||||||
const char *GetDescription(u32 addr);
|
const char *GetDescription(u32 addr);
|
||||||
|
|
||||||
void Clear();
|
void Clear(const char *prefix = "");
|
||||||
void List();
|
void List();
|
||||||
void Index();
|
void Index();
|
||||||
void FillInCallers();
|
void FillInCallers();
|
||||||
|
|
|
@ -256,6 +256,7 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam
|
||||||
{
|
{
|
||||||
wxMenu *pSymbolsMenu = new wxMenu;
|
wxMenu *pSymbolsMenu = new wxMenu;
|
||||||
pSymbolsMenu->Append(IDM_CLEARSYMBOLS, _T("&Clear symbols"));
|
pSymbolsMenu->Append(IDM_CLEARSYMBOLS, _T("&Clear symbols"));
|
||||||
|
// pSymbolsMenu->Append(IDM_CLEANSYMBOLS, _T("&Clean symbols (zz)"));
|
||||||
pSymbolsMenu->Append(IDM_SCANFUNCTIONS, _T("&Generate symbol map"));
|
pSymbolsMenu->Append(IDM_SCANFUNCTIONS, _T("&Generate symbol map"));
|
||||||
pSymbolsMenu->AppendSeparator();
|
pSymbolsMenu->AppendSeparator();
|
||||||
pSymbolsMenu->Append(IDM_LOADMAPFILE, _T("&Load symbol map"));
|
pSymbolsMenu->Append(IDM_LOADMAPFILE, _T("&Load symbol map"));
|
||||||
|
@ -316,13 +317,17 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
g_symbolDB.Clear();
|
g_symbolDB.Clear();
|
||||||
Host_NotifyMapLoaded();
|
Host_NotifyMapLoaded();
|
||||||
break;
|
break;
|
||||||
|
case IDM_CLEANSYMBOLS:
|
||||||
|
g_symbolDB.Clear("zz");
|
||||||
|
Host_NotifyMapLoaded();
|
||||||
|
break;
|
||||||
case IDM_SCANFUNCTIONS:
|
case IDM_SCANFUNCTIONS:
|
||||||
{
|
{
|
||||||
PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB);
|
PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB);
|
||||||
SignatureDB db;
|
SignatureDB db;
|
||||||
if (db.Load("data/totaldb.dsy"))
|
if (db.Load("data/totaldb.dsy"))
|
||||||
db.Apply(&g_symbolDB);
|
db.Apply(&g_symbolDB);
|
||||||
Host_NotifyMapLoaded();
|
NotifyMapLoaded();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IDM_LOADMAPFILE:
|
case IDM_LOADMAPFILE:
|
||||||
|
@ -336,7 +341,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
} else {
|
} else {
|
||||||
g_symbolDB.LoadMap(mapfile.c_str());
|
g_symbolDB.LoadMap(mapfile.c_str());
|
||||||
}
|
}
|
||||||
Host_NotifyMapLoaded();
|
NotifyMapLoaded();
|
||||||
break;
|
break;
|
||||||
case IDM_SAVEMAPFILE:
|
case IDM_SAVEMAPFILE:
|
||||||
g_symbolDB.SaveMap(mapfile.c_str());
|
g_symbolDB.SaveMap(mapfile.c_str());
|
||||||
|
@ -367,7 +372,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
db.Apply(&g_symbolDB);
|
db.Apply(&g_symbolDB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Host_NotifyMapLoaded();
|
NotifyMapLoaded();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,8 +446,10 @@ void CCodeWindow::UpdateLists()
|
||||||
{
|
{
|
||||||
u32 caller_addr = symbol->callers[i].callAddress;
|
u32 caller_addr = symbol->callers[i].callAddress;
|
||||||
Symbol *caller_symbol = g_symbolDB.GetSymbolFromAddr(caller_addr);
|
Symbol *caller_symbol = g_symbolDB.GetSymbolFromAddr(caller_addr);
|
||||||
int idx = callers->Append(wxString::Format( _T("< %s (%08x)"), caller_symbol->name.c_str(), caller_addr));
|
if (caller_symbol) {
|
||||||
callers->SetClientData(idx, (void*)caller_addr);
|
int idx = callers->Append(wxString::Format( "< %s (%08x)", caller_symbol->name.c_str(), caller_addr));
|
||||||
|
callers->SetClientData(idx, (void*)caller_addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
calls->Clear();
|
calls->Clear();
|
||||||
|
@ -450,8 +457,10 @@ void CCodeWindow::UpdateLists()
|
||||||
{
|
{
|
||||||
u32 call_addr = symbol->calls[i].function;
|
u32 call_addr = symbol->calls[i].function;
|
||||||
Symbol *call_symbol = g_symbolDB.GetSymbolFromAddr(call_addr);
|
Symbol *call_symbol = g_symbolDB.GetSymbolFromAddr(call_addr);
|
||||||
int idx = calls->Append(wxString::Format( _T("> %s (%08x)"), call_symbol->name.c_str(), call_addr));
|
if (call_symbol) {
|
||||||
calls->SetClientData(idx, (void*)call_addr);
|
int idx = calls->Append(wxString::Format("> %s (%08x)", call_symbol->name.c_str(), call_addr).c_str());
|
||||||
|
calls->SetClientData(idx, (void*)call_addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ class CCodeWindow
|
||||||
IDM_LOADMAPFILE,
|
IDM_LOADMAPFILE,
|
||||||
IDM_SAVEMAPFILE,
|
IDM_SAVEMAPFILE,
|
||||||
IDM_CLEARSYMBOLS,
|
IDM_CLEARSYMBOLS,
|
||||||
|
IDM_CLEANSYMBOLS,
|
||||||
IDM_CREATESIGNATUREFILE,
|
IDM_CREATESIGNATUREFILE,
|
||||||
IDM_USESIGNATUREFILE,
|
IDM_USESIGNATUREFILE,
|
||||||
IDM_USESYMBOLFILE,
|
IDM_USESYMBOLFILE,
|
||||||
|
|
Loading…
Reference in New Issue