DebugInterface: MemoryPatches methods added

CodeView: Restore instruction added
This commit is contained in:
Sepalani
2018-05-21 18:46:03 +04:00
parent 7eaba154a4
commit 8fa898fe9a
15 changed files with 365 additions and 81 deletions

View File

@ -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

View File

@ -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" />

View File

@ -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" />

View File

@ -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

View File

@ -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

View File

@ -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;