diff options
| author | Léo Lam <leo@innovatetechnologi.es> | 2018-05-22 19:15:51 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-05-22 19:15:51 +0200 |
| commit | 0e9255c46999865a2d2e8a748ecccdfec7f6d476 (patch) | |
| tree | 9d0d0b14f39a01b44ae2cb885999deda06e7a267 /Source/Core/Common | |
| parent | 43680f314c87339524ca04e817483e89c367529d (diff) | |
| parent | 8fa898fe9a6ac5a090320613957ed5d511d05a28 (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.txt | 1 | ||||
| -rw-r--r-- | Source/Core/Common/Common.vcxproj | 2 | ||||
| -rw-r--r-- | Source/Core/Common/Common.vcxproj.filters | 8 | ||||
| -rw-r--r-- | Source/Core/Common/Debug/MemoryPatches.cpp | 99 | ||||
| -rw-r--r-- | Source/Core/Common/Debug/MemoryPatches.h | 52 | ||||
| -rw-r--r-- | Source/Core/Common/DebugInterface.h | 13 |
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; |
