mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
DebugInterface: MemoryPatches methods added
CodeView: Restore instruction added
This commit is contained in:
@ -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
|
||||
|
@ -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" />
|
||||
|
@ -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" />
|
||||
|
99
Source/Core/Common/Debug/MemoryPatches.cpp
Normal file
99
Source/Core/Common/Debug/MemoryPatches.cpp
Normal 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
|
52
Source/Core/Common/Debug/MemoryPatches.h
Normal file
52
Source/Core/Common/Debug/MemoryPatches.h
Normal 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
|
@ -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;
|
||||
|
Reference in New Issue
Block a user