From c0c6fc9e6daa10a5a30e4dfb3444d29a0baf482c Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sun, 24 Aug 2008 18:50:51 +0000 Subject: [PATCH] Ok, part 2/2 of the symbol code rewrite. You can now create and use function signature files. A monkey ball signature file included. Now to add some cooler features... git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@294 8ced0084-cf51-0410-be5f-012b33b47a6e --- Binary/win32/Data/monkey.dsy | Bin 0 -> 4220 bytes Source/Core/Core/Core.vcproj | 16 +- Source/Core/Core/Src/Boot/Boot.cpp | 7 +- Source/Core/Core/Src/Boot/ElfReader.cpp | 11 +- Source/Core/Core/Src/Console.cpp | 8 +- .../Src/Debugger/Debugger_BreakPoints.cpp | 16 +- .../Core/Src/Debugger/Debugger_SymbolMap.cpp | 228 +------------- .../Core/Src/Debugger/Debugger_SymbolMap.h | 64 ---- .../Core/Src/Debugger/PPCDebugInterface.cpp | 13 +- Source/Core/Core/Src/HLE/HLE.cpp | 22 +- .../Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp | 7 +- .../Core/Core/Src/HW/EXI_DeviceMemoryCard.h | 2 +- Source/Core/Core/Src/LogManager.cpp | 6 +- Source/Core/Core/Src/PowerPC/FunctionDB.cpp | 170 ---------- Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp | 33 +- Source/Core/Core/Src/PowerPC/PPCAnalyst.h | 8 +- Source/Core/Core/Src/PowerPC/SignatureDB.cpp | 22 +- Source/Core/Core/Src/PowerPC/SignatureDB.h | 6 +- Source/Core/Core/Src/PowerPC/SymbolDB.cpp | 293 ++++++++++++++++++ .../Src/PowerPC/{FunctionDB.h => SymbolDB.h} | 55 +++- Source/Core/Core/Src/SConscript | 2 +- Source/Core/DebuggerWX/DebuggerWX.vcproj | 48 +++ Source/Core/DebuggerWX/src/BreakpointView.cpp | 20 +- Source/Core/DebuggerWX/src/CodeView.cpp | 21 +- Source/Core/DebuggerWX/src/CodeWindow.cpp | 65 ++-- Source/Core/DebuggerWX/src/CodeWindow.h | 2 + Source/Core/DebuggerWX/src/JitWindow.cpp | 2 +- Source/Core/DebuggerWX/src/MemoryWindow.cpp | 18 +- Source/Core/VideoCommon/Src/Fifo.cpp | 3 +- 29 files changed, 546 insertions(+), 622 deletions(-) create mode 100644 Binary/win32/Data/monkey.dsy delete mode 100644 Source/Core/Core/Src/PowerPC/FunctionDB.cpp create mode 100644 Source/Core/Core/Src/PowerPC/SymbolDB.cpp rename Source/Core/Core/Src/PowerPC/{FunctionDB.h => SymbolDB.h} (63%) diff --git a/Binary/win32/Data/monkey.dsy b/Binary/win32/Data/monkey.dsy new file mode 100644 index 0000000000000000000000000000000000000000..f83f6890d29141f5aae2a4aa7a1693e6ccb7f540 GIT binary patch literal 4220 zcmc(i&ubGw6vsF92klKo5k;_2Pz zLPUEJlRvMKIDX2{ZV>usEF}>qm{r@pJo^Ems7sH5E&K`J#`Jlp87L&xJw#{V! zH~gO!W7*9kQ^;YvGza38R1_F-sFJ*_L7pwT%*w8#YmrX*KcVUbh)Bkli>Exy2P<+L z%a)j~&jo9NY8u>_|9UQk94UA%3jr01-(}L*6ulj0;c5C}9XU{+KEbMKPih>!pZs$5 z5^{KfZ$oa9DQBc+( z!u4F!b7mjUB1cJb#fSoxfJ!5!^t`M86C>HpYA;{c)oXEA_qJzh9{Rcy*eXhc?wUo8 zRQ7reohv$zc~nvd73xhBPiLF4M(VZm$RQc@TQiW72{iv#Cx(9NOULY7uX|Ac)%e825VmDVqR E0e*TC+W-In literal 0 HcmV?d00001 diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj index dd95f17409..25b31ce173 100644 --- a/Source/Core/Core/Core.vcproj +++ b/Source/Core/Core/Core.vcproj @@ -796,14 +796,6 @@ - - - - @@ -844,6 +836,14 @@ RelativePath=".\Src\PowerPC\SignatureDB.h" > + + + + diff --git a/Source/Core/Core/Src/Boot/Boot.cpp b/Source/Core/Core/Src/Boot/Boot.cpp index 42424156da..82663f3221 100644 --- a/Source/Core/Core/Src/Boot/Boot.cpp +++ b/Source/Core/Core/Src/Boot/Boot.cpp @@ -40,7 +40,7 @@ #include "../VolumeHandler.h" #include "../PatchEngine.h" #include "../PowerPC/SignatureDB.h" -#include "../PowerPC/FunctionDB.h" +#include "../PowerPC/SymbolDB.h" #include "../MemTools.h" #include "MappedFile.h" @@ -401,17 +401,16 @@ bool CBoot::LoadMapFromFilename(const std::string &_rFilename, const char *_game std::string strMapFilename = GenerateMapFilename(); bool success = false; - if (!Debugger::LoadSymbolMap(strMapFilename.c_str())) + if (!g_symbolDB.LoadMap(strMapFilename.c_str())) { if (_gameID != NULL) { BuildCompleteFilename(strMapFilename, _T("maps"), std::string(_gameID) + _T(".map")); - success = Debugger::LoadSymbolMap(strMapFilename.c_str()); + success = g_symbolDB.LoadMap(strMapFilename.c_str()); } } else { - Debugger::PushMapToFunctionDB(&g_funcDB); success = true; } diff --git a/Source/Core/Core/Src/Boot/ElfReader.cpp b/Source/Core/Core/Src/Boot/ElfReader.cpp index 28241a9993..a3e4277253 100644 --- a/Source/Core/Core/Src/Boot/ElfReader.cpp +++ b/Source/Core/Core/Src/Boot/ElfReader.cpp @@ -3,6 +3,7 @@ #include "Common.h" #include "../Debugger/Debugger_SymbolMap.h" #include "../HW/Memmap.h" +#include "../PowerPC/SymbolDB.h" #include "ElfReader.h" void bswap(Elf32_Word &w) {w = Common::swap32(w);} @@ -232,22 +233,20 @@ bool ElfReader::LoadSymbols() if (bRelocate) value += sectionAddrs[sectionIndex]; - Debugger::ESymbolType symtype = Debugger::ST_DATA; + int symtype = Symbol::SYMBOL_DATA; switch (type) { case STT_OBJECT: - symtype = Debugger::ST_DATA; break; + symtype = Symbol::SYMBOL_DATA; break; case STT_FUNC: - symtype =Debugger:: ST_FUNCTION; break; + symtype = Symbol::SYMBOL_FUNCTION; break; default: continue; } - //host->AddSymbol(name, value, size, symtype); - Debugger::AddSymbol(Debugger::Symbol(value, size, symtype, name)); + g_symbolDB.AddKnownSymbol(value, size, name, symtype); hasSymbols = true; - //... } } return hasSymbols; diff --git a/Source/Core/Core/Src/Console.cpp b/Source/Core/Core/Src/Console.cpp index 4b14f63830..6b4c89b5a3 100644 --- a/Source/Core/Core/Src/Console.cpp +++ b/Source/Core/Core/Src/Console.cpp @@ -27,7 +27,7 @@ #include "CoreTiming.h" #include "Core.h" #include "PowerPC/Jit64/JitCache.h" -#include "PowerPC/FunctionDB.h" +#include "PowerPC/SymbolDB.h" #include "PowerPCDisasm.h" #define CASE(x) else if (memcmp(cmd, x, 4*sizeof(TCHAR))==0) @@ -93,7 +93,7 @@ void Console_Submit(const char *cmd) sscanf(cmd, "%s %08x", temp, &addr); if (addr!=0) { - g_funcDB.PrintCalls(addr); + g_symbolDB.PrintCalls(addr); } else { @@ -107,7 +107,7 @@ void Console_Submit(const char *cmd) sscanf(cmd, "%s %08x", temp, &addr); if (addr!=0) { - g_funcDB.PrintCallers(addr); + g_symbolDB.PrintCallers(addr); } else { @@ -167,7 +167,7 @@ void Console_Submit(const char *cmd) } CASE("lisf") { - g_funcDB.List(); + g_symbolDB.List(); } else { printf("blach\n"); diff --git a/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp b/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp index 7160b27a7b..53b61d5a19 100644 --- a/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp +++ b/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp @@ -29,11 +29,9 @@ #include "../HW/CPU.h" #include "../Host.h" -#include "Debugger_SymbolMap.h" +#include "../PowerPC/SymbolDB.h" #include "Debugger_BreakPoints.h" -using namespace Debugger; - CBreakPoints::TBreakPoints CBreakPoints::m_BreakPoints; CBreakPoints::TMemChecks CBreakPoints::m_MemChecks; u32 CBreakPoints::m_iBreakOnCount = 0; @@ -51,7 +49,7 @@ void TMemCheck::Action(u32 iValue, u32 addr, bool write, int size, u32 pc) { LOG(MEMMAP,"CHK %08x %s%i at %08x (%s)", iValue, write ? "Write" : "Read", size*8, addr, - Debugger::GetDescription(addr)); + g_symbolDB.GetDescription(addr)); } if (Break) CCPU::Break(); @@ -154,14 +152,10 @@ void CBreakPoints::AddAutoBreakpoints() for (int i = 0; i < sizeof(bps) / sizeof(const char *); i++) { - XSymbolIndex idx = FindSymbol(bps[i]); - if (idx != 0) - { - const Symbol &symbol = GetSymbol(idx); - AddBreakPoint(symbol.vaddress, false); - } + Symbol *symbol = g_symbolDB.GetSymbolFromName(bps[i]); + if (symbol) + AddBreakPoint(symbol->address, false); } - Host_UpdateBreakPointView(); #endif #endif diff --git a/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.cpp b/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.cpp index 980bc4e54e..fbfe449493 100644 --- a/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.cpp +++ b/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.cpp @@ -22,223 +22,12 @@ #include "../HW/Memmap.h" #include "../PowerPC/PowerPC.h" #include "../PowerPC/PPCAnalyst.h" -#include "../PowerPC/FunctionDB.h" +#include "../PowerPC/SymbolDB.h" #include "../../../../Externals/Bochs_disasm/PowerPCDisasm.h" namespace Debugger { -static XVectorSymbol g_Symbols; - -Symbol::Symbol(u32 _Address, u32 _Size, ESymbolType _Type, const char *_rName) : - vaddress(_Address), - size(_Size), - runCount(0), - type(_Type), - m_strName(_rName) -{ - // invalid entry - if (m_strName.size() < 2) - { - _Address = -1; - _Size = 0; - } -} - -Symbol::~Symbol() -{ - m_vecBackwardLinks.clear(); -} - -void Reset() -{ - g_Symbols.clear(); - - // 0 is an invalid entry - Symbol Invalid(static_cast(-1), 0, ST_FUNCTION, "Invalid"); - g_Symbols.push_back(Invalid); -} - -XSymbolIndex AddSymbol(const Symbol& symbol) -{ - XSymbolIndex old = FindSymbol(symbol.GetName().c_str()); - if (old != 0) - return old; - g_Symbols.push_back(symbol); - return (XSymbolIndex)(g_Symbols.size() - 1); -} - -const Symbol& GetSymbol(XSymbolIndex _Index) -{ - if (_Index < (XSymbolIndex)g_Symbols.size()) - return g_Symbols[_Index]; - - PanicAlert("GetSymbol is called with an invalid index %i", _Index); - return g_Symbols[0]; -} - -const XVectorSymbol& AccessSymbols() -{ - return g_Symbols; -} - -Symbol& AccessSymbol(XSymbolIndex _Index) -{ - if (_Index < (XSymbolIndex)g_Symbols.size()) - return g_Symbols[_Index]; - - PanicAlert("AccessSymbol is called with an invalid index %i", _Index); - return g_Symbols[0]; -} - -XSymbolIndex FindSymbol(u32 _Address) -{ - for (int i = 0; i < (int)g_Symbols.size(); i++) - { - const Symbol& rSymbol = g_Symbols[i]; - if ((_Address >= rSymbol.vaddress) && (_Address < rSymbol.vaddress + rSymbol.size)) - { - return (XSymbolIndex)i; - } - } - - // invalid index - return 0; -} - -XSymbolIndex FindSymbol(const char *name) -{ - for (int i = 0; i < (int)g_Symbols.size(); i++) - { - const Symbol& rSymbol = g_Symbols[i]; - if (!strcasecmp(rSymbol.GetName().c_str(), name)) - { - return (XSymbolIndex)i; - } - } - - // invalid index - return 0; -} - -// This one can load both leftover map files on game discs (like Zelda), and mapfiles -// produced by SaveSymbolMap below. -bool LoadSymbolMap(const char *_szFilename) -{ - Reset(); - FILE *f = fopen(_szFilename, "r"); - if (!f) - return false; - - bool started = false; - while (!feof(f)) - { - char line[512],temp[256]; - fgets(line, 511, f); - if (strlen(line) < 4) - continue; - - sscanf(line,"%s",temp); - if (strcmp(temp,"UNUSED")==0) continue; - if (strcmp(temp,".text")==0) {started = true; continue;}; - if (strcmp(temp,".init")==0) {started = true; continue;}; - if (strcmp(temp,"Starting")==0) continue; - if (strcmp(temp,"extab")==0) continue; - if (strcmp(temp,".ctors")==0) break; //uh? - if (strcmp(temp,".dtors")==0) break; - if (strcmp(temp,".rodata")==0) continue; - if (strcmp(temp,".data")==0) continue; - if (strcmp(temp,".sbss")==0) continue; - if (strcmp(temp,".sdata")==0) continue; - if (strcmp(temp,".sdata2")==0) continue; - if (strcmp(temp,"address")==0) continue; - if (strcmp(temp,"-----------------------")==0) continue; - if (strcmp(temp,".sbss2")==0) break; - if (temp[1]==']') continue; - - if (!started) continue; - - u32 address, vaddress, size, unknown; - char name[512]; - sscanf(line, "%08x %08x %08x %i %s", &address, &size, &vaddress, &unknown, name); - - const char *namepos = strstr(line, name); - if (namepos != 0) //would be odd if not :P - strcpy(name, namepos); - name[strlen(name) - 1] = 0; - - // we want the function names only .... TODO: or do we really? aren't we wasting information here? - for (size_t i = 0; i < strlen(name); i++) - { - if (name[i] == ' ') name[i] = 0x00; - if (name[i] == '(') name[i] = 0x00; - } - - // Check if this is a valid entry. - if (strcmp(name, ".text") != 0 || strcmp(name, ".init") != 0 || strlen(name) > 0) - { - AddSymbol(Symbol(vaddress | 0x80000000, size, ST_FUNCTION, name)); - } - } - - fclose(f); - return true; -} - -void SaveSymbolMap(const char *_rFilename) -{ - FILE *f = fopen(_rFilename,"w"); - if (!f) - return; - - fprintf(f,".text\n"); - XVectorSymbol::const_iterator itr = g_Symbols.begin(); - while (itr != g_Symbols.end()) - { - const Symbol& rSymbol = *itr; - fprintf(f,"%08x %08x %08x %i %s\n",rSymbol.vaddress,rSymbol.size,rSymbol.vaddress,0,rSymbol.GetName().c_str()); - itr++; - } - fclose(f); -} - -void PushMapToFunctionDB(FunctionDB *func_db) -{ - XVectorSymbol::const_iterator itr = g_Symbols.begin(); - while (itr != g_Symbols.end()) - { - const Symbol& rSymbol = *itr; - - if (rSymbol.type == ST_FUNCTION && rSymbol.size>=12) - { - func_db->AddKnownFunction(rSymbol.vaddress, rSymbol.size / 4, rSymbol.GetName().c_str()); -// if (!beginning || !strlen(beginning) || !(memcmp(beginning,rSymbol.name,strlen(beginning)))) -// PPCAnalyst::AddToSignatureDB(rSymbol.vaddress, rSymbol.size, rSymbol.GetName().c_str()); - } - - itr++; - } -} - -void GetFromAnalyzer() -{ - struct local {static void AddSymb(SFunction *f) - { - Debugger::AddSymbol(Symbol(f->address, f->size * 4, ST_FUNCTION, f->name.c_str())); - }}; - g_funcDB.GetAllFuncs(local::AddSymb); -} - -const char *GetDescription(u32 _Address) -{ - Debugger::XSymbolIndex Index = Debugger::FindSymbol(_Address); - if (Index > 0) - return GetSymbol(Index).GetName().c_str(); - else - return "(unk.)"; -} - - bool GetCallstack(std::vector &output) { if (Core::GetState() == Core::CORE_UNINITIALIZED) @@ -256,10 +45,10 @@ bool GetCallstack(std::vector &output) return false; } int count = 1; - if (GetDescription(PowerPC::ppcState.pc) != GetDescription(LR)) + if (g_symbolDB.GetDescription(PowerPC::ppcState.pc) != g_symbolDB.GetDescription(LR)) { CallstackEntry entry; - entry.Name = StringFromFormat(" * %s [ LR = %08x ]\n", Debugger::GetDescription(LR), LR); + entry.Name = StringFromFormat(" * %s [ LR = %08x ]\n", g_symbolDB.GetDescription(LR), LR); entry.vAddress = 0x0; count++; } @@ -271,7 +60,7 @@ bool GetCallstack(std::vector &output) return false; u32 func = Memory::ReadUnchecked_U32(addr + 4); - const char *str = Debugger::GetDescription(func); + const char *str = g_symbolDB.GetDescription(func); if (!str || strlen(str) == 0 || !strcmp(str, "Invalid")) str = "(unknown)"; @@ -289,7 +78,8 @@ bool GetCallstack(std::vector &output) return true; } -void PrintCallstack() { +void PrintCallstack() +{ u32 addr = Memory::ReadUnchecked_U32(PowerPC::ppcState.gpr[1]); // SP printf("\n == STACK TRACE - SP = %08x ==\n", PowerPC::ppcState.gpr[1]); @@ -298,9 +88,9 @@ void PrintCallstack() { printf(" LR = 0 - this is bad\n"); } int count = 1; - if (GetDescription(PowerPC::ppcState.pc) != GetDescription(LR)) + if (g_symbolDB.GetDescription(PowerPC::ppcState.pc) != g_symbolDB.GetDescription(LR)) { - printf(" * %s [ LR = %08x ]\n", Debugger::GetDescription(LR), LR); + printf(" * %s [ LR = %08x ]\n", g_symbolDB.GetDescription(LR), LR); count++; } @@ -308,7 +98,7 @@ void PrintCallstack() { while ((addr != 0xFFFFFFFF) && (addr != 0) && (count++ < 20) && (PowerPC::ppcState.gpr[1] != 0)) { u32 func = Memory::ReadUnchecked_U32(addr + 4); - const char *str = Debugger::GetDescription(func); + const char *str = g_symbolDB.GetDescription(func); if (!str || strlen(str) == 0 || !strcmp(str, "Invalid")) str = "(unknown)"; printf( " * %s [ addr = %08x ]\n", str, func); diff --git a/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.h b/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.h index 66b3d6256c..d3446354a2 100644 --- a/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.h +++ b/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.h @@ -23,62 +23,9 @@ #include "Common.h" -class FunctionDB; - namespace Debugger { -enum ESymbolType -{ - ST_FUNCTION = 1, - ST_DATA = 2 -}; - -class Symbol -{ -public: - u32 vaddress; - u32 size; - u32 runCount; - - ESymbolType type; - - Symbol(u32 _Address, u32 _Size, ESymbolType _Type, const char *_rName); - ~Symbol(); - - const std::string &GetName() const { return m_strName; } - void SetName(const char *_rName) { m_strName = _rName; } - -private: - std::string m_strName; - std::vector m_vecBackwardLinks; -}; - -typedef int XSymbolIndex; -typedef std::vector XVectorSymbol; - -void Reset(); - -XSymbolIndex AddSymbol(const Symbol& _rSymbolMapEntry); - -const Symbol& GetSymbol(XSymbolIndex _Index); -Symbol& AccessSymbol(XSymbolIndex _Index); - -const XVectorSymbol& AccessSymbols(); - -XSymbolIndex FindSymbol(u32 _Address); -XSymbolIndex FindSymbol(const char *name); - -bool LoadSymbolMap(const char *_rFilename); -void SaveSymbolMap(const char *_rFilename); - -const char *GetDescription(u32 _Address); - -bool RenameSymbol(XSymbolIndex _Index, const char *_Name); - -void GetFromAnalyzer(); -void PushMapToFunctionDB(FunctionDB *func_db); - struct CallstackEntry { std::string Name; @@ -88,17 +35,6 @@ struct CallstackEntry bool GetCallstack(std::vector &output); void PrintCallstack(); -// TODO: move outta here -#ifdef _WIN32 -} -#include -#include -namespace Debugger -{ -void FillSymbolListBox(HWND listbox, ESymbolType symmask); -void FillListBoxBLinks(HWND listbox, XSymbolIndex Index); -#endif - } // end of namespace Debugger #endif diff --git a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp index a935671715..65527fa768 100644 --- a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp +++ b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp @@ -23,6 +23,7 @@ #include "../Core.h" #include "../HW/Memmap.h" #include "../PowerPC/PowerPC.h" +#include "../PowerPC/SymbolDB.h" // Not thread safe. const char *PPCDebugInterface::disasm(unsigned int address) @@ -82,15 +83,17 @@ int PPCDebugInterface::getColor(unsigned int address) { if (!Memory::IsRAMAddress(address)) return 0xeeeeee; - int colors[6] = {0xe0FFFF,0xFFe0e0,0xe8e8FF,0xFFe0FF,0xe0FFe0,0xFFFFe0}; - int n = Debugger::FindSymbol(address); - if (n == -1) return 0xFFFFFF; - return colors[n%6]; + int colors[6] = {0xe0FFFF, 0xFFe0e0, 0xe8e8FF, 0xFFe0FF, 0xe0FFe0, 0xFFFFe0}; + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(address); + if (!symbol) return 0xFFFFFF; + if (symbol->type != Symbol::SYMBOL_FUNCTION) + return 0xEEEEFF; + return colors[symbol->index % 6]; } std::string PPCDebugInterface::getDescription(unsigned int address) { - return Debugger::GetDescription(address); + return g_symbolDB.GetDescription(address); } unsigned int PPCDebugInterface::getPC() diff --git a/Source/Core/Core/Src/HLE/HLE.cpp b/Source/Core/Core/Src/HLE/HLE.cpp index 192762ffba..be04833c7a 100644 --- a/Source/Core/Core/Src/HLE/HLE.cpp +++ b/Source/Core/Core/Src/HLE/HLE.cpp @@ -18,6 +18,7 @@ #include "HLE.h" #include "../PowerPC/PowerPC.h" +#include "../PowerPC/SymbolDB.h" #include "../HW/Memmap.h" #include "../Debugger/Debugger_SymbolMap.h" #include "../Debugger/Debugger_BreakPoints.h" @@ -99,28 +100,23 @@ void PatchFunctions() { for (u32 i = 0; i < sizeof(OSPatches) / sizeof(SPatch); i++) { - int SymbolIndex = Debugger::FindSymbol(OSPatches[i].m_szPatchName); - if (SymbolIndex > 0) + Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName); + if (symbol > 0) { - const Debugger::Symbol& symbol = Debugger::GetSymbol(SymbolIndex); u32 HLEPatchValue = (1 & 0x3f) << 26; - for (size_t addr = symbol.vaddress; addr < symbol.vaddress + symbol.size; addr += 4) { + for (size_t addr = symbol->address; addr < symbol->address + symbol->size; addr += 4) Memory::Write_U32(HLEPatchValue | i, addr); - } - //PanicAlert("patched %s", OSPatches[i].m_szPatchName); - LOG(HLE,"Patching %s %08x", OSPatches[i].m_szPatchName, symbol.vaddress); + LOG(HLE,"Patching %s %08x", OSPatches[i].m_szPatchName, symbol->address); } } for (size_t i = 1; i < sizeof(OSBreakPoints) / sizeof(SPatch); i++) { - int SymbolIndex = Debugger::FindSymbol(OSBreakPoints[i].m_szPatchName); - if (SymbolIndex != -1) + Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName); + if (symbol > 0) { - const Debugger::Symbol& symbol = Debugger::GetSymbol(SymbolIndex); - CBreakPoints::AddBreakPoint(symbol.vaddress, false); - - LOG(HLE,"Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol.vaddress); + CBreakPoints::AddBreakPoint(symbol->address, false); + LOG(HLE,"Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol->address); } } diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp index 8d9425a2e3..41403a7db9 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp @@ -78,7 +78,7 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF status = MC_STATUS_BUSY | MC_STATUS_UNLOCKED | MC_STATUS_READY; } -void CEXIMemoryCard::Flush() +void CEXIMemoryCard::Flush(bool exiting) { FILE* pFile = NULL; pFile = fopen(m_strFilename.c_str(), "wb"); @@ -97,13 +97,14 @@ void CEXIMemoryCard::Flush() } fwrite(memory_card_content, memory_card_size, 1, pFile); fclose(pFile); - Core::DisplayMessage(StringFromFormat("Wrote memory card contents to %s", GetFileName().c_str()), 4000); + if (!exiting) + Core::DisplayMessage(StringFromFormat("Wrote memory card contents to %s", GetFileName().c_str()), 4000); } CEXIMemoryCard::~CEXIMemoryCard() { - Flush(); + Flush(true); delete [] memory_card_content; } diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h index b4e0fb1512..0a26916296 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h @@ -36,7 +36,7 @@ private: static void FlushCallback(u64 userdata, int cyclesLate); // Flushes the memory card contents to disk. - void Flush(); + void Flush(bool exiting = false); enum { diff --git a/Source/Core/Core/Src/LogManager.cpp b/Source/Core/Core/Src/LogManager.cpp index 3472f4f73a..2d076d0f08 100644 --- a/Source/Core/Core/Src/LogManager.cpp +++ b/Source/Core/Core/Src/LogManager.cpp @@ -167,7 +167,7 @@ void LogManager::Log(LogTypes::LOG_TYPE _type, const char *_fmt, ...) char* Msg2 = (char*)alloca(strlen(_fmt)+512); - Debugger::XSymbolIndex Index = 0; //Debugger::FindSymbol(PC); + int Index = 0; //Debugger::FindSymbol(PC); #ifdef _WIN32 const char *eol = "\x0D\x0A"; #else @@ -175,12 +175,12 @@ void LogManager::Log(LogTypes::LOG_TYPE _type, const char *_fmt, ...) #endif if (Index > 0) { - const Debugger::Symbol& symbol = Debugger::GetSymbol(Index); + // const Debugger::Symbol& symbol = Debugger::GetSymbol(Index); sprintf(Msg2, "%i: %x %s (%s, %08x ) : %s%s", ++count, PowerPC::ppcState.DebugCount, m_Log[_type]->m_szShortName, - symbol.GetName().c_str(), + "", //symbol.GetName().c_str(), PC, Msg, eol); } diff --git a/Source/Core/Core/Src/PowerPC/FunctionDB.cpp b/Source/Core/Core/Src/PowerPC/FunctionDB.cpp deleted file mode 100644 index d88f6134c0..0000000000 --- a/Source/Core/Core/Src/PowerPC/FunctionDB.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (C) 2003-2008 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#include "Common.h" - -#include -#include -#include - -#include "FunctionDB.h" -#include "SignatureDB.h" -#include "PPCAnalyst.h" - -FunctionDB g_funcDB; - -void FunctionDB::List() -{ - for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++) - { - LOG(HLE,"%s @ %08x: %i bytes (hash %08x) : %i calls",iter->second.name.c_str(),iter->second.address,iter->second.size,iter->second.hash,iter->second.numCalls); - } - LOG(HLE,"%i functions known in this program above.",functions.size()); -} - -void FunctionDB::Clear() -{ - -} - -// Adds the function to the list, unless it's already there -SFunction *FunctionDB::AddFunction(u32 startAddr) -{ - if (startAddr < 0x80000010) - return 0; - XFuncMap::iterator iter = functions.find(startAddr); - if (iter != functions.end()) - { - // it's already in the list - return 0; - } - else - { - SFunction tempFunc; //the current one we're working on - u32 targetEnd = PPCAnalyst::AnalyzeFunction(startAddr, tempFunc); - if (targetEnd == 0) - return 0; //found a dud :( - //LOG(HLE,"SFunction found at %08x",startAddr); - functions[startAddr] = tempFunc; - checksumToFunction[tempFunc.hash] = &(functions[startAddr]); - return &functions[startAddr]; - } -} - -void FunctionDB::AddKnownFunction(u32 startAddr, u32 size, const char *name) -{ - XFuncMap::iterator iter = functions.find(startAddr); - if (iter != functions.end()) - { - SFunction *tempfunc = &iter->second; - tempfunc->name = name; - tempfunc->hash = SignatureDB::ComputeCodeChecksum(startAddr, startAddr + size); - } - else - { - SFunction tf; - tf.name = name; - PPCAnalyst::AnalyzeFunction(startAddr, tf); - functions[startAddr] = tf; - checksumToFunction[tf.hash] = &(functions[startAddr]); - } -} - -void FunctionDB::FillInCallers() -{ - for (XFuncMap::iterator iter = functions.begin(); iter!=functions.end(); iter++) - { - SFunction &f = iter->second; - for (size_t i=0; ifirst, f.calls[i].callAddress); - u32 FunctionAddress = f.calls[i].function; - XFuncMap::iterator FuncIterator = functions.find(FunctionAddress); - if (FuncIterator != functions.end()) - { - SFunction& rCalledFunction = FuncIterator->second; - rCalledFunction.callers.push_back(NewCall); - } - else - { - LOG(HLE,"FillInCallers tries to fill data in an unknown fuction 0x%08x.", FunctionAddress); - } - } - } -} - -void FunctionDB::PrintCalls(u32 funcAddr) -{ - XFuncMap::iterator iter = functions.find(funcAddr); - if (iter != functions.end()) - { - SFunction &f = iter->second; - LOG(HLE, "The function %s at %08x calls:", f.name.c_str(), f.address); - for (std::vector::iterator fiter = f.calls.begin(); fiter!=f.calls.end(); fiter++) - { - XFuncMap::iterator n = functions.find(fiter->function); - if (n != functions.end()) - { - LOG(CONSOLE,"* %08x : %s", fiter->callAddress, n->second.name.c_str()); - } - } - } - else - { - LOG(CONSOLE,"SFunction does not exist"); - } -} - -void FunctionDB::PrintCallers(u32 funcAddr) -{ - XFuncMap::iterator iter = functions.find(funcAddr); - if (iter != functions.end()) - { - SFunction &f = iter->second; - LOG(CONSOLE,"The function %s at %08x is called by:",f.name.c_str(),f.address); - for (std::vector::iterator fiter = f.callers.begin(); fiter != f.callers.end(); fiter++) - { - XFuncMap::iterator n = functions.find(fiter->function); - if (n != functions.end()) - { - LOG(CONSOLE,"* %08x : %s", fiter->callAddress, n->second.name.c_str()); - } - } - } -} - -void FunctionDB::GetAllFuncs(functionGetterCallback callback) -{ - XFuncMap::iterator iter = functions.begin(); - while (iter != functions.end()) - { - callback(&(iter->second)); - iter++; - } -} - -void FunctionDB::LogFunctionCall(u32 addr) -{ - //u32 from = PC; - XFuncMap::iterator iter = functions.find(addr); - if (iter != functions.end()) - { - SFunction &f = iter->second; - f.numCalls++; - } -} - diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp index 6615fce33f..8c830e8e99 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp @@ -21,7 +21,7 @@ #include "Interpreter/Interpreter.h" #include "../HW/Memmap.h" #include "PPCTables.h" -#include "FunctionDB.h" +#include "SymbolDB.h" #include "SignatureDB.h" #include "PPCAnalyst.h" @@ -40,7 +40,7 @@ using namespace std; // VERY ugly. TODO: remove. PPCAnalyst::CodeOp codebuffer[20000]; -void AnalyzeFunction2(SFunction &func); +void AnalyzeFunction2(Symbol &func); u32 EvaluateBranchTarget(UGeckoInstruction instr, u32 pc); // void FixUpInternalBranches(CodeOp *code, int begin, int end); @@ -73,7 +73,7 @@ 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, SFunction &func) +bool AnalyzeFunction(u32 startAddr, Symbol &func) { if (!func.name.size()) func.name = StringFromFormat("zzz_%08x ??", startAddr); @@ -110,7 +110,9 @@ bool AnalyzeFunction(u32 startAddr, SFunction &func) //a final blr! //We're done! Looks like we have a neat valid function. Perfect. //Let's calc the checksum and get outta here + func.size *= 4; // into bytes func.address = startAddr; + func.analyzed = 1; func.hash = SignatureDB::ComputeCodeChecksum(startAddr, addr); if (numInternalBranches == 0) func.flags |= FFLAG_STRAIGHT; @@ -165,7 +167,7 @@ bool AnalyzeFunction(u32 startAddr, SFunction &func) // Second pass analysis, done after the first pass is done for all functions // so we have more information to work with -void AnalyzeFunction2(SFunction &func) +void AnalyzeFunction2(Symbol &func) { // u32 addr = func.address; u32 flags = func.flags; @@ -193,7 +195,7 @@ void AnalyzeFunction2(SFunction &func) for (size_t i = 0; i < func.calls.size(); i++) { SCall c = func.calls[i]; - SFunction *called_func = g_funcDB.GetFunction(c.function); + Symbol *called_func = g_symbolDB.GetSymbolFromAddr(c.function); if (called_func && (called_func->flags & FFLAG_LEAF) == 0) { nonleafcall = true; @@ -272,7 +274,7 @@ CodeOp *Flatten(u32 address, u32 &realsize, BlockStats &st, BlockRegStats &gpa, }; Todo todo = Nothing; - SFunction *f = g_funcDB.GetFunction(address); + Symbol *f = g_symbolDB.GetSymbolFromAddr(address); int maxsize = 20000; //for now, all will return JustCopy :P if (f) @@ -548,8 +550,7 @@ CodeOp *Flatten(u32 address, u32 &realsize, BlockStats &st, BlockRegStats &gpa, // called by another function. Therefore, let's scan the // entire space for bl operations and find what functions // get called. - -void FindFunctionsFromBranches(u32 startAddr, u32 endAddr, FunctionDB *func_db) +void FindFunctionsFromBranches(u32 startAddr, u32 endAddr, SymbolDB *func_db) { for (u32 addr = startAddr; addr < endAddr; addr+=4) { @@ -580,12 +581,12 @@ void FindFunctionsFromBranches(u32 startAddr, u32 endAddr, FunctionDB *func_db) } } -void FindFunctionsAfterBLR(FunctionDB *func_db) +void FindFunctionsAfterBLR(SymbolDB *func_db) { vector funcAddrs; - for (FunctionDB::XFuncMap::iterator iter = func_db->GetIterator(); iter != func_db->End(); iter++) - funcAddrs.push_back(iter->second.address + iter->second.size*4); + for (SymbolDB::XFuncMap::iterator iter = func_db->GetIterator(); iter != func_db->End(); iter++) + funcAddrs.push_back(iter->second.address + iter->second.size); for (vector::iterator iter = funcAddrs.begin(); iter != funcAddrs.end(); iter++) { @@ -595,11 +596,11 @@ void FindFunctionsAfterBLR(FunctionDB *func_db) if (PPCTables::IsValidInstruction(Memory::Read_Instruction(location))) { //check if this function is already mapped - SFunction *f = func_db->AddFunction(location); + Symbol *f = func_db->AddFunction(location); if (!f) break; else - location += f->size * 4; + location += f->size; } else break; @@ -607,7 +608,7 @@ void FindFunctionsAfterBLR(FunctionDB *func_db) } } -void PPCAnalyst::FindFunctions(u32 startAddr, u32 endAddr, FunctionDB *func_db) +void PPCAnalyst::FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db) { //Step 1: Find all functions FindFunctionsFromBranches(startAddr, endAddr, func_db); @@ -618,7 +619,7 @@ void PPCAnalyst::FindFunctions(u32 startAddr, u32 endAddr, FunctionDB *func_db) int numLeafs = 0, numNice = 0, numUnNice = 0, numTimer=0, numRFI=0, numStraightLeaf=0; int leafSize = 0, niceSize = 0, unniceSize = 0; - for (FunctionDB::XFuncMap::iterator iter = func_db->GetIterator(); iter != func_db->End(); iter++) + for (SymbolDB::XFuncMap::iterator iter = func_db->GetIterator(); iter != func_db->End(); iter++) { if (iter->second.address == 4) { @@ -626,7 +627,7 @@ void PPCAnalyst::FindFunctions(u32 startAddr, u32 endAddr, FunctionDB *func_db) continue; } AnalyzeFunction2(iter->second); - SFunction &f = iter->second; + Symbol &f = iter->second; 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 34c180ba29..dcc0c7dc1c 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.h +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.h @@ -26,8 +26,8 @@ #include "Common.h" #include "Gekko.h" -class FunctionDB; -struct SFunction; +class SymbolDB; +struct Symbol; namespace PPCAnalyst { @@ -82,8 +82,8 @@ namespace PPCAnalyst void LogFunctionCall(u32 addr); - void FindFunctions(u32 startAddr, u32 endAddr, FunctionDB *func_db); - bool AnalyzeFunction(u32 startAddr, SFunction &func); + void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db); + bool AnalyzeFunction(u32 startAddr, Symbol &func); } // namespace #endif diff --git a/Source/Core/Core/Src/PowerPC/SignatureDB.cpp b/Source/Core/Core/Src/PowerPC/SignatureDB.cpp index 38f382c019..afd6f5bb9a 100644 --- a/Source/Core/Core/Src/PowerPC/SignatureDB.cpp +++ b/Source/Core/Core/Src/PowerPC/SignatureDB.cpp @@ -20,7 +20,7 @@ #include "../HW/Memmap.h" #include "SignatureDB.h" -#include "FunctionDB.h" +#include "SymbolDB.h" namespace { @@ -109,31 +109,33 @@ void SignatureDB::Clear() database.clear(); } -void SignatureDB::Apply(FunctionDB *func_db) +void SignatureDB::Apply(SymbolDB *symbol_db) { for (FuncDB::const_iterator iter = database.begin(); iter != database.end(); iter++) { - u32 checkSum = iter->first; - SFunction *function = func_db->GetFunction(checkSum); + u32 hash = iter->first; + Symbol *function = symbol_db->GetSymbolFromHash(hash); if (function) { // Found the function. Let's rename it according to the symbol file. - if (iter->second.size == (unsigned int)function->size * 4) + if (iter->second.size == (unsigned int)function->size) { function->name = iter->second.name; - LOG(HLE,"Found %s at %08x (size: %08x)!", iter->second.name.c_str(), function->address, function->size); - } else + LOG(HLE, "Found %s at %08x (size: %08x)!", iter->second.name.c_str(), function->address, function->size); + } + else { function->name = iter->second.name; - LOG(HLE,"Wrong sizzze! Found %s at %08x (size: %08x instead of %08x)!", iter->second.name.c_str(), function->address, function->size, iter->second.size); + LOG(HLE, "Wrong sizzze! Found %s at %08x (size: %08x instead of %08x)!", iter->second.name.c_str(), function->address, function->size, iter->second.size); } } } + symbol_db->Index(); } -void SignatureDB::Initialize(FunctionDB *func_db) +void SignatureDB::Initialize(SymbolDB *symbol_db) { - for (FunctionDB::XFuncMap::const_iterator iter = func_db->GetConstIterator(); iter != func_db->End(); iter++) + for (SymbolDB::XFuncMap::const_iterator iter = symbol_db->GetConstIterator(); iter != symbol_db->End(); iter++) { DBFunc temp_dbfunc; temp_dbfunc.name = iter->second.name; diff --git a/Source/Core/Core/Src/PowerPC/SignatureDB.h b/Source/Core/Core/Src/PowerPC/SignatureDB.h index 51b8905110..9798772fab 100644 --- a/Source/Core/Core/Src/PowerPC/SignatureDB.h +++ b/Source/Core/Core/Src/PowerPC/SignatureDB.h @@ -22,7 +22,7 @@ // You're not meant to keep around SignatureDB objects persistently. Use 'em, throw them away. -class FunctionDB; +class SymbolDB; class SignatureDB { @@ -50,8 +50,8 @@ public: void Clear(); void List(); - void Initialize(FunctionDB *func_db); - void Apply(FunctionDB *func_db); + void Initialize(SymbolDB *func_db); + void Apply(SymbolDB *func_db); static u32 ComputeCodeChecksum(u32 offsetStart, u32 offsetEnd); }; diff --git a/Source/Core/Core/Src/PowerPC/SymbolDB.cpp b/Source/Core/Core/Src/PowerPC/SymbolDB.cpp new file mode 100644 index 0000000000..8caf0e542f --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/SymbolDB.cpp @@ -0,0 +1,293 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" + +#include +#include +#include + +#include "SymbolDB.h" +#include "SignatureDB.h" +#include "PPCAnalyst.h" + +SymbolDB g_symbolDB; + +void SymbolDB::List() +{ + for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++) + { + LOG(HLE,"%s @ %08x: %i bytes (hash %08x) : %i calls", iter->second.name.c_str(), iter->second.address, iter->second.size, iter->second.hash,iter->second.numCalls); + } + LOG(HLE,"%i functions known in this program above.", functions.size()); +} + +void SymbolDB::Clear() +{ + functions.clear(); + checksumToFunction.clear(); +} + +void SymbolDB::Index() +{ + int i = 0; + for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++) + { + iter->second.index = i++; + } +} + +// Adds the function to the list, unless it's already there +Symbol *SymbolDB::AddFunction(u32 startAddr) +{ + if (startAddr < 0x80000010) + return 0; + XFuncMap::iterator iter = functions.find(startAddr); + if (iter != functions.end()) + { + // it's already in the list + return 0; + } + else + { + Symbol tempFunc; //the current one we're working on + u32 targetEnd = PPCAnalyst::AnalyzeFunction(startAddr, tempFunc); + if (targetEnd == 0) + return 0; //found a dud :( + //LOG(HLE,"Symbol found at %08x",startAddr); + functions[startAddr] = tempFunc; + tempFunc.type = Symbol::SYMBOL_FUNCTION; + checksumToFunction[tempFunc.hash] = &(functions[startAddr]); + return &functions[startAddr]; + } +} + +void SymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const char *name, int type) +{ + XFuncMap::iterator iter = functions.find(startAddr); + if (iter != functions.end()) + { + // already got it, let's just update name and checksum to be sure. + Symbol *tempfunc = &iter->second; + tempfunc->name = name; + tempfunc->hash = SignatureDB::ComputeCodeChecksum(startAddr, startAddr + size); + tempfunc->type = type; + } + else + { + // new symbol. run analyze. + Symbol tf; + tf.name = name; + tf.type = type; + if (tf.type == Symbol::SYMBOL_FUNCTION) { + PPCAnalyst::AnalyzeFunction(startAddr, tf); + checksumToFunction[tf.hash] = &(functions[startAddr]); + } + functions[startAddr] = tf; + } +} + +Symbol *SymbolDB::GetSymbolFromAddr(u32 addr) +{ + XFuncMap::iterator iter = functions.find(addr); + if (iter != functions.end()) + return &iter->second; + else + { + for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++) + { + if (addr >= iter->second.address && addr < iter->second.address + iter->second.size) + return &iter->second; + } + } + return 0; +} + +Symbol *SymbolDB::GetSymbolFromName(const char *name) +{ + for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++) + { + if (!strcmp(iter->second.name.c_str(), name)) + return &iter->second; + } + return 0; +} + +const char *SymbolDB::GetDescription(u32 addr) +{ + Symbol *symbol = GetSymbolFromAddr(addr); + if (symbol) + return symbol->name.c_str(); + else + return " --- "; +} + +void SymbolDB::FillInCallers() +{ + for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++) + { + Symbol &f = iter->second; + for (size_t i = 0; i < f.calls.size(); i++) + { + SCall NewCall(iter->first, f.calls[i].callAddress); + u32 FunctionAddress = f.calls[i].function; + XFuncMap::iterator FuncIterator = functions.find(FunctionAddress); + if (FuncIterator != functions.end()) + { + Symbol& rCalledFunction = FuncIterator->second; + rCalledFunction.callers.push_back(NewCall); + } + else + { + LOG(HLE,"FillInCallers tries to fill data in an unknown function 0x%08x.", FunctionAddress); + } + } + } +} + +void SymbolDB::PrintCalls(u32 funcAddr) +{ + XFuncMap::iterator iter = functions.find(funcAddr); + if (iter != functions.end()) + { + Symbol &f = iter->second; + LOG(HLE, "The function %s at %08x calls:", f.name.c_str(), f.address); + for (std::vector::iterator fiter = f.calls.begin(); fiter!=f.calls.end(); fiter++) + { + XFuncMap::iterator n = functions.find(fiter->function); + if (n != functions.end()) + { + LOG(CONSOLE,"* %08x : %s", fiter->callAddress, n->second.name.c_str()); + } + } + } + else + { + LOG(CONSOLE, "Symbol does not exist"); + } +} + +void SymbolDB::PrintCallers(u32 funcAddr) +{ + XFuncMap::iterator iter = functions.find(funcAddr); + if (iter != functions.end()) + { + Symbol &f = iter->second; + LOG(CONSOLE,"The function %s at %08x is called by:",f.name.c_str(),f.address); + for (std::vector::iterator fiter = f.callers.begin(); fiter != f.callers.end(); fiter++) + { + XFuncMap::iterator n = functions.find(fiter->function); + if (n != functions.end()) + { + LOG(CONSOLE,"* %08x : %s", fiter->callAddress, n->second.name.c_str()); + } + } + } +} + +void SymbolDB::LogFunctionCall(u32 addr) +{ + //u32 from = PC; + XFuncMap::iterator iter = functions.find(addr); + if (iter != functions.end()) + { + Symbol &f = iter->second; + f.numCalls++; + } +} + +// This one can load both leftover map files on game discs (like Zelda), and mapfiles +// produced by SaveSymbolMap below. +bool SymbolDB::LoadMap(const char *filename) +{ + FILE *f = fopen(filename, "r"); + if (!f) + return false; + + bool started = false; + while (!feof(f)) + { + char line[512],temp[256]; + fgets(line, 511, f); + if (strlen(line) < 4) + continue; + + sscanf(line,"%s",temp); + if (strcmp(temp,"UNUSED")==0) continue; + if (strcmp(temp,".text")==0) {started = true; continue;}; + if (strcmp(temp,".init")==0) {started = true; continue;}; + if (strcmp(temp,"Starting")==0) continue; + if (strcmp(temp,"extab")==0) continue; + if (strcmp(temp,".ctors")==0) break; //uh? + if (strcmp(temp,".dtors")==0) break; + if (strcmp(temp,".rodata")==0) continue; + if (strcmp(temp,".data")==0) continue; + if (strcmp(temp,".sbss")==0) continue; + if (strcmp(temp,".sdata")==0) continue; + if (strcmp(temp,".sdata2")==0) continue; + if (strcmp(temp,"address")==0) continue; + if (strcmp(temp,"-----------------------")==0) continue; + if (strcmp(temp,".sbss2")==0) break; + if (temp[1] == ']') continue; + + if (!started) continue; + + u32 address, vaddress, size, unknown; + char name[512]; + sscanf(line, "%08x %08x %08x %i %s", &address, &size, &vaddress, &unknown, name); + + const char *namepos = strstr(line, name); + if (namepos != 0) //would be odd if not :P + strcpy(name, namepos); + name[strlen(name) - 1] = 0; + + // we want the function names only .... TODO: or do we really? aren't we wasting information here? + for (size_t i = 0; i < strlen(name); i++) + { + if (name[i] == ' ') name[i] = 0x00; + if (name[i] == '(') name[i] = 0x00; + } + + // Check if this is a valid entry. + if (strcmp(name, ".text") != 0 || strcmp(name, ".init") != 0 || strlen(name) > 0) + { + AddKnownSymbol(vaddress | 0x80000000, size, name); // ST_FUNCTION + } + } + + fclose(f); + Index(); + return true; +} + +bool SymbolDB::SaveMap(const char *filename) +{ + FILE *f = fopen(filename, "w"); + if (!f) + return false; + + fprintf(f,".text\n"); + XFuncMap::const_iterator itr = functions.begin(); + while (itr != functions.end()) + { + const Symbol &rSymbol = itr->second; + fprintf(f,"%08x %08x %08x %i %s\n", rSymbol.address, rSymbol.size, rSymbol.address, 0, rSymbol.name.c_str()); + itr++; + } + fclose(f); + return true; +} \ No newline at end of file diff --git a/Source/Core/Core/Src/PowerPC/FunctionDB.h b/Source/Core/Core/Src/PowerPC/SymbolDB.h similarity index 63% rename from Source/Core/Core/Src/PowerPC/FunctionDB.h rename to Source/Core/Core/Src/PowerPC/SymbolDB.h index cc1bc2c78f..353eab4665 100644 --- a/Source/Core/Core/Src/PowerPC/FunctionDB.h +++ b/Source/Core/Core/Src/PowerPC/SymbolDB.h @@ -31,18 +31,24 @@ struct SCall u32 callAddress; }; -struct SFunction +struct Symbol { - SFunction() : + enum { + SYMBOL_FUNCTION = 0, + SYMBOL_DATA = 1, + }; + + Symbol() : hash(0), address(0), flags(0), size(0), numCalls(0), - analyzed(0) + analyzed(0), + type(SYMBOL_FUNCTION) {} - ~SFunction() + ~Symbol() { callers.clear(); calls.clear(); @@ -56,6 +62,8 @@ struct SFunction u32 flags; int size; int numCalls; + int type; + int index; // only used for coloring the disasm view int analyzed; }; @@ -72,42 +80,55 @@ enum // This has functionality overlapping Debugger_Symbolmap. Should merge that stuff in here later. -class FunctionDB +class SymbolDB { public: - typedef std::map XFuncMap; - typedef std::map XFuncPtrMap; + typedef std::map XFuncMap; + typedef std::map XFuncPtrMap; private: XFuncMap functions; XFuncPtrMap checksumToFunction; public: - - typedef void (*functionGetterCallback)(SFunction *f); + typedef void (*functionGetterCallback)(Symbol *f); - FunctionDB() {} + SymbolDB() {} - SFunction *AddFunction(u32 startAddr); - void AddKnownFunction(u32 startAddr, u32 size, const char *name); + Symbol *AddFunction(u32 startAddr); + void AddKnownSymbol(u32 startAddr, u32 size, const char *name, int type = Symbol::SYMBOL_FUNCTION); - void GetAllFuncs(functionGetterCallback callback); - SFunction *GetFunction(u32 hash) { - // TODO: sanity check - return checksumToFunction[hash]; + Symbol *GetSymbolFromAddr(u32 addr); + Symbol *GetSymbolFromName(const char *name); + Symbol *GetSymbolFromHash(u32 hash) { + XFuncPtrMap::iterator iter = checksumToFunction.find(hash); + if (iter != checksumToFunction.end()) + return iter->second; + else + return 0; } + const XFuncMap &Symbols() const {return functions;} + XFuncMap &AccessSymbols() {return functions;} + + // deprecated XFuncMap::iterator GetIterator() { return functions.begin(); } XFuncMap::const_iterator GetConstIterator() { return functions.begin(); } XFuncMap::iterator End() { return functions.end(); } + const char *GetDescription(u32 addr); + void Clear(); void List(); + void Index(); void FillInCallers(); + bool LoadMap(const char *filename); + bool SaveMap(const char *filename); + void PrintCalls(u32 funcAddr); void PrintCallers(u32 funcAddr); void LogFunctionCall(u32 addr); }; -extern FunctionDB g_funcDB; +extern SymbolDB g_symbolDB; diff --git a/Source/Core/Core/Src/SConscript b/Source/Core/Core/Src/SConscript index a1b7bca50e..50b2746b24 100644 --- a/Source/Core/Core/Src/SConscript +++ b/Source/Core/Core/Src/SConscript @@ -58,7 +58,7 @@ files = ["Console.cpp", "PowerPC/PPCAnalyst.cpp", "PowerPC/PPCTables.cpp", "PowerPC/SignatureDB.cpp", - "PowerPC/FunctionDB.cpp", + "PowerPC/SymbolDB.cpp", "PowerPC/Interpreter/Interpreter.cpp", "PowerPC/Interpreter/Interpreter_Branch.cpp", "PowerPC/Interpreter/Interpreter_Integer.cpp", diff --git a/Source/Core/DebuggerWX/DebuggerWX.vcproj b/Source/Core/DebuggerWX/DebuggerWX.vcproj index 7612ee032b..13c182f340 100644 --- a/Source/Core/DebuggerWX/DebuggerWX.vcproj +++ b/Source/Core/DebuggerWX/DebuggerWX.vcproj @@ -499,6 +499,54 @@ + + + + + + + + + + + + + + + + + + 0) + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(rBP.iAddress); + if (symbol) { - temp = wxString::FromAscii(Debugger::GetDescription(rBP.iAddress)); + temp = wxString::FromAscii("halloj"); //Debugger::GetDescription(rBP.iAddress)); SetItem(Item, 2, temp); } @@ -75,7 +75,7 @@ CBreakPointView::Update() } const CBreakPoints::TMemChecks& rMemChecks = CBreakPoints::GetMemChecks(); - for (size_t i=0; i 0) + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(rMemCheck.StartAddress); + if (symbol) { - temp = wxString::FromAscii(Debugger::GetDescription(rMemCheck.StartAddress)); + temp = wxString::FromAscii("bjorn"); //Debugger::GetDescription(rMemCheck.StartAddress)); SetItem(Item, 2, temp); } diff --git a/Source/Core/DebuggerWX/src/CodeView.cpp b/Source/Core/DebuggerWX/src/CodeView.cpp index 3edc50be01..cb2a76a6e7 100644 --- a/Source/Core/DebuggerWX/src/CodeView.cpp +++ b/Source/Core/DebuggerWX/src/CodeView.cpp @@ -17,7 +17,7 @@ #include "Debugger.h" #include "Debugger/PPCDebugInterface.h" -#include "Debugger/Debugger_SymbolMap.h" +#include "PowerPC/SymbolDB.h" #include "Common.h" #include "StringUtil.h" @@ -184,13 +184,13 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event) break; case IDM_COPYFUNCTION: { - int sel = Debugger::FindSymbol(selection); - if (sel > 0) { + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(selection); + if (symbol) { std::string text; - text = text + Debugger::GetSymbol(sel).GetName() + "\r\n"; + text = text + symbol->name + "\r\n"; // we got a function - u32 start = Debugger::GetSymbol(sel).vaddress; - u32 end = start + Debugger::GetSymbol(sel).size; + u32 start = symbol->address; + u32 end = start + symbol->size; for (u32 addr = start; addr != end; addr += 4) { text = text + StringFromFormat("%08x: ", addr) + debugger->disasm(addr) + "\r\n"; } @@ -217,11 +217,12 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event) case IDM_RENAMESYMBOL: { - int sel = Debugger::FindSymbol(selection); - if (sel > 0) { - wxTextEntryDialog input_symbol(this, wxString::FromAscii("Rename symbol:"), wxGetTextFromUserPromptStr, wxString::FromAscii(Debugger::GetSymbol(sel).GetName().c_str())); + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(selection); + if (symbol) { + wxTextEntryDialog input_symbol(this, wxString::FromAscii("Rename symbol:"), wxGetTextFromUserPromptStr, + wxString::FromAscii(symbol->name.c_str())); if (input_symbol.ShowModal() == wxID_OK) { - Debugger::AccessSymbol(sel).SetName(input_symbol.GetValue().mb_str()); + symbol->name = input_symbol.GetValue().mb_str(); } // redraw(); Host_NotifyMapLoaded(); diff --git a/Source/Core/DebuggerWX/src/CodeWindow.cpp b/Source/Core/DebuggerWX/src/CodeWindow.cpp index 3a156d0f95..045268debf 100644 --- a/Source/Core/DebuggerWX/src/CodeWindow.cpp +++ b/Source/Core/DebuggerWX/src/CodeWindow.cpp @@ -48,7 +48,7 @@ #include "Debugger/PPCDebugInterface.h" #include "Debugger/Debugger_SymbolMap.h" #include "PowerPC/PPCAnalyst.h" -#include "PowerPC/FunctionDB.h" +#include "PowerPC/SymbolDB.h" #include "PowerPC/SignatureDB.h" #include "PowerPC/PPCTables.h" #include "PowerPC/Jit64/Jit.h" @@ -73,6 +73,8 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxFrame) EVT_MENU(IDM_BREAKPOINTWINDOW, CCodeWindow::OnToggleBreakPointWindow) EVT_MENU(IDM_MEMORYWINDOW, CCodeWindow::OnToggleMemoryWindow) + EVT_MENU(IDM_CLEARSYMBOLS, CCodeWindow::OnSymbolsMenu) + EVT_MENU(IDM_LOADMAPFILE, CCodeWindow::OnSymbolsMenu) EVT_MENU(IDM_SCANFUNCTIONS, CCodeWindow::OnSymbolsMenu) EVT_MENU(IDM_SAVEMAPFILE, CCodeWindow::OnSymbolsMenu) EVT_MENU(IDM_CREATESIGNATUREFILE, CCodeWindow::OnSymbolsMenu) @@ -173,12 +175,13 @@ void CCodeWindow::CreateGUIControls(const SCoreStartupParameter& _LocalCoreStart DebugInterface* di = new PPCDebugInterface(); - sizerLeft->Add(callstack = new wxListBox(this, IDM_CALLSTACKLIST, wxDefaultPosition, wxSize(90, 100)), 0, wxEXPAND); - sizerLeft->Add(symbols = new wxListBox(this, IDM_SYMBOLLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 1, wxEXPAND); codeview = new CCodeView(di, this, wxID_ANY); sizerBig->Add(sizerLeft, 2, wxEXPAND); sizerBig->Add(codeview, 5, wxEXPAND); + sizerLeft->Add(callstack = new wxListBox(this, IDM_CALLSTACKLIST, wxDefaultPosition, wxSize(90, 100)), 0, wxEXPAND); + sizerLeft->Add(symbols = new wxListBox(this, IDM_SYMBOLLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 1, wxEXPAND); + SetSizer(sizerBig); sizerLeft->SetSizeHints(this); @@ -246,7 +249,10 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam { wxMenu *pSymbolsMenu = new wxMenu; - pSymbolsMenu->Append(IDM_SCANFUNCTIONS, _T("&Load/generate symbol map")); + pSymbolsMenu->Append(IDM_CLEARSYMBOLS, _T("&Clear symbols")); + pSymbolsMenu->Append(IDM_SCANFUNCTIONS, _T("&Generate symbol map")); + pSymbolsMenu->AppendSeparator(); + pSymbolsMenu->Append(IDM_LOADMAPFILE, _T("&Load symbol map")); pSymbolsMenu->Append(IDM_SAVEMAPFILE, _T("&Save symbol map")); pSymbolsMenu->AppendSeparator(); pSymbolsMenu->Append(IDM_CREATESIGNATUREFILE, _T("&Create signature file...")); @@ -305,23 +311,34 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) std::string mapfile = CBoot::GenerateMapFilename(); switch (event.GetId()) { + case IDM_CLEARSYMBOLS: + g_symbolDB.Clear(); + 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(); + break; + } + case IDM_LOADMAPFILE: if (!File::Exists(mapfile)) { - g_funcDB.Clear(); - PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_funcDB); + g_symbolDB.Clear(); + PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB); SignatureDB db; if (db.Load("data/totaldb.dsy")) - db.Apply(&g_funcDB); - Debugger::GetFromAnalyzer(); + db.Apply(&g_symbolDB); } else { - Debugger::LoadSymbolMap(mapfile.c_str()); - Debugger::PushMapToFunctionDB(&g_funcDB); + g_symbolDB.LoadMap(mapfile.c_str()); } Host_NotifyMapLoaded(); break; case IDM_SAVEMAPFILE: - Debugger::SaveSymbolMap(mapfile.c_str()); + g_symbolDB.SaveMap(mapfile.c_str()); break; case IDM_CREATESIGNATUREFILE: { @@ -331,7 +348,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) this); if (path) { SignatureDB db; - db.Initialize(&g_funcDB); + db.Initialize(&g_symbolDB); std::string filename(path.ToAscii()); // PPCAnalyst::SaveSignatureDB( db.Save(path.ToAscii()); } @@ -346,9 +363,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) if (path) { SignatureDB db; db.Load(path.ToAscii()); - db.Apply(&g_funcDB); - Debugger::Reset(); - Debugger::GetFromAnalyzer(); + db.Apply(&g_symbolDB); } } Host_NotifyMapLoaded(); @@ -426,7 +441,6 @@ void CCodeWindow::OnAddrBoxChange(wxCommandEvent& event) void CCodeWindow::Update() { codeview->Refresh(); - callstack->Clear(); std::vector stack; @@ -445,7 +459,6 @@ void CCodeWindow::Update() } UpdateButtonStates(); - Host_UpdateLogDisplay(); } @@ -454,18 +467,12 @@ void CCodeWindow::NotifyMapLoaded() { symbols->Show(false); // hide it for faster filling symbols->Clear(); -#ifdef _WIN32 - const Debugger::XVectorSymbol& syms = Debugger::AccessSymbols(); - - for (int i = 0; i < (int)syms.size(); i++) + + for (SymbolDB::XFuncMap::iterator iter = g_symbolDB.GetIterator(); iter != g_symbolDB.End(); iter++) { - int idx = symbols->Append(syms[i].GetName().c_str()); - symbols->SetClientData(idx, (void*)&syms[i]); + int idx = symbols->Append(iter->second.name.c_str()); + symbols->SetClientData(idx, (void*)&iter->second); } - - // -#endif - symbols->Show(true); Update(); } @@ -508,11 +515,11 @@ void CCodeWindow::UpdateButtonStates() void CCodeWindow::OnSymbolListChange(wxCommandEvent& event) { int index = symbols->GetSelection(); - Debugger::Symbol* pSymbol = static_cast(symbols->GetClientData(index)); + Symbol* pSymbol = static_cast(symbols->GetClientData(index)); if (pSymbol != NULL) { - codeview->Center(pSymbol->vaddress); + codeview->Center(pSymbol->address); } } diff --git a/Source/Core/DebuggerWX/src/CodeWindow.h b/Source/Core/DebuggerWX/src/CodeWindow.h index 45e965928e..e90a589cdd 100644 --- a/Source/Core/DebuggerWX/src/CodeWindow.h +++ b/Source/Core/DebuggerWX/src/CodeWindow.h @@ -81,7 +81,9 @@ class CCodeWindow IDM_MEMORYWINDOW, IDM_SCANFUNCTIONS, IDM_LOGINSTRUCTIONS, + IDM_LOADMAPFILE, IDM_SAVEMAPFILE, + IDM_CLEARSYMBOLS, IDM_CREATESIGNATUREFILE, IDM_USESIGNATUREFILE, IDM_USESYMBOLFILE, diff --git a/Source/Core/DebuggerWX/src/JitWindow.cpp b/Source/Core/DebuggerWX/src/JitWindow.cpp index a48d645220..d859c46e52 100644 --- a/Source/Core/DebuggerWX/src/JitWindow.cpp +++ b/Source/Core/DebuggerWX/src/JitWindow.cpp @@ -49,7 +49,7 @@ CJitWindow *the_jit_window; enum { - IDM_REFRESH_LIST = 33350, + IDM_REFRESH_LIST = 23350, IDM_PPC_BOX, IDM_X86_BOX, IDM_NEXT, diff --git a/Source/Core/DebuggerWX/src/MemoryWindow.cpp b/Source/Core/DebuggerWX/src/MemoryWindow.cpp index 7e276d8b5a..1c7906025d 100644 --- a/Source/Core/DebuggerWX/src/MemoryWindow.cpp +++ b/Source/Core/DebuggerWX/src/MemoryWindow.cpp @@ -30,7 +30,7 @@ #include "Host.h" #include "Debugger/PPCDebugInterface.h" -#include "Debugger/Debugger_SymbolMap.h" +#include "PowerPC/SymbolDB.h" #include "Core.h" #include "LogManager.h" @@ -148,18 +148,18 @@ void CMemoryWindow::NotifyMapLoaded() { symbols->Show(false); // hide it for faster filling symbols->Clear(); + /* #ifdef _WIN32 - const Debugger::XVectorSymbol& syms = Debugger::AccessSymbols(); - - for (int i = 0; i < (int)syms.size(); i++) + const FunctionDB::XFuncMap &syms = g_symbolDB.Symbols(); + for (FuntionDB::XFuncMap::iterator iter = syms.begin(); iter != syms.end(); ++iter) { - int idx = symbols->Append(syms[i].GetName().c_str()); - symbols->SetClientData(idx, (void*)&syms[i]); + int idx = symbols->Append(iter->second.name.c_str()); + symbols->SetClientData(idx, (void*)&iter->second); } // #endif - +*/ symbols->Show(true); Update(); } @@ -167,11 +167,11 @@ void CMemoryWindow::NotifyMapLoaded() void CMemoryWindow::OnSymbolListChange(wxCommandEvent& event) { int index = symbols->GetSelection(); - Debugger::Symbol* pSymbol = static_cast(symbols->GetClientData(index)); + Symbol* pSymbol = static_cast(symbols->GetClientData(index)); if (pSymbol != NULL) { - memview->Center(pSymbol->vaddress); + memview->Center(pSymbol->address); } } diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index 94577f9d70..7b407a934b 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -26,8 +26,9 @@ #define FIFO_SIZE (1024*1024) -// STATE_TO_SAVE FifoReader fifo; + +// STATE_TO_SAVE static u8 *videoBuffer; static int size = 0; static int readptr = 0;