gdb: Implement z0/Z0 software breakpoints

This commit is contained in:
Coxxs 2025-06-22 05:28:31 +08:00
parent 7d5f7bc479
commit bad1dd8899
2 changed files with 280 additions and 3 deletions

View file

@ -35,6 +35,8 @@ namespace Ryujinx.HLE.Debugger
private ulong? cThread;
private ulong? gThread;
private BreakpointManager BreakpointManager;
private string previousThreadListXml = "";
public Debugger(Switch device, ushort port)
@ -48,11 +50,12 @@ namespace Ryujinx.HLE.Debugger
DebuggerThread.Start();
MessageHandlerThread = new Thread(MessageHandlerMain);
MessageHandlerThread.Start();
BreakpointManager = new BreakpointManager(this);
}
private IDebuggableProcess DebugProcess => Device.System?.DebugGetApplicationProcess();
internal IDebuggableProcess DebugProcess => Device.System?.DebugGetApplicationProcess();
private KThread[] GetThreads() => DebugProcess.GetThreadUids().Select(x => DebugProcess.GetThread(x)).ToArray();
private bool IsProcessAarch32 => DebugProcess.GetThread(gThread.Value).Context.IsAarch32;
internal bool IsProcessAarch32 => DebugProcess.GetThread(gThread.Value).Context.IsAarch32;
private KernelContext KernelContext => Device.System.KernelContext;
const int GdbRegisterCount64 = 68;
@ -514,6 +517,75 @@ namespace Ryujinx.HLE.Debugger
break;
}
goto unknownCommand;
case 'Z':
{
string type = ss.ReadUntil(',');
ulong addr = ss.ReadUntilAsHex(',');
ulong len = ss.ReadLengthAsHex(1);
string extra = ss.ReadRemaining();
if (extra.Length > 0)
{
Logger.Notice.Print(LogClass.GdbStub, $"Unsupported Z command extra data: {extra}");
ReplyError();
return;
}
switch (type)
{
case "0": // Software breakpoint
if (!BreakpointManager.SetBreakPoint(addr, len, false))
{
ReplyError();
}
ReplyOK();
return;
case "1": // Hardware breakpoint
case "2": // Write watchpoint
case "3": // Read watchpoint
case "4": // Access watchpoint
ReplyError();
return;
default:
ReplyError();
return;
}
}
case 'z':
{
string type = ss.ReadUntil(',');
ss.ConsumePrefix(",");
ulong addr = ss.ReadUntilAsHex(',');
ulong len = ss.ReadLengthAsHex(1);
string extra = ss.ReadRemaining();
if (extra.Length > 0)
{
Logger.Notice.Print(LogClass.GdbStub, $"Unsupported z command extra data: {extra}");
ReplyError();
return;
}
switch (type)
{
case "0": // Software breakpoint
if (!BreakpointManager.ClearBreakPoint(addr, len))
{
ReplyError();
}
ReplyOK();
return;
case "1": // Hardware breakpoint
case "2": // Write watchpoint
case "3": // Read watchpoint
case "4": // Access watchpoint
ReplyError();
return;
default:
ReplyError();
return;
}
}
default:
unknownCommand:
Logger.Notice.Print(LogClass.GdbStub, $"Unknown command: {cmd}");
@ -666,7 +738,7 @@ namespace Ryujinx.HLE.Debugger
void CommandDetach()
{
// TODO: Remove all breakpoints
BreakpointManager.ClearAll();
CommandContinue(null);
}
@ -1017,6 +1089,8 @@ namespace Ryujinx.HLE.Debugger
WriteStream = null;
ClientSocket.Close();
ClientSocket = null;
BreakpointManager.ClearAll();
}
}