Merge pull request #6341 from sepalani/debug-watches
DebugInterface: Watches methods added
This commit is contained in:
commit
76b031184c
|
@ -9,6 +9,7 @@ add_library(common
|
|||
Crypto/AES.cpp
|
||||
Crypto/bn.cpp
|
||||
Crypto/ec.cpp
|
||||
Debug/Watches.cpp
|
||||
ENetUtil.cpp
|
||||
File.cpp
|
||||
FileSearch.cpp
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
<ClInclude Include="Config\Layer.h" />
|
||||
<ClInclude Include="CPUDetect.h" />
|
||||
<ClInclude Include="DebugInterface.h" />
|
||||
<ClInclude Include="Debug\Watches.h" />
|
||||
<ClInclude Include="ENetUtil.h" />
|
||||
<ClInclude Include="Event.h" />
|
||||
<ClInclude Include="File.h" />
|
||||
|
@ -173,6 +174,7 @@
|
|||
<ClCompile Include="Config\Config.cpp" />
|
||||
<ClCompile Include="Config\ConfigInfo.cpp" />
|
||||
<ClCompile Include="Config\Layer.cpp" />
|
||||
<ClCompile Include="Debug\Watches.cpp" />
|
||||
<ClCompile Include="ENetUtil.cpp" />
|
||||
<ClCompile Include="File.cpp" />
|
||||
<ClCompile Include="FileSearch.cpp" />
|
||||
|
@ -239,4 +241,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -16,6 +16,9 @@
|
|||
<Filter Include="GL\GLExtensions">
|
||||
<UniqueIdentifier>{c1d6f1fe-5ec5-406d-84f2-ed64d733d2c3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Debug">
|
||||
<UniqueIdentifier>{c6eef5b2-5e78-4f8c-8a51-8a4ffb768137}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Align.h" />
|
||||
|
@ -37,7 +40,6 @@
|
|||
<ClInclude Include="Config\Config.h" />
|
||||
<ClInclude Include="Config\Enums.h" />
|
||||
<ClInclude Include="Config\Layer.h" />
|
||||
<ClInclude Include="Config\Section.h" />
|
||||
<ClInclude Include="CPUDetect.h" />
|
||||
<ClInclude Include="DebugInterface.h" />
|
||||
<ClInclude Include="ENetUtil.h" />
|
||||
|
@ -261,6 +263,10 @@
|
|||
<ClInclude Include="GL\GLExtensions\ARB_texture_compression_bptc.h">
|
||||
<Filter>GL\GLExtensions</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\ConfigInfo.h" />
|
||||
<ClInclude Include="Debug\Watches.h">
|
||||
<Filter>Debug</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CDUtils.cpp" />
|
||||
|
@ -268,7 +274,6 @@
|
|||
<ClCompile Include="CommonFuncs.cpp" />
|
||||
<ClCompile Include="Config\Config.cpp" />
|
||||
<ClCompile Include="Config\Layer.cpp" />
|
||||
<ClCompile Include="Config\Section.cpp" />
|
||||
<ClCompile Include="ENetUtil.cpp" />
|
||||
<ClCompile Include="FileSearch.cpp" />
|
||||
<ClCompile Include="FileUtil.cpp" />
|
||||
|
@ -331,6 +336,10 @@
|
|||
<ClCompile Include="File.cpp" />
|
||||
<ClCompile Include="LdrWatcher.cpp" />
|
||||
<ClCompile Include="CompatPatches.cpp" />
|
||||
<ClCompile Include="Config\ConfigInfo.cpp" />
|
||||
<ClCompile Include="Debug\Watches.cpp">
|
||||
<Filter>Debug</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
|
@ -338,4 +347,4 @@
|
|||
<ItemGroup>
|
||||
<Natvis Include="BitField.natvis" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -0,0 +1,118 @@
|
|||
// Copyright 2018 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Common/Debug/Watches.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
namespace Common::Debug
|
||||
{
|
||||
Watch::Watch(u32 address_, const std::string& name_, Watch::State is_enabled_)
|
||||
: address(address_), name(name_), is_enabled(is_enabled_)
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t Watches::SetWatch(u32 address, const std::string& name)
|
||||
{
|
||||
const std::size_t size = m_watches.size();
|
||||
for (std::size_t index = 0; index < size; index++)
|
||||
{
|
||||
if (m_watches.at(index).address == address)
|
||||
{
|
||||
UpdateWatch(index, address, name);
|
||||
return index;
|
||||
}
|
||||
}
|
||||
m_watches.emplace_back(address, name, Watch::State::Enabled);
|
||||
return size;
|
||||
}
|
||||
|
||||
const Watch& Watches::GetWatch(std::size_t index) const
|
||||
{
|
||||
return m_watches.at(index);
|
||||
}
|
||||
|
||||
const std::vector<Watch>& Watches::GetWatches() const
|
||||
{
|
||||
return m_watches;
|
||||
}
|
||||
|
||||
void Watches::UnsetWatch(u32 address)
|
||||
{
|
||||
m_watches.erase(std::remove_if(m_watches.begin(), m_watches.end(),
|
||||
[address](const auto& watch) { return watch.address == address; }),
|
||||
m_watches.end());
|
||||
}
|
||||
|
||||
void Watches::UpdateWatch(std::size_t index, u32 address, const std::string& name)
|
||||
{
|
||||
m_watches[index].address = address;
|
||||
m_watches[index].name = name;
|
||||
}
|
||||
|
||||
void Watches::UpdateWatchAddress(std::size_t index, u32 address)
|
||||
{
|
||||
m_watches[index].address = address;
|
||||
}
|
||||
|
||||
void Watches::UpdateWatchName(std::size_t index, const std::string& name)
|
||||
{
|
||||
m_watches[index].name = name;
|
||||
}
|
||||
|
||||
void Watches::EnableWatch(std::size_t index)
|
||||
{
|
||||
m_watches[index].is_enabled = Watch::State::Enabled;
|
||||
}
|
||||
|
||||
void Watches::DisableWatch(std::size_t index)
|
||||
{
|
||||
m_watches[index].is_enabled = Watch::State::Disabled;
|
||||
}
|
||||
|
||||
bool Watches::HasEnabledWatch(u32 address) const
|
||||
{
|
||||
return std::any_of(m_watches.begin(), m_watches.end(), [address](const auto& watch) {
|
||||
return watch.address == address && watch.is_enabled == Watch::State::Enabled;
|
||||
});
|
||||
}
|
||||
|
||||
void Watches::RemoveWatch(std::size_t index)
|
||||
{
|
||||
m_watches.erase(m_watches.begin() + index);
|
||||
}
|
||||
|
||||
void Watches::LoadFromStrings(const std::vector<std::string>& watches)
|
||||
{
|
||||
for (const std::string& watch : watches)
|
||||
{
|
||||
std::stringstream ss;
|
||||
u32 address;
|
||||
std::string name;
|
||||
ss << std::hex << watch;
|
||||
ss >> address;
|
||||
ss >> std::ws;
|
||||
std::getline(ss, name);
|
||||
SetWatch(address, name);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> Watches::SaveToStrings() const
|
||||
{
|
||||
std::vector<std::string> watches;
|
||||
for (const auto& watch : m_watches)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex << watch.address << " " << watch.name;
|
||||
watches.push_back(ss.str());
|
||||
}
|
||||
return watches;
|
||||
}
|
||||
|
||||
void Watches::Clear()
|
||||
{
|
||||
m_watches.clear();
|
||||
}
|
||||
} // namespace Common::Debug
|
|
@ -0,0 +1,51 @@
|
|||
// 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 Watch
|
||||
{
|
||||
enum class State : bool
|
||||
{
|
||||
Enabled = true,
|
||||
Disabled = false
|
||||
};
|
||||
|
||||
u32 address;
|
||||
std::string name;
|
||||
State is_enabled;
|
||||
|
||||
Watch(u32 address, const std::string& name, State is_enabled);
|
||||
};
|
||||
|
||||
class Watches
|
||||
{
|
||||
public:
|
||||
std::size_t SetWatch(u32 address, const std::string& name);
|
||||
const Watch& GetWatch(std::size_t index) const;
|
||||
const std::vector<Watch>& GetWatches() const;
|
||||
void UnsetWatch(u32 address);
|
||||
void UpdateWatch(std::size_t index, u32 address, const std::string& name);
|
||||
void UpdateWatchAddress(std::size_t index, u32 address);
|
||||
void UpdateWatchName(std::size_t index, const std::string& name);
|
||||
void EnableWatch(std::size_t index);
|
||||
void DisableWatch(std::size_t index);
|
||||
bool HasEnabledWatch(u32 address) const;
|
||||
void RemoveWatch(std::size_t index);
|
||||
void LoadFromStrings(const std::vector<std::string>& watches);
|
||||
std::vector<std::string> SaveToStrings() const;
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
std::vector<Watch> m_watches;
|
||||
};
|
||||
} // namespace Common::Debug
|
|
@ -7,6 +7,10 @@
|
|||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Debug/Watches.h"
|
||||
|
||||
class DebugInterface
|
||||
{
|
||||
|
@ -14,6 +18,22 @@ protected:
|
|||
virtual ~DebugInterface() {}
|
||||
|
||||
public:
|
||||
// Watches
|
||||
virtual std::size_t SetWatch(u32 address, const std::string& name = "") = 0;
|
||||
virtual const Common::Debug::Watch& GetWatch(std::size_t index) const = 0;
|
||||
virtual const std::vector<Common::Debug::Watch>& GetWatches() const = 0;
|
||||
virtual void UnsetWatch(u32 address) = 0;
|
||||
virtual void UpdateWatch(std::size_t index, u32 address, const std::string& name) = 0;
|
||||
virtual void UpdateWatchAddress(std::size_t index, u32 address) = 0;
|
||||
virtual void UpdateWatchName(std::size_t index, const std::string& name) = 0;
|
||||
virtual void EnableWatch(std::size_t index) = 0;
|
||||
virtual void DisableWatch(std::size_t index) = 0;
|
||||
virtual bool HasEnabledWatch(u32 address) const = 0;
|
||||
virtual void RemoveWatch(std::size_t index) = 0;
|
||||
virtual void LoadWatchesFromStrings(const std::vector<std::string>& watches) = 0;
|
||||
virtual std::vector<std::string> SaveWatchesToStrings() const = 0;
|
||||
virtual void ClearWatches() = 0;
|
||||
|
||||
virtual std::string Disassemble(unsigned int /*address*/) { return "NODEBUGGER"; }
|
||||
virtual std::string GetRawMemoryString(int /*memory*/, unsigned int /*address*/)
|
||||
{
|
||||
|
@ -26,7 +46,6 @@ public:
|
|||
virtual void ClearBreakpoint(unsigned int /*address*/) {}
|
||||
virtual void ClearAllBreakpoints() {}
|
||||
virtual void ToggleBreakpoint(unsigned int /*address*/) {}
|
||||
virtual void AddWatch(unsigned int /*address*/) {}
|
||||
virtual void ClearAllMemChecks() {}
|
||||
virtual bool IsMemCheck(unsigned int /*address*/, size_t /*size*/) { return false; }
|
||||
virtual void ToggleMemCheck(unsigned int /*address*/, bool /*read*/, bool /*write*/, bool /*log*/)
|
||||
|
@ -43,4 +62,5 @@ public:
|
|||
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;
|
||||
};
|
||||
|
|
|
@ -15,6 +15,76 @@
|
|||
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
std::size_t PPCDebugInterface::SetWatch(u32 address, const std::string& name)
|
||||
{
|
||||
return m_watches.SetWatch(address, name);
|
||||
}
|
||||
|
||||
const Common::Debug::Watch& PPCDebugInterface::GetWatch(std::size_t index) const
|
||||
{
|
||||
return m_watches.GetWatch(index);
|
||||
}
|
||||
|
||||
const std::vector<Common::Debug::Watch>& PPCDebugInterface::GetWatches() const
|
||||
{
|
||||
return m_watches.GetWatches();
|
||||
}
|
||||
|
||||
void PPCDebugInterface::UnsetWatch(u32 address)
|
||||
{
|
||||
m_watches.UnsetWatch(address);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::UpdateWatch(std::size_t index, u32 address, const std::string& name)
|
||||
{
|
||||
return m_watches.UpdateWatch(index, address, name);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::UpdateWatchAddress(std::size_t index, u32 address)
|
||||
{
|
||||
return m_watches.UpdateWatchAddress(index, address);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::UpdateWatchName(std::size_t index, const std::string& name)
|
||||
{
|
||||
return m_watches.UpdateWatchName(index, name);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::EnableWatch(std::size_t index)
|
||||
{
|
||||
m_watches.EnableWatch(index);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::DisableWatch(std::size_t index)
|
||||
{
|
||||
m_watches.DisableWatch(index);
|
||||
}
|
||||
|
||||
bool PPCDebugInterface::HasEnabledWatch(u32 address) const
|
||||
{
|
||||
return m_watches.HasEnabledWatch(address);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::RemoveWatch(std::size_t index)
|
||||
{
|
||||
return m_watches.RemoveWatch(index);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::LoadWatchesFromStrings(const std::vector<std::string>& watches)
|
||||
{
|
||||
m_watches.LoadFromStrings(watches);
|
||||
}
|
||||
|
||||
std::vector<std::string> PPCDebugInterface::SaveWatchesToStrings() const
|
||||
{
|
||||
return m_watches.SaveToStrings();
|
||||
}
|
||||
|
||||
void PPCDebugInterface::ClearWatches()
|
||||
{
|
||||
m_watches.Clear();
|
||||
}
|
||||
|
||||
std::string PPCDebugInterface::Disassemble(unsigned int address)
|
||||
{
|
||||
// PowerPC::HostRead_U32 seemed to crash on shutdown
|
||||
|
@ -117,11 +187,6 @@ void PPCDebugInterface::ToggleBreakpoint(unsigned int address)
|
|||
PowerPC::breakpoints.Add(address);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::AddWatch(unsigned int address)
|
||||
{
|
||||
PowerPC::watches.Add(address);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::ClearAllMemChecks()
|
||||
{
|
||||
PowerPC::memchecks.Clear();
|
||||
|
@ -204,3 +269,10 @@ void PPCDebugInterface::SetPC(unsigned int address)
|
|||
void PPCDebugInterface::RunToBreakpoint()
|
||||
{
|
||||
}
|
||||
|
||||
void PPCDebugInterface::Clear()
|
||||
{
|
||||
ClearAllBreakpoints();
|
||||
ClearAllMemChecks();
|
||||
ClearWatches();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,22 @@ class PPCDebugInterface final : public DebugInterface
|
|||
{
|
||||
public:
|
||||
PPCDebugInterface() {}
|
||||
// Watches
|
||||
std::size_t SetWatch(u32 address, const std::string& name = "") override;
|
||||
const Common::Debug::Watch& GetWatch(std::size_t index) const override;
|
||||
const std::vector<Common::Debug::Watch>& GetWatches() const override;
|
||||
void UnsetWatch(u32 address) override;
|
||||
void UpdateWatch(std::size_t index, u32 address, const std::string& name) override;
|
||||
void UpdateWatchAddress(std::size_t index, u32 address) override;
|
||||
void UpdateWatchName(std::size_t index, const std::string& name) override;
|
||||
void EnableWatch(std::size_t index) override;
|
||||
void DisableWatch(std::size_t index) override;
|
||||
bool HasEnabledWatch(u32 address) const override;
|
||||
void RemoveWatch(std::size_t index) override;
|
||||
void LoadWatchesFromStrings(const std::vector<std::string>& watches) override;
|
||||
std::vector<std::string> SaveWatchesToStrings() const override;
|
||||
void ClearWatches() override;
|
||||
|
||||
std::string Disassemble(unsigned int address) override;
|
||||
std::string GetRawMemoryString(int memory, unsigned int address) override;
|
||||
int GetInstructionSize(int /*instruction*/) override { return 4; }
|
||||
|
@ -23,7 +39,6 @@ public:
|
|||
void SetBreakpoint(unsigned int address) override;
|
||||
void ClearBreakpoint(unsigned int address) override;
|
||||
void ClearAllBreakpoints() override;
|
||||
void AddWatch(unsigned int address) override;
|
||||
void ToggleBreakpoint(unsigned int address) override;
|
||||
void ClearAllMemChecks() override;
|
||||
bool IsMemCheck(unsigned int address, size_t size = 1) override;
|
||||
|
@ -45,4 +60,9 @@ public:
|
|||
void Patch(unsigned int address, unsigned int value) override;
|
||||
int GetColor(unsigned int address) override;
|
||||
std::string GetDescription(unsigned int address) override;
|
||||
|
||||
void Clear() override;
|
||||
|
||||
private:
|
||||
Common::Debug::Watches m_watches;
|
||||
};
|
||||
|
|
|
@ -17,6 +17,76 @@ namespace DSP
|
|||
{
|
||||
namespace LLE
|
||||
{
|
||||
std::size_t DSPDebugInterface::SetWatch(u32 address, const std::string& name)
|
||||
{
|
||||
return m_watches.SetWatch(address, name);
|
||||
}
|
||||
|
||||
const Common::Debug::Watch& DSPDebugInterface::GetWatch(std::size_t index) const
|
||||
{
|
||||
return m_watches.GetWatch(index);
|
||||
}
|
||||
|
||||
const std::vector<Common::Debug::Watch>& DSPDebugInterface::GetWatches() const
|
||||
{
|
||||
return m_watches.GetWatches();
|
||||
}
|
||||
|
||||
void DSPDebugInterface::UnsetWatch(u32 address)
|
||||
{
|
||||
m_watches.UnsetWatch(address);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::UpdateWatch(std::size_t index, u32 address, const std::string& name)
|
||||
{
|
||||
return m_watches.UpdateWatch(index, address, name);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::UpdateWatchAddress(std::size_t index, u32 address)
|
||||
{
|
||||
return m_watches.UpdateWatchAddress(index, address);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::UpdateWatchName(std::size_t index, const std::string& name)
|
||||
{
|
||||
return m_watches.UpdateWatchName(index, name);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::EnableWatch(std::size_t index)
|
||||
{
|
||||
m_watches.EnableWatch(index);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::DisableWatch(std::size_t index)
|
||||
{
|
||||
m_watches.DisableWatch(index);
|
||||
}
|
||||
|
||||
bool DSPDebugInterface::HasEnabledWatch(u32 address) const
|
||||
{
|
||||
return m_watches.HasEnabledWatch(address);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::RemoveWatch(std::size_t index)
|
||||
{
|
||||
return m_watches.RemoveWatch(index);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::LoadWatchesFromStrings(const std::vector<std::string>& watches)
|
||||
{
|
||||
m_watches.LoadFromStrings(watches);
|
||||
}
|
||||
|
||||
std::vector<std::string> DSPDebugInterface::SaveWatchesToStrings() const
|
||||
{
|
||||
return m_watches.SaveToStrings();
|
||||
}
|
||||
|
||||
void DSPDebugInterface::ClearWatches()
|
||||
{
|
||||
m_watches.Clear();
|
||||
}
|
||||
|
||||
std::string DSPDebugInterface::Disassemble(unsigned int address)
|
||||
{
|
||||
// we'll treat addresses as line numbers.
|
||||
|
@ -191,5 +261,10 @@ void DSPDebugInterface::SetPC(unsigned int address)
|
|||
void DSPDebugInterface::RunToBreakpoint()
|
||||
{
|
||||
}
|
||||
|
||||
void DSPDebugInterface::Clear()
|
||||
{
|
||||
ClearWatches();
|
||||
}
|
||||
} // namespace LLE
|
||||
} // namespace DSP
|
||||
|
|
|
@ -18,6 +18,22 @@ class DSPDebugInterface final : public DebugInterface
|
|||
{
|
||||
public:
|
||||
DSPDebugInterface() {}
|
||||
// Watches
|
||||
std::size_t SetWatch(u32 address, const std::string& name = "") override;
|
||||
const Common::Debug::Watch& GetWatch(std::size_t index) const override;
|
||||
const std::vector<Common::Debug::Watch>& GetWatches() const override;
|
||||
void UnsetWatch(u32 address) override;
|
||||
void UpdateWatch(std::size_t index, u32 address, const std::string& name) override;
|
||||
void UpdateWatchAddress(std::size_t index, u32 address) override;
|
||||
void UpdateWatchName(std::size_t index, const std::string& name) override;
|
||||
void EnableWatch(std::size_t index) override;
|
||||
void DisableWatch(std::size_t index) override;
|
||||
bool HasEnabledWatch(u32 address) const override;
|
||||
void RemoveWatch(std::size_t index) override;
|
||||
void LoadWatchesFromStrings(const std::vector<std::string>& watches) override;
|
||||
std::vector<std::string> SaveWatchesToStrings() const override;
|
||||
void ClearWatches() override;
|
||||
|
||||
std::string Disassemble(unsigned int address) override;
|
||||
std::string GetRawMemoryString(int memory, unsigned int address) override;
|
||||
int GetInstructionSize(int instruction) override { return 1; }
|
||||
|
@ -40,6 +56,11 @@ public:
|
|||
void Patch(unsigned int address, unsigned int value) override;
|
||||
int GetColor(unsigned int address) override;
|
||||
std::string GetDescription(unsigned int address) override;
|
||||
|
||||
void Clear() override;
|
||||
|
||||
private:
|
||||
Common::Debug::Watches m_watches;
|
||||
};
|
||||
} // namespace LLE
|
||||
} // namespace DSP
|
||||
|
|
|
@ -243,83 +243,3 @@ bool TMemCheck::Action(DebugInterface* debug_interface, u32 value, u32 addr, boo
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Watches::IsAddressWatch(u32 address) const
|
||||
{
|
||||
return std::any_of(m_watches.begin(), m_watches.end(),
|
||||
[address](const auto& watch) { return watch.address == address; });
|
||||
}
|
||||
|
||||
Watches::TWatchesStr Watches::GetStrings() const
|
||||
{
|
||||
TWatchesStr watch_strings;
|
||||
for (const TWatch& watch : m_watches)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex << watch.address << " " << watch.name;
|
||||
watch_strings.push_back(ss.str());
|
||||
}
|
||||
|
||||
return watch_strings;
|
||||
}
|
||||
|
||||
void Watches::AddFromStrings(const TWatchesStr& watch_strings)
|
||||
{
|
||||
for (const std::string& watch_string : watch_strings)
|
||||
{
|
||||
TWatch watch;
|
||||
std::stringstream ss;
|
||||
ss << std::hex << watch_string;
|
||||
ss >> watch.address;
|
||||
ss >> std::ws;
|
||||
std::getline(ss, watch.name);
|
||||
Add(watch);
|
||||
}
|
||||
}
|
||||
|
||||
void Watches::Add(const TWatch& watch)
|
||||
{
|
||||
if (IsAddressWatch(watch.address))
|
||||
return;
|
||||
|
||||
m_watches.push_back(watch);
|
||||
}
|
||||
|
||||
void Watches::Add(u32 address)
|
||||
{
|
||||
// Only add new addresses
|
||||
if (IsAddressWatch(address))
|
||||
return;
|
||||
|
||||
TWatch watch; // watch settings
|
||||
watch.is_enabled = true;
|
||||
watch.address = address;
|
||||
|
||||
m_watches.push_back(watch);
|
||||
}
|
||||
|
||||
void Watches::Update(int count, u32 address)
|
||||
{
|
||||
m_watches.at(count).address = address;
|
||||
}
|
||||
|
||||
void Watches::UpdateName(int count, const std::string name)
|
||||
{
|
||||
m_watches.at(count).name = name;
|
||||
}
|
||||
|
||||
void Watches::Remove(u32 address)
|
||||
{
|
||||
const auto iter = std::find_if(m_watches.cbegin(), m_watches.cend(),
|
||||
[address](const auto& watch) { return watch.address == address; });
|
||||
|
||||
if (iter == m_watches.cend())
|
||||
return;
|
||||
|
||||
m_watches.erase(iter);
|
||||
}
|
||||
|
||||
void Watches::Clear()
|
||||
{
|
||||
m_watches.clear();
|
||||
}
|
||||
|
|
|
@ -38,13 +38,6 @@ struct TMemCheck
|
|||
bool Action(DebugInterface* dbg_interface, u32 value, u32 addr, bool write, size_t size, u32 pc);
|
||||
};
|
||||
|
||||
struct TWatch
|
||||
{
|
||||
std::string name;
|
||||
u32 address = 0;
|
||||
bool is_enabled = false;
|
||||
};
|
||||
|
||||
// Code breakpoints.
|
||||
class BreakPoints
|
||||
{
|
||||
|
@ -97,30 +90,3 @@ public:
|
|||
private:
|
||||
TMemChecks m_mem_checks;
|
||||
};
|
||||
|
||||
class Watches
|
||||
{
|
||||
public:
|
||||
using TWatches = std::vector<TWatch>;
|
||||
using TWatchesStr = std::vector<std::string>;
|
||||
|
||||
const TWatches& GetWatches() const { return m_watches; }
|
||||
TWatchesStr GetStrings() const;
|
||||
void AddFromStrings(const TWatchesStr& watch_strings);
|
||||
|
||||
bool IsAddressWatch(u32 address) const;
|
||||
|
||||
// Add watch
|
||||
void Add(u32 address);
|
||||
void Add(const TWatch& watch);
|
||||
|
||||
void Update(int count, u32 address);
|
||||
void UpdateName(int count, const std::string name);
|
||||
|
||||
// Remove watch
|
||||
void Remove(u32 address);
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
TWatches m_watches;
|
||||
};
|
||||
|
|
|
@ -34,7 +34,6 @@ static bool s_cpu_core_base_is_injected = false;
|
|||
Interpreter* const s_interpreter = Interpreter::getInstance();
|
||||
static CoreMode s_mode = CoreMode::Interpreter;
|
||||
|
||||
Watches watches;
|
||||
BreakPoints breakpoints;
|
||||
MemChecks memchecks;
|
||||
PPCDebugInterface debug_interface;
|
||||
|
|
|
@ -135,7 +135,6 @@ static_assert(offsetof(PowerPC::PowerPCState, above_fits_in_first_0x100) <= 0x10
|
|||
|
||||
extern PowerPCState ppcState;
|
||||
|
||||
extern Watches watches;
|
||||
extern BreakPoints breakpoints;
|
||||
extern MemChecks memchecks;
|
||||
extern PPCDebugInterface debug_interface;
|
||||
|
|
|
@ -117,7 +117,7 @@ void WatchWidget::Update()
|
|||
|
||||
m_table->clear();
|
||||
|
||||
int size = static_cast<int>(PowerPC::watches.GetWatches().size());
|
||||
int size = static_cast<int>(PowerPC::debug_interface.GetWatches().size());
|
||||
|
||||
m_table->setRowCount(size + 1);
|
||||
|
||||
|
@ -127,7 +127,7 @@ void WatchWidget::Update()
|
|||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
auto entry = PowerPC::watches.GetWatches().at(i);
|
||||
auto entry = PowerPC::debug_interface.GetWatch(i);
|
||||
|
||||
auto* label = new QTableWidgetItem(QString::fromStdString(entry.name));
|
||||
auto* address =
|
||||
|
@ -195,7 +195,7 @@ void WatchWidget::OnLoad()
|
|||
{
|
||||
IniFile ini;
|
||||
|
||||
Watches::TWatchesStr watches;
|
||||
std::vector<std::string> watches;
|
||||
|
||||
if (!ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini",
|
||||
false))
|
||||
|
@ -205,8 +205,8 @@ void WatchWidget::OnLoad()
|
|||
|
||||
if (ini.GetLines("Watches", &watches, false))
|
||||
{
|
||||
PowerPC::watches.Clear();
|
||||
PowerPC::watches.AddFromStrings(watches);
|
||||
PowerPC::debug_interface.ClearWatches();
|
||||
PowerPC::debug_interface.LoadWatchesFromStrings(watches);
|
||||
}
|
||||
|
||||
Update();
|
||||
|
@ -217,7 +217,7 @@ void WatchWidget::OnSave()
|
|||
IniFile ini;
|
||||
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini",
|
||||
false);
|
||||
ini.SetLines("Watches", PowerPC::watches.GetStrings());
|
||||
ini.SetLines("Watches", PowerPC::debug_interface.SaveWatchesToStrings());
|
||||
ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini");
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ void WatchWidget::OnItemChanged(QTableWidgetItem* item)
|
|||
if (item->text().isEmpty())
|
||||
DeleteWatch(row);
|
||||
else
|
||||
PowerPC::watches.UpdateName(row, item->text().toStdString());
|
||||
PowerPC::debug_interface.UpdateWatchName(row, item->text().toStdString());
|
||||
break;
|
||||
// Address
|
||||
// Hexadecimal
|
||||
|
@ -293,9 +293,9 @@ void WatchWidget::OnItemChanged(QTableWidgetItem* item)
|
|||
if (good)
|
||||
{
|
||||
if (column == 1)
|
||||
PowerPC::watches.Update(row, value);
|
||||
PowerPC::debug_interface.UpdateWatchAddress(row, value);
|
||||
else
|
||||
PowerPC::HostWrite_U32(value, PowerPC::watches.GetWatches().at(row).address);
|
||||
PowerPC::HostWrite_U32(value, PowerPC::debug_interface.GetWatch(row).address);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -311,18 +311,16 @@ void WatchWidget::OnItemChanged(QTableWidgetItem* item)
|
|||
|
||||
void WatchWidget::DeleteWatch(int row)
|
||||
{
|
||||
PowerPC::watches.Remove(PowerPC::watches.GetWatches().at(row).address);
|
||||
PowerPC::debug_interface.RemoveWatch(row);
|
||||
Update();
|
||||
}
|
||||
|
||||
void WatchWidget::AddWatchBreakpoint(int row)
|
||||
{
|
||||
emit RequestMemoryBreakpoint(PowerPC::watches.GetWatches().at(row).address);
|
||||
emit RequestMemoryBreakpoint(PowerPC::debug_interface.GetWatch(row).address);
|
||||
}
|
||||
|
||||
void WatchWidget::AddWatch(QString name, u32 addr)
|
||||
{
|
||||
PowerPC::watches.Add(addr);
|
||||
PowerPC::watches.UpdateName(static_cast<int>(PowerPC::watches.GetWatches().size()) - 1,
|
||||
name.toStdString());
|
||||
PowerPC::debug_interface.SetWatch(addr, name.toStdString());
|
||||
}
|
||||
|
|
|
@ -275,7 +275,7 @@ void CMemoryView::OnPopupMenu(wxCommandEvent& event)
|
|||
#endif
|
||||
|
||||
case IDM_WATCHADDRESS:
|
||||
debugger->AddWatch(selection);
|
||||
debugger->SetWatch(selection);
|
||||
if (watch_window)
|
||||
watch_window->NotifyUpdate();
|
||||
Refresh();
|
||||
|
|
|
@ -541,7 +541,7 @@ void CRegisterView::OnPopupMenu(wxCommandEvent& event)
|
|||
switch (event.GetId())
|
||||
{
|
||||
case IDM_WATCHADDRESS:
|
||||
PowerPC::watches.Add(m_selectedAddress);
|
||||
PowerPC::debug_interface.SetWatch(m_selectedAddress);
|
||||
if (watch_window)
|
||||
watch_window->NotifyUpdate();
|
||||
Refresh();
|
||||
|
|
|
@ -30,12 +30,12 @@ enum
|
|||
|
||||
static std::string GetWatchName(int count)
|
||||
{
|
||||
return PowerPC::watches.GetWatches().at(count - 1).name;
|
||||
return PowerPC::debug_interface.GetWatch(count - 1).name;
|
||||
}
|
||||
|
||||
static u32 GetWatchAddr(int count)
|
||||
{
|
||||
return PowerPC::watches.GetWatches().at(count - 1).address;
|
||||
return PowerPC::debug_interface.GetWatch(count - 1).address;
|
||||
}
|
||||
|
||||
static u32 GetWatchValue(int count)
|
||||
|
@ -45,24 +45,23 @@ static u32 GetWatchValue(int count)
|
|||
|
||||
static void AddWatchAddr(int count, u32 value)
|
||||
{
|
||||
PowerPC::watches.Add(value);
|
||||
PowerPC::debug_interface.SetWatch(value);
|
||||
}
|
||||
|
||||
static void UpdateWatchAddr(int count, u32 value)
|
||||
{
|
||||
PowerPC::watches.Update(count - 1, value);
|
||||
PowerPC::debug_interface.UpdateWatchAddress(count - 1, value);
|
||||
}
|
||||
|
||||
static void SetWatchName(int count, const std::string& value)
|
||||
{
|
||||
if ((count - 1) < (int)PowerPC::watches.GetWatches().size())
|
||||
if (count - 1 < static_cast<int>(PowerPC::debug_interface.GetWatches().size()))
|
||||
{
|
||||
PowerPC::watches.UpdateName(count - 1, value);
|
||||
PowerPC::debug_interface.UpdateWatchName(count - 1, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
PowerPC::watches.Add(0);
|
||||
PowerPC::watches.UpdateName(PowerPC::watches.GetWatches().size() - 1, value);
|
||||
PowerPC::debug_interface.SetWatch(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +93,7 @@ static wxString GetValueByRowCol(int row, int col)
|
|||
return wxEmptyString;
|
||||
}
|
||||
}
|
||||
else if (row <= (int)PowerPC::watches.GetWatches().size())
|
||||
else if (row <= static_cast<int>(PowerPC::debug_interface.GetWatches().size()))
|
||||
{
|
||||
if (Core::IsRunning())
|
||||
{
|
||||
|
@ -145,10 +144,10 @@ void CWatchTable::SetValue(int row, int col, const wxString& strNewVal)
|
|||
}
|
||||
case 1:
|
||||
{
|
||||
if (row > (int)PowerPC::watches.GetWatches().size())
|
||||
if (row > static_cast<int>(PowerPC::debug_interface.GetWatches().size()))
|
||||
{
|
||||
AddWatchAddr(row, newVal);
|
||||
row = (int)PowerPC::watches.GetWatches().size();
|
||||
row = static_cast<int>(PowerPC::debug_interface.GetWatches().size());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -170,7 +169,7 @@ void CWatchTable::SetValue(int row, int col, const wxString& strNewVal)
|
|||
|
||||
void CWatchTable::UpdateWatch()
|
||||
{
|
||||
for (int i = 0; i < (int)PowerPC::watches.GetWatches().size(); ++i)
|
||||
for (int i = 0; i < static_cast<int>(PowerPC::debug_interface.GetWatches().size()); ++i)
|
||||
{
|
||||
m_CachedWatchHasChanged[i] = (m_CachedWatch[i] != GetWatchValue(i + 1));
|
||||
m_CachedWatch[i] = GetWatchValue(i + 1);
|
||||
|
@ -212,7 +211,8 @@ wxGridCellAttr* CWatchTable::GetAttr(int row, int col, wxGridCellAttr::wxAttrKin
|
|||
|
||||
attr->SetTextColour(red ? *wxRED : *wxBLACK);
|
||||
|
||||
if (row > (int)(PowerPC::watches.GetWatches().size() + 1) || !Core::IsRunning())
|
||||
if (row > static_cast<int>(PowerPC::debug_interface.GetWatches().size() + 1) ||
|
||||
!Core::IsRunning())
|
||||
{
|
||||
attr->SetReadOnly(true);
|
||||
attr->SetBackgroundColour(*wxLIGHT_GREY);
|
||||
|
@ -259,14 +259,15 @@ void CWatchView::OnMouseDownR(wxGridEvent& event)
|
|||
}
|
||||
|
||||
wxMenu menu;
|
||||
if (row != 0 && row != (int)(PowerPC::watches.GetWatches().size() + 1))
|
||||
if (row != 0 && row != static_cast<int>(PowerPC::debug_interface.GetWatches().size() + 1))
|
||||
{
|
||||
// i18n: This kind of "watch" is used for watching emulated memory.
|
||||
// It's not related to timekeeping devices.
|
||||
menu.Append(IDM_DELETEWATCH, _("&Delete watch"));
|
||||
}
|
||||
|
||||
if (row != 0 && row != (int)(PowerPC::watches.GetWatches().size() + 1) && (col == 1 || col == 2))
|
||||
if (row != 0 && row != static_cast<int>(PowerPC::debug_interface.GetWatches().size() + 1) &&
|
||||
(col == 1 || col == 2))
|
||||
{
|
||||
menu.Append(IDM_ADDMEMCHECK, _("Add memory &breakpoint"));
|
||||
menu.Append(IDM_VIEWMEMORY, _("View &memory"));
|
||||
|
@ -290,7 +291,7 @@ void CWatchView::OnPopupMenu(wxCommandEvent& event)
|
|||
wxString strNewVal = GetValueByRowCol(m_selectedRow, 1);
|
||||
if (TryParse("0x" + WxStrToStr(strNewVal), &m_selectedAddress))
|
||||
{
|
||||
PowerPC::watches.Remove(m_selectedAddress);
|
||||
PowerPC::debug_interface.UnsetWatch(m_selectedAddress);
|
||||
if (watch_window)
|
||||
watch_window->NotifyUpdate();
|
||||
Refresh();
|
||||
|
|
|
@ -122,7 +122,7 @@ void CWatchWindow::SaveAll()
|
|||
IniFile ini;
|
||||
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini",
|
||||
false);
|
||||
ini.SetLines("Watches", PowerPC::watches.GetStrings());
|
||||
ini.SetLines("Watches", PowerPC::debug_interface.SaveWatchesToStrings());
|
||||
ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini");
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ void CWatchWindow::Event_LoadAll(wxCommandEvent& WXUNUSED(event))
|
|||
void CWatchWindow::LoadAll()
|
||||
{
|
||||
IniFile ini;
|
||||
Watches::TWatchesStr watches;
|
||||
std::vector<std::string> watches;
|
||||
|
||||
if (!ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini",
|
||||
false))
|
||||
|
@ -144,8 +144,8 @@ void CWatchWindow::LoadAll()
|
|||
|
||||
if (ini.GetLines("Watches", &watches, false))
|
||||
{
|
||||
PowerPC::watches.Clear();
|
||||
PowerPC::watches.AddFromStrings(watches);
|
||||
PowerPC::debug_interface.ClearWatches();
|
||||
PowerPC::debug_interface.LoadWatchesFromStrings(watches);
|
||||
}
|
||||
|
||||
NotifyUpdate();
|
||||
|
|
|
@ -884,9 +884,7 @@ void CFrame::DoStop()
|
|||
|
||||
if (m_use_debugger && m_code_window)
|
||||
{
|
||||
PowerPC::watches.Clear();
|
||||
PowerPC::breakpoints.Clear();
|
||||
PowerPC::memchecks.Clear();
|
||||
PowerPC::debug_interface.Clear();
|
||||
if (m_code_window->HasPanel<CBreakPointWindow>())
|
||||
m_code_window->GetPanel<CBreakPointWindow>()->NotifyUpdate();
|
||||
g_symbolDB.Clear();
|
||||
|
|
Loading…
Reference in New Issue