From 622d5d5d3fa0c2511b0f15adead1fb0ab2c81ebe Mon Sep 17 00:00:00 2001 From: zilmar Date: Mon, 5 Feb 2018 17:43:46 +1100 Subject: [PATCH] [Debugger] Fix Read break points --- .../N64System/Interpreter/InterpreterOps.cpp | 58 ++++++++++++++++- .../Interpreter/InterpreterOps32.cpp | 39 +++++++++++- .../Project64-core/Settings/DebugSettings.cpp | 5 +- .../Project64-core/Settings/SettingsClass.cpp | 1 + .../UserInterface/Debugger/Breakpoints.cpp | 63 ++++++++++++++++++- .../Debugger/Debugger-ViewMemory.cpp | 2 +- .../UserInterface/Debugger/Debugger.cpp | 22 ++++++- 7 files changed, 181 insertions(+), 9 deletions(-) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 262862d10..f149ccb15 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -1025,6 +1025,10 @@ void R4300iOp::LDL() uint64_t Value; Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint()) + { + return; + } Offset = Address & 7; if (!g_MMU->LD_VAddr((Address & ~7), Value)) @@ -1052,6 +1056,10 @@ void R4300iOp::LDR() uint64_t Value; Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint()) + { + return; + } Offset = Address & 7; if (!g_MMU->LD_VAddr((Address & ~7), Value)) @@ -1071,6 +1079,10 @@ void R4300iOp::LDR() void R4300iOp::LB() { uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + if (HaveReadBP() && g_Debugger->ReadBP8(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LB_VAddr(Address, _GPR[m_Opcode.rt].UB[0])) { if (bShowTLBMisses()) @@ -1092,6 +1104,10 @@ void R4300iOp::LH() { ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP16(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0])) { if (bShowTLBMisses()) @@ -1111,6 +1127,10 @@ void R4300iOp::LWL() uint32_t Offset, Address, Value; Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } Offset = Address & 3; if (!g_MMU->LW_VAddr((Address & ~3), Value)) @@ -1134,7 +1154,10 @@ void R4300iOp::LW() { ADDRESS_ERROR_EXCEPTION(Address, true); } - + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } if (GenerateLog()) { Log_LW((*_PROGRAM_COUNTER), Address); @@ -1157,6 +1180,10 @@ void R4300iOp::LW() void R4300iOp::LBU() { uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + if (HaveReadBP() && g_Debugger->ReadBP8(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LB_VAddr(Address, _GPR[m_Opcode.rt].UB[0])) { if (bShowTLBMisses()) @@ -1178,6 +1205,10 @@ void R4300iOp::LHU() { ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP16(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0])) { if (bShowTLBMisses()) @@ -1198,6 +1229,10 @@ void R4300iOp::LWR() Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; Offset = Address & 3; + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LW_VAddr((Address & ~3), Value)) { @@ -1220,6 +1255,10 @@ void R4300iOp::LWU() { ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) { @@ -1507,6 +1546,11 @@ void R4300iOp::LL() ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } + if (!g_MMU->LW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) { if (bShowTLBMisses()) @@ -1530,6 +1574,10 @@ void R4300iOp::LWC1() { ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LW_VAddr(Address, *(uint32_t *)_FPR_S[m_Opcode.ft])) { if (bShowTLBMisses()) @@ -1573,6 +1621,10 @@ void R4300iOp::LD() { ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LD_VAddr(Address, _GPR[m_Opcode.rt].UDW)) { if (HaveDebugger()) @@ -1602,6 +1654,10 @@ void R4300iOp::LDC1() { ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LD_VAddr(Address, *(uint64_t *)_FPR_D[m_Opcode.ft])) { if (HaveDebugger()) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp index 2dbaa3fb7..53b2dc4ac 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp @@ -15,6 +15,7 @@ #include #include #include +#include bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); @@ -891,6 +892,10 @@ void R4300iOp32::BGTZL() void R4300iOp32::LB() { uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + if (HaveReadBP() && g_Debugger->ReadBP8(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LB_VAddr(Address, _GPR[m_Opcode.rt].UB[0])) { if (bShowTLBMisses()) @@ -912,6 +917,10 @@ void R4300iOp32::LH() { ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP16(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0])) { if (bShowTLBMisses()) @@ -933,6 +942,10 @@ void R4300iOp32::LWL() Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; Offset = Address & 3; + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LW_VAddr((Address & ~3), Value)) { if (bShowTLBMisses()) @@ -954,6 +967,10 @@ void R4300iOp32::LW() { ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } if (GenerateLog()) { @@ -977,6 +994,10 @@ void R4300iOp32::LW() void R4300iOp32::LBU() { uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + if (HaveReadBP() && g_Debugger->ReadBP8(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LB_VAddr(Address, _GPR[m_Opcode.rt].UB[0])) { if (bShowTLBMisses()) @@ -998,6 +1019,10 @@ void R4300iOp32::LHU() { ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP16(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0])) { if (bShowTLBMisses()) @@ -1018,7 +1043,10 @@ void R4300iOp32::LWR() Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; Offset = Address & 3; - + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LW_VAddr((Address & ~3), Value)) { g_Notify->BreakPoint(__FILE__, __LINE__); @@ -1041,6 +1069,10 @@ void R4300iOp32::LWU() ADDRESS_ERROR_EXCEPTION(Address, true); } + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) { if (bShowTLBMisses()) @@ -1062,7 +1094,10 @@ void R4300iOp32::LL() { ADDRESS_ERROR_EXCEPTION(Address, true); } - + if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) + { + return; + } if (!g_MMU->LW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) { if (bShowTLBMisses()) diff --git a/Source/Project64-core/Settings/DebugSettings.cpp b/Source/Project64-core/Settings/DebugSettings.cpp index adfc93c35..3ec21d99a 100644 --- a/Source/Project64-core/Settings/DebugSettings.cpp +++ b/Source/Project64-core/Settings/DebugSettings.cpp @@ -26,6 +26,7 @@ bool CDebugSettings::m_bShowDivByZero = false; bool CDebugSettings::m_RecordExecutionTimes = false; bool CDebugSettings::m_HaveExecutionBP = false; bool CDebugSettings::m_HaveWriteBP = false; +bool CDebugSettings::m_HaveReadBP = false; CDebugSettings::CDebugSettings() { @@ -42,6 +43,7 @@ CDebugSettings::CDebugSettings() g_Settings->RegisterChangeCB(Debugger_SkipOp, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); g_Settings->RegisterChangeCB(Debugger_HaveExecutionBP, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); g_Settings->RegisterChangeCB(Debugger_WriteBPExists, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + g_Settings->RegisterChangeCB(Debugger_ReadBPExists, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); g_Settings->RegisterChangeCB(Debugger_WaitingForStep, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); RefreshSettings(); @@ -78,6 +80,7 @@ void CDebugSettings::RefreshSettings() m_WaitingForStep = g_Settings->LoadBool(Debugger_WaitingForStep); m_HaveExecutionBP = m_HaveDebugger && g_Settings->LoadBool(Debugger_HaveExecutionBP); m_HaveWriteBP = m_HaveDebugger && g_Settings->LoadBool(Debugger_WriteBPExists); + m_HaveReadBP = m_HaveDebugger && g_Settings->LoadBool(Debugger_ReadBPExists); - m_Debugging = m_HaveDebugger && (m_HaveExecutionBP || m_WaitingForStep || m_HaveWriteBP); + m_Debugging = m_HaveDebugger && (m_HaveExecutionBP || m_WaitingForStep || m_HaveWriteBP || m_HaveReadBP); } \ No newline at end of file diff --git a/Source/Project64-core/Settings/SettingsClass.cpp b/Source/Project64-core/Settings/SettingsClass.cpp index aca495770..d9c184fd7 100644 --- a/Source/Project64-core/Settings/SettingsClass.cpp +++ b/Source/Project64-core/Settings/SettingsClass.cpp @@ -318,6 +318,7 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory) AddHandler(Debugger_SkipOp, new CSettingTypeTempBool(false)); AddHandler(Debugger_HaveExecutionBP, new CSettingTypeTempBool(false)); AddHandler(Debugger_WriteBPExists, new CSettingTypeTempBool(false)); + AddHandler(Debugger_ReadBPExists, new CSettingTypeTempBool(false)); AddHandler(Debugger_WaitingForStep, new CSettingTypeTempBool(false)); AddHandler(Debugger_DebugLanguage, new CSettingTypeApplication("Debugger", "Debug Language", false)); AddHandler(Debugger_ShowDivByZero, new CSettingTypeApplication("Debugger", "Show Div by zero", false)); diff --git a/Source/Project64/UserInterface/Debugger/Breakpoints.cpp b/Source/Project64/UserInterface/Debugger/Breakpoints.cpp index ba961c8ab..9bc7b4c55 100644 --- a/Source/Project64/UserInterface/Debugger/Breakpoints.cpp +++ b/Source/Project64/UserInterface/Debugger/Breakpoints.cpp @@ -23,9 +23,14 @@ CBreakpoints::CBreakpoints() bool CBreakpoints::RBPAdd(uint32_t address) { - if (!ReadBPExists(address)) + if (!ReadBPExists8(address)) { m_ReadMem.insert(breakpoints_t::value_type(address, false)); + UpdateAlignedReadBP(); + if (!HaveReadBP()) + { + g_Settings->SaveBool(Debugger_ReadBPExists, true); + } return true; } return false; @@ -67,6 +72,11 @@ void CBreakpoints::RBPRemove(uint32_t address) if (itr != m_ReadMem.end()) { m_ReadMem.erase(itr); + UpdateAlignedWriteBP(); + if (m_ReadMem.size() == 0) + { + g_Settings->SaveBool(Debugger_ReadBPExists, false); + } } } @@ -77,7 +87,7 @@ void CBreakpoints::WBPRemove(uint32_t address) { m_WriteMem.erase(itr); UpdateAlignedWriteBP(); - if (m_Execution.size() == 0) + if (m_WriteMem.size() == 0) { g_Settings->SaveBool(Debugger_WriteBPExists, false); } @@ -124,6 +134,8 @@ void CBreakpoints::EBPToggle(uint32_t address, bool bTemporary) void CBreakpoints::RBPClear() { m_ReadMem.clear(); + UpdateAlignedReadBP(); + g_Settings->SaveBool(Debugger_ReadBPExists, false); } void CBreakpoints::WBPClear() @@ -136,6 +148,7 @@ void CBreakpoints::WBPClear() void CBreakpoints::EBPClear() { m_Execution.clear(); + g_Settings->SaveBool(Debugger_HaveExecutionBP, false); } void CBreakpoints::BPClear() @@ -145,7 +158,7 @@ void CBreakpoints::BPClear() EBPClear(); } -CBreakpoints::BPSTATE CBreakpoints::ReadBPExists(uint32_t address) +CBreakpoints::BPSTATE CBreakpoints::ReadBPExists8(uint32_t address) { breakpoints_t::const_iterator itr = m_ReadMem.find(address); if (itr != m_ReadMem.end()) @@ -155,6 +168,36 @@ CBreakpoints::BPSTATE CBreakpoints::ReadBPExists(uint32_t address) return BP_NOT_SET; } +CBreakpoints::BPSTATE CBreakpoints::ReadBPExists16(uint32_t address) +{ + breakpoints_t::const_iterator itr = m_ReadMem16.find(address); + if (itr != m_ReadMem.end()) + { + return BP_SET; + } + return BP_NOT_SET; +} + +CBreakpoints::BPSTATE CBreakpoints::ReadBPExists32(uint32_t address) +{ + breakpoints_t::const_iterator itr = m_ReadMem32.find(address); + if (itr != m_ReadMem.end()) + { + return BP_SET; + } + return BP_NOT_SET; +} + +CBreakpoints::BPSTATE CBreakpoints::ReadBPExists64(uint32_t address) +{ + breakpoints_t::const_iterator itr = m_ReadMem64.find(address); + if (itr != m_ReadMem.end()) + { + return BP_SET; + } + return BP_NOT_SET; +} + CBreakpoints::BPSTATE CBreakpoints::WriteBPExists8(uint32_t address) { breakpoints_t::const_iterator itr = m_WriteMem.find(address); @@ -213,6 +256,20 @@ CBreakpoints::BPSTATE CBreakpoints::ExecutionBPExists(uint32_t address, bool bRe return BP_NOT_SET; } +void CBreakpoints::UpdateAlignedReadBP() +{ + m_ReadMem16.clear(); + m_ReadMem32.clear(); + m_ReadMem64.clear(); + + for (breakpoints_t::const_iterator itr = m_ReadMem.begin(); itr != m_ReadMem.end(); itr++) + { + m_ReadMem16.insert(breakpoints_t::value_type((itr->first & ~0x1), false)); + m_ReadMem32.insert(breakpoints_t::value_type((itr->first & ~0x3), false)); + m_ReadMem64.insert(breakpoints_t::value_type((itr->first & ~0x7), false)); + } +} + void CBreakpoints::UpdateAlignedWriteBP() { m_WriteMem16.clear(); diff --git a/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.cpp b/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.cpp index 578bed68a..2cdc0a346 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.cpp @@ -717,7 +717,7 @@ void CDebugMemoryView::SelectColors(uint32_t vaddr, bool changed, COLORREF& bgCo CSymbols::LeaveCriticalSection(); - bool bHaveReadBP = m_Breakpoints->ReadBPExists(vaddr) == CBreakpoints::BP_SET; + bool bHaveReadBP = m_Breakpoints->ReadBPExists8(vaddr) == CBreakpoints::BP_SET; bool bHaveWriteBP = m_Breakpoints->WriteBPExists8(vaddr) == CBreakpoints::BP_SET; fgHiColor = RGB(0x00, 0x00, 0x00); diff --git a/Source/Project64/UserInterface/Debugger/Debugger.cpp b/Source/Project64/UserInterface/Debugger/Debugger.cpp index 24c575779..7505c5b9b 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger.cpp @@ -405,7 +405,7 @@ void CDebuggerUI::CPUStepStarted() { m_ScriptSystem->HookCPURead()->InvokeByParamInRange(memoryAddress); - if (m_Breakpoints->ReadBPExists(memoryAddress)) + if (m_Breakpoints->ReadBPExists8(memoryAddress)) { goto breakpoint_hit; } @@ -535,6 +535,26 @@ bool CDebuggerUI::ExecutionBP(uint32_t address) return m_Breakpoints != NULL && m_Breakpoints->ExecutionBPExists(address, true) != CBreakpoints::BP_NOT_SET; } +bool CDebuggerUI::ReadBP8(uint32_t address) +{ + return m_Breakpoints != NULL && m_Breakpoints->ReadBPExists8(address) != CBreakpoints::BP_NOT_SET; +} + +bool CDebuggerUI::ReadBP16(uint32_t address) +{ + return m_Breakpoints != NULL && m_Breakpoints->ReadBPExists16(address) != CBreakpoints::BP_NOT_SET; +} + +bool CDebuggerUI::ReadBP32(uint32_t address) +{ + return m_Breakpoints != NULL && m_Breakpoints->ReadBPExists32(address) != CBreakpoints::BP_NOT_SET; +} + +bool CDebuggerUI::ReadBP64(uint32_t address) +{ + return m_Breakpoints != NULL && m_Breakpoints->ReadBPExists64(address) != CBreakpoints::BP_NOT_SET; +} + bool CDebuggerUI::WriteBP8(uint32_t address) { return m_Breakpoints != NULL && m_Breakpoints->WriteBPExists8(address) != CBreakpoints::BP_NOT_SET;