diff --git a/Source/Core/Core/Src/Boot/ElfReader.cpp b/Source/Core/Core/Src/Boot/ElfReader.cpp index a3e4277253..a37c555ece 100644 --- a/Source/Core/Core/Src/Boot/ElfReader.cpp +++ b/Source/Core/Core/Src/Boot/ElfReader.cpp @@ -245,10 +245,10 @@ bool ElfReader::LoadSymbols() continue; } g_symbolDB.AddKnownSymbol(value, size, name, symtype); - hasSymbols = true; } } + g_symbolDB.Index(); return hasSymbols; } diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp index f26769747a..f8cc4fead0 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp @@ -73,10 +73,10 @@ u32 EvaluateBranchTarget(UGeckoInstruction instr, u32 pc) //If any one goes farther than the blr, assume that there is more than //one blr, and keep scanning. -bool AnalyzeFunction(u32 startAddr, Symbol &func) +bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size) { if (!func.name.size()) - func.name = StringFromFormat("zzz_%08x ??", startAddr); + func.name = StringFromFormat("zz_%07x_", startAddr & 0x0FFFFFF); if (func.analyzed >= 1) return true; // No error, just already did it. @@ -93,9 +93,17 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func) func.size++; if (func.size > 1024*16) //weird return false; - + 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 (instr.hex == 0x4e800020) //4e800021 is blrl, not the end of a function @@ -119,6 +127,21 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func) 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) { func.flags &= ~FFLAG_LEAF; @@ -133,12 +156,12 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func) { if (instr.OPCD == 16) { - u32 target = SignExt16(instr.BD<<2); + u32 target = SignExt16(instr.BD << 2); if (!instr.AA) target += addr; - if (target > farthestInternalBranchTarget) + if (target > farthestInternalBranchTarget && !instr.LK) { farthestInternalBranchTarget = target; } @@ -628,6 +651,13 @@ void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db) } AnalyzeFunction2(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) { numLeafs++; diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.h b/Source/Core/Core/Src/PowerPC/PPCAnalyst.h index dcc0c7dc1c..5d996cc2de 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.h +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.h @@ -83,7 +83,7 @@ namespace PPCAnalyst void LogFunctionCall(u32 addr); 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 #endif diff --git a/Source/Core/Core/Src/PowerPC/SymbolDB.cpp b/Source/Core/Core/Src/PowerPC/SymbolDB.cpp index 80511116ef..68be69317f 100644 --- a/Source/Core/Core/Src/PowerPC/SymbolDB.cpp +++ b/Source/Core/Core/Src/PowerPC/SymbolDB.cpp @@ -36,8 +36,9 @@ void SymbolDB::List() 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(); checksumToFunction.clear(); } @@ -94,7 +95,7 @@ void SymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const char *name, int typ tf.name = name; tf.type = type; if (tf.type == Symbol::SYMBOL_FUNCTION) { - PPCAnalyst::AnalyzeFunction(startAddr, tf); + PPCAnalyst::AnalyzeFunction(startAddr, tf, size); checksumToFunction[tf.hash] = &(functions[startAddr]); } functions[startAddr] = tf; diff --git a/Source/Core/Core/Src/PowerPC/SymbolDB.h b/Source/Core/Core/Src/PowerPC/SymbolDB.h index 353eab4665..e078079551 100644 --- a/Source/Core/Core/Src/PowerPC/SymbolDB.h +++ b/Source/Core/Core/Src/PowerPC/SymbolDB.h @@ -118,7 +118,7 @@ public: const char *GetDescription(u32 addr); - void Clear(); + void Clear(const char *prefix = ""); void List(); void Index(); void FillInCallers(); diff --git a/Source/Core/DebuggerWX/src/CodeWindow.cpp b/Source/Core/DebuggerWX/src/CodeWindow.cpp index 46c28debb7..a169f4a11d 100644 --- a/Source/Core/DebuggerWX/src/CodeWindow.cpp +++ b/Source/Core/DebuggerWX/src/CodeWindow.cpp @@ -256,6 +256,7 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam { wxMenu *pSymbolsMenu = new wxMenu; pSymbolsMenu->Append(IDM_CLEARSYMBOLS, _T("&Clear symbols")); + // pSymbolsMenu->Append(IDM_CLEANSYMBOLS, _T("&Clean symbols (zz)")); pSymbolsMenu->Append(IDM_SCANFUNCTIONS, _T("&Generate symbol map")); pSymbolsMenu->AppendSeparator(); pSymbolsMenu->Append(IDM_LOADMAPFILE, _T("&Load symbol map")); @@ -316,13 +317,17 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) g_symbolDB.Clear(); Host_NotifyMapLoaded(); break; + case IDM_CLEANSYMBOLS: + g_symbolDB.Clear("zz"); + Host_NotifyMapLoaded(); + break; case IDM_SCANFUNCTIONS: { PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB); SignatureDB db; if (db.Load("data/totaldb.dsy")) db.Apply(&g_symbolDB); - Host_NotifyMapLoaded(); + NotifyMapLoaded(); break; } case IDM_LOADMAPFILE: @@ -336,7 +341,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) } else { g_symbolDB.LoadMap(mapfile.c_str()); } - Host_NotifyMapLoaded(); + NotifyMapLoaded(); break; case IDM_SAVEMAPFILE: g_symbolDB.SaveMap(mapfile.c_str()); @@ -367,7 +372,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) db.Apply(&g_symbolDB); } } - Host_NotifyMapLoaded(); + NotifyMapLoaded(); break; } } @@ -441,8 +446,10 @@ void CCodeWindow::UpdateLists() { u32 caller_addr = symbol->callers[i].callAddress; Symbol *caller_symbol = g_symbolDB.GetSymbolFromAddr(caller_addr); - int idx = callers->Append(wxString::Format( _T("< %s (%08x)"), caller_symbol->name.c_str(), caller_addr)); - callers->SetClientData(idx, (void*)caller_addr); + if (caller_symbol) { + int idx = callers->Append(wxString::Format( "< %s (%08x)", caller_symbol->name.c_str(), caller_addr)); + callers->SetClientData(idx, (void*)caller_addr); + } } calls->Clear(); @@ -450,8 +457,10 @@ void CCodeWindow::UpdateLists() { u32 call_addr = symbol->calls[i].function; Symbol *call_symbol = g_symbolDB.GetSymbolFromAddr(call_addr); - int idx = calls->Append(wxString::Format( _T("> %s (%08x)"), call_symbol->name.c_str(), call_addr)); - calls->SetClientData(idx, (void*)call_addr); + if (call_symbol) { + int idx = calls->Append(wxString::Format("> %s (%08x)", call_symbol->name.c_str(), call_addr).c_str()); + calls->SetClientData(idx, (void*)call_addr); + } } } diff --git a/Source/Core/DebuggerWX/src/CodeWindow.h b/Source/Core/DebuggerWX/src/CodeWindow.h index ec0d083ffe..e8f6edea3f 100644 --- a/Source/Core/DebuggerWX/src/CodeWindow.h +++ b/Source/Core/DebuggerWX/src/CodeWindow.h @@ -88,6 +88,7 @@ class CCodeWindow IDM_LOADMAPFILE, IDM_SAVEMAPFILE, IDM_CLEARSYMBOLS, + IDM_CLEANSYMBOLS, IDM_CREATESIGNATUREFILE, IDM_USESIGNATUREFILE, IDM_USESYMBOLFILE,