From 7992ff46271344b85ba8a68717b5957191c08a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Nov 2024 15:19:30 +0100 Subject: [PATCH] Make CBreakpoints an object --- Core/Core.cpp | 12 +-- Core/Debugger/Breakpoints.cpp | 96 +++++++++--------- Core/Debugger/Breakpoints.h | 98 +++++++++---------- Core/Debugger/MemBlockInfo.cpp | 6 +- .../WebSocket/BreakpointSubscriber.cpp | 38 +++---- Core/Debugger/WebSocket/CPUCoreSubscriber.cpp | 2 +- Core/Debugger/WebSocket/DisasmSubscriber.cpp | 4 +- .../Debugger/WebSocket/SteppingSubscriber.cpp | 14 +-- Core/HLE/ReplaceTables.cpp | 4 +- Core/MIPS/ARM/ArmJit.cpp | 20 ++-- Core/MIPS/ARM64/Arm64IRCompSystem.cpp | 4 +- Core/MIPS/ARM64/Arm64Jit.cpp | 20 ++-- Core/MIPS/IR/IRFrontend.cpp | 10 +- Core/MIPS/IR/IRInterpreter.cpp | 8 +- Core/MIPS/MIPSDebugInterface.cpp | 8 +- Core/MIPS/MIPSTables.cpp | 20 ++-- Core/MIPS/fake/FakeJit.cpp | 2 +- Core/MIPS/x86/Jit.cpp | 24 ++--- Core/MIPS/x86/X64IRCompSystem.cpp | 4 +- UI/ImDebugger/ImDisasmView.cpp | 24 ++--- UI/ImDebugger/ImStructViewer.cpp | 12 +-- Windows/Debugger/BreakpointWindow.cpp | 16 +-- Windows/Debugger/CtrlDisAsmView.cpp | 22 ++--- Windows/Debugger/Debugger_Disasm.cpp | 17 ++-- Windows/Debugger/Debugger_Disasm.h | 5 +- Windows/Debugger/Debugger_Lists.cpp | 20 ++-- 26 files changed, 252 insertions(+), 258 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index 5eec7f2425..0e5be48aea 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -260,7 +260,7 @@ static void Core_PerformStep(MIPSDebugInterface *cpu, CPUStepType stepType, int u32 currentPc = cpu->GetPC(); u32 newAddress = currentPc + stepSize; // If the current PC is on a breakpoint, the user still wants the step to happen. - CBreakPoints::SetSkipFirst(currentPc); + g_breakpoints.SetSkipFirst(currentPc); for (int i = 0; i < (int)(newAddress - currentPc) / 4; i++) { currentMIPS->SingleStep(); } @@ -271,7 +271,7 @@ static void Core_PerformStep(MIPSDebugInterface *cpu, CPUStepType stepType, int u32 currentPc = cpu->GetPC(); u32 breakpointAddress = currentPc + stepSize; - CBreakPoints::SetSkipFirst(currentPc); + g_breakpoints.SetSkipFirst(currentPc); MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(cpu, cpu->GetPC()); if (info.isBranch) { @@ -292,7 +292,7 @@ static void Core_PerformStep(MIPSDebugInterface *cpu, CPUStepType stepType, int } } - CBreakPoints::AddBreakPoint(breakpointAddress, true); + g_breakpoints.AddBreakPoint(breakpointAddress, true); Core_Resume(); break; } @@ -319,8 +319,8 @@ static void Core_PerformStep(MIPSDebugInterface *cpu, CPUStepType stepType, int u32 breakpointAddress = frames[1].pc; // If the current PC is on a breakpoint, the user doesn't want to do nothing. - CBreakPoints::SetSkipFirst(currentMIPS->pc); - CBreakPoints::AddBreakPoint(breakpointAddress, true); + g_breakpoints.SetSkipFirst(currentMIPS->pc); + g_breakpoints.AddBreakPoint(breakpointAddress, true); Core_Resume(); break; } @@ -345,7 +345,7 @@ void Core_ProcessStepping(MIPSDebugInterface *cpu) { // We're not inside jit now, so it's safe to clear the breakpoints. static int lastSteppingCounter = -1; if (lastSteppingCounter != steppingCounter) { - CBreakPoints::ClearTemporaryBreakPoints(); + g_breakpoints.ClearTemporaryBreakPoints(); System_Notify(SystemNotification::DISASSEMBLY_AFTERSTEP); System_Notify(SystemNotification::MEM_VIEW); lastSteppingCounter = steppingCounter; diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp index 9446fc715f..09c04f79bb 100644 --- a/Core/Debugger/Breakpoints.cpp +++ b/Core/Debugger/Breakpoints.cpp @@ -31,17 +31,13 @@ #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/CoreTiming.h" +BreakpointManager g_breakpoints; + std::atomic anyBreakPoints_(false); std::atomic anyMemChecks_(false); static std::mutex breakPointsMutex_; -std::vector CBreakPoints::breakPoints_; -u32 CBreakPoints::breakSkipFirstAt_ = 0; -u64 CBreakPoints::breakSkipFirstTicks_ = 0; static std::mutex memCheckMutex_; -std::vector CBreakPoints::memChecks_; -std::vector CBreakPoints::memCheckRangesRead_; -std::vector CBreakPoints::memCheckRangesWrite_; void MemCheck::Log(u32 addr, bool write, int size, u32 pc, const char *reason) { if (result & BREAK_ACTION_LOG) { @@ -50,7 +46,7 @@ void MemCheck::Log(u32 addr, bool write, int size, u32 pc, const char *reason) { NOTICE_LOG(Log::MemMap, "CHK %s%i(%s) at %08x (%s), PC=%08x (%s)", type, size * 8, reason, addr, g_symbolMap->GetDescription(addr).c_str(), pc, g_symbolMap->GetDescription(pc).c_str()); } else { std::string formatted; - CBreakPoints::EvaluateLogFormat(currentDebugMIPS, logFormat, formatted); + g_breakpoints.EvaluateLogFormat(currentDebugMIPS, logFormat, formatted); NOTICE_LOG(Log::MemMap, "CHK %s%i(%s) at %08x: %s", type, size * 8, reason, addr, formatted.c_str()); } } @@ -82,7 +78,7 @@ BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc, const char } // Note: must lock while calling this. -size_t CBreakPoints::FindBreakpoint(u32 addr, bool matchTemp, bool temp) +size_t BreakpointManager::FindBreakpoint(u32 addr, bool matchTemp, bool temp) { size_t found = INVALID_BREAKPOINT; for (size_t i = 0; i < breakPoints_.size(); ++i) @@ -101,7 +97,7 @@ size_t CBreakPoints::FindBreakpoint(u32 addr, bool matchTemp, bool temp) return found; } -size_t CBreakPoints::FindMemCheck(u32 start, u32 end) +size_t BreakpointManager::FindMemCheck(u32 start, u32 end) { for (size_t i = 0; i < memChecks_.size(); ++i) { @@ -112,7 +108,7 @@ size_t CBreakPoints::FindMemCheck(u32 start, u32 end) return INVALID_MEMCHECK; } -bool CBreakPoints::IsAddressBreakPoint(u32 addr) +bool BreakpointManager::IsAddressBreakPoint(u32 addr) { if (!anyBreakPoints_) return false; @@ -121,7 +117,7 @@ bool CBreakPoints::IsAddressBreakPoint(u32 addr) return bp != INVALID_BREAKPOINT && breakPoints_[bp].result != BREAK_ACTION_IGNORE; } -bool CBreakPoints::IsAddressBreakPoint(u32 addr, bool* enabled) +bool BreakpointManager::IsAddressBreakPoint(u32 addr, bool* enabled) { if (!anyBreakPoints_) return false; @@ -133,14 +129,14 @@ bool CBreakPoints::IsAddressBreakPoint(u32 addr, bool* enabled) return true; } -bool CBreakPoints::IsTempBreakPoint(u32 addr) +bool BreakpointManager::IsTempBreakPoint(u32 addr) { std::lock_guard guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr, true, true); return bp != INVALID_BREAKPOINT; } -bool CBreakPoints::RangeContainsBreakPoint(u32 addr, u32 size) +bool BreakpointManager::RangeContainsBreakPoint(u32 addr, u32 size) { if (!anyBreakPoints_) return false; @@ -155,7 +151,7 @@ bool CBreakPoints::RangeContainsBreakPoint(u32 addr, u32 size) return false; } -void CBreakPoints::AddBreakPoint(u32 addr, bool temp) +void BreakpointManager::AddBreakPoint(u32 addr, bool temp) { std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr, true, temp); @@ -180,7 +176,7 @@ void CBreakPoints::AddBreakPoint(u32 addr, bool temp) } } -void CBreakPoints::RemoveBreakPoint(u32 addr) +void BreakpointManager::RemoveBreakPoint(u32 addr) { std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); @@ -199,7 +195,7 @@ void CBreakPoints::RemoveBreakPoint(u32 addr) } } -void CBreakPoints::ChangeBreakPoint(u32 addr, bool status) +void BreakpointManager::ChangeBreakPoint(u32 addr, bool status) { std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); @@ -215,7 +211,7 @@ void CBreakPoints::ChangeBreakPoint(u32 addr, bool status) } } -void CBreakPoints::ChangeBreakPoint(u32 addr, BreakAction result) +void BreakpointManager::ChangeBreakPoint(u32 addr, BreakAction result) { std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); @@ -227,7 +223,7 @@ void CBreakPoints::ChangeBreakPoint(u32 addr, BreakAction result) } } -void CBreakPoints::ClearAllBreakPoints() +void BreakpointManager::ClearAllBreakPoints() { if (!anyBreakPoints_) return; @@ -240,7 +236,7 @@ void CBreakPoints::ClearAllBreakPoints() } } -void CBreakPoints::ClearTemporaryBreakPoints() +void BreakpointManager::ClearTemporaryBreakPoints() { if (!anyBreakPoints_) return; @@ -261,7 +257,7 @@ void CBreakPoints::ClearTemporaryBreakPoints() Update(); } -void CBreakPoints::ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond) +void BreakpointManager::ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond) { std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); @@ -274,7 +270,7 @@ void CBreakPoints::ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond) } } -void CBreakPoints::ChangeBreakPointRemoveCond(u32 addr) +void BreakpointManager::ChangeBreakPointRemoveCond(u32 addr) { std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); @@ -286,7 +282,7 @@ void CBreakPoints::ChangeBreakPointRemoveCond(u32 addr) } } -BreakPointCond *CBreakPoints::GetBreakPointCondition(u32 addr) +BreakPointCond *BreakpointManager::GetBreakPointCondition(u32 addr) { std::lock_guard guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); @@ -295,7 +291,7 @@ BreakPointCond *CBreakPoints::GetBreakPointCondition(u32 addr) return NULL; } -void CBreakPoints::ChangeBreakPointLogFormat(u32 addr, const std::string &fmt) { +void BreakpointManager::ChangeBreakPointLogFormat(u32 addr, const std::string &fmt) { std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr, true, false); if (bp != INVALID_BREAKPOINT) { @@ -305,7 +301,7 @@ void CBreakPoints::ChangeBreakPointLogFormat(u32 addr, const std::string &fmt) { } } -BreakAction CBreakPoints::ExecBreakPoint(u32 addr) { +BreakAction BreakpointManager::ExecBreakPoint(u32 addr) { if (!anyBreakPoints_) return BREAK_ACTION_IGNORE; std::unique_lock guard(breakPointsMutex_); @@ -316,7 +312,7 @@ BreakAction CBreakPoints::ExecBreakPoint(u32 addr) { if (info.hasCond) { // Evaluate the breakpoint and abort if necessary. - auto cond = CBreakPoints::GetBreakPointCondition(currentMIPS->pc); + auto cond = BreakpointManager::GetBreakPointCondition(currentMIPS->pc); if (cond && !cond->Evaluate()) return BREAK_ACTION_IGNORE; } @@ -326,7 +322,7 @@ BreakAction CBreakPoints::ExecBreakPoint(u32 addr) { NOTICE_LOG(Log::JIT, "BKP PC=%08x (%s)", addr, g_symbolMap->GetDescription(addr).c_str()); } else { std::string formatted; - CBreakPoints::EvaluateLogFormat(currentDebugMIPS, info.logFormat, formatted); + BreakpointManager::EvaluateLogFormat(currentDebugMIPS, info.logFormat, formatted); NOTICE_LOG(Log::JIT, "BKP PC=%08x: %s", addr, formatted.c_str()); } } @@ -340,7 +336,7 @@ BreakAction CBreakPoints::ExecBreakPoint(u32 addr) { return BREAK_ACTION_IGNORE; } -void CBreakPoints::AddMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result) +void BreakpointManager::AddMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result) { std::unique_lock guard(memCheckMutex_); @@ -372,7 +368,7 @@ void CBreakPoints::AddMemCheck(u32 start, u32 end, MemCheckCondition cond, Break } } -void CBreakPoints::RemoveMemCheck(u32 start, u32 end) +void BreakpointManager::RemoveMemCheck(u32 start, u32 end) { std::unique_lock guard(memCheckMutex_); @@ -388,7 +384,7 @@ void CBreakPoints::RemoveMemCheck(u32 start, u32 end) } } -void CBreakPoints::ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result) +void BreakpointManager::ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result) { std::unique_lock guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); @@ -401,7 +397,7 @@ void CBreakPoints::ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, Br } } -void CBreakPoints::ClearAllMemChecks() +void BreakpointManager::ClearAllMemChecks() { std::unique_lock guard(memCheckMutex_); @@ -417,7 +413,7 @@ void CBreakPoints::ClearAllMemChecks() } -void CBreakPoints::ChangeMemCheckAddCond(u32 start, u32 end, const BreakPointCond &cond) { +void BreakpointManager::ChangeMemCheckAddCond(u32 start, u32 end, const BreakPointCond &cond) { std::unique_lock guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK) { @@ -429,7 +425,7 @@ void CBreakPoints::ChangeMemCheckAddCond(u32 start, u32 end, const BreakPointCon } } -void CBreakPoints::ChangeMemCheckRemoveCond(u32 start, u32 end) { +void BreakpointManager::ChangeMemCheckRemoveCond(u32 start, u32 end) { std::unique_lock guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK) { @@ -440,7 +436,7 @@ void CBreakPoints::ChangeMemCheckRemoveCond(u32 start, u32 end) { } } -BreakPointCond *CBreakPoints::GetMemCheckCondition(u32 start, u32 end) { +BreakPointCond *BreakpointManager::GetMemCheckCondition(u32 start, u32 end) { std::unique_lock guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK && memChecks_[mc].hasCondition) @@ -448,7 +444,7 @@ BreakPointCond *CBreakPoints::GetMemCheckCondition(u32 start, u32 end) { return nullptr; } -void CBreakPoints::ChangeMemCheckLogFormat(u32 start, u32 end, const std::string &fmt) { +void BreakpointManager::ChangeMemCheckLogFormat(u32 start, u32 end, const std::string &fmt) { std::unique_lock guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK) { @@ -458,7 +454,7 @@ void CBreakPoints::ChangeMemCheckLogFormat(u32 start, u32 end, const std::string } } -bool CBreakPoints::GetMemCheck(u32 start, u32 end, MemCheck *check) { +bool BreakpointManager::GetMemCheck(u32 start, u32 end, MemCheck *check) { std::lock_guard guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK) { @@ -475,7 +471,7 @@ static inline u32 NotCached(u32 val) { return val & ~0x40000000; } -bool CBreakPoints::GetMemCheckInRange(u32 address, int size, MemCheck *check) { +bool BreakpointManager::GetMemCheckInRange(u32 address, int size, MemCheck *check) { std::lock_guard guard(memCheckMutex_); auto result = GetMemCheckLocked(address, size); if (result) @@ -483,7 +479,7 @@ bool CBreakPoints::GetMemCheckInRange(u32 address, int size, MemCheck *check) { return result != nullptr; } -MemCheck *CBreakPoints::GetMemCheckLocked(u32 address, int size) { +MemCheck *BreakpointManager::GetMemCheckLocked(u32 address, int size) { std::vector::iterator iter; for (iter = memChecks_.begin(); iter != memChecks_.end(); ++iter) { @@ -504,7 +500,7 @@ MemCheck *CBreakPoints::GetMemCheckLocked(u32 address, int size) { return 0; } -BreakAction CBreakPoints::ExecMemCheck(u32 address, bool write, int size, u32 pc, const char *reason) +BreakAction BreakpointManager::ExecMemCheck(u32 address, bool write, int size, u32 pc, const char *reason) { if (!anyMemChecks_) return BREAK_ACTION_IGNORE; @@ -522,7 +518,7 @@ BreakAction CBreakPoints::ExecMemCheck(u32 address, bool write, int size, u32 pc return BREAK_ACTION_IGNORE; } -BreakAction CBreakPoints::ExecOpMemCheck(u32 address, u32 pc) +BreakAction BreakpointManager::ExecOpMemCheck(u32 address, u32 pc) { // Note: currently, we don't check "on changed" for HLE (ExecMemCheck.) // We'd need to more carefully specify memory changes in HLE for that. @@ -560,12 +556,12 @@ BreakAction CBreakPoints::ExecOpMemCheck(u32 address, u32 pc) return BREAK_ACTION_IGNORE; } -void CBreakPoints::SetSkipFirst(u32 pc) +void BreakpointManager::SetSkipFirst(u32 pc) { breakSkipFirstAt_ = pc; breakSkipFirstTicks_ = CoreTiming::GetTicks(); } -u32 CBreakPoints::CheckSkipFirst() +u32 BreakpointManager::CheckSkipFirst() { u32 pc = breakSkipFirstAt_; if (breakSkipFirstTicks_ == CoreTiming::GetTicks()) @@ -593,7 +589,7 @@ static MemCheck VRAMMirror(uint8_t mirror, MemCheck mc) { return mc; } -void CBreakPoints::UpdateCachedMemCheckRanges() { +void BreakpointManager::UpdateCachedMemCheckRanges() { std::lock_guard guard(memCheckMutex_); memCheckRangesRead_.clear(); memCheckRangesWrite_.clear(); @@ -622,34 +618,34 @@ void CBreakPoints::UpdateCachedMemCheckRanges() { } } -std::vector CBreakPoints::GetMemCheckRanges(bool write) { +std::vector BreakpointManager::GetMemCheckRanges(bool write) { std::lock_guard guard(memCheckMutex_); if (write) return memCheckRangesWrite_; return memCheckRangesRead_; } -std::vector CBreakPoints::GetMemChecks() +std::vector BreakpointManager::GetMemChecks() { std::lock_guard guard(memCheckMutex_); return memChecks_; } -std::vector CBreakPoints::GetBreakpoints() +std::vector BreakpointManager::GetBreakpoints() { std::lock_guard guard(breakPointsMutex_); return breakPoints_; } -bool CBreakPoints::HasBreakPoints() { +bool BreakpointManager::HasBreakPoints() { return anyBreakPoints_; } -bool CBreakPoints::HasMemChecks() { +bool BreakpointManager::HasMemChecks() { return anyMemChecks_; } -void CBreakPoints::Update(u32 addr) { +void BreakpointManager::Update(u32 addr) { if (MIPSComp::jit && addr != -1) { bool resume = false; if (Core_IsStepping() == false) { @@ -675,12 +671,12 @@ void CBreakPoints::Update(u32 addr) { System_Notify(SystemNotification::DISASSEMBLY); } -bool CBreakPoints::ValidateLogFormat(DebugInterface *cpu, const std::string &fmt) { +bool BreakpointManager::ValidateLogFormat(DebugInterface *cpu, const std::string &fmt) { std::string ignore; return EvaluateLogFormat(cpu, fmt, ignore); } -bool CBreakPoints::EvaluateLogFormat(DebugInterface *cpu, const std::string &fmt, std::string &result) { +bool BreakpointManager::EvaluateLogFormat(DebugInterface *cpu, const std::string &fmt, std::string &result) { PostfixExpression exp; result.clear(); diff --git a/Core/Debugger/Breakpoints.h b/Core/Debugger/Breakpoints.h index 88add84761..c6e40a14d7 100644 --- a/Core/Debugger/Breakpoints.h +++ b/Core/Debugger/Breakpoints.h @@ -115,79 +115,79 @@ struct MemCheck { // BreakPoints cannot overlap, only one is allowed per address. // MemChecks can overlap, as long as their ends are different. // WARNING: MemChecks are not always tracked in HLE currently. -class CBreakPoints -{ +class BreakpointManager { public: static const size_t INVALID_BREAKPOINT = -1; static const size_t INVALID_MEMCHECK = -1; - static bool IsAddressBreakPoint(u32 addr); - static bool IsAddressBreakPoint(u32 addr, bool* enabled); - static bool IsTempBreakPoint(u32 addr); - static bool RangeContainsBreakPoint(u32 addr, u32 size); - static void AddBreakPoint(u32 addr, bool temp = false); - static void RemoveBreakPoint(u32 addr); - static void ChangeBreakPoint(u32 addr, bool enable); - static void ChangeBreakPoint(u32 addr, BreakAction result); - static void ClearAllBreakPoints(); - static void ClearTemporaryBreakPoints(); + bool IsAddressBreakPoint(u32 addr); + bool IsAddressBreakPoint(u32 addr, bool* enabled); + bool IsTempBreakPoint(u32 addr); + bool RangeContainsBreakPoint(u32 addr, u32 size); + void AddBreakPoint(u32 addr, bool temp = false); + void RemoveBreakPoint(u32 addr); + void ChangeBreakPoint(u32 addr, bool enable); + void ChangeBreakPoint(u32 addr, BreakAction result); + void ClearAllBreakPoints(); + void ClearTemporaryBreakPoints(); // Makes a copy of the condition. - static void ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond); - static void ChangeBreakPointRemoveCond(u32 addr); - static BreakPointCond *GetBreakPointCondition(u32 addr); + void ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond); + void ChangeBreakPointRemoveCond(u32 addr); + BreakPointCond *GetBreakPointCondition(u32 addr); - static void ChangeBreakPointLogFormat(u32 addr, const std::string &fmt); + void ChangeBreakPointLogFormat(u32 addr, const std::string &fmt); - static BreakAction ExecBreakPoint(u32 addr); + BreakAction ExecBreakPoint(u32 addr); - static void AddMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result); - static void RemoveMemCheck(u32 start, u32 end); - static void ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result); - static void ClearAllMemChecks(); + void AddMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result); + void RemoveMemCheck(u32 start, u32 end); + void ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result); + void ClearAllMemChecks(); - static void ChangeMemCheckAddCond(u32 start, u32 end, const BreakPointCond &cond); - static void ChangeMemCheckRemoveCond(u32 start, u32 end); - static BreakPointCond *GetMemCheckCondition(u32 start, u32 end); + void ChangeMemCheckAddCond(u32 start, u32 end, const BreakPointCond &cond); + void ChangeMemCheckRemoveCond(u32 start, u32 end); + BreakPointCond *GetMemCheckCondition(u32 start, u32 end); - static void ChangeMemCheckLogFormat(u32 start, u32 end, const std::string &fmt); + void ChangeMemCheckLogFormat(u32 start, u32 end, const std::string &fmt); - static bool GetMemCheck(u32 start, u32 end, MemCheck *check); - static bool GetMemCheckInRange(u32 address, int size, MemCheck *check); - static BreakAction ExecMemCheck(u32 address, bool write, int size, u32 pc, const char *reason); - static BreakAction ExecOpMemCheck(u32 address, u32 pc); + bool GetMemCheck(u32 start, u32 end, MemCheck *check); + bool GetMemCheckInRange(u32 address, int size, MemCheck *check); + BreakAction ExecMemCheck(u32 address, bool write, int size, u32 pc, const char *reason); + BreakAction ExecOpMemCheck(u32 address, u32 pc); - static void SetSkipFirst(u32 pc); - static u32 CheckSkipFirst(); + void SetSkipFirst(u32 pc); + u32 CheckSkipFirst(); // Includes uncached addresses. - static std::vector GetMemCheckRanges(bool write); + std::vector GetMemCheckRanges(bool write); - static std::vector GetMemChecks(); - static std::vector GetBreakpoints(); + std::vector GetMemChecks(); + std::vector GetBreakpoints(); - static bool HasBreakPoints(); - static bool HasMemChecks(); + bool HasBreakPoints(); + bool HasMemChecks(); - static void Update(u32 addr = 0); + void Update(u32 addr = 0); - static bool ValidateLogFormat(DebugInterface *cpu, const std::string &fmt); - static bool EvaluateLogFormat(DebugInterface *cpu, const std::string &fmt, std::string &result); + bool ValidateLogFormat(DebugInterface *cpu, const std::string &fmt); + bool EvaluateLogFormat(DebugInterface *cpu, const std::string &fmt, std::string &result); private: - static size_t FindBreakpoint(u32 addr, bool matchTemp = false, bool temp = false); + size_t FindBreakpoint(u32 addr, bool matchTemp = false, bool temp = false); // Finds exactly, not using a range check. - static size_t FindMemCheck(u32 start, u32 end); - static MemCheck *GetMemCheckLocked(u32 address, int size); - static void UpdateCachedMemCheckRanges(); + size_t FindMemCheck(u32 start, u32 end); + MemCheck *GetMemCheckLocked(u32 address, int size); + void UpdateCachedMemCheckRanges(); - static std::vector breakPoints_; - static u32 breakSkipFirstAt_; - static u64 breakSkipFirstTicks_; + std::vector breakPoints_; + u32 breakSkipFirstAt_ = 0; + u64 breakSkipFirstTicks_ = 0; - static std::vector memChecks_; - static std::vector memCheckRangesRead_; - static std::vector memCheckRangesWrite_; + std::vector memChecks_; + std::vector memCheckRangesRead_; + std::vector memCheckRangesWrite_; }; +extern BreakpointManager g_breakpoints; diff --git a/Core/Debugger/MemBlockInfo.cpp b/Core/Debugger/MemBlockInfo.cpp index e3a51305fb..087a8fba5b 100644 --- a/Core/Debugger/MemBlockInfo.cpp +++ b/Core/Debugger/MemBlockInfo.cpp @@ -525,9 +525,9 @@ void NotifyMemInfoPC(MemBlockFlags flags, uint32_t start, uint32_t size, uint32_ if (!(flags & MemBlockFlags::SKIP_MEMCHECK)) { if (flags & MemBlockFlags::WRITE) { - CBreakPoints::ExecMemCheck(start, true, size, pc, tagStr); + g_breakpoints.ExecMemCheck(start, true, size, pc, tagStr); } else if (flags & MemBlockFlags::READ) { - CBreakPoints::ExecMemCheck(start, false, size, pc, tagStr); + g_breakpoints.ExecMemCheck(start, false, size, pc, tagStr); } } } @@ -541,7 +541,7 @@ void NotifyMemInfoCopy(uint32_t destPtr, uint32_t srcPtr, uint32_t size, const c return; bool needsFlush = false; - if (CBreakPoints::HasMemChecks()) { + if (g_breakpoints.HasMemChecks()) { // This will cause a flush, but it's needed to trigger memchecks with proper data. char tagData[128]; size_t tagSize = FormatMemWriteTagAt(tagData, sizeof(tagData), prefix, srcPtr, size); diff --git a/Core/Debugger/WebSocket/BreakpointSubscriber.cpp b/Core/Debugger/WebSocket/BreakpointSubscriber.cpp index abb297cdc6..1c0c039f57 100644 --- a/Core/Debugger/WebSocket/BreakpointSubscriber.cpp +++ b/Core/Debugger/WebSocket/BreakpointSubscriber.cpp @@ -94,18 +94,18 @@ struct WebSocketCPUBreakpointParams { cond.debug = currentDebugMIPS; cond.expressionString = condition; cond.expression = compiledCondition; - CBreakPoints::ChangeBreakPointAddCond(address, cond); + g_breakpoints.ChangeBreakPointAddCond(address, cond); } else if (hasCondition && condition.empty()) { - CBreakPoints::ChangeBreakPointRemoveCond(address); + g_breakpoints.ChangeBreakPointRemoveCond(address); } if (hasLogFormat) { - CBreakPoints::ChangeBreakPointLogFormat(address, logFormat); + g_breakpoints.ChangeBreakPointLogFormat(address, logFormat); } // TODO: Fix this interface. if (hasLog && !hasEnabled) { - CBreakPoints::IsAddressBreakPoint(address, &enabled); + g_breakpoints.IsAddressBreakPoint(address, &enabled); hasEnabled = true; } if (hasLog && hasEnabled) { @@ -114,9 +114,9 @@ struct WebSocketCPUBreakpointParams { result |= BREAK_ACTION_LOG; if (enabled) result |= BREAK_ACTION_PAUSE; - CBreakPoints::ChangeBreakPoint(address, result); + g_breakpoints.ChangeBreakPoint(address, result); } else if (hasEnabled) { - CBreakPoints::ChangeBreakPoint(address, enabled); + g_breakpoints.ChangeBreakPoint(address, enabled); } } }; @@ -138,7 +138,7 @@ void WebSocketCPUBreakpointAdd(DebuggerRequest &req) { if (!params.Parse(req)) return; - CBreakPoints::AddBreakPoint(params.address); + g_breakpoints.AddBreakPoint(params.address); params.Apply(); req.Respond(); } @@ -158,7 +158,7 @@ void WebSocketCPUBreakpointUpdate(DebuggerRequest &req) { if (!params.Parse(req)) return; bool enabled; - if (!CBreakPoints::IsAddressBreakPoint(params.address, &enabled)) + if (!g_breakpoints.IsAddressBreakPoint(params.address, &enabled)) return req.Fail("Breakpoint not found"); params.Apply(); @@ -180,7 +180,7 @@ void WebSocketCPUBreakpointRemove(DebuggerRequest &req) { if (!req.ParamU32("address", &address)) return; - CBreakPoints::RemoveBreakPoint(address); + g_breakpoints.RemoveBreakPoint(address); req.Respond(); } @@ -204,7 +204,7 @@ void WebSocketCPUBreakpointList(DebuggerRequest &req) { JsonWriter &json = req.Respond(); json.pushArray("breakpoints"); - auto bps = CBreakPoints::GetBreakpoints(); + auto bps = g_breakpoints.GetBreakpoints(); for (const auto &bp : bps) { if (bp.temporary) continue; @@ -312,7 +312,7 @@ struct WebSocketMemoryBreakpointParams { bits = (enabled ? BREAK_ACTION_PAUSE : 0) | (log ? BREAK_ACTION_LOG : 0); } else { MemCheck prev; - if (CBreakPoints::GetMemCheck(address, end, &prev)) + if (g_breakpoints.GetMemCheck(address, end, &prev)) bits = prev.result; if (hasEnabled) @@ -330,12 +330,12 @@ struct WebSocketMemoryBreakpointParams { cond.debug = currentDebugMIPS; cond.expressionString = condition; cond.expression = compiledCondition; - CBreakPoints::ChangeMemCheckAddCond(address, end, cond); + g_breakpoints.ChangeMemCheckAddCond(address, end, cond); } else if (hasCondition && condition.empty()) { - CBreakPoints::ChangeMemCheckRemoveCond(address, end); + g_breakpoints.ChangeMemCheckRemoveCond(address, end); } if (hasLogFormat) { - CBreakPoints::ChangeMemCheckLogFormat(address, end, logFormat); + g_breakpoints.ChangeMemCheckLogFormat(address, end, logFormat); } } }; @@ -362,7 +362,7 @@ void WebSocketMemoryBreakpointAdd(DebuggerRequest &req) { if (!params.Parse(req)) return; - CBreakPoints::AddMemCheck(params.address, params.end, params.cond, params.Result(true)); + g_breakpoints.AddMemCheck(params.address, params.end, params.cond, params.Result(true)); params.Apply(); req.Respond(); } @@ -388,10 +388,10 @@ void WebSocketMemoryBreakpointUpdate(DebuggerRequest &req) { return; MemCheck mc; - if (!CBreakPoints::GetMemCheck(params.address, params.end, &mc)) + if (!g_breakpoints.GetMemCheck(params.address, params.end, &mc)) return req.Fail("Breakpoint not found"); - CBreakPoints::ChangeMemCheck(params.address, params.end, params.cond, params.Result(true)); + g_breakpoints.ChangeMemCheck(params.address, params.end, params.cond, params.Result(true)); params.Apply(); req.Respond(); } @@ -415,7 +415,7 @@ void WebSocketMemoryBreakpointRemove(DebuggerRequest &req) { if (!req.ParamU32("size", &size)) return; - CBreakPoints::RemoveMemCheck(address, size == 0 ? 0 : address + size); + g_breakpoints.RemoveMemCheck(address, size == 0 ? 0 : address + size); req.Respond(); } @@ -443,7 +443,7 @@ void WebSocketMemoryBreakpointList(DebuggerRequest &req) { JsonWriter &json = req.Respond(); json.pushArray("breakpoints"); - auto mcs = CBreakPoints::GetMemChecks(); + auto mcs = g_breakpoints.GetMemChecks(); for (const auto &mc : mcs) { json.pushDict(); json.writeUint("address", mc.start); diff --git a/Core/Debugger/WebSocket/CPUCoreSubscriber.cpp b/Core/Debugger/WebSocket/CPUCoreSubscriber.cpp index 71d7e0bc07..5540a31e65 100644 --- a/Core/Debugger/WebSocket/CPUCoreSubscriber.cpp +++ b/Core/Debugger/WebSocket/CPUCoreSubscriber.cpp @@ -88,7 +88,7 @@ void WebSocketCPUResume(DebuggerRequest &req) { return req.Fail("CPU not stepping"); } - CBreakPoints::SetSkipFirst(currentMIPS->pc); + g_breakpoints.SetSkipFirst(currentMIPS->pc); if (currentMIPS->inDelaySlot) { Core_RequestSingleStep(CPUStepType::Into, 1); } diff --git a/Core/Debugger/WebSocket/DisasmSubscriber.cpp b/Core/Debugger/WebSocket/DisasmSubscriber.cpp index 499952930d..023fc98955 100644 --- a/Core/Debugger/WebSocket/DisasmSubscriber.cpp +++ b/Core/Debugger/WebSocket/DisasmSubscriber.cpp @@ -138,7 +138,7 @@ void WebSocketDisasmState::WriteDisasmLine(JsonWriter &json, const DisassemblyLi bool enabled = false; int breakpointOffset = -1; for (u32 i = 0; i < l.totalSize; i += 4) { - if (CBreakPoints::IsAddressBreakPoint(addr + i, &enabled)) + if (g_breakpoints.IsAddressBreakPoint(addr + i, &enabled)) breakpointOffset = i; if (breakpointOffset != -1 && enabled) break; @@ -148,7 +148,7 @@ void WebSocketDisasmState::WriteDisasmLine(JsonWriter &json, const DisassemblyLi json.pushDict("breakpoint"); json.writeBool("enabled", enabled); json.writeUint("address", addr + breakpointOffset); - auto cond = CBreakPoints::GetBreakPointCondition(addr + breakpointOffset); + auto cond = g_breakpoints.GetBreakPointCondition(addr + breakpointOffset); if (cond) json.writeString("condition", cond->expressionString); else diff --git a/Core/Debugger/WebSocket/SteppingSubscriber.cpp b/Core/Debugger/WebSocket/SteppingSubscriber.cpp index 03693817ad..b0d4cf37de 100644 --- a/Core/Debugger/WebSocket/SteppingSubscriber.cpp +++ b/Core/Debugger/WebSocket/SteppingSubscriber.cpp @@ -104,7 +104,7 @@ void WebSocketSteppingState::Into(DebuggerRequest &req) { if (cpuDebug == currentDebugMIPS) { // If the current PC is on a breakpoint, the user doesn't want to do nothing. - CBreakPoints::SetSkipFirst(currentMIPS->pc); + g_breakpoints.SetSkipFirst(currentMIPS->pc); int c = GetNextInstructionCount(cpuDebug); Core_RequestSingleStep(CPUStepType::Into, c); @@ -115,7 +115,7 @@ void WebSocketSteppingState::Into(DebuggerRequest &req) { // Note: we need to get cpuDebug again anyway (in case we ran some HLE above.) cpuDebug = CPUFromRequest(req); if (cpuDebug != currentDebugMIPS) { - CBreakPoints::AddBreakPoint(breakpointAddress, true); + g_breakpoints.AddBreakPoint(breakpointAddress, true); AddThreadCondition(breakpointAddress, threadID); Core_Resume(); } @@ -168,7 +168,7 @@ void WebSocketSteppingState::Over(DebuggerRequest &req) { // Could have advanced to the breakpoint already in PrepareResume(). cpuDebug = CPUFromRequest(req); if (cpuDebug->GetPC() != breakpointAddress) { - CBreakPoints::AddBreakPoint(breakpointAddress, true); + g_breakpoints.AddBreakPoint(breakpointAddress, true); if (cpuDebug != currentDebugMIPS) AddThreadCondition(breakpointAddress, threadID); Core_Resume(); @@ -217,7 +217,7 @@ void WebSocketSteppingState::Out(DebuggerRequest &req) { // Could have advanced to the breakpoint already in PrepareResume(). cpuDebug = CPUFromRequest(req); if (cpuDebug->GetPC() != breakpointAddress) { - CBreakPoints::AddBreakPoint(breakpointAddress, true); + g_breakpoints.AddBreakPoint(breakpointAddress, true); if (cpuDebug != currentDebugMIPS) AddThreadCondition(breakpointAddress, threadID); Core_Resume(); @@ -245,7 +245,7 @@ void WebSocketSteppingState::RunUntil(DebuggerRequest &req) { PrepareResume(); // We may have arrived already if PauseResume() stepped out of a delay slot. if (currentMIPS->pc != address || wasAtAddress) { - CBreakPoints::AddBreakPoint(address, true); + g_breakpoints.AddBreakPoint(address, true); Core_Resume(); } } @@ -280,7 +280,7 @@ void WebSocketSteppingState::PrepareResume() { Core_RequestSingleStep(CPUStepType::Into, 1); } else { // If the current PC is on a breakpoint, the user doesn't want to do nothing. - CBreakPoints::SetSkipFirst(currentMIPS->pc); + g_breakpoints.SetSkipFirst(currentMIPS->pc); } } @@ -289,5 +289,5 @@ void WebSocketSteppingState::AddThreadCondition(uint32_t breakpointAddress, uint cond.debug = currentDebugMIPS; cond.expressionString = StringFromFormat("threadid == 0x%08x", threadID); if (currentDebugMIPS->initExpression(cond.expressionString.c_str(), cond.expression)) - CBreakPoints::ChangeBreakPointAddCond(breakpointAddress, cond); + g_breakpoints.ChangeBreakPointAddCond(breakpointAddress, cond); } diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index aaa7914490..8c86d1f57c 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -1773,12 +1773,12 @@ bool CanReplaceJalTo(u32 dest, const ReplacementTableEntry **entry, u32 *funcSiz // Make sure we don't replace if there are any breakpoints inside. *funcSize = g_symbolMap->GetFunctionSize(dest); if (*funcSize == SymbolMap::INVALID_ADDRESS) { - if (CBreakPoints::IsAddressBreakPoint(dest)) { + if (g_breakpoints.IsAddressBreakPoint(dest)) { return false; } *funcSize = (u32)sizeof(u32); } else { - if (CBreakPoints::RangeContainsBreakPoint(dest, *funcSize)) { + if (g_breakpoints.RangeContainsBreakPoint(dest, *funcSize)) { return false; } } diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 2b05f9a4e1..89ecbdcb45 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -75,10 +75,10 @@ void DisassembleArm(const u8 *data, int size) { static u32 JitBreakpoint(uint32_t addr) { // Should we skip this breakpoint? - if (CBreakPoints::CheckSkipFirst() == currentMIPS->pc || CBreakPoints::CheckSkipFirst() == addr) + if (g_breakpoints.CheckSkipFirst() == currentMIPS->pc || g_breakpoints.CheckSkipFirst() == addr) return 0; - BreakAction result = CBreakPoints::ExecBreakPoint(addr); + BreakAction result = g_breakpoints.ExecBreakPoint(addr); if ((result & BREAK_ACTION_PAUSE) == 0) return 0; @@ -86,7 +86,7 @@ static u32 JitBreakpoint(uint32_t addr) { } static u32 JitMemCheck(u32 pc) { - if (CBreakPoints::CheckSkipFirst() == currentMIPS->pc) + if (g_breakpoints.CheckSkipFirst() == currentMIPS->pc) return 0; // Note: pc may be the delay slot. @@ -96,7 +96,7 @@ static u32 JitMemCheck(u32 pc) { offset &= 0xFFFC; u32 addr = currentMIPS->r[MIPS_GET_RS(op)] + offset; - CBreakPoints::ExecOpMemCheck(addr, pc); + g_breakpoints.ExecOpMemCheck(addr, pc); return coreState == CORE_RUNNING || coreState == CORE_NEXTFRAME ? 0 : 1; } @@ -120,7 +120,7 @@ ArmJit::ArmJit(MIPSState *mipsState) : blocks(mipsState, this), gpr(mipsState, & // The debugger sets this so that "go" on a breakpoint will actually... go. // But if they reset, we can end up hitting it by mistake, since it's based on PC and ticks. - CBreakPoints::SetSkipFirst(0); + g_breakpoints.SetSkipFirst(0); } ArmJit::~ArmJit() { @@ -147,7 +147,7 @@ void ArmJit::DoState(PointerWrap &p) // The debugger sets this so that "go" on a breakpoint will actually... go. // But if they reset, we can end up hitting it by mistake, since it's based on PC and ticks. - CBreakPoints::SetSkipFirst(0); + g_breakpoints.SetSkipFirst(0); } void ArmJit::UpdateFCR31() { @@ -536,7 +536,7 @@ bool ArmJit::ReplaceJalTo(u32 dest) { js.compilerPC += 4; // No writing exits, keep going! - if (CBreakPoints::HasMemChecks()) { + if (g_breakpoints.HasMemChecks()) { // We could modify coreState, so we need to write PC and check. // Otherwise, PC may end up on the jal. We add 4 to skip the delay slot. FlushAll(); @@ -572,7 +572,7 @@ void ArmJit::Comp_ReplacementFunc(MIPSOpcode op) if ((entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) == 0) { // Any breakpoint at the func entry was already tripped, so we can still run the replacement. // That's a common case - just to see how often the replacement hits. - disabled = CBreakPoints::RangeContainsBreakPoint(GetCompilerPC() + sizeof(u32), funcSize - sizeof(u32)); + disabled = g_breakpoints.RangeContainsBreakPoint(GetCompilerPC() + sizeof(u32), funcSize - sizeof(u32)); } } @@ -793,7 +793,7 @@ void ArmJit::WriteSyscallExit() } bool ArmJit::CheckJitBreakpoint(u32 addr, int downcountOffset) { - if (CBreakPoints::IsAddressBreakPoint(addr)) { + if (g_breakpoints.IsAddressBreakPoint(addr)) { MRS(R8); FlushAll(); MOVI2R(SCRATCHREG1, GetCompilerPC()); @@ -821,7 +821,7 @@ bool ArmJit::CheckJitBreakpoint(u32 addr, int downcountOffset) { } bool ArmJit::CheckMemoryBreakpoint(int instructionOffset) { - if (CBreakPoints::HasMemChecks()) { + if (g_breakpoints.HasMemChecks()) { int off = instructionOffset + (js.inDelaySlot ? 1 : 0); MRS(R8); diff --git a/Core/MIPS/ARM64/Arm64IRCompSystem.cpp b/Core/MIPS/ARM64/Arm64IRCompSystem.cpp index 92f076760a..54a759f1bd 100644 --- a/Core/MIPS/ARM64/Arm64IRCompSystem.cpp +++ b/Core/MIPS/ARM64/Arm64IRCompSystem.cpp @@ -117,7 +117,7 @@ void Arm64JitBackend::CompIR_Breakpoint(IRInst inst) { bool isWrite = MIPSAnalyst::IsOpMemoryWrite(checkedPC); MemCheck check; - if (CBreakPoints::GetMemCheckInRange(iaddr, size, &check)) { + if (g_breakpoints.GetMemCheckInRange(iaddr, size, &check)) { if (!(check.cond & MEMCHECK_READ) && !isWrite) break; if (!(check.cond & (MEMCHECK_WRITE | MEMCHECK_WRITE_ONCHANGE)) && isWrite) @@ -148,7 +148,7 @@ void Arm64JitBackend::CompIR_Breakpoint(IRInst inst) { } bool isWrite = MIPSAnalyst::IsOpMemoryWrite(checkedPC); - const auto memchecks = CBreakPoints::GetMemCheckRanges(isWrite); + const auto memchecks = g_breakpoints.GetMemCheckRanges(isWrite); // We can trivially skip if there are no checks for this type (i.e. read vs write.) if (memchecks.empty()) break; diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index 92d481b6d3..501852d9e7 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -66,10 +66,10 @@ static void DisassembleArm64Print(const u8 *data, int size) { static u32 JitBreakpoint(uint32_t addr) { // Should we skip this breakpoint? - if (CBreakPoints::CheckSkipFirst() == currentMIPS->pc || CBreakPoints::CheckSkipFirst() == addr) + if (g_breakpoints.CheckSkipFirst() == currentMIPS->pc || g_breakpoints.CheckSkipFirst() == addr) return 0; - BreakAction result = CBreakPoints::ExecBreakPoint(addr); + BreakAction result = g_breakpoints.ExecBreakPoint(addr); if ((result & BREAK_ACTION_PAUSE) == 0) return 0; @@ -77,7 +77,7 @@ static u32 JitBreakpoint(uint32_t addr) { } static u32 JitMemCheck(u32 pc) { - if (CBreakPoints::CheckSkipFirst() == currentMIPS->pc) + if (g_breakpoints.CheckSkipFirst() == currentMIPS->pc) return 0; // Note: pc may be the delay slot. @@ -87,7 +87,7 @@ static u32 JitMemCheck(u32 pc) { offset &= 0xFFFC; u32 addr = currentMIPS->r[MIPS_GET_RS(op)] + offset; - CBreakPoints::ExecOpMemCheck(addr, pc); + g_breakpoints.ExecOpMemCheck(addr, pc); return coreState == CORE_RUNNING || coreState == CORE_NEXTFRAME ? 0 : 1; } @@ -118,7 +118,7 @@ Arm64Jit::Arm64Jit(MIPSState *mipsState) : blocks(mipsState, this), gpr(mipsStat // The debugger sets this so that "go" on a breakpoint will actually... go. // But if they reset, we can end up hitting it by mistake, since it's based on PC and ticks. - CBreakPoints::SetSkipFirst(0); + g_breakpoints.SetSkipFirst(0); } Arm64Jit::~Arm64Jit() { @@ -146,7 +146,7 @@ void Arm64Jit::DoState(PointerWrap &p) { // The debugger sets this so that "go" on a breakpoint will actually... go. // But if they reset, we can end up hitting it by mistake, since it's based on PC and ticks. - CBreakPoints::SetSkipFirst(0); + g_breakpoints.SetSkipFirst(0); } void Arm64Jit::UpdateFCR31() { @@ -537,7 +537,7 @@ bool Arm64Jit::ReplaceJalTo(u32 dest) { js.compilerPC += 4; // No writing exits, keep going! - if (CBreakPoints::HasMemChecks()) { + if (g_breakpoints.HasMemChecks()) { // We could modify coreState, so we need to write PC and check. // Otherwise, PC may end up on the jal. We add 4 to skip the delay slot. FlushAll(); @@ -574,7 +574,7 @@ void Arm64Jit::Comp_ReplacementFunc(MIPSOpcode op) if ((entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) == 0) { // Any breakpoint at the func entry was already tripped, so we can still run the replacement. // That's a common case - just to see how often the replacement hits. - disabled = CBreakPoints::RangeContainsBreakPoint(GetCompilerPC() + sizeof(u32), funcSize - sizeof(u32)); + disabled = g_breakpoints.RangeContainsBreakPoint(GetCompilerPC() + sizeof(u32), funcSize - sizeof(u32)); } } @@ -772,7 +772,7 @@ void Arm64Jit::WriteSyscallExit() { } bool Arm64Jit::CheckJitBreakpoint(u32 addr, int downcountOffset) { - if (CBreakPoints::IsAddressBreakPoint(addr)) { + if (g_breakpoints.IsAddressBreakPoint(addr)) { MRS(FLAGTEMPREG, FIELD_NZCV); FlushAll(); MOVI2R(SCRATCH1, GetCompilerPC()); @@ -801,7 +801,7 @@ bool Arm64Jit::CheckJitBreakpoint(u32 addr, int downcountOffset) { } bool Arm64Jit::CheckMemoryBreakpoint(int instructionOffset) { - if (CBreakPoints::HasMemChecks()) { + if (g_breakpoints.HasMemChecks()) { int off = instructionOffset + (js.inDelaySlot ? 1 : 0); MRS(FLAGTEMPREG, FIELD_NZCV); diff --git a/Core/MIPS/IR/IRFrontend.cpp b/Core/MIPS/IR/IRFrontend.cpp index 6c8e59fa38..65cfedf1cf 100644 --- a/Core/MIPS/IR/IRFrontend.cpp +++ b/Core/MIPS/IR/IRFrontend.cpp @@ -40,7 +40,7 @@ IRFrontend::IRFrontend(bool startDefaultPrefix) { // The debugger sets this so that "go" on a breakpoint will actually... go. // But if they reset, we can end up hitting it by mistake, since it's based on PC and ticks. - CBreakPoints::SetSkipFirst(0); + g_breakpoints.SetSkipFirst(0); } void IRFrontend::DoState(PointerWrap &p) { @@ -58,7 +58,7 @@ void IRFrontend::DoState(PointerWrap &p) { // The debugger sets this so that "go" on a breakpoint will actually... go. // But if they reset, we can end up hitting it by mistake, since it's based on PC and ticks. - CBreakPoints::SetSkipFirst(0); + g_breakpoints.SetSkipFirst(0); } void IRFrontend::FlushAll() { @@ -155,7 +155,7 @@ void IRFrontend::Comp_ReplacementFunc(MIPSOpcode op) { if ((entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) == 0) { // Any breakpoint at the func entry was already tripped, so we can still run the replacement. // That's a common case - just to see how often the replacement hits. - disabled = CBreakPoints::RangeContainsBreakPoint(GetCompilerPC() + sizeof(u32), funcSize - sizeof(u32)); + disabled = g_breakpoints.RangeContainsBreakPoint(GetCompilerPC() + sizeof(u32), funcSize - sizeof(u32)); } } @@ -356,7 +356,7 @@ void IRFrontend::Comp_RunBlock(MIPSOpcode op) { } void IRFrontend::CheckBreakpoint(u32 addr) { - if (CBreakPoints::IsAddressBreakPoint(addr)) { + if (g_breakpoints.IsAddressBreakPoint(addr)) { FlushAll(); // Can't skip this even at the start of a block, might impact block linking. @@ -387,7 +387,7 @@ void IRFrontend::CheckBreakpoint(u32 addr) { } void IRFrontend::CheckMemoryBreakpoint(int rs, int offset) { - if (CBreakPoints::HasMemChecks()) { + if (g_breakpoints.HasMemChecks()) { FlushAll(); // Can't skip this even at the start of a block, might impact block linking. diff --git a/Core/MIPS/IR/IRInterpreter.cpp b/Core/MIPS/IR/IRInterpreter.cpp index afd002aa82..45cfefd351 100644 --- a/Core/MIPS/IR/IRInterpreter.cpp +++ b/Core/MIPS/IR/IRInterpreter.cpp @@ -64,7 +64,7 @@ alignas(16) static const uint32_t lowBytesMask[4] = { u32 IRRunBreakpoint(u32 pc) { // Should we skip this breakpoint? - uint32_t skipFirst = CBreakPoints::CheckSkipFirst(); + uint32_t skipFirst = g_breakpoints.CheckSkipFirst(); if (skipFirst == pc || skipFirst == currentMIPS->pc) return 0; @@ -72,13 +72,13 @@ u32 IRRunBreakpoint(u32 pc) { if (coreState != CORE_RUNNING && coreState != CORE_NEXTFRAME) return 1; - CBreakPoints::ExecBreakPoint(pc); + g_breakpoints.ExecBreakPoint(pc); return coreState != CORE_RUNNING ? 1 : 0; } u32 IRRunMemCheck(u32 pc, u32 addr) { // Should we skip this breakpoint? - uint32_t skipFirst = CBreakPoints::CheckSkipFirst(); + uint32_t skipFirst = g_breakpoints.CheckSkipFirst(); if (skipFirst == pc || skipFirst == currentMIPS->pc) return 0; @@ -86,7 +86,7 @@ u32 IRRunMemCheck(u32 pc, u32 addr) { if (coreState != CORE_RUNNING && coreState != CORE_NEXTFRAME) return 1; - CBreakPoints::ExecOpMemCheck(addr, pc); + g_breakpoints.ExecOpMemCheck(addr, pc); return coreState != CORE_RUNNING ? 1 : 0; } diff --git a/Core/MIPS/MIPSDebugInterface.cpp b/Core/MIPS/MIPSDebugInterface.cpp index ab0798409b..d1fdaf1fa4 100644 --- a/Core/MIPS/MIPSDebugInterface.cpp +++ b/Core/MIPS/MIPSDebugInterface.cpp @@ -225,21 +225,21 @@ bool MIPSDebugInterface::isAlive() bool MIPSDebugInterface::isBreakpoint(unsigned int address) { - return CBreakPoints::IsAddressBreakPoint(address); + return g_breakpoints.IsAddressBreakPoint(address); } void MIPSDebugInterface::setBreakpoint(unsigned int address) { - CBreakPoints::AddBreakPoint(address); + g_breakpoints.AddBreakPoint(address); } void MIPSDebugInterface::clearBreakpoint(unsigned int address) { - CBreakPoints::RemoveBreakPoint(address); + g_breakpoints.RemoveBreakPoint(address); } void MIPSDebugInterface::clearAllBreakpoints() {} void MIPSDebugInterface::toggleBreakpoint(unsigned int address) { - CBreakPoints::IsAddressBreakPoint(address)?CBreakPoints::RemoveBreakPoint(address):CBreakPoints::AddBreakPoint(address); + g_breakpoints.IsAddressBreakPoint(address)?g_breakpoints.RemoveBreakPoint(address):g_breakpoints.AddBreakPoint(address); } diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index d5eaa63ef8..0eb4ebec33 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -992,8 +992,8 @@ static inline void RunUntilFast() { static void RunUntilWithChecks(u64 globalTicks) { MIPSState *curMips = currentMIPS; // NEVER stop in a delay slot! - bool hasBPs = CBreakPoints::HasBreakPoints(); - bool hasMCs = CBreakPoints::HasMemChecks(); + bool hasBPs = g_breakpoints.HasBreakPoints(); + bool hasMCs = g_breakpoints.HasMemChecks(); while (curMips->downcount >= 0 && coreState == CORE_RUNNING) { do { // Replacements and similar are processed here, intentionally. @@ -1001,25 +1001,25 @@ static void RunUntilWithChecks(u64 globalTicks) { const MIPSInstruction *instr = MIPSGetInstruction(op); // Check for breakpoint - if (hasBPs && CBreakPoints::IsAddressBreakPoint(curMips->pc) && CBreakPoints::CheckSkipFirst() != curMips->pc) { - auto cond = CBreakPoints::GetBreakPointCondition(currentMIPS->pc); + if (hasBPs && g_breakpoints.IsAddressBreakPoint(curMips->pc) && g_breakpoints.CheckSkipFirst() != curMips->pc) { + auto cond = g_breakpoints.GetBreakPointCondition(currentMIPS->pc); if (!cond || cond->Evaluate()) { Core_Break("cpu.breakpoint", curMips->pc); - if (CBreakPoints::IsTempBreakPoint(curMips->pc)) - CBreakPoints::RemoveBreakPoint(curMips->pc); + if (g_breakpoints.IsTempBreakPoint(curMips->pc)) + g_breakpoints.RemoveBreakPoint(curMips->pc); break; } } - if (hasMCs && (instr->flags & (IN_MEM | OUT_MEM)) != 0 && CBreakPoints::CheckSkipFirst() != curMips->pc && instr->interpret != &Int_Syscall) { + if (hasMCs && (instr->flags & (IN_MEM | OUT_MEM)) != 0 && g_breakpoints.CheckSkipFirst() != curMips->pc && instr->interpret != &Int_Syscall) { // This is common for all IN_MEM/OUT_MEM funcs. int offset = (instr->flags & IS_VFPU) != 0 ? SignExtend16ToS32(op & 0xFFFC) : SignExtend16ToS32(op); u32 addr = (R(_RS) + offset) & 0xFFFFFFFC; int sz = MIPSGetMemoryAccessSize(op); if ((instr->flags & IN_MEM) != 0) - CBreakPoints::ExecMemCheck(addr, false, sz, curMips->pc, "interpret"); + g_breakpoints.ExecMemCheck(addr, false, sz, curMips->pc, "interpret"); if ((instr->flags & OUT_MEM) != 0) - CBreakPoints::ExecMemCheck(addr, true, sz, curMips->pc, "interpret"); + g_breakpoints.ExecMemCheck(addr, true, sz, curMips->pc, "interpret"); // If it tripped, bail without running. if (coreState == CORE_STEPPING) @@ -1048,7 +1048,7 @@ int MIPSInterpret_RunUntil(u64 globalTicks) { CoreTiming::Advance(); uint64_t ticksLeft = globalTicks - CoreTiming::GetTicks(); - if (CBreakPoints::HasBreakPoints() || CBreakPoints::HasMemChecks() || ticksLeft <= curMips->downcount) + if (g_breakpoints.HasBreakPoints() || g_breakpoints.HasMemChecks() || ticksLeft <= curMips->downcount) RunUntilWithChecks(globalTicks); else RunUntilFast(); diff --git a/Core/MIPS/fake/FakeJit.cpp b/Core/MIPS/fake/FakeJit.cpp index 081655752b..088f4d50d8 100644 --- a/Core/MIPS/fake/FakeJit.cpp +++ b/Core/MIPS/fake/FakeJit.cpp @@ -64,7 +64,7 @@ void FakeJit::DoState(PointerWrap &p) { // The debugger sets this so that "go" on a breakpoint will actually... go. // But if they load a state, we can end up hitting it by mistake, since it's based on PC and ticks. - CBreakPoints::SetSkipFirst(0); + g_breakpoints.SetSkipFirst(0); } // This is here so the savestate matches between jit and non-jit. diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index 4077ba815e..085b4525cf 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -61,10 +61,10 @@ std::pair flip_pair(const std::pair &p) { u32 JitBreakpoint(uint32_t addr) { // Should we skip this breakpoint? - if (CBreakPoints::CheckSkipFirst() == currentMIPS->pc || CBreakPoints::CheckSkipFirst() == addr) + if (g_breakpoints.CheckSkipFirst() == currentMIPS->pc || g_breakpoints.CheckSkipFirst() == addr) return 0; - BreakAction result = CBreakPoints::ExecBreakPoint(addr); + BreakAction result = g_breakpoints.ExecBreakPoint(addr); if ((result & BREAK_ACTION_PAUSE) == 0) return 0; @@ -93,7 +93,7 @@ u32 JitBreakpoint(uint32_t addr) static u32 JitMemCheck(u32 addr, u32 pc) { // Should we skip this breakpoint? - if (CBreakPoints::CheckSkipFirst() == currentMIPS->pc) + if (g_breakpoints.CheckSkipFirst() == currentMIPS->pc) return 0; // Did we already hit one? @@ -101,7 +101,7 @@ static u32 JitMemCheck(u32 addr, u32 pc) { return 1; // Note: pc may be the delay slot. - CBreakPoints::ExecOpMemCheck(addr, pc); + g_breakpoints.ExecOpMemCheck(addr, pc); return coreState == CORE_RUNNING || coreState == CORE_NEXTFRAME ? 0 : 1; } @@ -132,7 +132,7 @@ Jit::Jit(MIPSState *mipsState) // The debugger sets this so that "go" on a breakpoint will actually... go. // But if they reset, we can end up hitting it by mistake, since it's based on PC and ticks. - CBreakPoints::SetSkipFirst(0); + g_breakpoints.SetSkipFirst(0); } Jit::~Jit() { @@ -158,7 +158,7 @@ void Jit::DoState(PointerWrap &p) { // The debugger sets this so that "go" on a breakpoint will actually... go. // But if they load a state, we can end up hitting it by mistake, since it's based on PC and ticks. - CBreakPoints::SetSkipFirst(0); + g_breakpoints.SetSkipFirst(0); } void Jit::UpdateFCR31() { @@ -583,7 +583,7 @@ bool Jit::ReplaceJalTo(u32 dest) { js.compilerPC += 4; // No writing exits, keep going! - if (CBreakPoints::HasMemChecks()) { + if (g_breakpoints.HasMemChecks()) { // We could modify coreState, so we need to write PC and check. // Otherwise, PC may end up on the jal. We add 4 to skip the delay slot. MOV(32, MIPSSTATE_VAR(pc), Imm32(GetCompilerPC() + 4)); @@ -616,7 +616,7 @@ void Jit::Comp_ReplacementFunc(MIPSOpcode op) { if ((entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) == 0) { // Any breakpoint at the func entry was already tripped, so we can still run the replacement. // That's a common case - just to see how often the replacement hits. - disabled = CBreakPoints::RangeContainsBreakPoint(GetCompilerPC() + sizeof(u32), funcSize - sizeof(u32)); + disabled = g_breakpoints.RangeContainsBreakPoint(GetCompilerPC() + sizeof(u32), funcSize - sizeof(u32)); } } @@ -840,7 +840,7 @@ void Jit::WriteSyscallExit() { } bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset) { - if (CBreakPoints::IsAddressBreakPoint(addr)) { + if (g_breakpoints.IsAddressBreakPoint(addr)) { SaveFlags(); FlushAll(); MOV(32, MIPSSTATE_VAR(pc), Imm32(GetCompilerPC())); @@ -866,7 +866,7 @@ bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset) { } void Jit::CheckMemoryBreakpoint(int instructionOffset, MIPSGPReg rs, int offset) { - if (!CBreakPoints::HasMemChecks()) + if (!g_breakpoints.HasMemChecks()) return; int totalInstructionOffset = instructionOffset + (js.inDelaySlot ? 1 : 0); @@ -884,7 +884,7 @@ void Jit::CheckMemoryBreakpoint(int instructionOffset, MIPSGPReg rs, int offset) if (gpr.IsImm(rs)) { uint32_t iaddr = gpr.GetImm(rs) + offset; MemCheck check; - if (CBreakPoints::GetMemCheckInRange(iaddr, size, &check)) { + if (g_breakpoints.GetMemCheckInRange(iaddr, size, &check)) { if (!(check.cond & MEMCHECK_READ) && !isWrite) return; if (!(check.cond & MEMCHECK_WRITE) && isWrite) @@ -904,7 +904,7 @@ void Jit::CheckMemoryBreakpoint(int instructionOffset, MIPSGPReg rs, int offset) SetJumpTarget(skipCheck); } } else { - const auto memchecks = CBreakPoints::GetMemCheckRanges(isWrite); + const auto memchecks = g_breakpoints.GetMemCheckRanges(isWrite); bool possible = !memchecks.empty(); if (!possible) return; diff --git a/Core/MIPS/x86/X64IRCompSystem.cpp b/Core/MIPS/x86/X64IRCompSystem.cpp index 33b3205493..b137ee176d 100644 --- a/Core/MIPS/x86/X64IRCompSystem.cpp +++ b/Core/MIPS/x86/X64IRCompSystem.cpp @@ -125,7 +125,7 @@ void X64JitBackend::CompIR_Breakpoint(IRInst inst) { bool isWrite = MIPSAnalyst::IsOpMemoryWrite(checkedPC); MemCheck check; - if (CBreakPoints::GetMemCheckInRange(iaddr, size, &check)) { + if (g_breakpoints.GetMemCheckInRange(iaddr, size, &check)) { if (!(check.cond & MEMCHECK_READ) && !isWrite) break; if (!(check.cond & (MEMCHECK_WRITE | MEMCHECK_WRITE_ONCHANGE)) && isWrite) @@ -147,7 +147,7 @@ void X64JitBackend::CompIR_Breakpoint(IRInst inst) { } bool isWrite = MIPSAnalyst::IsOpMemoryWrite(checkedPC); - const auto memchecks = CBreakPoints::GetMemCheckRanges(isWrite); + const auto memchecks = g_breakpoints.GetMemCheckRanges(isWrite); // We can trivially skip if there are no checks for this type (i.e. read vs write.) if (memchecks.empty()) break; diff --git a/UI/ImDebugger/ImDisasmView.cpp b/UI/ImDebugger/ImDisasmView.cpp index 02bc68cd9c..38a8768c8c 100644 --- a/UI/ImDebugger/ImDisasmView.cpp +++ b/UI/ImDebugger/ImDisasmView.cpp @@ -394,7 +394,7 @@ void ImDisasmView::Draw(ImDrawList *drawList) { // display breakpoint, if any bool enabled; - if (CBreakPoints::IsAddressBreakPoint(address, &enabled)) { + if (g_breakpoints.IsAddressBreakPoint(address, &enabled)) { ImColor breakColor = 0xFF0000FF; if (!enabled) breakColor = 0xFF909090; @@ -538,8 +538,8 @@ void ImDisasmView::editBreakpoint(ImConfig &cfg) { BreakpointWindow win(wnd, debugger); bool exists = false; - if (CBreakPoints::IsAddressBreakPoint(curAddress)) { - auto breakpoints = CBreakPoints::GetBreakpoints(); + if (g_breakpoints.IsAddressBreakPoint(curAddress)) { + auto breakpoints = g_breakpoints.GetBreakpoints(); for (size_t i = 0; i < breakpoints.size(); i++) { if (breakpoints[i].addr == curAddress) { win.loadFromBreakpoint(breakpoints[i]); @@ -555,7 +555,7 @@ void ImDisasmView::editBreakpoint(ImConfig &cfg) { if (win.exec()) { if (exists) - CBreakPoints::RemoveBreakPoint(curAddress); + g_breakpoints.RemoveBreakPoint(curAddress); win.addBreakpoint(); } */ @@ -694,26 +694,26 @@ bool ImDisasmView::curAddressIsVisible() { void ImDisasmView::toggleBreakpoint(bool toggleEnabled) { bool enabled; - if (CBreakPoints::IsAddressBreakPoint(curAddress_, &enabled)) { + if (g_breakpoints.IsAddressBreakPoint(curAddress_, &enabled)) { if (!enabled) { // enable disabled breakpoints - CBreakPoints::ChangeBreakPoint(curAddress_, true); - } else if (!toggleEnabled && CBreakPoints::GetBreakPointCondition(curAddress_) != nullptr) { + g_breakpoints.ChangeBreakPoint(curAddress_, true); + } else if (!toggleEnabled && g_breakpoints.GetBreakPointCondition(curAddress_) != nullptr) { // don't just delete a breakpoint with a custom condition /* int ret = MessageBox(wnd, L"This breakpoint has a custom condition.\nDo you want to remove it?", L"Confirmation", MB_YESNO); if (ret == IDYES) - CBreakPoints::RemoveBreakPoint(curAddress); + g_breakpoints.RemoveBreakPoint(curAddress); */ } else if (toggleEnabled) { // disable breakpoint - CBreakPoints::ChangeBreakPoint(curAddress_, false); + g_breakpoints.ChangeBreakPoint(curAddress_, false); } else { // otherwise just remove breakpoint - CBreakPoints::RemoveBreakPoint(curAddress_); + g_breakpoints.RemoveBreakPoint(curAddress_); } } else { - CBreakPoints::AddBreakPoint(curAddress_); + g_breakpoints.AddBreakPoint(curAddress_); } } @@ -819,7 +819,7 @@ void ImDisasmView::PopupMenu() { FollowBranch(); } if (ImGui::MenuItem("Run to here")) { - // CBreakPoints::AddBreakPoint(pos, true); + // g_breakpoints.AddBreakPoint(pos, true); // Core_Resume(); } ImGui::Separator(); diff --git a/UI/ImDebugger/ImStructViewer.cpp b/UI/ImDebugger/ImStructViewer.cpp index e557415f58..73bee1a514 100644 --- a/UI/ImDebugger/ImStructViewer.cpp +++ b/UI/ImDebugger/ImStructViewer.cpp @@ -848,10 +848,10 @@ void ImStructViewer::DrawContextMenu( if (length > 0) { const u32 end = address + length; MemCheck memCheck; - const bool hasMemCheck = CBreakPoints::GetMemCheck(address, end, &memCheck); + const bool hasMemCheck = g_breakpoints.GetMemCheck(address, end, &memCheck); if (hasMemCheck) { if (ImGui::MenuItem("Remove memory breakpoint")) { - CBreakPoints::RemoveMemCheck(address, end); + g_breakpoints.RemoveMemCheck(address, end); } } const bool canAddRead = !hasMemCheck || !(memCheck.cond & MEMCHECK_READ); @@ -860,17 +860,17 @@ void ImStructViewer::DrawContextMenu( if ((canAddRead || canAddWrite || canAddWriteOnChange) && ImGui::BeginMenu("Add memory breakpoint")) { if (canAddRead && canAddWrite && ImGui::MenuItem("Read/Write")) { constexpr auto cond = static_cast(MEMCHECK_READ | MEMCHECK_WRITE); - CBreakPoints::AddMemCheck(address, end, cond, BREAK_ACTION_PAUSE); + g_breakpoints.AddMemCheck(address, end, cond, BREAK_ACTION_PAUSE); } if (canAddRead && ImGui::MenuItem("Read")) { - CBreakPoints::AddMemCheck(address, end, MEMCHECK_READ, BREAK_ACTION_PAUSE); + g_breakpoints.AddMemCheck(address, end, MEMCHECK_READ, BREAK_ACTION_PAUSE); } if (canAddWrite && ImGui::MenuItem("Write")) { - CBreakPoints::AddMemCheck(address, end, MEMCHECK_WRITE, BREAK_ACTION_PAUSE); + g_breakpoints.AddMemCheck(address, end, MEMCHECK_WRITE, BREAK_ACTION_PAUSE); } if (canAddWriteOnChange && ImGui::MenuItem("Write Change")) { constexpr auto cond = static_cast(MEMCHECK_WRITE | MEMCHECK_WRITE_ONCHANGE); - CBreakPoints::AddMemCheck(address, end, cond, BREAK_ACTION_PAUSE); + g_breakpoints.AddMemCheck(address, end, cond, BREAK_ACTION_PAUSE); } ImGui::EndMenu(); } diff --git a/Windows/Debugger/BreakpointWindow.cpp b/Windows/Debugger/BreakpointWindow.cpp index d26c5f6c29..6a9b5786b9 100644 --- a/Windows/Debugger/BreakpointWindow.cpp +++ b/Windows/Debugger/BreakpointWindow.cpp @@ -185,7 +185,7 @@ bool BreakpointWindow::fetchDialogData(HWND hwnd) wchar_t tempLogFormat[512]; GetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), tempLogFormat, 512); logFormat = ConvertWStringToUTF8(tempLogFormat); - if (!CBreakPoints::ValidateLogFormat(cpu, logFormat)) { + if (!g_breakpoints.ValidateLogFormat(cpu, logFormat)) { snprintf(errorMessage, sizeof(errorMessage), "Invalid log format (example: \"{a1}\")."); MessageBoxA(hwnd, errorMessage, "Error", MB_OK); return false; @@ -219,32 +219,32 @@ void BreakpointWindow::addBreakpoint() { if (onChange) cond |= MEMCHECK_WRITE_ONCHANGE; - CBreakPoints::AddMemCheck(address, address + size, (MemCheckCondition)cond, result); + g_breakpoints.AddMemCheck(address, address + size, (MemCheckCondition)cond, result); if (!condition.empty()) { BreakPointCond cond; cond.debug = cpu; cond.expressionString = condition; cond.expression = compiledCondition; - CBreakPoints::ChangeMemCheckAddCond(address, address + size, cond); + g_breakpoints.ChangeMemCheckAddCond(address, address + size, cond); } - CBreakPoints::ChangeMemCheckLogFormat(address, address + size, logFormat); + g_breakpoints.ChangeMemCheckLogFormat(address, address + size, logFormat); } else { // add breakpoint - CBreakPoints::AddBreakPoint(address, false); + g_breakpoints.AddBreakPoint(address, false); if (!condition.empty()) { BreakPointCond cond; cond.debug = cpu; cond.expressionString = condition; cond.expression = compiledCondition; - CBreakPoints::ChangeBreakPointAddCond(address, cond); + g_breakpoints.ChangeBreakPointAddCond(address, cond); } - CBreakPoints::ChangeBreakPoint(address, result); - CBreakPoints::ChangeBreakPointLogFormat(address, logFormat); + g_breakpoints.ChangeBreakPoint(address, result); + g_breakpoints.ChangeBreakPointLogFormat(address, logFormat); } } diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 889b5a4cb4..87929268df 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -561,7 +561,7 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) // display address/symbol bool enabled; - if (CBreakPoints::IsAddressBreakPoint(address,&enabled)) + if (g_breakpoints.IsAddressBreakPoint(address,&enabled)) { if (enabled) textColor = 0x0000FF; int yOffset = std::max(-1, (rowHeight - 14 + 1) / 2); @@ -690,9 +690,9 @@ void CtrlDisAsmView::editBreakpoint() BreakpointWindow win(wnd,debugger); bool exists = false; - if (CBreakPoints::IsAddressBreakPoint(curAddress)) + if (g_breakpoints.IsAddressBreakPoint(curAddress)) { - auto breakpoints = CBreakPoints::GetBreakpoints(); + auto breakpoints = g_breakpoints.GetBreakpoints(); for (size_t i = 0; i < breakpoints.size(); i++) { if (breakpoints[i].addr == curAddress) @@ -710,7 +710,7 @@ void CtrlDisAsmView::editBreakpoint() if (win.exec()) { if (exists) - CBreakPoints::RemoveBreakPoint(curAddress); + g_breakpoints.RemoveBreakPoint(curAddress); win.addBreakpoint(); } } @@ -868,24 +868,24 @@ void CtrlDisAsmView::redraw() void CtrlDisAsmView::toggleBreakpoint(bool toggleEnabled) { bool enabled; - if (CBreakPoints::IsAddressBreakPoint(curAddress, &enabled)) { + if (g_breakpoints.IsAddressBreakPoint(curAddress, &enabled)) { if (!enabled) { // enable disabled breakpoints - CBreakPoints::ChangeBreakPoint(curAddress, true); - } else if (!toggleEnabled && CBreakPoints::GetBreakPointCondition(curAddress) != nullptr) { + g_breakpoints.ChangeBreakPoint(curAddress, true); + } else if (!toggleEnabled && g_breakpoints.GetBreakPointCondition(curAddress) != nullptr) { // don't just delete a breakpoint with a custom condition int ret = MessageBox(wnd,L"This breakpoint has a custom condition.\nDo you want to remove it?",L"Confirmation",MB_YESNO); if (ret == IDYES) - CBreakPoints::RemoveBreakPoint(curAddress); + g_breakpoints.RemoveBreakPoint(curAddress); } else if (toggleEnabled) { // disable breakpoint - CBreakPoints::ChangeBreakPoint(curAddress, false); + g_breakpoints.ChangeBreakPoint(curAddress, false); } else { // otherwise just remove breakpoint - CBreakPoints::RemoveBreakPoint(curAddress); + g_breakpoints.RemoveBreakPoint(curAddress); } } else { - CBreakPoints::AddBreakPoint(curAddress); + g_breakpoints.AddBreakPoint(curAddress); } } diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index 7d50e466da..11b2972e1e 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -94,6 +94,7 @@ static constexpr UINT UPDATE_DELAY = 1000 / 60; CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Dialog((LPCSTR)IDD_DISASM, _hInstance, _hParent) { cpu = _cpu; lastTicks_ = PSP_IsInited() ? CoreTiming::GetTicks() : 0; + breakpoints_ = &g_breakpoints; SetWindowText(m_hDlg, ConvertUTF8ToWString(_cpu->GetName()).c_str()); @@ -222,22 +223,18 @@ void CDisasm::runToLine() { lastTicks_ = CoreTiming::GetTicks(); ptr->setDontRedraw(true); - CBreakPoints::AddBreakPoint(pos,true); + breakpoints_->AddBreakPoint(pos,true); Core_Resume(); } -BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) -{ - //if (!m_hDlg) return FALSE; - switch(message) - { +BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { + switch(message) { case WM_INITDIALOG: // DarkModeInitDialog(m_hDlg); return TRUE; case WM_NOTIFY: - switch (wParam) - { + switch (wParam) { case IDC_LEFTTABS: leftTabs->HandleNotify(lParam); break; @@ -409,7 +406,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) lastTicks_ = CoreTiming::GetTicks(); // If the current PC is on a breakpoint, the user doesn't want to do nothing. - CBreakPoints::SetSkipFirst(currentMIPS->pc); + breakpoints_->SetSkipFirst(currentMIPS->pc); Core_Resume(); } @@ -435,7 +432,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) lastTicks_ = CoreTiming::GetTicks(); // If the current PC is on a breakpoint, the user doesn't want to do nothing. - CBreakPoints::SetSkipFirst(currentMIPS->pc); + breakpoints_->SetSkipFirst(currentMIPS->pc); hleDebugBreak(); Core_Resume(); diff --git a/Windows/Debugger/Debugger_Disasm.h b/Windows/Debugger/Debugger_Disasm.h index c6e0212276..faf986d4d5 100644 --- a/Windows/Debugger/Debugger_Disasm.h +++ b/Windows/Debugger/Debugger_Disasm.h @@ -11,9 +11,9 @@ #include "Common/CommonWindows.h" class CtrlDisAsmView; +class BreakpointManager; -class CDisasm : public Dialog -{ +class CDisasm : public Dialog { private: int minWidth; int minHeight; @@ -28,6 +28,7 @@ private: CtrlWatchList *watchList_; TabControl* leftTabs; TabControl* bottomTabs; + BreakpointManager *breakpoints_; std::vector displayedBreakPoints_; std::vector displayedMemChecks_; bool keepStatusBarText = false; diff --git a/Windows/Debugger/Debugger_Lists.cpp b/Windows/Debugger/Debugger_Lists.cpp index f960eedad5..58535d4ed9 100644 --- a/Windows/Debugger/Debugger_Lists.cpp +++ b/Windows/Debugger/Debugger_Lists.cpp @@ -317,8 +317,8 @@ bool CtrlBreakpointList::WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, L void CtrlBreakpointList::reloadBreakpoints() { // Update the items we're displaying from the debugger. - displayedBreakPoints_ = CBreakPoints::GetBreakpoints(); - displayedMemChecks_= CBreakPoints::GetMemChecks(); + displayedBreakPoints_ = g_breakpoints.GetBreakpoints(); + displayedMemChecks_= g_breakpoints.GetMemChecks(); for (int i = 0; i < GetRowCount(); i++) { @@ -349,7 +349,7 @@ void CtrlBreakpointList::editBreakpoint(int itemIndex) win.loadFromMemcheck(mem); if (win.exec()) { - CBreakPoints::RemoveMemCheck(mem.start,mem.end); + g_breakpoints.RemoveMemCheck(mem.start,mem.end); win.addBreakpoint(); } } else { @@ -357,7 +357,7 @@ void CtrlBreakpointList::editBreakpoint(int itemIndex) win.loadFromBreakpoint(bp); if (win.exec()) { - CBreakPoints::RemoveBreakPoint(bp.addr); + g_breakpoints.RemoveBreakPoint(bp.addr); win.addBreakpoint(); } } @@ -371,10 +371,10 @@ void CtrlBreakpointList::toggleEnabled(int itemIndex) if (isMemory) { MemCheck mcPrev = displayedMemChecks_[index]; - CBreakPoints::ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, BreakAction(mcPrev.result ^ BREAK_ACTION_PAUSE)); + g_breakpoints.ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, BreakAction(mcPrev.result ^ BREAK_ACTION_PAUSE)); } else { BreakPoint bpPrev = displayedBreakPoints_[index]; - CBreakPoints::ChangeBreakPoint(bpPrev.addr, BreakAction(bpPrev.result ^ BREAK_ACTION_PAUSE)); + g_breakpoints.ChangeBreakPoint(bpPrev.addr, BreakAction(bpPrev.result ^ BREAK_ACTION_PAUSE)); } } @@ -406,10 +406,10 @@ void CtrlBreakpointList::removeBreakpoint(int itemIndex) if (isMemory) { auto mc = displayedMemChecks_[index]; - CBreakPoints::RemoveMemCheck(mc.start, mc.end); + g_breakpoints.RemoveMemCheck(mc.start, mc.end); } else { u32 address = displayedBreakPoints_[index].addr; - CBreakPoints::RemoveBreakPoint(address); + g_breakpoints.RemoveBreakPoint(address); } } @@ -611,9 +611,9 @@ void CtrlBreakpointList::showBreakpointMenu(int itemIndex, const POINT &pt) { case ID_DISASM_DISABLEBREAKPOINT: if (isMemory) { - CBreakPoints::ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, BreakAction(mcPrev.result ^ BREAK_ACTION_PAUSE)); + g_breakpoints.ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, BreakAction(mcPrev.result ^ BREAK_ACTION_PAUSE)); } else { - CBreakPoints::ChangeBreakPoint(bpPrev.addr, BreakAction(bpPrev.result ^ BREAK_ACTION_PAUSE)); + g_breakpoints.ChangeBreakPoint(bpPrev.addr, BreakAction(bpPrev.result ^ BREAK_ACTION_PAUSE)); } break; case ID_DISASM_EDITBREAKPOINT: