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:
hrydgard 2008-08-24 21:30:59 +00:00
parent 241896ee4c
commit 71ea240890
7 changed files with 59 additions and 18 deletions

View File

@ -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;
} }

View File

@ -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++;

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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);
}
} }
} }

View File

@ -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,