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:
hrydgard 2008-08-24 18:50:51 +00:00
parent 23665a7b93
commit c0c6fc9e6d
29 changed files with 546 additions and 622 deletions

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -81,7 +81,9 @@ class CCodeWindow
IDM_MEMORYWINDOW,
IDM_SCANFUNCTIONS,
IDM_LOGINSTRUCTIONS,
IDM_LOADMAPFILE,
IDM_SAVEMAPFILE,
IDM_CLEARSYMBOLS,
IDM_CREATESIGNATUREFILE,
IDM_USESIGNATUREFILE,
IDM_USESYMBOLFILE,

View File

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

View File

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

View File

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