Merge pull request #1516 from shygoo2/better-address-checks

[Debugger] Improve address checks (fix #1515)
This commit is contained in:
zilmar 2018-12-09 15:45:57 +10:30 committed by GitHub
commit 56a10af580
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 313 additions and 182 deletions

View File

@ -308,6 +308,16 @@ uint8_t * CMipsMemoryVM::PifRam()
return m_PifRam; return m_PifRam;
} }
CSram* CMipsMemoryVM::GetSram(void)
{
return dynamic_cast<CSram*>(this);
}
CFlashram* CMipsMemoryVM::GetFlashram()
{
return dynamic_cast<CFlashram*>(this);
}
bool CMipsMemoryVM::LB_VAddr(uint32_t VAddr, uint8_t& Value) bool CMipsMemoryVM::LB_VAddr(uint32_t VAddr, uint8_t& Value)
{ {
if (m_TLB_ReadMap[VAddr >> 12] == 0) if (m_TLB_ReadMap[VAddr >> 12] == 0)

View File

@ -68,6 +68,9 @@ public:
uint8_t * Imem(); uint8_t * Imem();
uint8_t * PifRam(); uint8_t * PifRam();
CSram * GetSram();
CFlashram * GetFlashram();
bool LB_VAddr(uint32_t VAddr, uint8_t & Value); bool LB_VAddr(uint32_t VAddr, uint8_t & Value);
bool LH_VAddr(uint32_t VAddr, uint16_t & Value); bool LH_VAddr(uint32_t VAddr, uint16_t & Value);
bool LW_VAddr(uint32_t VAddr, uint32_t & Value); bool LW_VAddr(uint32_t VAddr, uint32_t & Value);

View File

@ -331,7 +331,7 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory)
AddHandler(Debugger_WriteBPExists, new CSettingTypeTempBool(false)); AddHandler(Debugger_WriteBPExists, new CSettingTypeTempBool(false));
AddHandler(Debugger_ReadBPExists, new CSettingTypeTempBool(false)); AddHandler(Debugger_ReadBPExists, new CSettingTypeTempBool(false));
AddHandler(Debugger_WaitingForStep, new CSettingTypeTempBool(false)); AddHandler(Debugger_WaitingForStep, new CSettingTypeTempBool(false));
AddHandler(Debugger_AutoRefreshMemoryView, new CSettingTypeApplication("Debugger", "Auto Referesh Memory View", true)); AddHandler(Debugger_AutoRefreshMemoryView, new CSettingTypeApplication("Debugger", "Auto Refresh Memory View", true));
AddHandler(Debugger_DebugLanguage, new CSettingTypeApplication("Debugger", "Debug Language", false)); AddHandler(Debugger_DebugLanguage, new CSettingTypeApplication("Debugger", "Debug Language", false));
AddHandler(Debugger_ShowDivByZero, new CSettingTypeApplication("Debugger", "Show Div by zero", false)); AddHandler(Debugger_ShowDivByZero, new CSettingTypeApplication("Debugger", "Show Div by zero", false));
AddHandler(Debugger_AppLogFlush, new CSettingTypeApplication("Logging", "Log Auto Flush", (uint32_t)false)); AddHandler(Debugger_AppLogFlush, new CSettingTypeApplication("Logging", "Log Auto Flush", (uint32_t)false));

View File

@ -64,7 +64,7 @@ CDebugCommandsView::~CDebugCommandsView()
{ {
} }
LRESULT CDebugCommandsView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) LRESULT CDebugCommandsView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{ {
g_Settings->RegisterChangeCB(Debugger_WaitingForStep, this, (CSettings::SettingChangedFunc)StaticWaitingForStepChanged); g_Settings->RegisterChangeCB(Debugger_WaitingForStep, this, (CSettings::SettingChangedFunc)StaticWaitingForStepChanged);
g_Settings->RegisterChangeCB(Debugger_SteppingOps, this, (CSettings::SettingChangedFunc)StaticSteppingOpsChanged); g_Settings->RegisterChangeCB(Debugger_SteppingOps, this, (CSettings::SettingChangedFunc)StaticSteppingOpsChanged);
@ -214,7 +214,7 @@ LRESULT CALLBACK CDebugCommandsView::HookProc(int nCode, WPARAM wParam, LPARAM l
return 0; return 0;
} }
LRESULT CDebugCommandsView::OnOpKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) LRESULT CDebugCommandsView::OnOpKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{ {
if (wParam == VK_UP) if (wParam == VK_UP)
{ {
@ -251,25 +251,6 @@ LRESULT CDebugCommandsView::OnOpKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*l
return 1; return 1;
} }
// Check if KSEG0 addr is out of bounds
bool CDebugCommandsView::AddressSafe(uint32_t vaddr)
{
if (g_MMU == NULL)
{
return false;
}
if (vaddr >= 0x80000000 && vaddr <= 0x9FFFFFFF)
{
if ((vaddr & 0x1FFFFFFF) >= g_MMU->RdramSize())
{
return false;
}
}
return true;
}
void CDebugCommandsView::ClearBranchArrows() void CDebugCommandsView::ClearBranchArrows()
{ {
m_BranchArrows.clear(); m_BranchArrows.clear();
@ -551,14 +532,8 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top)
COpInfo OpInfo; COpInfo OpInfo;
OPCODE& OpCode = OpInfo.m_OpCode; OPCODE& OpCode = OpInfo.m_OpCode;
bool bAddrOkay = false;
if (AddressSafe(opAddr)) if (!m_Debugger->DebugLW_VAddr(opAddr, OpCode.Hex))
{
bAddrOkay = g_MMU->LW_VAddr(opAddr, OpCode.Hex);
}
if (!bAddrOkay)
{ {
m_CommandList.AddItem(i, CCommandList::COL_COMMAND, "***"); m_CommandList.AddItem(i, CCommandList::COL_COMMAND, "***");
m_bvAnnotatedLines.push_back(false); m_bvAnnotatedLines.push_back(false);
@ -590,15 +565,9 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top)
{ {
for (int offset = -4; offset > -24; offset -= 4) for (int offset = -4; offset > -24; offset -= 4)
{ {
if (!AddressSafe(opAddr + offset))
{
break;
}
OPCODE OpCodeTest; OPCODE OpCodeTest;
bAddrOkay = g_MMU->LW_VAddr(opAddr + offset, OpCodeTest.Hex);
if (!bAddrOkay) if (!m_Debugger->DebugLW_VAddr(opAddr + offset, OpCodeTest.Hex))
{ {
break; break;
} }
@ -715,11 +684,7 @@ LRESULT CDebugCommandsView::OnCustomDrawList(NMHDR* pNMHDR)
uint32_t pc = (g_Reg != NULL) ? g_Reg->m_PROGRAM_COUNTER : 0; uint32_t pc = (g_Reg != NULL) ? g_Reg->m_PROGRAM_COUNTER : 0;
OPCODE pcOpcode; OPCODE pcOpcode;
if (g_MMU != NULL) if (!m_Debugger->DebugLW_VAddr(pc, pcOpcode.Hex))
{
g_MMU->LW_VAddr(pc, pcOpcode.Hex);
}
else
{ {
pcOpcode.Hex = 0; pcOpcode.Hex = 0;
} }
@ -769,12 +734,7 @@ LRESULT CDebugCommandsView::OnCustomDrawList(NMHDR* pNMHDR)
// cmd & args // cmd & args
COpInfo OpInfo; COpInfo OpInfo;
OPCODE& OpCode = OpInfo.m_OpCode; OPCODE& OpCode = OpInfo.m_OpCode;
bool bAddrOkay = false; bool bAddrOkay = m_Debugger->DebugLW_VAddr(address, OpCode.Hex);
if (AddressSafe(address))
{
bAddrOkay = g_MMU->LW_VAddr(address, OpCode.Hex);
}
struct { struct {
COLORREF bg; COLORREF bg;
@ -884,7 +844,7 @@ LRESULT CDebugCommandsView::OnCustomDrawList(NMHDR* pNMHDR)
return CDRF_DODEFAULT; return CDRF_DODEFAULT;
} }
LRESULT CDebugCommandsView::OnMeasureItem(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) LRESULT CDebugCommandsView::OnMeasureItem(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{ {
if (wParam == IDC_CMD_LIST) if (wParam == IDC_CMD_LIST)
{ {
@ -1094,14 +1054,12 @@ void CDebugCommandsView::CPUResume()
void CDebugCommandsView::CPUStepOver() void CDebugCommandsView::CPUStepOver()
{ {
if (g_MMU == NULL) COpInfo opInfo;
if (!m_Debugger->DebugLW_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex))
{ {
return; return;
} }
COpInfo opInfo;
g_MMU->LW_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex);
if (opInfo.IsJAL()) if (opInfo.IsJAL())
{ {
// put temp BP on return address and resume // put temp BP on return address and resume
@ -1294,6 +1252,12 @@ void CDebugCommandsView::GotoEnteredAddress()
void CDebugCommandsView::BeginOpEdit(uint32_t address) void CDebugCommandsView::BeginOpEdit(uint32_t address)
{ {
uint32_t opcode;
if (m_Debugger->DebugLW_VAddr(address, opcode))
{
return;
}
CRect listRect; CRect listRect;
m_CommandList.GetWindowRect(&listRect); m_CommandList.GetWindowRect(&listRect);
ScreenToClient(&listRect); ScreenToClient(&listRect);
@ -1307,9 +1271,7 @@ void CDebugCommandsView::BeginOpEdit(uint32_t address)
//itemRect.bottom += 0; //itemRect.bottom += 0;
itemRect.left += listRect.left + 3; itemRect.left += listRect.left + 3;
itemRect.right += 100; itemRect.right += 100;
uint32_t opcode;
g_MMU->LW_VAddr(address, opcode);
char* command = (char*)R4300iOpcodeName(opcode, address); char* command = (char*)R4300iOpcodeName(opcode, address);
m_OpEdit.ShowWindow(SW_SHOW); m_OpEdit.ShowWindow(SW_SHOW);
@ -1363,13 +1325,13 @@ LRESULT CDebugCommandsView::OnPCChanged(WORD /*wNotifyCode*/, WORD /*wID*/, HWND
return 0; return 0;
} }
LRESULT CDebugCommandsView::OnCommandListClicked(NMHDR* /*pNMHDR*/) LRESULT CDebugCommandsView::OnCommandListClicked(NMHDR* /*pNMHDR*/)
{ {
EndOpEdit(); EndOpEdit();
return 0; return 0;
} }
LRESULT CDebugCommandsView::OnCommandListDblClicked(NMHDR* pNMHDR) LRESULT CDebugCommandsView::OnCommandListDblClicked(NMHDR* pNMHDR)
{ {
// Set PC breakpoint // Set PC breakpoint
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR); NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
@ -1391,26 +1353,24 @@ LRESULT CDebugCommandsView::OnCommandListDblClicked(NMHDR* pNMHDR)
return 0; return 0;
} }
LRESULT CDebugCommandsView::OnCommandListRightClicked(NMHDR* pNMHDR) LRESULT CDebugCommandsView::OnCommandListRightClicked(NMHDR* pNMHDR)
{ {
EndOpEdit(); EndOpEdit();
if (g_MMU == NULL)
{
return 0;
}
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR); NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
int nItem = pIA->iItem; int nItem = pIA->iItem;
uint32_t address = m_StartAddress + nItem * 4; uint32_t address = m_StartAddress + nItem * 4;
m_SelectedAddress = address; m_SelectedAddress = address;
if (!m_Debugger->DebugLW_VAddr(m_SelectedAddress, m_SelectedOpCode.Hex))
{
return 0;
}
HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_OP_POPUP)); HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_OP_POPUP));
HMENU hPopupMenu = GetSubMenu(hMenu, 0); HMENU hPopupMenu = GetSubMenu(hMenu, 0);
g_MMU->LW_VAddr(m_SelectedAddress, m_SelectedOpCode.Hex);
if (m_SelectedOpInfo.IsStaticJump()) if (m_SelectedOpInfo.IsStaticJump())
{ {
m_FollowAddress = (m_SelectedAddress & 0xF0000000) | (m_SelectedOpCode.target * 4); m_FollowAddress = (m_SelectedAddress & 0xF0000000) | (m_SelectedOpCode.target * 4);
@ -1500,7 +1460,7 @@ LRESULT CDebugCommandsView::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam,
return FALSE; return FALSE;
} }
LRESULT CDebugCommandsView::OnSizing(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) LRESULT CDebugCommandsView::OnSizing(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{ {
CRect listRect; CRect listRect;
m_CommandList.GetWindowRect(listRect); m_CommandList.GetWindowRect(listRect);
@ -1609,7 +1569,10 @@ BOOL CDebugCommandsView::IsOpEdited(uint32_t address)
void CDebugCommandsView::EditOp(uint32_t address, uint32_t op) void CDebugCommandsView::EditOp(uint32_t address, uint32_t op)
{ {
uint32_t currentOp; uint32_t currentOp;
g_MMU->LW_VAddr(address, currentOp); if (!m_Debugger->DebugLW_VAddr(address, currentOp))
{
return;
}
if (currentOp == op) if (currentOp == op)
{ {

View File

@ -218,8 +218,6 @@ private:
void RefreshBreakpointList(); void RefreshBreakpointList();
void RemoveSelectedBreakpoints(); void RemoveSelectedBreakpoints();
bool AddressSafe(uint32_t vaddr);
void HistoryPushState(); void HistoryPushState();
void ToggleHistoryButtons(); void ToggleHistoryButtons();

View File

@ -14,7 +14,7 @@
#include "Symbols.h" #include "Symbols.h"
CDebugStackView::CDebugStackView(CDebuggerUI * debugger) : CDebugStackView::CDebugStackView(CDebuggerUI * debugger) :
CDebugDialog<CDebugStackView>(debugger) CDebugDialog<CDebugStackView>(debugger)
{ {
} }
@ -22,94 +22,94 @@ CDebugStackView::~CDebugStackView(void)
{ {
} }
LRESULT CDebugStackView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) LRESULT CDebugStackView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{ {
DlgResize_Init(false, true); DlgResize_Init(false, true);
m_StackList.Attach(GetDlgItem(IDC_STACK_LIST)); m_StackList.Attach(GetDlgItem(IDC_STACK_LIST));
m_StackList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); m_StackList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
m_StackList.AddColumn("#", 0); m_StackList.AddColumn("#", 0);
m_StackList.AddColumn("00", 1); m_StackList.AddColumn("00", 1);
m_StackList.AddColumn("04", 2); m_StackList.AddColumn("04", 2);
m_StackList.AddColumn("08", 3); m_StackList.AddColumn("08", 3);
m_StackList.AddColumn("0C", 4); m_StackList.AddColumn("0C", 4);
m_StackList.SetColumnWidth(0, 22); m_StackList.SetColumnWidth(0, 22);
m_StackList.SetColumnWidth(1, 64); m_StackList.SetColumnWidth(1, 64);
m_StackList.SetColumnWidth(2, 64); m_StackList.SetColumnWidth(2, 64);
m_StackList.SetColumnWidth(3, 64); m_StackList.SetColumnWidth(3, 64);
m_StackList.SetColumnWidth(4, 64); m_StackList.SetColumnWidth(4, 64);
m_SPStatic.Attach(GetDlgItem(IDC_SP_STATIC)); m_SPStatic.Attach(GetDlgItem(IDC_SP_STATIC));
WindowCreated(); WindowCreated();
return 0; return 0;
} }
LRESULT CDebugStackView::OnDestroy(void) LRESULT CDebugStackView::OnDestroy(void)
{ {
m_StackList.Detach(); m_StackList.Detach();
m_SPStatic.Detach(); m_SPStatic.Detach();
return 0; return 0;
} }
LRESULT CDebugStackView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) LRESULT CDebugStackView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{ {
switch (wID) switch (wID)
{ {
case IDC_MEM_BTN: case IDC_MEM_BTN:
if (g_Reg != NULL) if (g_Reg != NULL)
{ {
m_Debugger->Debug_ShowMemoryLocation(g_Reg->m_GPR[29].UW[0], true); m_Debugger->Debug_ShowMemoryLocation(g_Reg->m_GPR[29].UW[0], true);
} }
break; break;
case IDCANCEL: case IDCANCEL:
EndDialog(0); EndDialog(0);
break; break;
} }
return 0; return 0;
} }
void CDebugStackView::Refresh() void CDebugStackView::Refresh()
{ {
m_StackList.SetRedraw(FALSE); m_StackList.SetRedraw(FALSE);
m_StackList.DeleteAllItems(); m_StackList.DeleteAllItems();
uint32_t spBase; uint32_t spBase;
if (g_Reg != NULL) if (g_Reg != NULL)
{ {
spBase = g_Reg->m_GPR[29].UW[0]; spBase = g_Reg->m_GPR[29].UW[0];
m_SPStatic.SetWindowTextA(stdstr_f("SP: %08X", spBase).c_str()); m_SPStatic.SetWindowTextA(stdstr_f("SP: %08X", spBase).c_str());
} }
CSymbols::EnterCriticalSection(); CSymbols::EnterCriticalSection();
for (int i = 0; i < 0x10; i++) for (int i = 0; i < 0x10; i++)
{ {
char t[4]; char t[4];
sprintf(t, "%02X", i * 0x10); sprintf(t, "%02X", i * 0x10);
m_StackList.AddItem(i, 0, t); m_StackList.AddItem(i, 0, t);
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
{ {
if (g_MMU == NULL) uint32_t vaddr = spBase + (i * 0x10) + (j * 4);
{ uint32_t val;
m_StackList.AddItem(i, j + 1, "????????");
continue;
}
uint32_t val; if (!m_Debugger->DebugLW_VAddr(vaddr, val))
g_MMU->LW_VAddr(spBase + i * 0x10 + j * 4, val); {
m_StackList.AddItem(i, j + 1, "????????");
continue;
}
char valStr[9]; char valStr[9];
sprintf(valStr, "%08X", val); sprintf(valStr, "%08X", val);
m_StackList.AddItem(i, j + 1, valStr); m_StackList.AddItem(i, j + 1, valStr);
} }
} }
CSymbols::LeaveCriticalSection(); CSymbols::LeaveCriticalSection();
m_StackList.SetRedraw(TRUE); m_StackList.SetRedraw(TRUE);
} }

View File

@ -36,7 +36,7 @@ CDebugMemoryView::~CDebugMemoryView()
{ {
} }
LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{ {
m_SymbolColorStride = 0; m_SymbolColorStride = 0;
m_SymbolColorPhase = 0; m_SymbolColorPhase = 0;
@ -613,22 +613,14 @@ void CDebugMemoryView::RefreshMemory(bool ResetCompare)
if (m_DataVAddrr) if (m_DataVAddrr)
{ {
if (!AddressSafe(m_DataStartLoc & ~3)) if (!m_Debugger->DebugLW_VAddr(m_DataStartLoc & ~3, word.UW))
{
ValidData = false;
}
else if (!g_MMU->LW_VAddr(m_DataStartLoc & ~3, word.UW))
{ {
ValidData = false; ValidData = false;
} }
} }
else else
{ {
if ((m_DataStartLoc & ~3) >= g_MMU->RdramSize()) if (!m_Debugger->DebugLW_PAddr(m_DataStartLoc & ~3, word.UW))
{
ValidData = false;
}
else if (!g_MMU->LW_PAddr(m_DataStartLoc & ~3, word.UW))
{ {
ValidData = false; ValidData = false;
} }
@ -657,22 +649,14 @@ void CDebugMemoryView::RefreshMemory(bool ResetCompare)
if (m_DataVAddrr) if (m_DataVAddrr)
{ {
if (!AddressSafe(Pos)) if (!m_Debugger->DebugLW_VAddr(Pos, word.UW))
{
ValidData = false;
}
else if (!g_MMU->LW_VAddr(Pos, word.UW))
{ {
ValidData = false; ValidData = false;
} }
} }
else else
{ {
if (Pos >= g_MMU->RdramSize()) if (!m_Debugger->DebugLW_PAddr(Pos, word.UW))
{
ValidData = false;
}
else if (!g_MMU->LW_PAddr(Pos, word.UW))
{ {
ValidData = false; ValidData = false;
} }
@ -781,22 +765,3 @@ void CDebugMemoryView::SelectColors(uint32_t vaddr, bool changed, COLORREF& bgCo
m_SymbolColorStride--; m_SymbolColorStride--;
} }
} }
// Check if KSEG0 addr is out of bounds
bool CDebugMemoryView::AddressSafe(uint32_t vaddr)
{
if (g_MMU == NULL)
{
return false;
}
if (vaddr >= 0x80000000 && vaddr <= 0x9FFFFFFF)
{
if ((vaddr & 0x1FFFFFFF) >= g_MMU->RdramSize())
{
return false;
}
}
return true;
}

View File

@ -56,8 +56,6 @@ private:
bool GetItemOffset(LPNMHDR lpNMHDR, uint32_t &offset); bool GetItemOffset(LPNMHDR lpNMHDR, uint32_t &offset);
bool GetItemAddress(LPNMHDR lpNMHDR, uint32_t &address); bool GetItemAddress(LPNMHDR lpNMHDR, uint32_t &address);
bool AddressSafe(uint32_t vaddr);
enum { MemoryToDisplay = 0x100 }; enum { MemoryToDisplay = 0x100 };
static CDebugMemoryView* _this; static CDebugMemoryView* _this;

View File

@ -8,6 +8,7 @@
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * * GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* * * *
****************************************************************************/ ****************************************************************************/
#include "stdafx.h" #include "stdafx.h"
#include "DebuggerUI.h" #include "DebuggerUI.h"
#include "ScriptHook.h" #include "ScriptHook.h"
@ -376,6 +377,192 @@ CDMALog* CDebuggerUI::DMALog()
return m_DMALog; return m_DMALog;
} }
// thread safe LW_PAddr
// does not trigger application breakpoint if paddr is invalid
bool CDebuggerUI::DebugLW_PAddr(uint32_t paddr, uint32_t& value)
{
if (g_MMU == NULL)
{
return false;
}
if ((paddr < g_MMU->RdramSize()) || // RDRAM
(paddr >= 0x04000000 && paddr <= 0x04001FFF)) // DMEM/IMEM
{
value = *(uint32_t*)(g_MMU->Rdram() + paddr);
return true;
}
else if (paddr >= 0x05000000 && paddr <= 0x050004FF) // 64DD buffer
{
// todo
return false;
}
else if (paddr >= 0x06000000 && paddr <= 0x06FFFFFF) // Cartridge Domain 1 (Address 1) (64DD IPL ROM)
{
uint32_t iplRomOffset = paddr - 0x06000000;
if (g_DDRom != NULL && iplRomOffset < g_DDRom->GetRomSize())
{
value = *(uint32_t*)(g_MMU->Rdram() + paddr);
return true;
}
}
else if (paddr >= 0x08000000 && paddr < 0x08FFFFFF) // Cartridge Domain 2 (Address 2)
{
uint32_t saveOffset = paddr & 0x000FFFFF;
if (g_System->m_SaveUsing == SaveChip_Sram && saveOffset <= 0x7FFF) // sram
{
uint8_t tmp[4] = "";
CSram *sram = g_MMU->GetSram();
sram->DmaFromSram(tmp, paddr - 0x08000000, 4);
value = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0];
return true;
}
else if (g_System->m_SaveUsing == SaveChip_FlashRam && saveOffset == 0) // flash ram status
{
CFlashram* flashRam = g_MMU->GetFlashram();
value = flashRam->ReadFromFlashStatus(0x08000000);
return true;
}
}
else if (paddr >= 0x10000000 && paddr <= 0x15FFFFFF) // Cartridge ROM
{
uint32_t cartRomOffset = paddr - 0x10000000;
if (g_Rom != NULL && paddr < g_Rom->GetRomSize())
{
value = *(uint32_t*)(g_Rom->GetRomAddress() + cartRomOffset);
return true;
}
}
else if (paddr >= 0x1FC00000 && paddr <= 0x1FC007BF) // PIF ROM
{
return false;
}
else if (paddr >= 0x1FC007C0 && paddr <= 0x1FC007FF) // PIF RAM
{
uint32_t pifRamOffset = paddr - 0x1FC007C0;
value = *(uint32_t*)(g_MMU->PifRam() + pifRamOffset);
return true;
}
// note: write-only registers are excluded
switch (paddr)
{
case 0x03F00000: value = g_Reg->RDRAM_CONFIG_REG; return true;
case 0x03F00004: value = g_Reg->RDRAM_DEVICE_ID_REG; return true;
case 0x03F00008: value = g_Reg->RDRAM_DELAY_REG; return true;
case 0x03F0000C: value = g_Reg->RDRAM_MODE_REG; return true;
case 0x03F00010: value = g_Reg->RDRAM_REF_INTERVAL_REG; return true;
case 0x03F00014: value = g_Reg->RDRAM_REF_ROW_REG; return true;
case 0x03F00018: value = g_Reg->RDRAM_RAS_INTERVAL_REG; return true;
case 0x03F0001C: value = g_Reg->RDRAM_MIN_INTERVAL_REG; return true;
case 0x03F00020: value = g_Reg->RDRAM_ADDR_SELECT_REG; return true;
case 0x03F00024: value = g_Reg->RDRAM_DEVICE_MANUF_REG; return true;
case 0x04040010: value = g_Reg->SP_STATUS_REG; return true;
case 0x04040014: value = g_Reg->SP_DMA_FULL_REG; return true;
case 0x04040018: value = g_Reg->SP_DMA_BUSY_REG; return true;
case 0x0404001C: value = g_Reg->SP_SEMAPHORE_REG; return true;
case 0x04080000: value = g_Reg->SP_PC_REG; return true;
case 0x0410000C: value = g_Reg->DPC_STATUS_REG; return true;
case 0x04100010: value = g_Reg->DPC_CLOCK_REG; return true;
case 0x04100014: value = g_Reg->DPC_BUFBUSY_REG; return true;
case 0x04100018: value = g_Reg->DPC_PIPEBUSY_REG; return true;
case 0x0410001C: value = g_Reg->DPC_TMEM_REG; return true;
case 0x04300000: value = g_Reg->MI_MODE_REG; return true;
case 0x04300004: value = g_Reg->MI_VERSION_REG; return true;
case 0x04300008: value = g_Reg->MI_INTR_REG; return true;
case 0x0430000C: value = g_Reg->MI_INTR_MASK_REG; return true;
case 0x04400000: value = g_Reg->VI_STATUS_REG; return true;
case 0x04400004: value = g_Reg->VI_ORIGIN_REG; return true;
case 0x04400008: value = g_Reg->VI_WIDTH_REG; return true;
case 0x0440000C: value = g_Reg->VI_INTR_REG; return true;
case 0x04400010: value = g_Reg->VI_V_CURRENT_LINE_REG; return true;
case 0x04400014: value = g_Reg->VI_BURST_REG; return true;
case 0x04400018: value = g_Reg->VI_V_SYNC_REG; return true;
case 0x0440001C: value = g_Reg->VI_H_SYNC_REG; return true;
case 0x04400020: value = g_Reg->VI_LEAP_REG; return true;
case 0x04400024: value = g_Reg->VI_H_START_REG; return true;
case 0x04400028: value = g_Reg->VI_V_START_REG; return true;
case 0x0440002C: value = g_Reg->VI_V_BURST_REG; return true;
case 0x04400030: value = g_Reg->VI_X_SCALE_REG; return true;
case 0x04400034: value = g_Reg->VI_Y_SCALE_REG; return true;
case 0x04600000: value = g_Reg->PI_DRAM_ADDR_REG; return true;
case 0x04600004: value = g_Reg->PI_CART_ADDR_REG; return true;
case 0x04600008: value = g_Reg->PI_RD_LEN_REG; return true;
case 0x0460000C: value = g_Reg->PI_WR_LEN_REG; return true;
case 0x04600010: value = g_Reg->PI_STATUS_REG; return true;
case 0x04600014: value = g_Reg->PI_DOMAIN1_REG; return true;
case 0x04600018: value = g_Reg->PI_BSD_DOM1_PWD_REG; return true;
case 0x0460001C: value = g_Reg->PI_BSD_DOM1_PGS_REG; return true;
case 0x04600020: value = g_Reg->PI_BSD_DOM1_RLS_REG; return true;
case 0x04600024: value = g_Reg->PI_DOMAIN2_REG; return true;
case 0x04600028: value = g_Reg->PI_BSD_DOM2_PWD_REG; return true;
case 0x0460002C: value = g_Reg->PI_BSD_DOM2_PGS_REG; return true;
case 0x04600030: value = g_Reg->PI_BSD_DOM2_RLS_REG; return true;
case 0x04700000: value = g_Reg->RI_MODE_REG; return true;
case 0x04700004: value = g_Reg->RI_CONFIG_REG; return true;
case 0x04700008: value = g_Reg->RI_CURRENT_LOAD_REG; return true;
case 0x0470000C: value = g_Reg->RI_SELECT_REG; return true;
case 0x04700010: value = g_Reg->RI_REFRESH_REG; return true;
case 0x04700014: value = g_Reg->RI_LATENCY_REG; return true;
case 0x04700018: value = g_Reg->RI_RERROR_REG; return true;
case 0x0470001C: value = g_Reg->RI_WERROR_REG; return true;
case 0x04800018: value = g_Reg->SI_STATUS_REG; return true;
case 0x05000500: value = g_Reg->ASIC_DATA; return true;
case 0x05000504: value = g_Reg->ASIC_MISC_REG; return true;
case 0x05000508: value = g_Reg->ASIC_STATUS; return true;
case 0x0500050C: value = g_Reg->ASIC_CUR_TK; return true;
case 0x05000510: value = g_Reg->ASIC_BM_STATUS; return true;
case 0x05000514: value = g_Reg->ASIC_ERR_SECTOR; return true;
case 0x05000518: value = g_Reg->ASIC_SEQ_STATUS; return true;
case 0x0500051C: value = g_Reg->ASIC_CUR_SECTOR; return true;
case 0x05000520: value = g_Reg->ASIC_HARD_RESET; return true;
case 0x05000524: value = g_Reg->ASIC_C1_S0; return true;
case 0x05000528: value = g_Reg->ASIC_HOST_SECBYTE; return true;
case 0x0500052C: value = g_Reg->ASIC_C1_S2; return true;
case 0x05000530: value = g_Reg->ASIC_SEC_BYTE; return true;
case 0x05000534: value = g_Reg->ASIC_C1_S4; return true;
case 0x05000538: value = g_Reg->ASIC_C1_S6; return true;
case 0x0500053C: value = g_Reg->ASIC_CUR_ADDR; return true;
case 0x05000540: value = g_Reg->ASIC_ID_REG; return true;
case 0x05000544: value = g_Reg->ASIC_TEST_REG; return true;
case 0x05000548: value = g_Reg->ASIC_TEST_PIN_SEL; return true;
case 0x04500004:
if (g_System->bFixedAudio())
{
value = g_Audio->GetLength();
}
else
{
CAudioPlugin* audioPlg = g_Plugins->Audio();
value = (audioPlg->AiReadLength != NULL) ? audioPlg->AiReadLength() : 0;
}
return true;
case 0x0450000C:
value = g_System->bFixedAudio() ? g_Audio->GetStatus() : g_Reg->AI_STATUS_REG;
return true;
}
return false;
}
bool CDebuggerUI::DebugLW_VAddr(uint32_t vaddr, uint32_t& value)
{
if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB)
{
if (g_MMU == NULL)
{
return false;
}
return g_MMU->LW_VAddr(vaddr, value);
}
uint32_t paddr = vaddr & 0x1FFFFFFF;
return DebugLW_PAddr(paddr, value);
}
// CDebugger implementation // CDebugger implementation
void CDebuggerUI::TLBChanged() void CDebuggerUI::TLBChanged()
@ -384,7 +571,6 @@ void CDebuggerUI::TLBChanged()
} }
// Called from the interpreter core at the beginning of every CPU step // Called from the interpreter core at the beginning of every CPU step
// Returns false when the instruction should be skipped
void CDebuggerUI::CPUStepStarted() void CDebuggerUI::CPUStepStarted()
{ {
uint32_t PROGRAM_COUNTER = g_Reg->m_PROGRAM_COUNTER; uint32_t PROGRAM_COUNTER = g_Reg->m_PROGRAM_COUNTER;
@ -568,4 +754,3 @@ bool CDebuggerUI::WriteBP64(uint32_t address)
{ {
return m_Breakpoints != NULL && m_Breakpoints->WriteBPExists64(address) != CBreakpoints::BP_NOT_SET; return m_Breakpoints != NULL && m_Breakpoints->WriteBPExists64(address) != CBreakpoints::BP_NOT_SET;
} }

View File

@ -78,6 +78,9 @@ public:
static void GameReset(CDebuggerUI * _this); static void GameReset(CDebuggerUI * _this);
static void SteppingOpsChanged(CDebuggerUI * _this); static void SteppingOpsChanged(CDebuggerUI * _this);
bool DebugLW_PAddr(uint32_t vaddr, uint32_t& value);
bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value);
protected: protected:
void TLBChanged(void); void TLBChanged(void);
void CPUStepStarted(void); void CPUStepStarted(void);

View File

@ -1009,14 +1009,14 @@ BEGIN
LTEXT "CPU Coprocessor 0",-1,3,4,100,8 LTEXT "CPU Coprocessor 0",-1,3,4,100,8
END END
IDD_Debugger_Stack DIALOGEX 0, 0, 191, 204 IDD_Debugger_Stack DIALOGEX 0, 0, 197, 212
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Stack" CAPTION "Stack"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
CONTROL "",IDC_STACK_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,0,15,190,189 CONTROL "",IDC_STACK_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,3,20,190,189
LTEXT "SP: 00000000",IDC_SP_STATIC,5,3,45,10 LTEXT "SP: 00000000",IDC_SP_STATIC,3,7,51,10
PUSHBUTTON "View...",IDC_MEM_BTN,54,2,34,11 PUSHBUTTON "View...",IDC_MEM_BTN,153,5,39,12
END END
IDD_Debugger_RegSP DIALOGEX 0, 0, 190, 210 IDD_Debugger_RegSP DIALOGEX 0, 0, 190, 210
@ -1615,7 +1615,8 @@ BEGIN
IDD_Debugger_Stack, DIALOG IDD_Debugger_Stack, DIALOG
BEGIN BEGIN
BOTTOMMARGIN, 190 RIGHTMARGIN, 193
BOTTOMMARGIN, 198
END END
IDD_Debugger_RegSP, DIALOG IDD_Debugger_RegSP, DIALOG
@ -1886,6 +1887,11 @@ BEGIN
0 0
END END
IDD_Debugger_Stack AFX_DIALOG_LAYOUT
BEGIN
0
END
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //

View File

@ -639,7 +639,7 @@
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 196 #define _APS_NEXT_RESOURCE_VALUE 197
#define _APS_NEXT_COMMAND_VALUE 40043 #define _APS_NEXT_COMMAND_VALUE 40043
#define _APS_NEXT_CONTROL_VALUE 1447 #define _APS_NEXT_CONTROL_VALUE 1447
#define _APS_NEXT_SYMED_VALUE 102 #define _APS_NEXT_SYMED_VALUE 102