Debugger: Avoid ppcState global.
This commit is contained in:
parent
bfc951311f
commit
8adabb86cf
|
@ -16,6 +16,7 @@
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
namespace Dolphin_Debugger
|
namespace Dolphin_Debugger
|
||||||
{
|
{
|
||||||
|
@ -43,11 +44,13 @@ static bool IsStackBottom(u32 addr)
|
||||||
return !addr || !PowerPC::HostIsRAMAddress(addr);
|
return !addr || !PowerPC::HostIsRAMAddress(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WalkTheStack(const std::function<void(u32)>& stack_step)
|
static void WalkTheStack(Core::System& system, const std::function<void(u32)>& stack_step)
|
||||||
{
|
{
|
||||||
if (!IsStackBottom(PowerPC::ppcState.gpr[1]))
|
auto& ppc_state = system.GetPPCState();
|
||||||
|
|
||||||
|
if (!IsStackBottom(ppc_state.gpr[1]))
|
||||||
{
|
{
|
||||||
u32 addr = PowerPC::HostRead_U32(PowerPC::ppcState.gpr[1]); // SP
|
u32 addr = PowerPC::HostRead_U32(ppc_state.gpr[1]); // SP
|
||||||
|
|
||||||
// Walk the stack chain
|
// Walk the stack chain
|
||||||
for (int count = 0; !IsStackBottom(addr + 4) && (count++ < 20); ++count)
|
for (int count = 0; !IsStackBottom(addr + 4) && (count++ < 20); ++count)
|
||||||
|
@ -66,12 +69,14 @@ static void WalkTheStack(const std::function<void(u32)>& stack_step)
|
||||||
// Returns callstack "formatted for debugging" - meaning that it
|
// Returns callstack "formatted for debugging" - meaning that it
|
||||||
// includes LR as the last item, and all items are the last step,
|
// includes LR as the last item, and all items are the last step,
|
||||||
// instead of "pointing ahead"
|
// instead of "pointing ahead"
|
||||||
bool GetCallstack(std::vector<CallstackEntry>& output)
|
bool GetCallstack(Core::System& system, std::vector<CallstackEntry>& output)
|
||||||
{
|
{
|
||||||
if (!Core::IsRunning() || !PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[1]))
|
auto& ppc_state = system.GetPPCState();
|
||||||
|
|
||||||
|
if (!Core::IsRunning() || !PowerPC::HostIsRAMAddress(ppc_state.gpr[1]))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (LR(PowerPC::ppcState) == 0)
|
if (LR(ppc_state) == 0)
|
||||||
{
|
{
|
||||||
CallstackEntry entry;
|
CallstackEntry entry;
|
||||||
entry.Name = "(error: LR=0)";
|
entry.Name = "(error: LR=0)";
|
||||||
|
@ -81,13 +86,12 @@ bool GetCallstack(std::vector<CallstackEntry>& output)
|
||||||
}
|
}
|
||||||
|
|
||||||
CallstackEntry entry;
|
CallstackEntry entry;
|
||||||
entry.Name =
|
entry.Name = fmt::format(" * {} [ LR = {:08x} ]\n", g_symbolDB.GetDescription(LR(ppc_state)),
|
||||||
fmt::format(" * {} [ LR = {:08x} ]\n", g_symbolDB.GetDescription(LR(PowerPC::ppcState)),
|
LR(ppc_state) - 4);
|
||||||
LR(PowerPC::ppcState) - 4);
|
entry.vAddress = LR(ppc_state) - 4;
|
||||||
entry.vAddress = LR(PowerPC::ppcState) - 4;
|
|
||||||
output.push_back(entry);
|
output.push_back(entry);
|
||||||
|
|
||||||
WalkTheStack([&entry, &output](u32 func_addr) {
|
WalkTheStack(system, [&entry, &output](u32 func_addr) {
|
||||||
std::string func_desc = g_symbolDB.GetDescription(func_addr);
|
std::string func_desc = g_symbolDB.GetDescription(func_addr);
|
||||||
if (func_desc.empty() || func_desc == "Invalid")
|
if (func_desc.empty() || func_desc == "Invalid")
|
||||||
func_desc = "(unknown)";
|
func_desc = "(unknown)";
|
||||||
|
@ -99,23 +103,24 @@ bool GetCallstack(std::vector<CallstackEntry>& output)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintCallstack(Common::Log::LogType type, Common::Log::LogLevel level)
|
void PrintCallstack(Core::System& system, Common::Log::LogType type, Common::Log::LogLevel level)
|
||||||
{
|
{
|
||||||
GENERIC_LOG_FMT(type, level, "== STACK TRACE - SP = {:08x} ==", PowerPC::ppcState.gpr[1]);
|
auto& ppc_state = system.GetPPCState();
|
||||||
|
|
||||||
if (LR(PowerPC::ppcState) == 0)
|
GENERIC_LOG_FMT(type, level, "== STACK TRACE - SP = {:08x} ==", ppc_state.gpr[1]);
|
||||||
|
|
||||||
|
if (LR(ppc_state) == 0)
|
||||||
{
|
{
|
||||||
GENERIC_LOG_FMT(type, level, " LR = 0 - this is bad");
|
GENERIC_LOG_FMT(type, level, " LR = 0 - this is bad");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_symbolDB.GetDescription(PowerPC::ppcState.pc) !=
|
if (g_symbolDB.GetDescription(ppc_state.pc) != g_symbolDB.GetDescription(LR(ppc_state)))
|
||||||
g_symbolDB.GetDescription(LR(PowerPC::ppcState)))
|
|
||||||
{
|
{
|
||||||
GENERIC_LOG_FMT(type, level, " * {} [ LR = {:08x} ]",
|
GENERIC_LOG_FMT(type, level, " * {} [ LR = {:08x} ]", g_symbolDB.GetDescription(LR(ppc_state)),
|
||||||
g_symbolDB.GetDescription(LR(PowerPC::ppcState)), LR(PowerPC::ppcState));
|
LR(ppc_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkTheStack([type, level](u32 func_addr) {
|
WalkTheStack(system, [type, level](u32 func_addr) {
|
||||||
std::string func_desc = g_symbolDB.GetDescription(func_addr);
|
std::string func_desc = g_symbolDB.GetDescription(func_addr);
|
||||||
if (func_desc.empty() || func_desc == "Invalid")
|
if (func_desc.empty() || func_desc == "Invalid")
|
||||||
func_desc = "(unknown)";
|
func_desc = "(unknown)";
|
||||||
|
|
|
@ -10,6 +10,11 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Dolphin_Debugger
|
namespace Dolphin_Debugger
|
||||||
{
|
{
|
||||||
struct CallstackEntry
|
struct CallstackEntry
|
||||||
|
@ -18,8 +23,8 @@ struct CallstackEntry
|
||||||
u32 vAddress = 0;
|
u32 vAddress = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GetCallstack(std::vector<CallstackEntry>& output);
|
bool GetCallstack(Core::System& system, std::vector<CallstackEntry>& output);
|
||||||
void PrintCallstack(Common::Log::LogType type, Common::Log::LogLevel level);
|
void PrintCallstack(Core::System& system, Common::Log::LogType type, Common::Log::LogLevel level);
|
||||||
void PrintDataBuffer(Common::Log::LogType type, const u8* data, size_t size,
|
void PrintDataBuffer(Common::Log::LogType type, const u8* data, size_t size,
|
||||||
std::string_view title);
|
std::string_view title);
|
||||||
void AddAutoBreakpoints();
|
void AddAutoBreakpoints();
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
void ApplyMemoryPatch(Common::Debug::MemoryPatch& patch, bool store_existing_value)
|
void ApplyMemoryPatch(Common::Debug::MemoryPatch& patch, bool store_existing_value)
|
||||||
{
|
{
|
||||||
|
@ -81,7 +82,10 @@ void PPCPatches::UnPatch(std::size_t index)
|
||||||
PatchEngine::RemoveMemoryPatch(index);
|
PatchEngine::RemoveMemoryPatch(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
PPCDebugInterface::PPCDebugInterface() = default;
|
PPCDebugInterface::PPCDebugInterface(Core::System& system) : m_system(system)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
PPCDebugInterface::~PPCDebugInterface() = default;
|
PPCDebugInterface::~PPCDebugInterface() = default;
|
||||||
|
|
||||||
std::size_t PPCDebugInterface::SetWatch(u32 address, std::string name)
|
std::size_t PPCDebugInterface::SetWatch(u32 address, std::string name)
|
||||||
|
@ -449,7 +453,7 @@ PPCDebugInterface::GetMemoryAddressFromInstruction(const std::string& instructio
|
||||||
if (is_reg == offset_match[0])
|
if (is_reg == offset_match[0])
|
||||||
{
|
{
|
||||||
const int register_index = std::stoi(offset_match.substr(1), nullptr, 10);
|
const int register_index = std::stoi(offset_match.substr(1), nullptr, 10);
|
||||||
offset = (register_index == 0 ? 0 : PowerPC::ppcState.gpr[register_index]);
|
offset = (register_index == 0 ? 0 : m_system.GetPPCState().gpr[register_index]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -468,7 +472,7 @@ PPCDebugInterface::GetMemoryAddressFromInstruction(const std::string& instructio
|
||||||
else
|
else
|
||||||
i = std::stoi(register_match, nullptr, 10);
|
i = std::stoi(register_match, nullptr, 10);
|
||||||
|
|
||||||
const u32 base_address = PowerPC::ppcState.gpr[i];
|
const u32 base_address = m_system.GetPPCState().gpr[i];
|
||||||
|
|
||||||
if (!match.str(1).empty())
|
if (!match.str(1).empty())
|
||||||
return base_address - offset;
|
return base_address - offset;
|
||||||
|
@ -478,12 +482,12 @@ PPCDebugInterface::GetMemoryAddressFromInstruction(const std::string& instructio
|
||||||
|
|
||||||
u32 PPCDebugInterface::GetPC() const
|
u32 PPCDebugInterface::GetPC() const
|
||||||
{
|
{
|
||||||
return PowerPC::ppcState.pc;
|
return m_system.GetPPCState().pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCDebugInterface::SetPC(u32 address)
|
void PPCDebugInterface::SetPC(u32 address)
|
||||||
{
|
{
|
||||||
PowerPC::ppcState.pc = address;
|
m_system.GetPPCState().pc = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCDebugInterface::RunToBreakpoint()
|
void PPCDebugInterface::RunToBreakpoint()
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
#include "Common/DebugInterface.h"
|
#include "Common/DebugInterface.h"
|
||||||
#include "Core/NetworkCaptureLogger.h"
|
#include "Core/NetworkCaptureLogger.h"
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
void ApplyMemoryPatch(Common::Debug::MemoryPatch& patch, bool store_existing_value = true);
|
void ApplyMemoryPatch(Common::Debug::MemoryPatch& patch, bool store_existing_value = true);
|
||||||
|
|
||||||
class PPCPatches final : public Common::Debug::MemoryPatches
|
class PPCPatches final : public Common::Debug::MemoryPatches
|
||||||
|
@ -29,7 +34,7 @@ private:
|
||||||
class PPCDebugInterface final : public Common::DebugInterface
|
class PPCDebugInterface final : public Common::DebugInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PPCDebugInterface();
|
explicit PPCDebugInterface(Core::System& system);
|
||||||
~PPCDebugInterface() override;
|
~PPCDebugInterface() override;
|
||||||
|
|
||||||
// Watches
|
// Watches
|
||||||
|
@ -102,4 +107,5 @@ private:
|
||||||
Common::Debug::Watches m_watches;
|
Common::Debug::Watches m_watches;
|
||||||
PPCPatches m_patches;
|
PPCPatches m_patches;
|
||||||
std::shared_ptr<Core::NetworkCaptureLogger> m_network_logger;
|
std::shared_ptr<Core::NetworkCaptureLogger> m_network_logger;
|
||||||
|
Core::System& m_system;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "Core/Debugger/Debugger_SymbolMap.h"
|
#include "Core/Debugger/Debugger_SymbolMap.h"
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static T HostRead(u32 address);
|
static T HostRead(u32 address);
|
||||||
|
@ -109,7 +110,7 @@ static double CallstackFunc(expr_func* f, vec_expr_t* args, void* c)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
std::vector<Dolphin_Debugger::CallstackEntry> stack;
|
std::vector<Dolphin_Debugger::CallstackEntry> stack;
|
||||||
bool success = Dolphin_Debugger::GetCallstack(stack);
|
bool success = Dolphin_Debugger::GetCallstack(Core::System::GetInstance(), stack);
|
||||||
if (!success)
|
if (!success)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -342,7 +342,8 @@ void Interpreter::unknown_instruction(UGeckoInstruction inst)
|
||||||
const u32 opcode = PowerPC::HostRead_U32(last_pc);
|
const u32 opcode = PowerPC::HostRead_U32(last_pc);
|
||||||
const std::string disasm = Common::GekkoDisassembler::Disassemble(opcode, last_pc);
|
const std::string disasm = Common::GekkoDisassembler::Disassemble(opcode, last_pc);
|
||||||
NOTICE_LOG_FMT(POWERPC, "Last PC = {:08x} : {}", last_pc, disasm);
|
NOTICE_LOG_FMT(POWERPC, "Last PC = {:08x} : {}", last_pc, disasm);
|
||||||
Dolphin_Debugger::PrintCallstack(Common::Log::LogType::POWERPC, Common::Log::LogLevel::LNOTICE);
|
Dolphin_Debugger::PrintCallstack(Core::System::GetInstance(), Common::Log::LogType::POWERPC,
|
||||||
|
Common::Log::LogLevel::LNOTICE);
|
||||||
NOTICE_LOG_FMT(
|
NOTICE_LOG_FMT(
|
||||||
POWERPC,
|
POWERPC,
|
||||||
"\nIntCPU: Unknown instruction {:08x} at PC = {:08x} last_PC = {:08x} LR = {:08x}\n",
|
"\nIntCPU: Unknown instruction {:08x} at PC = {:08x} last_PC = {:08x} LR = {:08x}\n",
|
||||||
|
|
|
@ -45,7 +45,7 @@ static CoreMode s_mode = CoreMode::Interpreter;
|
||||||
|
|
||||||
BreakPoints breakpoints;
|
BreakPoints breakpoints;
|
||||||
MemChecks memchecks;
|
MemChecks memchecks;
|
||||||
PPCDebugInterface debug_interface;
|
PPCDebugInterface debug_interface(Core::System::GetInstance());
|
||||||
|
|
||||||
static CoreTiming::EventType* s_invalidate_cache_thread_safe;
|
static CoreTiming::EventType* s_invalidate_cache_thread_safe;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "DolphinQt/Host.h"
|
#include "DolphinQt/Host.h"
|
||||||
#include "DolphinQt/Settings.h"
|
#include "DolphinQt/Settings.h"
|
||||||
|
|
||||||
|
@ -328,7 +329,7 @@ void CodeWidget::UpdateCallstack()
|
||||||
|
|
||||||
std::vector<Dolphin_Debugger::CallstackEntry> stack;
|
std::vector<Dolphin_Debugger::CallstackEntry> stack;
|
||||||
|
|
||||||
bool success = Dolphin_Debugger::GetCallstack(stack);
|
bool success = Dolphin_Debugger::GetCallstack(Core::System::GetInstance(), stack);
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue