mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
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
This commit is contained in:
parent
23665a7b93
commit
c0c6fc9e6d
BIN
Binary/win32/Data/monkey.dsy
Normal file
BIN
Binary/win32/Data/monkey.dsy
Normal file
Binary file not shown.
@ -796,14 +796,6 @@
|
||||
<Filter
|
||||
Name="PowerPC"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\PowerPC\FunctionDB.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\PowerPC\FunctionDB.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\PowerPC\Gekko.h"
|
||||
>
|
||||
@ -844,6 +836,14 @@
|
||||
RelativePath=".\Src\PowerPC\SignatureDB.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\PowerPC\SymbolDB.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\PowerPC\SymbolDB.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Interpreter"
|
||||
>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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<u32>(-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<CallstackEntry> &output)
|
||||
{
|
||||
if (Core::GetState() == Core::CORE_UNINITIALIZED)
|
||||
@ -256,10 +45,10 @@ bool GetCallstack(std::vector<CallstackEntry> &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<CallstackEntry> &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<CallstackEntry> &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);
|
||||
|
@ -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 <u32> m_vecBackwardLinks;
|
||||
};
|
||||
|
||||
typedef int XSymbolIndex;
|
||||
typedef std::vector<Symbol> 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<CallstackEntry> &output);
|
||||
void PrintCallstack();
|
||||
|
||||
// TODO: move outta here
|
||||
#ifdef _WIN32
|
||||
}
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
namespace Debugger
|
||||
{
|
||||
void FillSymbolListBox(HWND listbox, ESymbolType symmask);
|
||||
void FillListBoxBLinks(HWND listbox, XSymbolIndex Index);
|
||||
#endif
|
||||
|
||||
} // end of namespace Debugger
|
||||
|
||||
#endif
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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; 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())
|
||||
{
|
||||
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<SCall>::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<SCall>::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++;
|
||||
}
|
||||
}
|
||||
|
@ -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<u32> 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<u32>::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++;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
};
|
||||
|
293
Source/Core/Core/Src/PowerPC/SymbolDB.cpp
Normal file
293
Source/Core/Core/Src/PowerPC/SymbolDB.cpp
Normal file
@ -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 <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<SCall>::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<SCall>::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;
|
||||
}
|
@ -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<u32, SFunction> XFuncMap;
|
||||
typedef std::map<u32, SFunction*> XFuncPtrMap;
|
||||
typedef std::map<u32, Symbol> XFuncMap;
|
||||
typedef std::map<u32, Symbol*> 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;
|
@ -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",
|
||||
|
@ -499,6 +499,54 @@
|
||||
<File
|
||||
RelativePath=".\src\CodeWindow.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="DebugFast|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="DebugFast|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\CodeWindow.h"
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "BreakpointView.h"
|
||||
#include "Debugger/Debugger_BreakPoints.h"
|
||||
#include "Debugger/Debugger_SymbolMap.h"
|
||||
#include "PowerPC/SymbolDB.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(CBreakPointView, wxListCtrl)
|
||||
|
||||
@ -35,8 +36,7 @@ CBreakPointView::CBreakPointView(wxWindow* parent, const wxWindowID id, const wx
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CBreakPointView::Update()
|
||||
void CBreakPointView::Update()
|
||||
{
|
||||
ClearAll();
|
||||
|
||||
@ -48,7 +48,7 @@ CBreakPointView::Update()
|
||||
|
||||
char szBuffer[64];
|
||||
const CBreakPoints::TBreakPoints& rBreakPoints = CBreakPoints::GetBreakPoints();
|
||||
for (size_t i=0; i<rBreakPoints.size(); i++)
|
||||
for (size_t i = 0; i < rBreakPoints.size(); i++)
|
||||
{
|
||||
const TBreakPoint& rBP = rBreakPoints[i];
|
||||
if (!rBP.bTemporary)
|
||||
@ -59,10 +59,10 @@ CBreakPointView::Update()
|
||||
temp = wxString::FromAscii("BP");
|
||||
SetItem(Item, 1, temp);
|
||||
|
||||
Debugger::XSymbolIndex index = Debugger::FindSymbol(rBP.iAddress);
|
||||
if (index > 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<rMemChecks.size(); i++)
|
||||
for (size_t i = 0; i < rMemChecks.size(); i++)
|
||||
{
|
||||
const TMemCheck& rMemCheck = rMemChecks[i];
|
||||
|
||||
@ -85,10 +85,10 @@ CBreakPointView::Update()
|
||||
temp = wxString::FromAscii("MC");
|
||||
SetItem(Item, 1, temp);
|
||||
|
||||
Debugger::XSymbolIndex index = Debugger::FindSymbol(rMemCheck.StartAddress);
|
||||
if (index > 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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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<Debugger::CallstackEntry> 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<Debugger::Symbol *>(symbols->GetClientData(index));
|
||||
Symbol* pSymbol = static_cast<Symbol *>(symbols->GetClientData(index));
|
||||
|
||||
if (pSymbol != NULL)
|
||||
{
|
||||
codeview->Center(pSymbol->vaddress);
|
||||
codeview->Center(pSymbol->address);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,9 @@ class CCodeWindow
|
||||
IDM_MEMORYWINDOW,
|
||||
IDM_SCANFUNCTIONS,
|
||||
IDM_LOGINSTRUCTIONS,
|
||||
IDM_LOADMAPFILE,
|
||||
IDM_SAVEMAPFILE,
|
||||
IDM_CLEARSYMBOLS,
|
||||
IDM_CREATESIGNATUREFILE,
|
||||
IDM_USESIGNATUREFILE,
|
||||
IDM_USESYMBOLFILE,
|
||||
|
@ -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,
|
||||
|
@ -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<Debugger::Symbol*>(symbols->GetClientData(index));
|
||||
Symbol* pSymbol = static_cast<Symbol *>(symbols->GetClientData(index));
|
||||
|
||||
if (pSymbol != NULL)
|
||||
{
|
||||
memview->Center(pSymbol->vaddress);
|
||||
memview->Center(pSymbol->address);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user