mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-06 19:45:33 +00:00
GDBServer: Implement memory breakpoints
This commit is contained in:
parent
a0c06f8d9c
commit
7bae23d79d
@ -53,8 +53,8 @@ static bool Cmd$G(ClientSocket* client, std::string_view data);
|
|||||||
static bool Cmd$m(ClientSocket* client, std::string_view data);
|
static bool Cmd$m(ClientSocket* client, std::string_view data);
|
||||||
static bool Cmd$M(ClientSocket* client, std::string_view data);
|
static bool Cmd$M(ClientSocket* client, std::string_view data);
|
||||||
static bool Cmd$s(ClientSocket* client, std::string_view data);
|
static bool Cmd$s(ClientSocket* client, std::string_view data);
|
||||||
static bool Cmd$z1(ClientSocket* client, std::string_view data);
|
template<bool add_breakpoint>
|
||||||
static bool Cmd$Z1(ClientSocket* client, std::string_view data);
|
static bool Cmd$z(ClientSocket* client, std::string_view data);
|
||||||
static bool Cmd$vMustReplyEmpty(ClientSocket* client, std::string_view data);
|
static bool Cmd$vMustReplyEmpty(ClientSocket* client, std::string_view data);
|
||||||
static bool Cmd$qSupported(ClientSocket* client, std::string_view data);
|
static bool Cmd$qSupported(ClientSocket* client, std::string_view data);
|
||||||
|
|
||||||
@ -122,10 +122,8 @@ static constexpr std::pair<std::string_view, bool (*)(ClientSocket*, std::string
|
|||||||
{"m", Cmd$m},
|
{"m", Cmd$m},
|
||||||
{"M", Cmd$M},
|
{"M", Cmd$M},
|
||||||
{"s", Cmd$s},
|
{"s", Cmd$s},
|
||||||
{"z0,", Cmd$z1},
|
{"z", Cmd$z<false>},
|
||||||
{"Z0,", Cmd$Z1},
|
{"Z", Cmd$z<true>},
|
||||||
{"z1,", Cmd$z1},
|
|
||||||
{"Z1,", Cmd$Z1},
|
|
||||||
{"vMustReplyEmpty", Cmd$vMustReplyEmpty},
|
{"vMustReplyEmpty", Cmd$vMustReplyEmpty},
|
||||||
{"qSupported", Cmd$qSupported},
|
{"qSupported", Cmd$qSupported},
|
||||||
};
|
};
|
||||||
@ -286,40 +284,76 @@ bool GDBServer::Cmd$s(ClientSocket* client, std::string_view data)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove hardware breakpoint.
|
/// Remove hardware breakpoint (z).
|
||||||
bool GDBServer::Cmd$z1(ClientSocket* client, std::string_view data)
|
/// Insert hardware breakpoint (Z).
|
||||||
|
template<bool add_breakpoint>
|
||||||
|
bool GDBServer::Cmd$z(ClientSocket* client, std::string_view data)
|
||||||
{
|
{
|
||||||
const std::optional<VirtualMemoryAddress> address = StringUtil::FromChars<VirtualMemoryAddress>(data, 16);
|
std::string_view caret = data;
|
||||||
if (address.has_value())
|
std::optional<u32> bptype;
|
||||||
|
std::optional<VirtualMemoryAddress> bpaddr;
|
||||||
|
|
||||||
|
// type,addr
|
||||||
|
if (!(bptype = StringUtil::FromChars<u32>(caret, 10, &caret)) || caret.empty() || caret[0] != ',' ||
|
||||||
|
!(bpaddr = StringUtil::FromChars<VirtualMemoryAddress>(caret.substr(1), 16)).has_value())
|
||||||
{
|
{
|
||||||
CPU::RemoveBreakpoint(CPU::BreakpointType::Execute, *address);
|
ERROR_LOG("Invalid {} hw breakpoint packet: {}", add_breakpoint ? "add" : "remove", data);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bptype.value() == 0 || bptype.value() == 1) // software/hardware breakpoint
|
||||||
|
{
|
||||||
|
if constexpr (add_breakpoint)
|
||||||
|
CPU::AddBreakpoint(CPU::BreakpointType::Execute, bpaddr.value());
|
||||||
|
else
|
||||||
|
CPU::RemoveBreakpoint(CPU::BreakpointType::Execute, bpaddr.value());
|
||||||
|
client->SendReplyWithAck("OK");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (bptype.value() == 2) // write breakpoint
|
||||||
|
{
|
||||||
|
if constexpr (add_breakpoint)
|
||||||
|
CPU::AddBreakpoint(CPU::BreakpointType::Write, bpaddr.value());
|
||||||
|
else
|
||||||
|
CPU::RemoveBreakpoint(CPU::BreakpointType::Write, bpaddr.value());
|
||||||
|
|
||||||
|
client->SendReplyWithAck("OK");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (bptype.value() == 3) // read breakpoint
|
||||||
|
{
|
||||||
|
if constexpr (add_breakpoint)
|
||||||
|
CPU::AddBreakpoint(CPU::BreakpointType::Read, bpaddr.value());
|
||||||
|
else
|
||||||
|
CPU::RemoveBreakpoint(CPU::BreakpointType::Read, bpaddr.value());
|
||||||
|
client->SendReplyWithAck("OK");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (bptype.value() == 4) // read+write breakpoint
|
||||||
|
{
|
||||||
|
if constexpr (add_breakpoint)
|
||||||
|
{
|
||||||
|
CPU::AddBreakpoint(CPU::BreakpointType::Read, bpaddr.value());
|
||||||
|
CPU::AddBreakpoint(CPU::BreakpointType::Write, bpaddr.value());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CPU::RemoveBreakpoint(CPU::BreakpointType::Read, bpaddr.value());
|
||||||
|
CPU::RemoveBreakpoint(CPU::BreakpointType::Write, bpaddr.value());
|
||||||
|
}
|
||||||
|
|
||||||
client->SendReplyWithAck("OK");
|
client->SendReplyWithAck("OK");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERROR_LOG("Invalid address to remove hw breakpoint: ", data);
|
ERROR_LOG("Unknown breakpoint type {}", bptype.value());
|
||||||
client->SendReplyWithAck();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert hardware breakpoint.
|
template bool GDBServer::Cmd$z<false>(ClientSocket* client, std::string_view data);
|
||||||
bool GDBServer::Cmd$Z1(ClientSocket* client, std::string_view data)
|
template bool GDBServer::Cmd$z<true>(ClientSocket* client, std::string_view data);
|
||||||
{
|
|
||||||
const std::optional<VirtualMemoryAddress> address = StringUtil::FromChars<VirtualMemoryAddress>(data, 16);
|
|
||||||
if (address)
|
|
||||||
{
|
|
||||||
CPU::AddBreakpoint(CPU::BreakpointType::Execute, *address, false);
|
|
||||||
client->SendReplyWithAck("OK");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERROR_LOG("Invalid address to insert hw breakpoint: ", data);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GDBServer::Cmd$vMustReplyEmpty(ClientSocket* client, std::string_view data)
|
bool GDBServer::Cmd$vMustReplyEmpty(ClientSocket* client, std::string_view data)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user