From 8bf27cf42fd83918c6a730ffddbc12a0204213dc Mon Sep 17 00:00:00 2001
From: aldelaro5 <aldelaro5@gmail.com>
Date: Thu, 2 Mar 2017 20:07:24 -0500
Subject: [PATCH] Fix memory breakpoint when checking the middle of the data

If the delimiters of a memory aren't exactly the same as an address, but their size includes the memory breakpoint delimiter, the break will not go through.  This makes it so that you can specify a search for a memory breakpoint with a data size and will check if the data fits with that size on all memory breakpoints so the breaks go through.
---
 Source/Core/Common/DebugInterface.h              |  3 ++-
 Source/Core/Core/Debugger/PPCDebugInterface.cpp  |  5 +++--
 Source/Core/Core/Debugger/PPCDebugInterface.h    |  3 ++-
 Source/Core/Core/HW/DSPLLE/DSPDebugInterface.cpp |  3 ++-
 Source/Core/Core/HW/DSPLLE/DSPDebugInterface.h   |  3 ++-
 Source/Core/Core/PowerPC/BreakPoints.cpp         | 14 +++++---------
 Source/Core/Core/PowerPC/BreakPoints.h           |  5 +++--
 Source/Core/Core/PowerPC/MMU.cpp                 |  4 ++--
 Source/Core/DolphinWX/Debugger/MemoryView.cpp    |  2 +-
 9 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/Source/Core/Common/DebugInterface.h b/Source/Core/Common/DebugInterface.h
index df9944ef23..521c16a8c7 100644
--- a/Source/Core/Common/DebugInterface.h
+++ b/Source/Core/Common/DebugInterface.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <cstddef>
 #include <cstring>
 #include <string>
 
@@ -26,7 +27,7 @@ public:
   virtual void ToggleBreakpoint(unsigned int /*address*/) {}
   virtual void AddWatch(unsigned int /*address*/) {}
   virtual void ClearAllMemChecks() {}
-  virtual bool IsMemCheck(unsigned int /*address*/) { return false; }
+  virtual bool IsMemCheck(unsigned int /*address*/, size_t /*size*/) { return false; }
   virtual void ToggleMemCheck(unsigned int /*address*/, bool /*read*/, bool /*write*/, bool /*log*/)
   {
   }
diff --git a/Source/Core/Core/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Debugger/PPCDebugInterface.cpp
index e00aa6c023..a47fe9a33a 100644
--- a/Source/Core/Core/Debugger/PPCDebugInterface.cpp
+++ b/Source/Core/Core/Debugger/PPCDebugInterface.cpp
@@ -4,6 +4,7 @@
 
 #include "Core/Debugger/PPCDebugInterface.h"
 
+#include <cstddef>
 #include <string>
 
 #include "Common/GekkoDisassembler.h"
@@ -129,9 +130,9 @@ void PPCDebugInterface::ClearAllMemChecks()
   PowerPC::memchecks.Clear();
 }
 
-bool PPCDebugInterface::IsMemCheck(unsigned int address)
+bool PPCDebugInterface::IsMemCheck(unsigned int address, size_t size)
 {
-  return PowerPC::memchecks.GetMemCheck(address) != nullptr;
+  return PowerPC::memchecks.GetMemCheck(address, size) != nullptr;
 }
 
 void PPCDebugInterface::ToggleMemCheck(unsigned int address, bool read, bool write, bool log)
diff --git a/Source/Core/Core/Debugger/PPCDebugInterface.h b/Source/Core/Core/Debugger/PPCDebugInterface.h
index 1d37de630e..3fa9680bb6 100644
--- a/Source/Core/Core/Debugger/PPCDebugInterface.h
+++ b/Source/Core/Core/Debugger/PPCDebugInterface.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <cstddef>
 #include <string>
 
 #include "Common/DebugInterface.h"
@@ -25,7 +26,7 @@ public:
   void AddWatch(unsigned int address) override;
   void ToggleBreakpoint(unsigned int address) override;
   void ClearAllMemChecks() override;
-  bool IsMemCheck(unsigned int address) override;
+  bool IsMemCheck(unsigned int address, size_t size = 1) override;
   void ToggleMemCheck(unsigned int address, bool read = true, bool write = true,
                       bool log = true) override;
   unsigned int ReadMemory(unsigned int address) override;
diff --git a/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.cpp b/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.cpp
index c77eaa75e3..1f92be7304 100644
--- a/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.cpp
+++ b/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.cpp
@@ -4,6 +4,7 @@
 
 #include "Core/HW/DSPLLE/DSPDebugInterface.h"
 
+#include <cstddef>
 #include <string>
 
 #include "Common/MsgHandler.h"
@@ -116,7 +117,7 @@ void DSPDebugInterface::ToggleBreakpoint(unsigned int address)
   }
 }
 
-bool DSPDebugInterface::IsMemCheck(unsigned int address)
+bool DSPDebugInterface::IsMemCheck(unsigned int address, size_t size)
 {
   return false;
 }
diff --git a/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.h b/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.h
index 894c2d31c6..69bde6c9b0 100644
--- a/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.h
+++ b/Source/Core/Core/HW/DSPLLE/DSPDebugInterface.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <cstddef>
 #include <string>
 
 #include "Common/CommonTypes.h"
@@ -27,7 +28,7 @@ public:
   void ClearAllBreakpoints() override;
   void ToggleBreakpoint(unsigned int address) override;
   void ClearAllMemChecks() override;
-  bool IsMemCheck(unsigned int address) override;
+  bool IsMemCheck(unsigned int address, size_t size) override;
   void ToggleMemCheck(unsigned int address, bool read = true, bool write = true,
                       bool log = true) override;
   unsigned int ReadMemory(unsigned int address) override;
diff --git a/Source/Core/Core/PowerPC/BreakPoints.cpp b/Source/Core/Core/PowerPC/BreakPoints.cpp
index 8714efda87..cca92af2f4 100644
--- a/Source/Core/Core/PowerPC/BreakPoints.cpp
+++ b/Source/Core/Core/PowerPC/BreakPoints.cpp
@@ -5,6 +5,7 @@
 #include "Core/PowerPC/BreakPoints.h"
 
 #include <algorithm>
+#include <cstddef>
 #include <sstream>
 #include <string>
 #include <vector>
@@ -201,16 +202,11 @@ void MemChecks::Remove(u32 address)
   }
 }
 
-TMemCheck* MemChecks::GetMemCheck(u32 address)
+TMemCheck* MemChecks::GetMemCheck(u32 address, size_t size)
 {
   for (TMemCheck& mc : m_mem_checks)
   {
-    if (mc.is_ranged)
-    {
-      if (address >= mc.start_address && address <= mc.end_address)
-        return &mc;
-    }
-    else if (mc.start_address == address)
+    if (mc.end_address >= address && address + size - 1 >= mc.start_address)
     {
       return &mc;
     }
@@ -239,8 +235,8 @@ bool MemChecks::OverlapsMemcheck(u32 address, u32 length)
   return false;
 }
 
-bool TMemCheck::Action(DebugInterface* debug_interface, u32 value, u32 addr, bool write, int size,
-                       u32 pc)
+bool TMemCheck::Action(DebugInterface* debug_interface, u32 value, u32 addr, bool write,
+                       size_t size, u32 pc)
 {
   if ((write && is_break_on_write) || (!write && is_break_on_read))
   {
diff --git a/Source/Core/Core/PowerPC/BreakPoints.h b/Source/Core/Core/PowerPC/BreakPoints.h
index cce1756513..7ddf324567 100644
--- a/Source/Core/Core/PowerPC/BreakPoints.h
+++ b/Source/Core/Core/PowerPC/BreakPoints.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <cstddef>
 #include <string>
 #include <vector>
 
@@ -34,7 +35,7 @@ struct TMemCheck
   u32 num_hits = 0;
 
   // returns whether to break
-  bool Action(DebugInterface* dbg_interface, u32 value, u32 addr, bool write, int size, u32 pc);
+  bool Action(DebugInterface* dbg_interface, u32 value, u32 addr, bool write, size_t size, u32 pc);
 };
 
 struct TWatch
@@ -86,7 +87,7 @@ public:
   void Add(const TMemCheck& memory_check);
 
   // memory breakpoint
-  TMemCheck* GetMemCheck(u32 address);
+  TMemCheck* GetMemCheck(u32 address, size_t size = 1);
   bool OverlapsMemcheck(u32 address, u32 length);
   void Remove(u32 address);
 
diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp
index 3ac3f2b9e1..12105eadb4 100644
--- a/Source/Core/Core/PowerPC/MMU.cpp
+++ b/Source/Core/Core/PowerPC/MMU.cpp
@@ -416,11 +416,11 @@ u32 HostRead_Instruction(const u32 address)
   return inst.hex;
 }
 
-static void Memcheck(u32 address, u32 var, bool write, int size)
+static void Memcheck(u32 address, u32 var, bool write, size_t size)
 {
   if (PowerPC::memchecks.HasAny())
   {
-    TMemCheck* mc = PowerPC::memchecks.GetMemCheck(address);
+    TMemCheck* mc = PowerPC::memchecks.GetMemCheck(address, size);
     if (mc)
     {
       if (CPU::IsStepping())
diff --git a/Source/Core/DolphinWX/Debugger/MemoryView.cpp b/Source/Core/DolphinWX/Debugger/MemoryView.cpp
index 5265058562..80c4efa5d7 100644
--- a/Source/Core/DolphinWX/Debugger/MemoryView.cpp
+++ b/Source/Core/DolphinWX/Debugger/MemoryView.cpp
@@ -418,7 +418,7 @@ void CMemoryView::OnPaint(wxPaintEvent& event)
       draw_text(StrToWxStr(desc), 2);
 
     // Show blue memory check dot
-    if (debugger->IsMemCheck(address))
+    if (debugger->IsMemCheck(address, sizeof(u8)))
     {
       dc.SetPen(*wxTRANSPARENT_PEN);
       dc.SetBrush(mc_brush);