2015-05-24 06:55:12 +02:00
|
|
|
// Copyright 2008 Dolphin Emulator Project
|
2015-05-18 01:08:10 +02:00
|
|
|
// Licensed under GPLv2+
|
2013-04-17 22:43:11 -04:00
|
|
|
// Refer to the license.txt file included.
|
2008-12-08 05:30:24 +00:00
|
|
|
|
2016-10-07 09:56:02 -04:00
|
|
|
#include "Core/Debugger/PPCDebugInterface.h"
|
|
|
|
|
|
2019-07-08 18:13:27 -04:00
|
|
|
#include <array>
|
2017-03-02 20:07:24 -05:00
|
|
|
#include <cstddef>
|
2014-07-17 21:33:51 -04:00
|
|
|
#include <string>
|
|
|
|
|
|
2019-07-08 18:00:56 -04:00
|
|
|
#include <fmt/format.h>
|
|
|
|
|
|
2018-05-21 18:46:03 +04:00
|
|
|
#include "Common/Align.h"
|
2014-07-17 21:33:51 -04:00
|
|
|
#include "Common/GekkoDisassembler.h"
|
2014-02-17 05:18:15 -05:00
|
|
|
|
2017-08-24 19:45:26 +01:00
|
|
|
#include "Core/Config/MainSettings.h"
|
2014-02-17 05:18:15 -05:00
|
|
|
#include "Core/Core.h"
|
2020-10-20 18:05:59 -04:00
|
|
|
#include "Core/Debugger/OSThread.h"
|
2014-02-17 05:18:15 -05:00
|
|
|
#include "Core/HW/DSP.h"
|
2018-05-17 17:09:55 -04:00
|
|
|
#include "Core/PowerPC/MMU.h"
|
2014-02-17 05:18:15 -05:00
|
|
|
#include "Core/PowerPC/PPCSymbolDB.h"
|
|
|
|
|
#include "Core/PowerPC/PowerPC.h"
|
2008-12-08 05:30:24 +00:00
|
|
|
|
2018-05-21 18:46:03 +04:00
|
|
|
void PPCPatches::Patch(std::size_t index)
|
|
|
|
|
{
|
|
|
|
|
auto& patch = m_patches[index];
|
|
|
|
|
if (patch.value.empty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
const u32 address = patch.address;
|
|
|
|
|
const std::size_t size = patch.value.size();
|
|
|
|
|
if (!PowerPC::HostIsRAMAddress(address))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (u32 offset = 0; offset < size; ++offset)
|
|
|
|
|
{
|
|
|
|
|
const u8 value = PowerPC::HostRead_U8(address + offset);
|
|
|
|
|
PowerPC::HostWrite_U8(patch.value[offset], address + offset);
|
|
|
|
|
patch.value[offset] = value;
|
|
|
|
|
|
|
|
|
|
if (((address + offset) % 4) == 3)
|
|
|
|
|
PowerPC::ScheduleInvalidateCacheThreadSafe(Common::AlignDown(address + offset, 4));
|
|
|
|
|
}
|
|
|
|
|
if (((address + size) % 4) != 0)
|
|
|
|
|
{
|
|
|
|
|
PowerPC::ScheduleInvalidateCacheThreadSafe(
|
|
|
|
|
Common::AlignDown(address + static_cast<u32>(size), 4));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 17:44:56 -04:00
|
|
|
PPCDebugInterface::PPCDebugInterface() = default;
|
|
|
|
|
PPCDebugInterface::~PPCDebugInterface() = default;
|
|
|
|
|
|
2019-07-08 17:28:07 -04:00
|
|
|
std::size_t PPCDebugInterface::SetWatch(u32 address, std::string name)
|
2018-01-29 17:58:02 +01:00
|
|
|
{
|
2019-07-08 17:28:07 -04:00
|
|
|
return m_watches.SetWatch(address, std::move(name));
|
2018-01-29 17:58:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 17:28:07 -04:00
|
|
|
void PPCDebugInterface::UpdateWatch(std::size_t index, u32 address, std::string name)
|
2018-01-29 17:58:02 +01:00
|
|
|
{
|
2019-07-08 17:28:07 -04:00
|
|
|
return m_watches.UpdateWatch(index, address, std::move(name));
|
2018-01-29 17:58:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PPCDebugInterface::UpdateWatchAddress(std::size_t index, u32 address)
|
|
|
|
|
{
|
|
|
|
|
return m_watches.UpdateWatchAddress(index, address);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 17:28:07 -04:00
|
|
|
void PPCDebugInterface::UpdateWatchName(std::size_t index, std::string name)
|
2018-01-29 17:58:02 +01:00
|
|
|
{
|
2019-07-08 17:28:07 -04:00
|
|
|
return m_watches.UpdateWatchName(index, std::move(name));
|
2018-01-29 17:58:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-21 18:46:03 +04:00
|
|
|
void PPCDebugInterface::SetPatch(u32 address, u32 value)
|
|
|
|
|
{
|
|
|
|
|
m_patches.SetPatch(address, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PPCDebugInterface::SetPatch(u32 address, std::vector<u8> value)
|
|
|
|
|
{
|
2019-07-08 17:28:07 -04:00
|
|
|
m_patches.SetPatch(address, std::move(value));
|
2018-05-21 18:46:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::vector<Common::Debug::MemoryPatch>& PPCDebugInterface::GetPatches() const
|
|
|
|
|
{
|
|
|
|
|
return m_patches.GetPatches();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PPCDebugInterface::UnsetPatch(u32 address)
|
|
|
|
|
{
|
|
|
|
|
m_patches.UnsetPatch(address);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PPCDebugInterface::EnablePatch(std::size_t index)
|
|
|
|
|
{
|
|
|
|
|
m_patches.EnablePatch(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PPCDebugInterface::DisablePatch(std::size_t index)
|
|
|
|
|
{
|
|
|
|
|
m_patches.DisablePatch(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PPCDebugInterface::HasEnabledPatch(u32 address) const
|
|
|
|
|
{
|
|
|
|
|
return m_patches.HasEnabledPatch(address);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PPCDebugInterface::RemovePatch(std::size_t index)
|
|
|
|
|
{
|
|
|
|
|
m_patches.RemovePatch(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PPCDebugInterface::ClearPatches()
|
|
|
|
|
{
|
|
|
|
|
m_patches.ClearPatches();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-21 11:48:49 +04:00
|
|
|
Common::Debug::Threads PPCDebugInterface::GetThreads() const
|
|
|
|
|
{
|
|
|
|
|
Common::Debug::Threads threads;
|
|
|
|
|
|
|
|
|
|
constexpr u32 ACTIVE_QUEUE_HEAD_ADDR = 0x800000dc;
|
|
|
|
|
if (!PowerPC::HostIsRAMAddress(ACTIVE_QUEUE_HEAD_ADDR))
|
|
|
|
|
return threads;
|
2020-08-01 00:17:23 +01:00
|
|
|
const u32 active_queue_head = PowerPC::HostRead_U32(ACTIVE_QUEUE_HEAD_ADDR);
|
|
|
|
|
if (!PowerPC::HostIsRAMAddress(active_queue_head))
|
2020-03-21 11:48:49 +04:00
|
|
|
return threads;
|
|
|
|
|
|
2020-10-20 18:05:59 -04:00
|
|
|
auto active_thread = std::make_unique<Core::Debug::OSThreadView>(active_queue_head);
|
2020-03-21 11:48:49 +04:00
|
|
|
if (!active_thread->IsValid())
|
|
|
|
|
return threads;
|
|
|
|
|
|
|
|
|
|
const auto insert_threads = [&threads](u32 addr, auto get_next_addr) {
|
|
|
|
|
while (addr != 0 && PowerPC::HostIsRAMAddress(addr))
|
|
|
|
|
{
|
2020-10-20 18:05:59 -04:00
|
|
|
auto thread = std::make_unique<Core::Debug::OSThreadView>(addr);
|
2020-03-21 11:48:49 +04:00
|
|
|
if (!thread->IsValid())
|
|
|
|
|
break;
|
|
|
|
|
addr = get_next_addr(*thread);
|
|
|
|
|
threads.emplace_back(std::move(thread));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-08-01 00:17:23 +01:00
|
|
|
const u32 prev_addr = active_thread->Data().thread_link.prev;
|
|
|
|
|
insert_threads(prev_addr, [](const auto& thread) { return thread.Data().thread_link.prev; });
|
2020-03-21 11:48:49 +04:00
|
|
|
std::reverse(threads.begin(), threads.end());
|
2020-08-01 00:17:23 +01:00
|
|
|
|
|
|
|
|
const u32 next_addr = active_thread->Data().thread_link.next;
|
2020-03-21 11:48:49 +04:00
|
|
|
threads.emplace_back(std::move(active_thread));
|
2020-08-01 00:17:23 +01:00
|
|
|
insert_threads(next_addr, [](const auto& thread) { return thread.Data().thread_link.next; });
|
2020-03-21 11:48:49 +04:00
|
|
|
|
|
|
|
|
return threads;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 18:25:14 -04:00
|
|
|
std::string PPCDebugInterface::Disassemble(u32 address) const
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2015-01-17 13:17:36 -08:00
|
|
|
// PowerPC::HostRead_U32 seemed to crash on shutdown
|
2016-05-12 09:17:17 +00:00
|
|
|
if (!IsAlive())
|
2014-07-17 21:33:51 -04:00
|
|
|
return "";
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2017-02-05 07:39:58 -05:00
|
|
|
if (Core::GetState() == Core::State::Paused)
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2015-01-17 13:17:36 -08:00
|
|
|
if (!PowerPC::HostIsRAMAddress(address))
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2015-01-17 13:17:36 -08:00
|
|
|
return "(No RAM here)";
|
2008-12-09 21:24:12 +00:00
|
|
|
}
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2018-04-07 22:18:42 -04:00
|
|
|
const u32 op = PowerPC::HostRead_Instruction(address);
|
2018-05-25 16:29:56 -04:00
|
|
|
std::string disasm = Common::GekkoDisassembler::Disassemble(op, address);
|
2018-04-07 22:18:42 -04:00
|
|
|
const UGeckoInstruction inst{op};
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2014-09-27 01:07:37 -07:00
|
|
|
if (inst.OPCD == 1)
|
2008-12-09 21:24:12 +00:00
|
|
|
{
|
2014-09-27 01:07:37 -07:00
|
|
|
disasm += " (hle)";
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2014-09-27 01:07:37 -07:00
|
|
|
return disasm;
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
2008-12-09 21:24:12 +00:00
|
|
|
else
|
|
|
|
|
{
|
2014-07-17 21:33:51 -04:00
|
|
|
return "<unknown>";
|
2016-06-24 10:43:46 +02:00
|
|
|
}
|
2008-12-09 21:24:12 +00:00
|
|
|
}
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2019-07-08 18:25:14 -04:00
|
|
|
std::string PPCDebugInterface::GetRawMemoryString(int memory, u32 address) const
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2016-05-12 09:17:17 +00:00
|
|
|
if (IsAlive())
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2016-10-07 09:56:02 -04:00
|
|
|
const bool is_aram = memory != 0;
|
|
|
|
|
|
|
|
|
|
if (is_aram || PowerPC::HostIsRAMAddress(address))
|
2019-07-08 18:00:56 -04:00
|
|
|
return fmt::format("{:08X}{}", ReadExtraMemory(memory, address), is_aram ? " (ARAM)" : "");
|
2016-10-07 09:56:02 -04:00
|
|
|
|
|
|
|
|
return is_aram ? "--ARAM--" : "--------";
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
2016-10-07 09:56:02 -04:00
|
|
|
|
|
|
|
|
return "<unknwn>"; // bad spelling - 8 chars
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 18:25:14 -04:00
|
|
|
u32 PPCDebugInterface::ReadMemory(u32 address) const
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2015-01-17 13:17:36 -08:00
|
|
|
return PowerPC::HostRead_U32(address);
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 18:25:14 -04:00
|
|
|
u32 PPCDebugInterface::ReadExtraMemory(int memory, u32 address) const
|
2009-06-17 19:50:59 +00:00
|
|
|
{
|
|
|
|
|
switch (memory)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
2015-01-17 13:17:36 -08:00
|
|
|
return PowerPC::HostRead_U32(address);
|
2009-06-17 19:50:59 +00:00
|
|
|
case 1:
|
|
|
|
|
return (DSP::ReadARAM(address) << 24) | (DSP::ReadARAM(address + 1) << 16) |
|
2014-02-16 15:30:18 -05:00
|
|
|
(DSP::ReadARAM(address + 2) << 8) | (DSP::ReadARAM(address + 3));
|
2009-06-17 19:50:59 +00:00
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 18:25:14 -04:00
|
|
|
u32 PPCDebugInterface::ReadInstruction(u32 address) const
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2015-01-17 13:17:36 -08:00
|
|
|
return PowerPC::HostRead_Instruction(address);
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 18:25:14 -04:00
|
|
|
bool PPCDebugInterface::IsAlive() const
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2018-01-06 17:27:15 -08:00
|
|
|
return Core::IsRunningAndStarted();
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 18:25:14 -04:00
|
|
|
bool PPCDebugInterface::IsBreakpoint(u32 address) const
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2009-06-28 11:47:39 +00:00
|
|
|
return PowerPC::breakpoints.IsAddressBreakPoint(address);
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 17:53:47 -04:00
|
|
|
void PPCDebugInterface::SetBreakpoint(u32 address)
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2010-08-08 06:00:22 +00:00
|
|
|
PowerPC::breakpoints.Add(address);
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 17:53:47 -04:00
|
|
|
void PPCDebugInterface::ClearBreakpoint(u32 address)
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2010-08-08 06:00:22 +00:00
|
|
|
PowerPC::breakpoints.Remove(address);
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
|
|
|
|
|
2014-03-03 13:56:28 -05:00
|
|
|
void PPCDebugInterface::ClearAllBreakpoints()
|
|
|
|
|
{
|
|
|
|
|
PowerPC::breakpoints.Clear();
|
|
|
|
|
}
|
2008-12-08 05:30:24 +00:00
|
|
|
|
2019-07-08 17:53:47 -04:00
|
|
|
void PPCDebugInterface::ToggleBreakpoint(u32 address)
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2009-06-28 11:47:39 +00:00
|
|
|
if (PowerPC::breakpoints.IsAddressBreakPoint(address))
|
|
|
|
|
PowerPC::breakpoints.Remove(address);
|
2008-12-20 14:00:33 +00:00
|
|
|
else
|
2009-06-28 11:47:39 +00:00
|
|
|
PowerPC::breakpoints.Add(address);
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
|
|
|
|
|
2014-03-05 20:51:27 -05:00
|
|
|
void PPCDebugInterface::ClearAllMemChecks()
|
|
|
|
|
{
|
|
|
|
|
PowerPC::memchecks.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 18:25:14 -04:00
|
|
|
bool PPCDebugInterface::IsMemCheck(u32 address, size_t size) const
|
2010-02-18 12:06:13 +00:00
|
|
|
{
|
2017-03-02 20:07:24 -05:00
|
|
|
return PowerPC::memchecks.GetMemCheck(address, size) != nullptr;
|
2010-02-18 12:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 17:53:47 -04:00
|
|
|
void PPCDebugInterface::ToggleMemCheck(u32 address, bool read, bool write, bool log)
|
2010-02-18 12:06:13 +00:00
|
|
|
{
|
2016-09-15 03:08:48 +00:00
|
|
|
if (!IsMemCheck(address))
|
2010-02-18 12:06:13 +00:00
|
|
|
{
|
|
|
|
|
// Add Memory Check
|
|
|
|
|
TMemCheck MemCheck;
|
2017-01-11 08:27:45 -05:00
|
|
|
MemCheck.start_address = address;
|
|
|
|
|
MemCheck.end_address = address;
|
|
|
|
|
MemCheck.is_break_on_read = read;
|
|
|
|
|
MemCheck.is_break_on_write = write;
|
2010-02-18 12:06:13 +00:00
|
|
|
|
2017-01-11 08:27:45 -05:00
|
|
|
MemCheck.log_on_hit = log;
|
|
|
|
|
MemCheck.break_on_hit = true;
|
2010-02-18 12:06:13 +00:00
|
|
|
|
|
|
|
|
PowerPC::memchecks.Add(MemCheck);
|
|
|
|
|
}
|
|
|
|
|
else
|
2016-09-15 03:08:48 +00:00
|
|
|
{
|
2011-02-25 09:35:56 +00:00
|
|
|
PowerPC::memchecks.Remove(address);
|
2016-09-15 03:08:48 +00:00
|
|
|
}
|
2010-02-18 12:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-08 05:30:24 +00:00
|
|
|
// =======================================================
|
|
|
|
|
// Separate the blocks with colors.
|
|
|
|
|
// -------------
|
2019-07-08 18:25:14 -04:00
|
|
|
u32 PPCDebugInterface::GetColor(u32 address) const
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2015-01-17 13:17:36 -08:00
|
|
|
if (!IsAlive())
|
|
|
|
|
return 0xFFFFFF;
|
|
|
|
|
if (!PowerPC::HostIsRAMAddress(address))
|
2008-12-08 05:30:24 +00:00
|
|
|
return 0xeeeeee;
|
2019-07-08 18:13:27 -04:00
|
|
|
|
|
|
|
|
Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(address);
|
|
|
|
|
if (!symbol)
|
|
|
|
|
return 0xFFFFFF;
|
|
|
|
|
if (symbol->type != Common::Symbol::Type::Function)
|
|
|
|
|
return 0xEEEEFF;
|
|
|
|
|
|
|
|
|
|
static constexpr std::array<u32, 6> colors{
|
2009-01-21 11:44:36 +00:00
|
|
|
0xd0FFFF, // light cyan
|
|
|
|
|
0xFFd0d0, // light red
|
|
|
|
|
0xd8d8FF, // light blue
|
|
|
|
|
0xFFd0FF, // light purple
|
|
|
|
|
0xd0FFd0, // light green
|
|
|
|
|
0xFFFFd0, // light yellow
|
2008-12-08 05:30:24 +00:00
|
|
|
};
|
2019-07-08 18:13:27 -04:00
|
|
|
return colors[symbol->index % colors.size()];
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
|
|
|
|
// =============
|
|
|
|
|
|
2019-07-08 18:25:14 -04:00
|
|
|
std::string PPCDebugInterface::GetDescription(u32 address) const
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
|
|
|
|
return g_symbolDB.GetDescription(address);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 18:25:14 -04:00
|
|
|
u32 PPCDebugInterface::GetPC() const
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
|
|
|
|
return PowerPC::ppcState.pc;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 17:53:47 -04:00
|
|
|
void PPCDebugInterface::SetPC(u32 address)
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
|
|
|
|
PowerPC::ppcState.pc = address;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-03 00:39:08 -05:00
|
|
|
void PPCDebugInterface::RunToBreakpoint()
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
|
|
|
|
}
|
2018-01-29 17:58:02 +01:00
|
|
|
|
2017-08-24 19:45:26 +01:00
|
|
|
std::shared_ptr<Core::NetworkCaptureLogger> PPCDebugInterface::NetworkLogger()
|
|
|
|
|
{
|
|
|
|
|
const bool has_ssl = Config::Get(Config::MAIN_NETWORK_SSL_DUMP_READ) ||
|
|
|
|
|
Config::Get(Config::MAIN_NETWORK_SSL_DUMP_WRITE);
|
2017-08-29 22:14:01 +01:00
|
|
|
const bool is_pcap = Config::Get(Config::MAIN_NETWORK_DUMP_AS_PCAP);
|
|
|
|
|
const auto current_capture_type = [&] {
|
|
|
|
|
if (is_pcap)
|
|
|
|
|
return Core::NetworkCaptureType::PCAP;
|
|
|
|
|
if (has_ssl)
|
|
|
|
|
return Core::NetworkCaptureType::Raw;
|
|
|
|
|
return Core::NetworkCaptureType::None;
|
|
|
|
|
}();
|
2017-08-24 19:45:26 +01:00
|
|
|
|
|
|
|
|
if (m_network_logger && m_network_logger->GetCaptureType() == current_capture_type)
|
|
|
|
|
return m_network_logger;
|
|
|
|
|
|
|
|
|
|
switch (current_capture_type)
|
|
|
|
|
{
|
2017-08-29 22:14:01 +01:00
|
|
|
case Core::NetworkCaptureType::PCAP:
|
|
|
|
|
m_network_logger = std::make_shared<Core::PCAPSSLCaptureLogger>();
|
|
|
|
|
break;
|
2017-08-24 19:45:26 +01:00
|
|
|
case Core::NetworkCaptureType::Raw:
|
|
|
|
|
m_network_logger = std::make_shared<Core::BinarySSLCaptureLogger>();
|
|
|
|
|
break;
|
|
|
|
|
case Core::NetworkCaptureType::None:
|
|
|
|
|
m_network_logger = std::make_shared<Core::DummyNetworkCaptureLogger>();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return m_network_logger;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-29 17:58:02 +01:00
|
|
|
void PPCDebugInterface::Clear()
|
|
|
|
|
{
|
|
|
|
|
ClearAllBreakpoints();
|
|
|
|
|
ClearAllMemChecks();
|
2018-05-21 18:46:03 +04:00
|
|
|
ClearPatches();
|
2018-01-29 17:58:02 +01:00
|
|
|
ClearWatches();
|
2017-08-24 19:45:26 +01:00
|
|
|
m_network_logger.reset();
|
2018-01-29 17:58:02 +01:00
|
|
|
}
|