[Debugger] Add memory locks feature (interpreter)

This commit is contained in:
shygoo 2018-03-17 20:14:52 -05:00
parent c506db57f3
commit 77daf1bad4
9 changed files with 168 additions and 21 deletions

View File

@ -321,6 +321,13 @@ void CInterpreterCPU::ExecuteCPU()
if (CDebugSettings::HaveDebugger())
{
g_Debugger->CPUStepStarted();
if (SkipOp())
{
g_Settings->SaveBool(Debugger_SkipOp, false);
PROGRAM_COUNTER += 4;
continue;
}
}
/* if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER < 0x80380000)

View File

@ -238,6 +238,21 @@ CBreakpoints::BPSTATE CBreakpoints::WriteBPExists64(uint32_t address)
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExistsInChunk(uint32_t address, uint32_t nBytes)
{
uint32_t endAddr = address + nBytes;
for (breakpoints_t::iterator breakpoint = m_WriteMem.begin(); breakpoint != m_WriteMem.end(); breakpoint++)
{
uint32_t wbpAddr = breakpoint->first;
if (wbpAddr >= address && wbpAddr < endAddr)
{
return BP_SET;
}
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::ExecutionBPExists(uint32_t address, bool bRemoveTemp)
{
breakpoints_t::const_iterator itr = m_Execution.find(address);
@ -283,3 +298,35 @@ void CBreakpoints::UpdateAlignedWriteBP()
m_WriteMem64.insert(breakpoints_t::value_type((itr->first & ~0x7), false));
}
}
void CBreakpoints::ToggleMemLock(uint32_t address)
{
if (m_MemLocks.count(address) == 0)
{
m_MemLocks.insert(address);
return;
}
m_MemLocks.erase(address);
}
bool CBreakpoints::MemLockExists(uint32_t address, int nBytes)
{
for (memlocks_t::const_iterator itr = m_MemLocks.begin(); itr != m_MemLocks.end(); itr++)
{
if (*itr >= address && *itr < (address + nBytes))
{
return true;
}
}
return false;
}
void CBreakpoints::ClearMemLocks()
{
m_MemLocks.clear();
}
size_t CBreakpoints::NumMemLocks()
{
return m_MemLocks.size();
}

View File

@ -19,6 +19,8 @@ public:
typedef std::map<uint32_t /*address*/, bool /*bTemporary*/> breakpoints_t;
typedef breakpoints_t::const_iterator breakpoint_t;
typedef std::set<uint32_t> memlocks_t;
enum BPSTATE
{
BP_NOT_SET,
@ -40,6 +42,7 @@ public:
BPSTATE WriteBPExists16(uint32_t address);
BPSTATE WriteBPExists32(uint32_t address);
BPSTATE WriteBPExists64(uint32_t address);
BPSTATE WriteBPExistsInChunk(uint32_t address, uint32_t nBytes);
BPSTATE ExecutionBPExists(uint32_t address, bool bRemoveTemp = false);
bool RBPAdd(uint32_t address);
@ -59,6 +62,11 @@ public:
void BPClear();
void ToggleMemLock(uint32_t address);
bool MemLockExists(uint32_t address, int nBytes);
void ClearMemLocks(void);
size_t NumMemLocks(void);
private:
void UpdateAlignedWriteBP(void);
void UpdateAlignedReadBP(void);
@ -66,4 +74,6 @@ private:
breakpoints_t m_ReadMem, m_ReadMem16, m_ReadMem32, m_ReadMem64;
breakpoints_t m_WriteMem, m_WriteMem16, m_WriteMem32, m_WriteMem64;
breakpoints_t m_Execution;
memlocks_t m_MemLocks;
};

View File

@ -583,7 +583,7 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top)
const char* annotation = NULL;
bool bLoadStoreAnnotation = false;
if (OpInfo.IsLoadStore())
if (OpInfo.IsLoadStoreCommand())
{
for (int offset = -4; offset > -24; offset -= 4)
{
@ -1413,7 +1413,7 @@ LRESULT CDebugCommandsView::OnCommandListRightClicked(NMHDR* pNMHDR)
EnableMenuItem(hPopupMenu, ID_POPUPMENU_FOLLOWJUMP, MF_DISABLED | MF_GRAYED);
}
if (m_SelectedOpInfo.IsLoadStore())
if (m_SelectedOpInfo.IsLoadStoreCommand())
{
m_FollowAddress = g_Reg->m_GPR[m_SelectedOpCode.base].UW[0] + (int16_t)m_SelectedOpCode.offset;
}

View File

@ -219,6 +219,14 @@ LRESULT CDebugMemoryView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL&
m_Breakpoints->WBPClear();
RefreshMemory(true);
break;
case ID_POPUPMENU_TOGGLELOCK:
m_Breakpoints->ToggleMemLock(m_CtxMenuAddr);
RefreshMemory(true);
break;
case ID_POPUPMENU_CLEARLOCKS:
m_Breakpoints->ClearMemLocks();
RefreshMemory(true);
break;
case ID_POPUPMENU_VIEWDISASM:
m_Debugger->Debug_ShowCommandsLocation(m_CtxMenuAddr, true);
break;
@ -248,6 +256,10 @@ LRESULT CDebugMemoryView::OnMemoryRightClicked(LPNMHDR lpNMHDR)
{
EnableMenuItem(hPopupMenu, ID_POPUPMENU_CLEARALLBPS, MF_DISABLED | MF_GRAYED);
}
if (m_Breakpoints->NumMemLocks() == 0)
{
EnableMenuItem(hPopupMenu, ID_POPUPMENU_CLEARLOCKS, MF_DISABLED | MF_GRAYED);
}
POINT mouse;
GetCursorPos(&mouse);
@ -725,12 +737,17 @@ void CDebugMemoryView::SelectColors(uint32_t vaddr, bool changed, COLORREF& bgCo
CSymbols::LeaveCriticalSection();
bool bLocked = m_Breakpoints->MemLockExists(vaddr, 1);
bool bHaveReadBP = m_Breakpoints->ReadBPExists8(vaddr) == CBreakpoints::BP_SET;
bool bHaveWriteBP = m_Breakpoints->WriteBPExists8(vaddr) == CBreakpoints::BP_SET;
fgHiColor = RGB(0x00, 0x00, 0x00);
if (bHaveReadBP && bHaveWriteBP)
if (bLocked)
{
bgColor = RGB(0xDD, 0xAA, 0xAA);
}
else if (bHaveReadBP && bHaveWriteBP)
{
bgColor = RGB(0xAA, 0xDD, 0xDD);
}

View File

@ -394,14 +394,13 @@ void CDebuggerUI::CPUStepStarted()
// Memory breakpoints
OPCODE Opcode = R4300iOp::m_Opcode;
uint32_t op = Opcode.op;
COpInfo opInfo(R4300iOp::m_Opcode);
if (op >= R4300i_LDL && op <= R4300i_SD && op != R4300i_CACHE) // Read and write instructions
if (opInfo.IsLoadStoreCommand()) // Read and write instructions
{
uint32_t memoryAddress = g_Reg->m_GPR[Opcode.base].UW[0] + (int16_t)Opcode.offset;
uint32_t memoryAddress = opInfo.GetLoadStoreAddress();
if ((op <= R4300i_LWU || (op >= R4300i_LL && op <= R4300i_LD))) // Read instructions
if (opInfo.IsLoadCommand()) // Read instructions
{
m_ScriptSystem->HookCPURead()->InvokeByParamInRange(memoryAddress);
@ -419,21 +418,20 @@ void CDebuggerUI::CPUStepStarted()
{
uint32_t dmaRomAddr = g_Reg->PI_CART_ADDR_REG & 0x0FFFFFFF;
uint32_t dmaRamAddr = g_Reg->PI_DRAM_ADDR_REG | 0x80000000;
uint32_t dmaLen = g_Reg->m_GPR[Opcode.rt].UW[0] + 1;
uint32_t endAddr = dmaRamAddr + dmaLen;
uint32_t dmaLen = opInfo.GetStoreValueUnsigned() + 1;
m_DMALog->AddEntry(dmaRomAddr, dmaRamAddr, dmaLen);
CBreakpoints::breakpoints_t breakpoints = m_Breakpoints->WriteMem();
for (CBreakpoints::breakpoints_t::iterator breakpoint = breakpoints.begin(); breakpoint != breakpoints.end(); breakpoint++)
if (m_Breakpoints->WriteBPExistsInChunk(dmaRamAddr, dmaLen))
{
uint32_t wbpAddr = breakpoint->first;
if (wbpAddr >= dmaRamAddr && wbpAddr < endAddr)
{
goto breakpoint_hit;
}
goto breakpoint_hit;
}
}
if (m_Breakpoints->MemLockExists(memoryAddress, opInfo.NumBytesToStore()))
{
g_Settings->SaveBool(Debugger_SkipOp, true);
}
}
}

View File

@ -20,6 +20,15 @@ public:
OPCODE m_OpCode;
COpInfo()
{
}
inline COpInfo(OPCODE opcode):
m_OpCode(opcode)
{
}
bool IsStaticJump()
{
// j, jal
@ -131,11 +140,16 @@ public:
return false;
}
bool IsLoadStore()
inline bool IsLoadStoreCommand()
{
return (m_OpCode.op >= R4300i_LDL && m_OpCode.op <= R4300i_SD && m_OpCode.op != R4300i_CACHE);
}
inline bool IsLoadCommand()
{
return (m_OpCode.op <= R4300i_LWU || (m_OpCode.op >= R4300i_LL && m_OpCode.op <= R4300i_LD));
}
bool IsStackShift()
{
return (m_OpCode.op == R4300i_ADDIU || m_OpCode.op == R4300i_ADDI) && m_OpCode.rt == 29;
@ -323,4 +337,53 @@ public:
}
return false;
}
inline uint32_t GetLoadStoreAddress()
{
return g_Reg->m_GPR[m_OpCode.base].UW[0] + (int16_t)m_OpCode.offset;
}
inline uint32_t GetStoreValueUnsigned()
{
return g_Reg->m_GPR[m_OpCode.rt].UW[0];
}
inline int NumBytesToLoad()
{
switch (m_OpCode.op)
{
case R4300i_LB:
case R4300i_LBU:
return 1;
case R4300i_LH:
case R4300i_LHU:
return 2;
case R4300i_LD:
case R4300i_LDL:
case R4300i_LDR:
case R4300i_LDC1:
return 8;
default:
return 4;
}
}
inline int NumBytesToStore()
{
switch (m_OpCode.op)
{
case R4300i_SB:
return 1;
case R4300i_SH:
return 2;
case R4300i_SD:
case R4300i_SDL:
case R4300i_SDR:
case R4300i_SDC1:
case R4300i_SDC2:
return 8;
default:
return 4;
}
}
};

View File

@ -685,7 +685,7 @@ BEGIN
PUSHBUTTON "...",IDC_SYMBOLS_BTN,357,1,17,15
PUSHBUTTON "Skip",IDC_SKIP_BTN,376,1,27,15,WS_DISABLED
PUSHBUTTON "Step",IDC_STEP_BTN,404,1,27,15,WS_DISABLED
PUSHBUTTON "St.Ovr", IDC_STEPOVER_BTN, 432, 1, 27, 15, WS_DISABLED
PUSHBUTTON "St.Ovr",IDC_STEPOVER_BTN,432,1,27,15,WS_DISABLED
PUSHBUTTON "Go",IDC_GO_BTN,460,1,27,15,WS_DISABLED
LTEXT "PC",IDC_PC_STATIC,292,24,8,9
EDITTEXT IDC_PC_EDIT,303,22,44,12,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
@ -1735,6 +1735,9 @@ BEGIN
MENUITEM "Toggle write breakpoint", ID_POPUPMENU_TOGGLEWBP
MENUITEM "Clear all breakpoints", ID_POPUPMENU_CLEARALLBPS
MENUITEM SEPARATOR
MENUITEM "Toggle lock", ID_POPUPMENU_TOGGLELOCK
MENUITEM "Clear locks", ID_POPUPMENU_CLEARLOCKS
MENUITEM SEPARATOR
MENUITEM "View disassembly...", ID_POPUPMENU_VIEWDISASM
MENUITEM SEPARATOR
MENUITEM "Add symbol...", ID_POPUPMENU_ADDSYMBOL

View File

@ -621,6 +621,8 @@
#define ID_POPUPMENU_VIEWMEMORY 40036
#define ID_POPUPMENU_TOGGLEBP 40039
#define ID_POPUPMENU_CLEARBPS 40040
#define ID_POPUPMENU_TOGGLELOCK 40041
#define ID_POPUPMENU_CLEARLOCKS 40042
#define ID_POPUPMENU_ROMDIRECTORY 40137
#define ID_POPUPMENU_REFRESHROMLIST 40138
#define ID_POPUPMENU_PLAYGAME 40152
@ -636,7 +638,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 194
#define _APS_NEXT_COMMAND_VALUE 40041
#define _APS_NEXT_COMMAND_VALUE 40043
#define _APS_NEXT_CONTROL_VALUE 1445
#define _APS_NEXT_SYMED_VALUE 102
#endif