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/Debug | |
| parent | 43680f314c87339524ca04e817483e89c367529d (diff) | |
| parent | 8fa898fe9a6ac5a090320613957ed5d511d05a28 (diff) | |
Merge pull request #6932 from sepalani/debug-patches
DebugInterface: MemoryPatches methods added
Diffstat (limited to 'Source/Core/Common/Debug')
| -rw-r--r-- | Source/Core/Common/Debug/MemoryPatches.cpp | 99 | ||||
| -rw-r--r-- | Source/Core/Common/Debug/MemoryPatches.h | 52 |
2 files changed, 151 insertions, 0 deletions
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 |
