New DSP debugger: step one. (not ready yet, but try loading zelda WW and look at the dsp debugger..).
Had to shuffle around quite a lot of code to be able to extract the CodeView into a library nicely so it can be used from both the main dolphin and the LLE plugin... also extracted the symboldb code. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3517 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
1 parent
80217a6ed7
commit
aecaf271f1
76 files changed
+1895
-794
No files matched your search
@@ -963,6 +963,14 @@
|
||||
RelativePath=".\Src\PowerPC\PPCAnalyst.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\PowerPC\PPCSymbolDB.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\PowerPC\PPCSymbolDB.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\PowerPC\PPCTables.cpp"
|
||||
>
|
||||
@@ -987,14 +995,6 @@
|
||||
RelativePath=".\Src\PowerPC\SignatureDB.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\PowerPC\SymbolDB.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\PowerPC\SymbolDB.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Interpreter"
|
||||
>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include "../VolumeHandler.h"
|
||||
#include "../PatchEngine.h"
|
||||
#include "../PowerPC/SignatureDB.h"
|
||||
#include "../PowerPC/SymbolDB.h"
|
||||
#include "../PowerPC/PPCSymbolDB.h"
|
||||
#include "../MemTools.h"
|
||||
|
||||
#include "../ConfigManager.h"
|
||||
@@ -314,7 +314,7 @@ bool CBoot::BootUp()
|
||||
|
||||
Boot_ELF(_StartupPara.m_strFilename.c_str());
|
||||
UpdateDebugger_MapLoaded();
|
||||
BreakPoints::AddAutoBreakpoints();
|
||||
Debugger::AddAutoBreakpoints();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "Common.h"
|
||||
#include "../Debugger/Debugger_SymbolMap.h"
|
||||
#include "../HW/Memmap.h"
|
||||
#include "../PowerPC/SymbolDB.h"
|
||||
#include "../PowerPC/PPCSymbolDB.h"
|
||||
#include "ElfReader.h"
|
||||
|
||||
void bswap(Elf32_Word &w) {w = Common::swap32(w);}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "CoreTiming.h"
|
||||
#include "Core.h"
|
||||
#include "PowerPC/Jit64/Jit.h"
|
||||
#include "PowerPC/SymbolDB.h"
|
||||
#include "PowerPC/PPCSymbolDB.h"
|
||||
#include "PowerPCDisasm.h"
|
||||
#include "Console.h"
|
||||
|
||||
|
||||
@@ -399,6 +399,7 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||
DSPInitialize dspInit;
|
||||
dspInit.hWnd = g_pWindowHandle;
|
||||
dspInit.pARAM_Read_U8 = (u8 (__cdecl *)(const u32))DSP::ReadARAM;
|
||||
dspInit.pARAM_Write_U8 = (void (__cdecl *)(const u8, const u32))DSP::WriteARAM;
|
||||
dspInit.pGetARAMPointer = DSP::GetARAMPtr;
|
||||
dspInit.pGetMemoryPointer = Memory::GetPointer;
|
||||
dspInit.pLog = Callback_DSPLog;
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#ifndef _DEBUGINTERFACE_H
|
||||
#define _DEBUGINTERFACE_H
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
class DebugInterface
|
||||
{
|
||||
protected:
|
||||
virtual ~DebugInterface() {}
|
||||
|
||||
public:
|
||||
virtual void disasm(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");}
|
||||
virtual void getRawMemoryString(int memory, unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");}
|
||||
virtual int getInstructionSize(int /*instruction*/) {return 1;}
|
||||
virtual bool isAlive() {return true;}
|
||||
virtual bool isBreakpoint(unsigned int /*address*/) {return false;}
|
||||
virtual void setBreakpoint(unsigned int /*address*/){}
|
||||
virtual void clearBreakpoint(unsigned int /*address*/){}
|
||||
virtual void clearAllBreakpoints() {}
|
||||
virtual void toggleBreakpoint(unsigned int /*address*/){}
|
||||
virtual unsigned int readMemory(unsigned int /*address*/){return 0;}
|
||||
virtual unsigned int readExtraMemory(int memory, unsigned int address){return 0;}
|
||||
virtual unsigned int readInstruction(unsigned int /*address*/){return 0;}
|
||||
virtual unsigned int getPC() {return 0;}
|
||||
virtual void setPC(unsigned int /*address*/) {}
|
||||
virtual void step() {}
|
||||
virtual void runToBreakpoint() {}
|
||||
virtual void insertBLR(unsigned int /*address*/, unsigned int) {}
|
||||
virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;}
|
||||
virtual std::string getDescription(unsigned int /*address*/) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -19,12 +19,11 @@
|
||||
|
||||
#include "../HW/CPU.h"
|
||||
#include "../Host.h"
|
||||
#include "../PowerPC/SymbolDB.h"
|
||||
#include "../PowerPC/PPCSymbolDB.h"
|
||||
#include "Debugger_BreakPoints.h"
|
||||
|
||||
BreakPoints::TBreakPoints BreakPoints::m_BreakPoints;
|
||||
|
||||
MemChecks::TMemChecks MemChecks::m_MemChecks;
|
||||
BreakPoints g_breakpoints;
|
||||
MemChecks g_memchecks;
|
||||
|
||||
void TMemCheck::Action(u32 iValue, u32 addr, bool write, int size, u32 pc)
|
||||
{
|
||||
@@ -99,24 +98,6 @@ void BreakPoints::Clear()
|
||||
Host_UpdateBreakPointView();
|
||||
}
|
||||
|
||||
void BreakPoints::AddAutoBreakpoints()
|
||||
{
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
#if 1
|
||||
const char *bps[] = {
|
||||
"PPCHalt",
|
||||
};
|
||||
|
||||
for (u32 i = 0; i < sizeof(bps) / sizeof(const char *); i++)
|
||||
{
|
||||
Symbol *symbol = g_symbolDB.GetSymbolFromName(bps[i]);
|
||||
if (symbol)
|
||||
BreakPoints::Add(symbol->address, false);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void BreakPoints::DeleteByAddress(u32 _Address)
|
||||
{
|
||||
// first check breakpoints
|
||||
|
||||
@@ -51,52 +51,52 @@ struct TMemCheck
|
||||
void Action(u32 _iValue, u32 addr, bool write, int size, u32 pc);
|
||||
};
|
||||
|
||||
|
||||
// Code breakpoints.
|
||||
class BreakPoints
|
||||
{
|
||||
public:
|
||||
typedef std::vector<TBreakPoint> TBreakPoints;
|
||||
|
||||
static const TBreakPoints& GetBreakPoints() { return m_BreakPoints; }
|
||||
const TBreakPoints& GetBreakPoints() { return m_BreakPoints; }
|
||||
|
||||
// is address breakpoint
|
||||
static bool IsAddressBreakPoint(u32 _iAddress);
|
||||
static bool IsTempBreakPoint(u32 _iAddress);
|
||||
bool IsAddressBreakPoint(u32 _iAddress);
|
||||
bool IsTempBreakPoint(u32 _iAddress);
|
||||
|
||||
// AddBreakPoint
|
||||
static bool Add(u32 em_address, bool temp=false);
|
||||
bool Add(u32 em_address, bool temp=false);
|
||||
|
||||
// Remove Breakpoint
|
||||
static bool Remove(u32 _iAddress);
|
||||
static void Clear();
|
||||
bool Remove(u32 _iAddress);
|
||||
void Clear();
|
||||
|
||||
static void UpdateBreakPointView();
|
||||
|
||||
static void AddAutoBreakpoints();
|
||||
static void DeleteByAddress(u32 _Address);
|
||||
void DeleteByAddress(u32 _Address);
|
||||
|
||||
private:
|
||||
static TBreakPoints m_BreakPoints;
|
||||
static u32 m_iBreakOnCount;
|
||||
TBreakPoints m_BreakPoints;
|
||||
u32 m_iBreakOnCount;
|
||||
};
|
||||
|
||||
extern BreakPoints g_breakpoints;
|
||||
|
||||
|
||||
// Memory breakpoints
|
||||
class MemChecks
|
||||
{
|
||||
public:
|
||||
typedef std::vector<TMemCheck> TMemChecks;
|
||||
static TMemChecks m_MemChecks;
|
||||
static const TMemChecks& GetMemChecks() { return m_MemChecks; }
|
||||
static void Add(const TMemCheck& _rMemoryCheck);
|
||||
TMemChecks m_MemChecks;
|
||||
const TMemChecks& GetMemChecks() { return m_MemChecks; }
|
||||
void Add(const TMemCheck& _rMemoryCheck);
|
||||
|
||||
//memory breakpoint
|
||||
static TMemCheck *GetMemCheck(u32 address);
|
||||
static void DeleteByAddress(u32 _Address);
|
||||
TMemCheck *GetMemCheck(u32 address);
|
||||
void DeleteByAddress(u32 _Address);
|
||||
|
||||
void Clear();
|
||||
};
|
||||
|
||||
extern MemChecks g_memchecks;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,16 +18,35 @@
|
||||
#include "Common.h"
|
||||
#include "StringUtil.h"
|
||||
#include "Debugger_SymbolMap.h"
|
||||
#include "Debugger_Breakpoints.h"
|
||||
#include "../Core.h"
|
||||
#include "../HW/Memmap.h"
|
||||
#include "../PowerPC/PowerPC.h"
|
||||
#include "../PowerPC/PPCAnalyst.h"
|
||||
#include "../PowerPC/SymbolDB.h"
|
||||
#include "../PowerPC/PPCSymbolDB.h"
|
||||
#include "../../../../Externals/Bochs_disasm/PowerPCDisasm.h"
|
||||
|
||||
namespace Debugger
|
||||
{
|
||||
|
||||
void AddAutoBreakpoints()
|
||||
{
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
#if 1
|
||||
const char *bps[] = {
|
||||
"PPCHalt",
|
||||
};
|
||||
|
||||
for (u32 i = 0; i < sizeof(bps) / sizeof(const char *); i++)
|
||||
{
|
||||
Symbol *symbol = g_symbolDB.GetSymbolFromName(bps[i]);
|
||||
if (symbol)
|
||||
g_breakpoints.Add(symbol->address, false);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GetCallstack(std::vector<CallstackEntry> &output)
|
||||
{
|
||||
if (Core::GetState() == Core::CORE_UNINITIALIZED)
|
||||
|
||||
@@ -36,6 +36,8 @@ bool GetCallstack(std::vector<CallstackEntry> &output);
|
||||
void PrintCallstack();
|
||||
void PrintCallstack(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level);
|
||||
void PrintDataBuffer(LogTypes::LOG_TYPE _Log, u8* _pData, size_t _Size, const char* _title);
|
||||
void AddAutoBreakpoints();
|
||||
|
||||
|
||||
} // end of namespace Debugger
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "../HW/Memmap.h"
|
||||
#include "../PowerPC/PowerPC.h"
|
||||
#include "../PowerPC/Jit64/Jit.h"
|
||||
#include "../PowerPC/SymbolDB.h"
|
||||
#include "../PowerPC/PPCSymbolDB.h"
|
||||
|
||||
void PPCDebugInterface::disasm(unsigned int address, char *dest, int max_size)
|
||||
{
|
||||
@@ -104,18 +104,18 @@ bool PPCDebugInterface::isAlive()
|
||||
|
||||
bool PPCDebugInterface::isBreakpoint(unsigned int address)
|
||||
{
|
||||
return BreakPoints::IsAddressBreakPoint(address);
|
||||
return g_breakpoints.IsAddressBreakPoint(address);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::setBreakpoint(unsigned int address)
|
||||
{
|
||||
if (BreakPoints::Add(address))
|
||||
if (g_breakpoints.Add(address))
|
||||
jit.NotifyBreakpoint(address, true);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::clearBreakpoint(unsigned int address)
|
||||
{
|
||||
if (BreakPoints::Remove(address))
|
||||
if (g_breakpoints.Remove(address))
|
||||
jit.NotifyBreakpoint(address, false);
|
||||
}
|
||||
|
||||
@@ -123,10 +123,10 @@ void PPCDebugInterface::clearAllBreakpoints() {}
|
||||
|
||||
void PPCDebugInterface::toggleBreakpoint(unsigned int address)
|
||||
{
|
||||
if (BreakPoints::IsAddressBreakPoint(address))
|
||||
BreakPoints::Remove(address);
|
||||
if (g_breakpoints.IsAddressBreakPoint(address))
|
||||
g_breakpoints.Remove(address);
|
||||
else
|
||||
BreakPoints::Add(address);
|
||||
g_breakpoints.Add(address);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::insertBLR(unsigned int address, unsigned int value)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "HLE.h"
|
||||
|
||||
#include "../PowerPC/PowerPC.h"
|
||||
#include "../PowerPC/SymbolDB.h"
|
||||
#include "../PowerPC/PPCSymbolDB.h"
|
||||
#include "../HW/Memmap.h"
|
||||
#include "../Debugger/Debugger_SymbolMap.h"
|
||||
#include "../Debugger/Debugger_BreakPoints.h"
|
||||
@@ -132,7 +132,7 @@ void PatchFunctions()
|
||||
Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName);
|
||||
if (symbol > 0)
|
||||
{
|
||||
BreakPoints::Add(symbol->address, false);
|
||||
g_breakpoints.Add(symbol->address, false);
|
||||
INFO_LOG(HLE,"Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol->address);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +474,7 @@ void UpdateAudioDMA()
|
||||
// Latch new parameters
|
||||
g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks;
|
||||
g_audioDMA.ReadAddress = g_audioDMA.SourceAddress;
|
||||
DEBUG_LOG(DSPLLE, "ADMA read addresses: %08x", g_audioDMA.ReadAddress);
|
||||
// DEBUG_LOG(DSPLLE, "ADMA read addresses: %08x", g_audioDMA.ReadAddress);
|
||||
GenerateDSPInterrupt(DSP::INT_AID);
|
||||
}
|
||||
} else {
|
||||
@@ -647,11 +647,35 @@ u8 ReadARAM(u32 _iAddress)
|
||||
return g_ARAM[_iAddress & ARAM_MASK];
|
||||
}
|
||||
|
||||
void WriteARAM(u8 value, u32 _uAddress)
|
||||
{
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
||||
{
|
||||
//LOGV(DSPINTERFACE, 0, "ARAM (w) 0x%08x 0x%08x 0x%08x", WII_MASK, _iAddress, (_iAddress & WII_MASK));
|
||||
|
||||
// Does this make any sense?
|
||||
if (_uAddress > WII_MASK)
|
||||
{
|
||||
if (_uAddress > WII_MEM2)
|
||||
_uAddress = (_uAddress & WII_MEM2);
|
||||
g_MEM2[_uAddress] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ARAM[_uAddress] = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
g_ARAM[_uAddress & ARAM_MASK] = value;
|
||||
}
|
||||
|
||||
|
||||
u8 *GetARAMPtr()
|
||||
{
|
||||
return g_ARAM;
|
||||
}
|
||||
|
||||
/*
|
||||
// Should this really be a function? The hardware only supports block DMA.
|
||||
void WriteARAM(u8 _iValue, u32 _iAddress)
|
||||
{
|
||||
@@ -661,7 +685,7 @@ void WriteARAM(u8 _iValue, u32 _iAddress)
|
||||
// rouge leader writes WAY outside
|
||||
// not really surprising since it uses a totally different memory model :P
|
||||
g_ARAM[_iAddress & ARAM_MASK] = _iValue;
|
||||
}
|
||||
}*/
|
||||
|
||||
} // end of namespace DSP
|
||||
// ===================
|
||||
@@ -48,6 +48,7 @@ void Write32(const u32 _uValue, const u32 _uAddress);
|
||||
|
||||
// Audio/DSP Plugin Helper
|
||||
u8 ReadARAM(const u32 _uAddress);
|
||||
void WriteARAM(u8 value, u32 _uAddress);
|
||||
|
||||
// Debugger Helper
|
||||
u8* GetARAMPtr();
|
||||
|
||||
@@ -254,7 +254,7 @@ u8 Read_U8(const u32 _Address)
|
||||
u8 _var = 0;
|
||||
ReadFromHardware<u8>(_var, _Address, _Address, FLAG_READ);
|
||||
#ifndef NOCHECK
|
||||
TMemCheck *mc = MemChecks::GetMemCheck(_Address);
|
||||
TMemCheck *mc = g_memchecks.GetMemCheck(_Address);
|
||||
if (mc)
|
||||
{
|
||||
mc->numHits++;
|
||||
@@ -269,7 +269,7 @@ u16 Read_U16(const u32 _Address)
|
||||
u16 _var = 0;
|
||||
ReadFromHardware<u16>(_var, _Address, _Address, FLAG_READ);
|
||||
#ifndef NOCHECK
|
||||
TMemCheck *mc = MemChecks::GetMemCheck(_Address);
|
||||
TMemCheck *mc = g_memchecks.GetMemCheck(_Address);
|
||||
if (mc)
|
||||
{
|
||||
mc->numHits++;
|
||||
@@ -291,7 +291,7 @@ u32 Read_U32(const u32 _Address)
|
||||
u32 _var = 0;
|
||||
ReadFromHardware<u32>(_var, _Address, _Address, FLAG_READ);
|
||||
#ifndef NOCHECK
|
||||
TMemCheck *mc = MemChecks::GetMemCheck(_Address);
|
||||
TMemCheck *mc = g_memchecks.GetMemCheck(_Address);
|
||||
if (mc)
|
||||
{
|
||||
mc->numHits++;
|
||||
@@ -307,7 +307,7 @@ u64 Read_U64(const u32 _Address)
|
||||
u64 _var = 0;
|
||||
ReadFromHardware<u64>(_var, _Address, _Address, FLAG_READ);
|
||||
#ifndef NOCHECK
|
||||
TMemCheck *mc = MemChecks::GetMemCheck(_Address);
|
||||
TMemCheck *mc = g_memchecks.GetMemCheck(_Address);
|
||||
if (mc)
|
||||
{
|
||||
mc->numHits++;
|
||||
@@ -321,7 +321,7 @@ u64 Read_U64(const u32 _Address)
|
||||
void Write_U8(const u8 _Data, const u32 _Address)
|
||||
{
|
||||
#ifndef NOCHECK
|
||||
TMemCheck *mc = MemChecks::GetMemCheck(_Address);
|
||||
TMemCheck *mc = g_memchecks.GetMemCheck(_Address);
|
||||
if (mc)
|
||||
{
|
||||
mc->numHits++;
|
||||
@@ -335,7 +335,7 @@ void Write_U8(const u8 _Data, const u32 _Address)
|
||||
void Write_U16(const u16 _Data, const u32 _Address)
|
||||
{
|
||||
#ifndef NOCHECK
|
||||
TMemCheck *mc = MemChecks::GetMemCheck(_Address);
|
||||
TMemCheck *mc = g_memchecks.GetMemCheck(_Address);
|
||||
if (mc)
|
||||
{
|
||||
mc->numHits++;
|
||||
@@ -350,7 +350,7 @@ void Write_U16(const u16 _Data, const u32 _Address)
|
||||
void Write_U32(const u32 _Data, const u32 _Address)
|
||||
{
|
||||
#ifndef NOCHECK
|
||||
TMemCheck *mc = MemChecks::GetMemCheck(_Address);
|
||||
TMemCheck *mc = g_memchecks.GetMemCheck(_Address);
|
||||
if (mc)
|
||||
{
|
||||
mc->numHits++;
|
||||
@@ -364,7 +364,7 @@ void Write_U32(const u32 _Data, const u32 _Address)
|
||||
void Write_U64(const u64 _Data, const u32 _Address)
|
||||
{
|
||||
#ifndef NOCHECK
|
||||
TMemCheck *mc = MemChecks::GetMemCheck(_Address);
|
||||
TMemCheck *mc = g_memchecks.GetMemCheck(_Address);
|
||||
if (mc)
|
||||
{
|
||||
mc->numHits++;
|
||||
|
||||
@@ -166,7 +166,7 @@ void Run()
|
||||
#endif
|
||||
|
||||
//2: check for breakpoint
|
||||
if (BreakPoints::IsAddressBreakPoint(PC))
|
||||
if (g_breakpoints.IsAddressBreakPoint(PC))
|
||||
{
|
||||
#ifdef SHOW_HISTORY
|
||||
NOTICE_LOG(POWERPC, "----------------------------");
|
||||
@@ -187,8 +187,8 @@ void Run()
|
||||
#endif
|
||||
INFO_LOG(POWERPC, "Hit Breakpoint - %08x", PC);
|
||||
CCPU::Break();
|
||||
if (BreakPoints::IsTempBreakPoint(PC))
|
||||
BreakPoints::Remove(PC);
|
||||
if (g_breakpoints.IsTempBreakPoint(PC))
|
||||
g_breakpoints.Remove(PC);
|
||||
|
||||
Host_UpdateDisasmDialog();
|
||||
return;
|
||||
|
||||
@@ -550,7 +550,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buffer, JitB
|
||||
}
|
||||
|
||||
// If starting from the breakpointed instruction, we don't break.
|
||||
if (em_address != ops[i].address && BreakPoints::IsAddressBreakPoint(ops[i].address))
|
||||
if (em_address != ops[i].address && g_breakpoints.IsAddressBreakPoint(ops[i].address))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "Interpreter/Interpreter.h"
|
||||
#include "../HW/Memmap.h"
|
||||
#include "PPCTables.h"
|
||||
#include "SymbolDB.h"
|
||||
#include "PPCSymbolDB.h"
|
||||
#include "SignatureDB.h"
|
||||
#include "PPCAnalyst.h"
|
||||
|
||||
@@ -582,11 +582,11 @@ void FindFunctionsFromBranches(u32 startAddr, u32 endAddr, SymbolDB *func_db)
|
||||
}
|
||||
}
|
||||
|
||||
void FindFunctionsAfterBLR(SymbolDB *func_db)
|
||||
void FindFunctionsAfterBLR(PPCSymbolDB *func_db)
|
||||
{
|
||||
vector<u32> funcAddrs;
|
||||
|
||||
for (SymbolDB::XFuncMap::iterator iter = func_db->GetIterator(); iter != func_db->End(); iter++)
|
||||
for (PPCSymbolDB::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++)
|
||||
@@ -609,7 +609,7 @@ void FindFunctionsAfterBLR(SymbolDB *func_db)
|
||||
}
|
||||
}
|
||||
|
||||
void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db)
|
||||
void FindFunctions(u32 startAddr, u32 endAddr, PPCSymbolDB *func_db)
|
||||
{
|
||||
//Step 1: Find all functions
|
||||
FindFunctionsFromBranches(startAddr, endAddr, func_db);
|
||||
@@ -621,7 +621,7 @@ void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db)
|
||||
int numLeafs = 0, numNice = 0, numUnNice = 0;
|
||||
int numTimer = 0, numRFI = 0, numStraightLeaf = 0;
|
||||
int leafSize = 0, niceSize = 0, unniceSize = 0;
|
||||
for (SymbolDB::XFuncMap::iterator iter = func_db->GetIterator(); iter != func_db->End(); iter++)
|
||||
for (PPCSymbolDB::XFuncMap::iterator iter = func_db->GetIterator(); iter != func_db->End(); iter++)
|
||||
{
|
||||
if (iter->second.address == 4)
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "Common.h"
|
||||
#include "Gekko.h"
|
||||
|
||||
class SymbolDB;
|
||||
class PPCSymbolDB;
|
||||
struct Symbol;
|
||||
|
||||
namespace PPCAnalyst
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
|
||||
bool Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, BlockRegStats *fpa, CodeBuffer *buffer);
|
||||
void LogFunctionCall(u32 addr);
|
||||
void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db);
|
||||
void FindFunctions(u32 startAddr, u32 endAddr, PPCSymbolDB *func_db);
|
||||
bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size = 0);
|
||||
|
||||
} // namespace
|
||||
|
||||
+14
-49
@@ -22,49 +22,24 @@
|
||||
#include <vector>
|
||||
|
||||
#include "../HW/Memmap.h"
|
||||
#include "SymbolDB.h"
|
||||
#include "PPCSymbolDB.h"
|
||||
#include "SignatureDB.h"
|
||||
#include "PPCAnalyst.h"
|
||||
|
||||
SymbolDB g_symbolDB;
|
||||
PPCSymbolDB g_symbolDB;
|
||||
|
||||
SymbolDB::SymbolDB()
|
||||
PPCSymbolDB::PPCSymbolDB()
|
||||
{
|
||||
// Get access to the disasm() fgnction
|
||||
debugger = new PPCDebugInterface();
|
||||
}
|
||||
|
||||
SymbolDB::~SymbolDB()
|
||||
PPCSymbolDB::~PPCSymbolDB()
|
||||
{
|
||||
}
|
||||
|
||||
void SymbolDB::List()
|
||||
{
|
||||
for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
|
||||
{
|
||||
DEBUG_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);
|
||||
}
|
||||
INFO_LOG(HLE,"%i functions known in this program above.", functions.size());
|
||||
}
|
||||
|
||||
void SymbolDB::Clear(const char *prefix)
|
||||
{
|
||||
// TODO: honor prefix
|
||||
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)
|
||||
Symbol *PPCSymbolDB::AddFunction(u32 startAddr)
|
||||
{
|
||||
if (startAddr < 0x80000010)
|
||||
return 0;
|
||||
@@ -88,7 +63,7 @@ Symbol *SymbolDB::AddFunction(u32 startAddr)
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const char *name, int type)
|
||||
void PPCSymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const char *name, int type)
|
||||
{
|
||||
XFuncMap::iterator iter = functions.find(startAddr);
|
||||
if (iter != functions.end())
|
||||
@@ -116,7 +91,7 @@ void SymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const char *name, int typ
|
||||
}
|
||||
}
|
||||
|
||||
Symbol *SymbolDB::GetSymbolFromAddr(u32 addr)
|
||||
Symbol *PPCSymbolDB::GetSymbolFromAddr(u32 addr)
|
||||
{
|
||||
if (!Memory::IsRAMAddress(addr))
|
||||
return 0;
|
||||
@@ -134,17 +109,7 @@ Symbol *SymbolDB::GetSymbolFromAddr(u32 addr)
|
||||
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)
|
||||
const char *PPCSymbolDB::GetDescription(u32 addr)
|
||||
{
|
||||
Symbol *symbol = GetSymbolFromAddr(addr);
|
||||
if (symbol)
|
||||
@@ -153,7 +118,7 @@ const char *SymbolDB::GetDescription(u32 addr)
|
||||
return " --- ";
|
||||
}
|
||||
|
||||
void SymbolDB::FillInCallers()
|
||||
void PPCSymbolDB::FillInCallers()
|
||||
{
|
||||
for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
|
||||
{
|
||||
@@ -183,7 +148,7 @@ void SymbolDB::FillInCallers()
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolDB::PrintCalls(u32 funcAddr) const
|
||||
void PPCSymbolDB::PrintCalls(u32 funcAddr) const
|
||||
{
|
||||
XFuncMap::const_iterator iter = functions.find(funcAddr);
|
||||
if (iter != functions.end())
|
||||
@@ -205,7 +170,7 @@ void SymbolDB::PrintCalls(u32 funcAddr) const
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolDB::PrintCallers(u32 funcAddr) const
|
||||
void PPCSymbolDB::PrintCallers(u32 funcAddr) const
|
||||
{
|
||||
XFuncMap::const_iterator iter = functions.find(funcAddr);
|
||||
if (iter != functions.end())
|
||||
@@ -223,7 +188,7 @@ void SymbolDB::PrintCallers(u32 funcAddr) const
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolDB::LogFunctionCall(u32 addr)
|
||||
void PPCSymbolDB::LogFunctionCall(u32 addr)
|
||||
{
|
||||
//u32 from = PC;
|
||||
XFuncMap::iterator iter = functions.find(addr);
|
||||
@@ -236,7 +201,7 @@ void SymbolDB::LogFunctionCall(u32 addr)
|
||||
|
||||
// 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)
|
||||
bool PPCSymbolDB::LoadMap(const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f)
|
||||
@@ -302,7 +267,7 @@ bool SymbolDB::LoadMap(const char *filename)
|
||||
// ===================================================
|
||||
/* Save the map file and save a code file */
|
||||
// ----------------
|
||||
bool SymbolDB::SaveMap(const char *filename, bool WithCodes) const
|
||||
bool PPCSymbolDB::SaveMap(const char *filename, bool WithCodes) const
|
||||
{
|
||||
// Format the name for the codes version
|
||||
std::string mapFile = filename;
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2003-2009 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 "../Debugger/PPCDebugInterface.h"
|
||||
|
||||
#include "SymbolDB.h"
|
||||
|
||||
// This has functionality overlapping Debugger_Symbolmap. Should merge that stuff in here later.
|
||||
class PPCSymbolDB : public SymbolDB
|
||||
{
|
||||
private:
|
||||
DebugInterface* debugger;
|
||||
|
||||
public:
|
||||
typedef void (*functionGetterCallback)(Symbol *f);
|
||||
|
||||
PPCSymbolDB();
|
||||
~PPCSymbolDB();
|
||||
|
||||
Symbol *AddFunction(u32 startAddr);
|
||||
void AddKnownSymbol(u32 startAddr, u32 size, const char *name, int type = Symbol::SYMBOL_FUNCTION);
|
||||
|
||||
Symbol *GetSymbolFromAddr(u32 addr);
|
||||
|
||||
const char *GetDescription(u32 addr);
|
||||
|
||||
void FillInCallers();
|
||||
|
||||
bool LoadMap(const char *filename);
|
||||
bool SaveMap(const char *filename, bool WithCodes = false) const;
|
||||
|
||||
void PrintCalls(u32 funcAddr) const;
|
||||
void PrintCallers(u32 funcAddr) const;
|
||||
void LogFunctionCall(u32 addr);
|
||||
};
|
||||
|
||||
extern PPCSymbolDB g_symbolDB;
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "SymbolDB.h"
|
||||
#include "PPCSymbolDB.h"
|
||||
|
||||
namespace Profiler
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "../HW/Memmap.h"
|
||||
|
||||
#include "SignatureDB.h"
|
||||
#include "SymbolDB.h"
|
||||
#include "PPCSymbolDB.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -111,7 +111,7 @@ void SignatureDB::Clear()
|
||||
database.clear();
|
||||
}
|
||||
|
||||
void SignatureDB::Apply(SymbolDB *symbol_db)
|
||||
void SignatureDB::Apply(PPCSymbolDB *symbol_db)
|
||||
{
|
||||
for (FuncDB::const_iterator iter = database.begin(); iter != database.end(); iter++)
|
||||
{
|
||||
@@ -135,10 +135,10 @@ void SignatureDB::Apply(SymbolDB *symbol_db)
|
||||
symbol_db->Index();
|
||||
}
|
||||
|
||||
void SignatureDB::Initialize(SymbolDB *symbol_db, const char *prefix)
|
||||
void SignatureDB::Initialize(PPCSymbolDB *symbol_db, const char *prefix)
|
||||
{
|
||||
std::string prefix_str(prefix);
|
||||
for (SymbolDB::XFuncMap::const_iterator iter = symbol_db->GetConstIterator(); iter != symbol_db->End(); iter++)
|
||||
for (PPCSymbolDB::XFuncMap::const_iterator iter = symbol_db->GetConstIterator(); iter != symbol_db->End(); iter++)
|
||||
{
|
||||
if (iter->second.name.substr(0, prefix_str.size()) == prefix_str)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
// You're not meant to keep around SignatureDB objects persistently. Use 'em, throw them away.
|
||||
|
||||
class SymbolDB;
|
||||
class PPCSymbolDB;
|
||||
|
||||
class SignatureDB
|
||||
{
|
||||
@@ -50,8 +50,8 @@ public:
|
||||
void Clear();
|
||||
void List();
|
||||
|
||||
void Initialize(SymbolDB *func_db, const char *prefix = "");
|
||||
void Apply(SymbolDB *func_db);
|
||||
void Initialize(PPCSymbolDB *func_db, const char *prefix = "");
|
||||
void Apply(PPCSymbolDB *func_db);
|
||||
|
||||
static u32 ComputeCodeChecksum(u32 offsetStart, u32 offsetEnd);
|
||||
};
|
||||
@@ -1,131 +0,0 @@
|
||||
// Copyright (C) 2003-2009 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 "../Debugger/PPCDebugInterface.h"
|
||||
#include "../Debugger/DebugInterface.h"
|
||||
|
||||
struct SCall
|
||||
{
|
||||
SCall(u32 a, u32 b) :
|
||||
function(a),
|
||||
callAddress(b)
|
||||
{}
|
||||
u32 function;
|
||||
u32 callAddress;
|
||||
};
|
||||
|
||||
struct Symbol
|
||||
{
|
||||
enum {
|
||||
SYMBOL_FUNCTION = 0,
|
||||
SYMBOL_DATA = 1,
|
||||
};
|
||||
|
||||
Symbol() :
|
||||
hash(0),
|
||||
address(0),
|
||||
flags(0),
|
||||
size(0),
|
||||
numCalls(0),
|
||||
type(SYMBOL_FUNCTION),
|
||||
analyzed(0)
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
std::vector<SCall> callers; //addresses of functions that call this function
|
||||
std::vector<SCall> calls; //addresses of functions that are called by this function
|
||||
u32 hash; //use for HLE function finding
|
||||
u32 address;
|
||||
u32 flags;
|
||||
int size;
|
||||
int numCalls;
|
||||
int type;
|
||||
int index; // only used for coloring the disasm view
|
||||
int analyzed;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FFLAG_TIMERINSTRUCTIONS=(1<<0),
|
||||
FFLAG_LEAF=(1<<1),
|
||||
FFLAG_ONLYCALLSNICELEAFS=(1<<2),
|
||||
FFLAG_EVIL=(1<<3),
|
||||
FFLAG_RFI=(1<<4),
|
||||
FFLAG_STRAIGHT=(1<<5)
|
||||
};
|
||||
|
||||
|
||||
// This has functionality overlapping Debugger_Symbolmap. Should merge that stuff in here later.
|
||||
class SymbolDB
|
||||
{
|
||||
public:
|
||||
typedef std::map<u32, Symbol> XFuncMap;
|
||||
typedef std::map<u32, Symbol*> XFuncPtrMap;
|
||||
|
||||
private:
|
||||
XFuncMap functions;
|
||||
XFuncPtrMap checksumToFunction;
|
||||
DebugInterface* debugger;
|
||||
|
||||
public:
|
||||
typedef void (*functionGetterCallback)(Symbol *f);
|
||||
|
||||
SymbolDB();
|
||||
~SymbolDB();
|
||||
|
||||
Symbol *AddFunction(u32 startAddr);
|
||||
void AddKnownSymbol(u32 startAddr, u32 size, const char *name, int type = Symbol::SYMBOL_FUNCTION);
|
||||
|
||||
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(const char *prefix = "");
|
||||
void List();
|
||||
void Index();
|
||||
void FillInCallers();
|
||||
|
||||
bool LoadMap(const char *filename);
|
||||
bool SaveMap(const char *filename, bool WithCodes = false) const;
|
||||
|
||||
void PrintCalls(u32 funcAddr) const;
|
||||
void PrintCallers(u32 funcAddr) const;
|
||||
void LogFunctionCall(u32 addr);
|
||||
};
|
||||
|
||||
extern SymbolDB g_symbolDB;
|
||||
@@ -75,7 +75,7 @@ files = ["ActionReplay.cpp",
|
||||
"PowerPC/PPCTables.cpp",
|
||||
"PowerPC/Profiler.cpp",
|
||||
"PowerPC/SignatureDB.cpp",
|
||||
"PowerPC/SymbolDB.cpp",
|
||||
"PowerPC/PPCSymbolDB.cpp",
|
||||
"PowerPC/Interpreter/Interpreter.cpp",
|
||||
"PowerPC/Interpreter/Interpreter_Branch.cpp",
|
||||
"PowerPC/Interpreter/Interpreter_Integer.cpp",
|
||||
|
||||
Reference in new issue
Block a user