summaryrefslogtreecommitdiff
path: root/Source/Core/Common
diff options
context:
space:
mode:
authorLéo Lam <leo@innovatetechnologi.es>2018-05-22 19:15:51 +0200
committerGitHub <noreply@github.com>2018-05-22 19:15:51 +0200
commit0e9255c46999865a2d2e8a748ecccdfec7f6d476 (patch)
tree9d0d0b14f39a01b44ae2cb885999deda06e7a267 /Source/Core/Common
parent43680f314c87339524ca04e817483e89c367529d (diff)
parent8fa898fe9a6ac5a090320613957ed5d511d05a28 (diff)
Merge pull request #6932 from sepalani/debug-patches
DebugInterface: MemoryPatches methods added
Diffstat (limited to 'Source/Core/Common')
-rw-r--r--Source/Core/Common/CMakeLists.txt1
-rw-r--r--Source/Core/Common/Common.vcxproj2
-rw-r--r--Source/Core/Common/Common.vcxproj.filters8
-rw-r--r--Source/Core/Common/Debug/MemoryPatches.cpp99
-rw-r--r--Source/Core/Common/Debug/MemoryPatches.h52
-rw-r--r--Source/Core/Common/DebugInterface.h13
6 files changed, 173 insertions, 2 deletions
diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt
index c0e3e94462..0feb950b91 100644
--- a/Source/Core/Common/CMakeLists.txt
+++ b/Source/Core/Common/CMakeLists.txt
@@ -9,6 +9,7 @@ add_library(common
Crypto/AES.cpp
Crypto/bn.cpp
Crypto/ec.cpp
+ Debug/MemoryPatches.cpp
Debug/Watches.cpp
ENetUtil.cpp
File.cpp
diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj
index c03dd0b6ac..995c6e733e 100644
--- a/Source/Core/Common/Common.vcxproj
+++ b/Source/Core/Common/Common.vcxproj
@@ -60,6 +60,7 @@
<ClInclude Include="Config\Layer.h" />
<ClInclude Include="CPUDetect.h" />
<ClInclude Include="DebugInterface.h" />
+ <ClInclude Include="Debug\MemoryPatches.h" />
<ClInclude Include="Debug\Watches.h" />
<ClInclude Include="ENetUtil.h" />
<ClInclude Include="Event.h" />
@@ -176,6 +177,7 @@
<ClCompile Include="Config\Config.cpp" />
<ClCompile Include="Config\ConfigInfo.cpp" />
<ClCompile Include="Config\Layer.cpp" />
+ <ClCompile Include="Debug\MemoryPatches.cpp" />
<ClCompile Include="Debug\Watches.cpp" />
<ClCompile Include="ENetUtil.cpp" />
<ClCompile Include="File.cpp" />
diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters
index b26498b90b..dd041d490b 100644
--- a/Source/Core/Common/Common.vcxproj.filters
+++ b/Source/Core/Common/Common.vcxproj.filters
@@ -269,6 +269,9 @@
<ClInclude Include="Debug\Watches.h">
<Filter>Debug</Filter>
</ClInclude>
+ <ClInclude Include="Debug\MemoryPatches.h">
+ <Filter>Debug</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CDUtils.cpp" />
@@ -292,7 +295,6 @@
<ClCompile Include="Network.cpp" />
<ClCompile Include="PcapFile.cpp" />
<ClCompile Include="Profiler.cpp" />
- <ClCompile Include="QoSSession.h" />
<ClCompile Include="SDCardUtil.cpp" />
<ClCompile Include="SettingsHandler.cpp" />
<ClCompile Include="StringUtil.cpp" />
@@ -344,6 +346,10 @@
<ClCompile Include="Debug\Watches.cpp">
<Filter>Debug</Filter>
</ClCompile>
+ <ClCompile Include="QoSSession.cpp" />
+ <ClCompile Include="Debug\MemoryPatches.cpp">
+ <Filter>Debug</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="CMakeLists.txt" />
diff --git a/Source/Core/Common/Debug/MemoryPatches.cpp b/Source/Core/Common/Debug/MemoryPatches.cpp
new file mode 100644
index 0000000000..db7a40c58b
--- /dev/null
+++ b/Source/Core/Common/Debug/MemoryPatches.cpp
@@ -0,0 +1,99 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Common/Debug/MemoryPatches.h"
+
+#include <algorithm>
+#include <sstream>
+
+namespace Common::Debug
+{
+MemoryPatch::MemoryPatch(u32 address_, std::vector<u8> value_)
+ : address(address_), value(value_), is_enabled(State::Enabled)
+{
+}
+
+MemoryPatch::MemoryPatch(u32 address, u32 value)
+ : MemoryPatch(address, {static_cast<u8>(value >> 24), static_cast<u8>(value >> 16),
+ static_cast<u8>(value >> 8), static_cast<u8>(value)})
+{
+}
+
+MemoryPatches::MemoryPatches() = default;
+MemoryPatches::~MemoryPatches() = default;
+
+void MemoryPatches::SetPatch(u32 address, u32 value)
+{
+ const std::size_t index = m_patches.size();
+ m_patches.emplace_back(address, value);
+ Patch(index);
+}
+
+void MemoryPatches::SetPatch(u32 address, std::vector<u8> value)
+{
+ const std::size_t index = m_patches.size();
+ m_patches.emplace_back(address, std::move(value));
+ Patch(index);
+}
+
+const std::vector<MemoryPatch>& MemoryPatches::GetPatches() const
+{
+ return m_patches;
+}
+
+void MemoryPatches::UnsetPatch(u32 address)
+{
+ const auto it = std::remove_if(m_patches.begin(), m_patches.end(),
+ [address](const auto& patch) { return patch.address == address; });
+
+ if (it == m_patches.end())
+ return;
+
+ const std::size_t size = m_patches.size();
+ std::size_t index = size - std::distance(it, m_patches.end());
+ while (index < size)
+ {
+ DisablePatch(index);
+ ++index;
+ }
+ m_patches.erase(it, m_patches.end());
+}
+
+void MemoryPatches::EnablePatch(std::size_t index)
+{
+ if (m_patches[index].is_enabled == MemoryPatch::State::Enabled)
+ return;
+ m_patches[index].is_enabled = MemoryPatch::State::Enabled;
+ Patch(index);
+}
+
+void MemoryPatches::DisablePatch(std::size_t index)
+{
+ if (m_patches[index].is_enabled == MemoryPatch::State::Disabled)
+ return;
+ m_patches[index].is_enabled = MemoryPatch::State::Disabled;
+ Patch(index);
+}
+
+bool MemoryPatches::HasEnabledPatch(u32 address) const
+{
+ return std::any_of(m_patches.begin(), m_patches.end(), [address](const MemoryPatch& patch) {
+ return patch.address == address && patch.is_enabled == MemoryPatch::State::Enabled;
+ });
+}
+
+void MemoryPatches::RemovePatch(std::size_t index)
+{
+ DisablePatch(index);
+ m_patches.erase(m_patches.begin() + index);
+}
+
+void MemoryPatches::ClearPatches()
+{
+ const std::size_t size = m_patches.size();
+ for (std::size_t index = 0; index < size; ++index)
+ DisablePatch(index);
+ m_patches.clear();
+}
+} // namespace Common::Debug
diff --git a/Source/Core/Common/Debug/MemoryPatches.h b/Source/Core/Common/Debug/MemoryPatches.h
new file mode 100644
index 0000000000..cee814c6b5
--- /dev/null
+++ b/Source/Core/Common/Debug/MemoryPatches.h
@@ -0,0 +1,52 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "Common/CommonTypes.h"
+
+namespace Common::Debug
+{
+struct MemoryPatch
+{
+ enum class State
+ {
+ Enabled,
+ Disabled
+ };
+
+ u32 address;
+ std::vector<u8> value;
+ State is_enabled;
+
+ MemoryPatch(u32 address, std::vector<u8> value);
+ MemoryPatch(u32 address, u32 value);
+};
+
+class MemoryPatches
+{
+public:
+ MemoryPatches();
+ virtual ~MemoryPatches();
+
+ void SetPatch(u32 address, u32 value);
+ void SetPatch(u32 address, std::vector<u8> value);
+ const std::vector<MemoryPatch>& GetPatches() const;
+ void UnsetPatch(u32 address);
+ void EnablePatch(std::size_t index);
+ void DisablePatch(std::size_t index);
+ bool HasEnabledPatch(u32 address) const;
+ void RemovePatch(std::size_t index);
+ void ClearPatches();
+
+protected:
+ virtual void Patch(std::size_t index) = 0;
+
+ std::vector<MemoryPatch> m_patches;
+};
+} // namespace Common::Debug
diff --git a/Source/Core/Common/DebugInterface.h b/Source/Core/Common/DebugInterface.h
index 363c8743e4..0d1ea6159a 100644
--- a/Source/Core/Common/DebugInterface.h
+++ b/Source/Core/Common/DebugInterface.h
@@ -10,6 +10,7 @@
#include <vector>
#include "Common/CommonTypes.h"
+#include "Common/Debug/MemoryPatches.h"
#include "Common/Debug/Watches.h"
class DebugInterface
@@ -34,6 +35,17 @@ public:
virtual std::vector<std::string> SaveWatchesToStrings() const = 0;
virtual void ClearWatches() = 0;
+ // Memory Patches
+ virtual void SetPatch(u32 address, u32 value) = 0;
+ virtual void SetPatch(u32 address, std::vector<u8> value) = 0;
+ virtual const std::vector<Common::Debug::MemoryPatch>& GetPatches() const = 0;
+ virtual void UnsetPatch(u32 address) = 0;
+ virtual void EnablePatch(std::size_t index) = 0;
+ virtual void DisablePatch(std::size_t index) = 0;
+ virtual bool HasEnabledPatch(u32 address) const = 0;
+ virtual void RemovePatch(std::size_t index) = 0;
+ virtual void ClearPatches() = 0;
+
virtual std::string Disassemble(unsigned int /*address*/) { return "NODEBUGGER"; }
virtual std::string GetRawMemoryString(int /*memory*/, unsigned int /*address*/)
{
@@ -59,7 +71,6 @@ public:
virtual void SetPC(unsigned int /*address*/) {}
virtual void Step() {}
virtual void RunToBreakpoint() {}
- virtual void Patch(unsigned int /*address*/, unsigned int /*value*/) {}
virtual int GetColor(unsigned int /*address*/) { return 0xFFFFFFFF; }
virtual std::string GetDescription(unsigned int /*address*/) = 0;
virtual void Clear() = 0;