Debugger: Do more stuff
# Conflicts: # src/Ryujinx.HLE/Debugger/Debugger.cs # src/Ryujinx.HLE/Debugger/GdbXml/aarch64-core.xml # src/Ryujinx.HLE/Debugger/GdbXml/aarch64-fpu.xml # src/Ryujinx.HLE/Debugger/GdbXml/target.xml # src/Ryujinx.HLE/Debugger/RegisterInformation.cs
This commit is contained in:
parent
1bb8f6381c
commit
a1de4f1b5b
7 changed files with 470 additions and 47 deletions
|
@ -3,7 +3,6 @@ using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
@ -70,31 +69,31 @@ namespace Ryujinx.HLE.Debugger
|
||||||
switch (gdbRegId)
|
switch (gdbRegId)
|
||||||
{
|
{
|
||||||
case >= 0 and <= 31:
|
case >= 0 and <= 31:
|
||||||
return $"{state.GetX(gdbRegId):x16}";
|
return ToHex(BitConverter.GetBytes(state.GetX(gdbRegId)));
|
||||||
case 32:
|
case 32:
|
||||||
return $"{state.DebugPc:x16}";
|
return ToHex(BitConverter.GetBytes(state.DebugPc));
|
||||||
case 33:
|
case 33:
|
||||||
return $"{state.Pstate:x8}";
|
return ToHex(BitConverter.GetBytes(state.Pstate));
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException();
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GdbWriteRegister(Ryujinx.Cpu.IExecutionContext state, int gdbRegId, ulong value)
|
private bool GdbWriteRegister(Ryujinx.Cpu.IExecutionContext state, int gdbRegId, ulong value)
|
||||||
{
|
{
|
||||||
switch (gdbRegId)
|
switch (gdbRegId)
|
||||||
{
|
{
|
||||||
case >= 0 and <= 31:
|
case >= 0 and <= 31:
|
||||||
state.SetX(gdbRegId, value);
|
state.SetX(gdbRegId, value);
|
||||||
return;
|
return true;
|
||||||
case 32:
|
case 32:
|
||||||
state.DebugPc = value;
|
state.DebugPc = value;
|
||||||
return;
|
return true;
|
||||||
case 33:
|
case 33:
|
||||||
state.Pstate = (uint)value;
|
state.Pstate = (uint)value;
|
||||||
return;
|
return true;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException();
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +136,7 @@ namespace Ryujinx.HLE.Debugger
|
||||||
goto unknownCommand;
|
goto unknownCommand;
|
||||||
}
|
}
|
||||||
// Enable extended mode
|
// Enable extended mode
|
||||||
Reply("OK");
|
ReplyOK();
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
if (!ss.IsEmpty())
|
if (!ss.IsEmpty())
|
||||||
|
@ -205,29 +204,74 @@ namespace Ryujinx.HLE.Debugger
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'q':
|
case 'q':
|
||||||
switch (ss.ReadUntil(':'))
|
if (ss.ConsumeRemaining("GDBServerVersion"))
|
||||||
{
|
{
|
||||||
case "GDBServerVersion":
|
Reply($"name:Ryujinx;version:{ReleaseInformation.GetVersion()};");
|
||||||
Reply($"name:Ryujinx;version:{ReleaseInformations.GetVersion()};");
|
|
||||||
break;
|
break;
|
||||||
case "HostInfo":
|
}
|
||||||
Reply($"triple:{ToHex("aarch64-none-elf")};endian:little;ptrsize:8;hostname:{ToHex("Ryujinx")};");
|
if (ss.ConsumeRemaining("HostInfo"))
|
||||||
|
{
|
||||||
|
Reply($"triple:{ToHex("aarch64-unknown-linux-android")};endian:little;ptrsize:8;hostname:{ToHex("Ryujinx")};");
|
||||||
break;
|
break;
|
||||||
case "ProcessInfo":
|
}
|
||||||
Reply("pid:1;cputype:100000c;cpusubtype:0;ostype:unknown;vendor:none;endian:little;ptrsize:8;");
|
if (ss.ConsumeRemaining("ProcessInfo"))
|
||||||
|
{
|
||||||
|
Reply($"pid:1;cputype:100000c;cpusubtype:0;triple:{ToHex("aarch64-unknown-linux-android")};ostype:unknown;vendor:none;endian:little;ptrsize:8;");
|
||||||
break;
|
break;
|
||||||
case "fThreadInfo":
|
}
|
||||||
|
if (ss.ConsumePrefix("Supported:") || ss.ConsumeRemaining("Supported"))
|
||||||
|
{
|
||||||
|
Reply("PacketSize=10000,qXfer:features:read+");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ss.ConsumeRemaining("fThreadInfo"))
|
||||||
|
{
|
||||||
Reply($"m{string.Join(",", GetThreadIds().Select(x => $"{x:x}"))}");
|
Reply($"m{string.Join(",", GetThreadIds().Select(x => $"{x:x}"))}");
|
||||||
break;
|
break;
|
||||||
case "sThreadInfo":
|
}
|
||||||
|
if (ss.ConsumeRemaining("sThreadInfo"))
|
||||||
|
{
|
||||||
Reply("l");
|
Reply("l");
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
goto unknownCommand;
|
|
||||||
}
|
}
|
||||||
|
if (ss.ConsumePrefix("Xfer:features:read:"))
|
||||||
|
{
|
||||||
|
string feature = ss.ReadUntil(':');
|
||||||
|
ulong addr = ss.ReadUntilAsHex(',');
|
||||||
|
ulong len = ss.ReadRemainingAsHex();
|
||||||
|
|
||||||
|
string data;
|
||||||
|
if (RegisterInformation.Features.TryGetValue(feature, out data))
|
||||||
|
{
|
||||||
|
if (addr >= (ulong)data.Length)
|
||||||
|
{
|
||||||
|
Reply("l");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len >= (ulong)data.Length - addr)
|
||||||
|
{
|
||||||
|
Reply("l" + data.Substring((int)addr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Reply("m" + data.Substring((int)addr, (int)len));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Reply("E00"); // Invalid annex
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto unknownCommand;
|
||||||
|
case 'Q':
|
||||||
|
goto unknownCommand;
|
||||||
default:
|
default:
|
||||||
Logger.Notice.Print(LogClass.GdbStub, $"Unknown command: {cmd}");
|
unknownCommand:
|
||||||
|
// Logger.Notice.Print(LogClass.GdbStub, $"Unknown command: {cmd}");
|
||||||
Reply("");
|
Reply("");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -276,9 +320,16 @@ namespace Ryujinx.HLE.Debugger
|
||||||
var ctx = GetThread(gThread);
|
var ctx = GetThread(gThread);
|
||||||
for (int i = 0; i < GdbRegisterCount; i++)
|
for (int i = 0; i < GdbRegisterCount; i++)
|
||||||
{
|
{
|
||||||
GdbWriteRegister(ctx, i, ss.ReadLengthAsHex(GdbRegisterHexSize(i)));
|
GdbWriteRegister(ctx, i, ss.ReadLengthAsLEHex(GdbRegisterHexSize(i)));
|
||||||
|
}
|
||||||
|
if (ss.IsEmpty())
|
||||||
|
{
|
||||||
|
ReplyOK();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReplyError();
|
||||||
}
|
}
|
||||||
Reply(ss.IsEmpty() ? "OK" : "E99");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandSetThread(char op, ulong threadId)
|
void CommandSetThread(char op, ulong threadId)
|
||||||
|
@ -287,26 +338,35 @@ namespace Ryujinx.HLE.Debugger
|
||||||
{
|
{
|
||||||
case 'c':
|
case 'c':
|
||||||
cThread = threadId;
|
cThread = threadId;
|
||||||
Reply("OK");
|
ReplyOK();
|
||||||
return;
|
return;
|
||||||
case 'g':
|
case 'g':
|
||||||
gThread = threadId;
|
gThread = threadId;
|
||||||
Reply("OK");
|
ReplyOK();
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
Reply("E99");
|
ReplyError();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandReadMemory(ulong addr, ulong len)
|
void CommandReadMemory(ulong addr, ulong len)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var data = new byte[len];
|
var data = new byte[len];
|
||||||
GetMemory().Read(addr, data);
|
GetMemory().Read(addr, data);
|
||||||
Reply(ToHex(data));
|
Reply(ToHex(data));
|
||||||
}
|
}
|
||||||
|
catch (InvalidMemoryRegionException)
|
||||||
|
{
|
||||||
|
ReplyError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CommandWriteMemory(ulong addr, ulong len, StringStream ss)
|
void CommandWriteMemory(ulong addr, ulong len, StringStream ss)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var data = new byte[len];
|
var data = new byte[len];
|
||||||
for (ulong i = 0; i < len; i++)
|
for (ulong i = 0; i < len; i++)
|
||||||
|
@ -314,26 +374,57 @@ namespace Ryujinx.HLE.Debugger
|
||||||
data[i] = (byte)ss.ReadLengthAsHex(2);
|
data[i] = (byte)ss.ReadLengthAsHex(2);
|
||||||
}
|
}
|
||||||
GetMemory().Write(addr, data);
|
GetMemory().Write(addr, data);
|
||||||
|
ReplyOK();
|
||||||
|
}
|
||||||
|
catch (InvalidMemoryRegionException)
|
||||||
|
{
|
||||||
|
ReplyError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandReadGeneralRegister(int gdbRegId)
|
void CommandReadGeneralRegister(int gdbRegId)
|
||||||
{
|
{
|
||||||
var ctx = GetThread(gThread);
|
var ctx = GetThread(gThread);
|
||||||
Reply(GdbReadRegister(ctx, gdbRegId));
|
string result = GdbReadRegister(ctx, gdbRegId);
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
Reply(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReplyError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandWriteGeneralRegister(int gdbRegId, ulong value)
|
void CommandWriteGeneralRegister(int gdbRegId, ulong value)
|
||||||
{
|
{
|
||||||
var ctx = GetThread(gThread);
|
var ctx = GetThread(gThread);
|
||||||
GdbWriteRegister(ctx, gdbRegId, value);
|
if (GdbWriteRegister(ctx, gdbRegId, value))
|
||||||
Reply("OK");
|
{
|
||||||
|
ReplyOK();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReplyError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Reply(string cmd)
|
private void Reply(string cmd)
|
||||||
{
|
{
|
||||||
|
Logger.Notice.Print(LogClass.GdbStub, $"Reply: {cmd}");
|
||||||
WriteStream.Write(Encoding.ASCII.GetBytes($"${cmd}#{CalculateChecksum(cmd):x2}"));
|
WriteStream.Write(Encoding.ASCII.GetBytes($"${cmd}#{CalculateChecksum(cmd):x2}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ReplyOK()
|
||||||
|
{
|
||||||
|
Reply("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReplyError()
|
||||||
|
{
|
||||||
|
Reply("E01");
|
||||||
|
}
|
||||||
|
|
||||||
private void SocketReaderThreadMain()
|
private void SocketReaderThreadMain()
|
||||||
{
|
{
|
||||||
restartListen:
|
restartListen:
|
||||||
|
@ -345,6 +436,7 @@ namespace Ryujinx.HLE.Debugger
|
||||||
Logger.Notice.Print(LogClass.GdbStub, $"Currently waiting on {endpoint} for GDB client");
|
Logger.Notice.Print(LogClass.GdbStub, $"Currently waiting on {endpoint} for GDB client");
|
||||||
|
|
||||||
ClientSocket = ListenerSocket.AcceptSocket();
|
ClientSocket = ListenerSocket.AcceptSocket();
|
||||||
|
ClientSocket.NoDelay = true;
|
||||||
ReadStream = new NetworkStream(ClientSocket, System.IO.FileAccess.Read);
|
ReadStream = new NetworkStream(ClientSocket, System.IO.FileAccess.Read);
|
||||||
WriteStream = new NetworkStream(ClientSocket, System.IO.FileAccess.Write);
|
WriteStream = new NetworkStream(ClientSocket, System.IO.FileAccess.Write);
|
||||||
Logger.Notice.Print(LogClass.GdbStub, "GDB client connected");
|
Logger.Notice.Print(LogClass.GdbStub, "GDB client connected");
|
||||||
|
|
93
src/Ryujinx.HLE/Debugger/GdbXml/aarch64-core.xml
Normal file
93
src/Ryujinx.HLE/Debugger/GdbXml/aarch64-core.xml
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Copyright (C) 2009-2022 Free Software Foundation, Inc.
|
||||||
|
Contributed by ARM Ltd.
|
||||||
|
Copying and distribution of this file, with or without modification,
|
||||||
|
are permitted in any medium without royalty provided the copyright
|
||||||
|
notice and this notice are preserved. -->
|
||||||
|
|
||||||
|
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||||
|
<feature name="org.gnu.gdb.aarch64.core">
|
||||||
|
<reg name="x0" bitsize="64"/>
|
||||||
|
<reg name="x1" bitsize="64"/>
|
||||||
|
<reg name="x2" bitsize="64"/>
|
||||||
|
<reg name="x3" bitsize="64"/>
|
||||||
|
<reg name="x4" bitsize="64"/>
|
||||||
|
<reg name="x5" bitsize="64"/>
|
||||||
|
<reg name="x6" bitsize="64"/>
|
||||||
|
<reg name="x7" bitsize="64"/>
|
||||||
|
<reg name="x8" bitsize="64"/>
|
||||||
|
<reg name="x9" bitsize="64"/>
|
||||||
|
<reg name="x10" bitsize="64"/>
|
||||||
|
<reg name="x11" bitsize="64"/>
|
||||||
|
<reg name="x12" bitsize="64"/>
|
||||||
|
<reg name="x13" bitsize="64"/>
|
||||||
|
<reg name="x14" bitsize="64"/>
|
||||||
|
<reg name="x15" bitsize="64"/>
|
||||||
|
<reg name="x16" bitsize="64"/>
|
||||||
|
<reg name="x17" bitsize="64"/>
|
||||||
|
<reg name="x18" bitsize="64"/>
|
||||||
|
<reg name="x19" bitsize="64"/>
|
||||||
|
<reg name="x20" bitsize="64"/>
|
||||||
|
<reg name="x21" bitsize="64"/>
|
||||||
|
<reg name="x22" bitsize="64"/>
|
||||||
|
<reg name="x23" bitsize="64"/>
|
||||||
|
<reg name="x24" bitsize="64"/>
|
||||||
|
<reg name="x25" bitsize="64"/>
|
||||||
|
<reg name="x26" bitsize="64"/>
|
||||||
|
<reg name="x27" bitsize="64"/>
|
||||||
|
<reg name="x28" bitsize="64"/>
|
||||||
|
<reg name="x29" bitsize="64"/>
|
||||||
|
<reg name="x30" bitsize="64"/>
|
||||||
|
<reg name="sp" bitsize="64" type="data_ptr"/>
|
||||||
|
|
||||||
|
<reg name="pc" bitsize="64" type="code_ptr"/>
|
||||||
|
|
||||||
|
<flags id="cpsr_flags" size="4">
|
||||||
|
<!-- Stack Pointer. -->
|
||||||
|
<field name="SP" start="0" end="0"/>
|
||||||
|
|
||||||
|
<!-- Exception Level. -->
|
||||||
|
<field name="EL" start="2" end="3"/>
|
||||||
|
<!-- Execution state. -->
|
||||||
|
<field name="nRW" start="4" end="4"/>
|
||||||
|
|
||||||
|
<!-- FIQ interrupt mask. -->
|
||||||
|
<field name="F" start="6" end="6"/>
|
||||||
|
<!-- IRQ interrupt mask. -->
|
||||||
|
<field name="I" start="7" end="7"/>
|
||||||
|
<!-- SError interrupt mask. -->
|
||||||
|
<field name="A" start="8" end="8"/>
|
||||||
|
<!-- Debug exception mask. -->
|
||||||
|
<field name="D" start="9" end="9"/>
|
||||||
|
|
||||||
|
<!-- ARMv8.5-A: Branch Target Identification BTYPE. -->
|
||||||
|
<field name="BTYPE" start="10" end="11"/>
|
||||||
|
|
||||||
|
<!-- ARMv8.0-A: Speculative Store Bypass. -->
|
||||||
|
<field name="SSBS" start="12" end="12"/>
|
||||||
|
|
||||||
|
<!-- Illegal Execution state. -->
|
||||||
|
<field name="IL" start="20" end="20"/>
|
||||||
|
<!-- Software Step. -->
|
||||||
|
<field name="SS" start="21" end="21"/>
|
||||||
|
<!-- ARMv8.1-A: Privileged Access Never. -->
|
||||||
|
<field name="PAN" start="22" end="22"/>
|
||||||
|
<!-- ARMv8.2-A: User Access Override. -->
|
||||||
|
<field name="UAO" start="23" end="23"/>
|
||||||
|
<!-- ARMv8.4-A: Data Independent Timing. -->
|
||||||
|
<field name="DIT" start="24" end="24"/>
|
||||||
|
<!-- ARMv8.5-A: Tag Check Override. -->
|
||||||
|
<field name="TCO" start="25" end="25"/>
|
||||||
|
|
||||||
|
<!-- Overflow Condition flag. -->
|
||||||
|
<field name="V" start="28" end="28"/>
|
||||||
|
<!-- Carry Condition flag. -->
|
||||||
|
<field name="C" start="29" end="29"/>
|
||||||
|
<!-- Zero Condition flag. -->
|
||||||
|
<field name="Z" start="30" end="30"/>
|
||||||
|
<!-- Negative Condition flag. -->
|
||||||
|
<field name="N" start="31" end="31"/>
|
||||||
|
</flags>
|
||||||
|
<reg name="cpsr" bitsize="32" type="cpsr_flags"/>
|
||||||
|
|
||||||
|
</feature>
|
159
src/Ryujinx.HLE/Debugger/GdbXml/aarch64-fpu.xml
Normal file
159
src/Ryujinx.HLE/Debugger/GdbXml/aarch64-fpu.xml
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Copyright (C) 2009-2022 Free Software Foundation, Inc.
|
||||||
|
Contributed by ARM Ltd.
|
||||||
|
Copying and distribution of this file, with or without modification,
|
||||||
|
are permitted in any medium without royalty provided the copyright
|
||||||
|
notice and this notice are preserved. -->
|
||||||
|
|
||||||
|
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||||
|
<feature name="org.gnu.gdb.aarch64.fpu">
|
||||||
|
<vector id="v2d" type="ieee_double" count="2"/>
|
||||||
|
<vector id="v2u" type="uint64" count="2"/>
|
||||||
|
<vector id="v2i" type="int64" count="2"/>
|
||||||
|
<vector id="v4f" type="ieee_single" count="4"/>
|
||||||
|
<vector id="v4u" type="uint32" count="4"/>
|
||||||
|
<vector id="v4i" type="int32" count="4"/>
|
||||||
|
<vector id="v8f" type="ieee_half" count="8"/>
|
||||||
|
<vector id="v8u" type="uint16" count="8"/>
|
||||||
|
<vector id="v8i" type="int16" count="8"/>
|
||||||
|
<vector id="v8bf16" type="bfloat16" count="8"/>
|
||||||
|
<vector id="v16u" type="uint8" count="16"/>
|
||||||
|
<vector id="v16i" type="int8" count="16"/>
|
||||||
|
<vector id="v1u" type="uint128" count="1"/>
|
||||||
|
<vector id="v1i" type="int128" count="1"/>
|
||||||
|
<union id="vnd">
|
||||||
|
<field name="f" type="v2d"/>
|
||||||
|
<field name="u" type="v2u"/>
|
||||||
|
<field name="s" type="v2i"/>
|
||||||
|
</union>
|
||||||
|
<union id="vns">
|
||||||
|
<field name="f" type="v4f"/>
|
||||||
|
<field name="u" type="v4u"/>
|
||||||
|
<field name="s" type="v4i"/>
|
||||||
|
</union>
|
||||||
|
<union id="vnh">
|
||||||
|
<field name="bf" type="v8bf16"/>
|
||||||
|
<field name="f" type="v8f"/>
|
||||||
|
<field name="u" type="v8u"/>
|
||||||
|
<field name="s" type="v8i"/>
|
||||||
|
</union>
|
||||||
|
<union id="vnb">
|
||||||
|
<field name="u" type="v16u"/>
|
||||||
|
<field name="s" type="v16i"/>
|
||||||
|
</union>
|
||||||
|
<union id="vnq">
|
||||||
|
<field name="u" type="v1u"/>
|
||||||
|
<field name="s" type="v1i"/>
|
||||||
|
</union>
|
||||||
|
<union id="aarch64v">
|
||||||
|
<field name="d" type="vnd"/>
|
||||||
|
<field name="s" type="vns"/>
|
||||||
|
<field name="h" type="vnh"/>
|
||||||
|
<field name="b" type="vnb"/>
|
||||||
|
<field name="q" type="vnq"/>
|
||||||
|
</union>
|
||||||
|
<reg name="v0" bitsize="128" type="aarch64v" regnum="34"/>
|
||||||
|
<reg name="v1" bitsize="128" type="aarch64v" />
|
||||||
|
<reg name="v2" bitsize="128" type="aarch64v" />
|
||||||
|
<reg name="v3" bitsize="128" type="aarch64v" />
|
||||||
|
<reg name="v4" bitsize="128" type="aarch64v" />
|
||||||
|
<reg name="v5" bitsize="128" type="aarch64v" />
|
||||||
|
<reg name="v6" bitsize="128" type="aarch64v" />
|
||||||
|
<reg name="v7" bitsize="128" type="aarch64v" />
|
||||||
|
<reg name="v8" bitsize="128" type="aarch64v" />
|
||||||
|
<reg name="v9" bitsize="128" type="aarch64v" />
|
||||||
|
<reg name="v10" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v11" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v12" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v13" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v14" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v15" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v16" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v17" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v18" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v19" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v20" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v21" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v22" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v23" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v24" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v25" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v26" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v27" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v28" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v29" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v30" bitsize="128" type="aarch64v"/>
|
||||||
|
<reg name="v31" bitsize="128" type="aarch64v"/>
|
||||||
|
|
||||||
|
<flags id="fpsr_flags" size="4">
|
||||||
|
<!-- Invalid Operation cumulative floating-point exception bit. -->
|
||||||
|
<field name="IOC" start="0" end="0"/>
|
||||||
|
<!-- Divide by Zero cumulative floating-point exception bit. -->
|
||||||
|
<field name="DZC" start="1" end="1"/>
|
||||||
|
<!-- Overflow cumulative floating-point exception bit. -->
|
||||||
|
<field name="OFC" start="2" end="2"/>
|
||||||
|
<!-- Underflow cumulative floating-point exception bit. -->
|
||||||
|
<field name="UFC" start="3" end="3"/>
|
||||||
|
<!-- Inexact cumulative floating-point exception bit.. -->
|
||||||
|
<field name="IXC" start="4" end="4"/>
|
||||||
|
<!-- Input Denormal cumulative floating-point exception bit. -->
|
||||||
|
<field name="IDC" start="7" end="7"/>
|
||||||
|
<!-- Cumulative saturation bit, Advanced SIMD only. -->
|
||||||
|
<field name="QC" start="27" end="27"/>
|
||||||
|
<!-- When AArch32 is supported at any Exception level and AArch32
|
||||||
|
floating-point is implemented: Overflow condition flag for AArch32
|
||||||
|
floating-point comparison operations. -->
|
||||||
|
<field name="V" start="28" end="28"/>
|
||||||
|
<!-- When AArch32 is supported at any Exception level and AArch32
|
||||||
|
floating-point is implemented:
|
||||||
|
Carry condition flag for AArch32 floating-point comparison operations.
|
||||||
|
-->
|
||||||
|
<field name="C" start="29" end="29"/>
|
||||||
|
<!-- When AArch32 is supported at any Exception level and AArch32
|
||||||
|
floating-point is implemented:
|
||||||
|
Zero condition flag for AArch32 floating-point comparison operations.
|
||||||
|
-->
|
||||||
|
<field name="Z" start="30" end="30"/>
|
||||||
|
<!-- When AArch32 is supported at any Exception level and AArch32
|
||||||
|
floating-point is implemented:
|
||||||
|
Negative condition flag for AArch32 floating-point comparison
|
||||||
|
operations. -->
|
||||||
|
<field name="N" start="31" end="31"/>
|
||||||
|
</flags>
|
||||||
|
<reg name="fpsr" bitsize="32" type="fpsr_flags"/>
|
||||||
|
|
||||||
|
<flags id="fpcr_flags" size="4">
|
||||||
|
<!-- Flush Inputs to Zero (part of Armv8.7). -->
|
||||||
|
<field name="FIZ" start="0" end="0"/>
|
||||||
|
<!-- Alternate Handling (part of Armv8.7). -->
|
||||||
|
<field name="AH" start="1" end="1"/>
|
||||||
|
<!-- Controls how the output elements other than the lowest element of the
|
||||||
|
vector are determined for Advanced SIMD scalar instructions (part of
|
||||||
|
Armv8.7). -->
|
||||||
|
<field name="NEP" start="2" end="2"/>
|
||||||
|
<!-- Invalid Operation floating-point exception trap enable. -->
|
||||||
|
<field name="IOE" start="8" end="8"/>
|
||||||
|
<!-- Divide by Zero floating-point exception trap enable. -->
|
||||||
|
<field name="DZE" start="9" end="9"/>
|
||||||
|
<!-- Overflow floating-point exception trap enable. -->
|
||||||
|
<field name="OFE" start="10" end="10"/>
|
||||||
|
<!-- Underflow floating-point exception trap enable. -->
|
||||||
|
<field name="UFE" start="11" end="11"/>
|
||||||
|
<!-- Inexact floating-point exception trap enable. -->
|
||||||
|
<field name="IXE" start="12" end="12"/>
|
||||||
|
<!-- Input Denormal floating-point exception trap enable. -->
|
||||||
|
<field name="IDE" start="15" end="15"/>
|
||||||
|
<!-- Flush-to-zero mode control bit on half-precision data-processing
|
||||||
|
instructions. -->
|
||||||
|
<field name="FZ16" start="19" end="19"/>
|
||||||
|
<!-- Rounding Mode control field. -->
|
||||||
|
<field name="RMode" start="22" end="23"/>
|
||||||
|
<!-- Flush-to-zero mode control bit. -->
|
||||||
|
<field name="FZ" start="24" end="24"/>
|
||||||
|
<!-- Default NaN mode control bit. -->
|
||||||
|
<field name="DN" start="25" end="25"/>
|
||||||
|
<!-- Alternative half-precision control bit. -->
|
||||||
|
<field name="AHP" start="26" end="26"/>
|
||||||
|
</flags>
|
||||||
|
<reg name="fpcr" bitsize="32" type="fpcr_flags"/>
|
||||||
|
</feature>
|
14
src/Ryujinx.HLE/Debugger/GdbXml/target.xml
Normal file
14
src/Ryujinx.HLE/Debugger/GdbXml/target.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by ARM Ltd.
|
||||||
|
|
||||||
|
Copying and distribution of this file, with or without modification,
|
||||||
|
are permitted in any medium without royalty provided the copyright
|
||||||
|
notice and this notice are preserved. -->
|
||||||
|
|
||||||
|
<!DOCTYPE target SYSTEM "gdb-target.dtd">
|
||||||
|
<target>
|
||||||
|
<architecture>aarch64</architecture>
|
||||||
|
<xi:include href="aarch64-core.xml"/>
|
||||||
|
<xi:include href="aarch64-fpu.xml"/>
|
||||||
|
</target>
|
25
src/Ryujinx.HLE/Debugger/RegisterInformation.cs
Normal file
25
src/Ryujinx.HLE/Debugger/RegisterInformation.cs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.Debugger
|
||||||
|
{
|
||||||
|
class RegisterInformation
|
||||||
|
{
|
||||||
|
public static readonly Dictionary<string, string> Features = new()
|
||||||
|
{
|
||||||
|
{ "target.xml", GetEmbeddedResourceContent("target.xml") },
|
||||||
|
{ "aarch64-core.xml", GetEmbeddedResourceContent("aarch64-core.xml") },
|
||||||
|
{ "aarch64-fpu.xml", GetEmbeddedResourceContent("aarch64-fpu.xml") },
|
||||||
|
};
|
||||||
|
|
||||||
|
private static string GetEmbeddedResourceContent(string resourceName)
|
||||||
|
{
|
||||||
|
Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Ryujinx.HLE.Debugger.GdbXml." + resourceName);
|
||||||
|
StreamReader reader = new StreamReader(stream);
|
||||||
|
string result = reader.ReadToEnd();
|
||||||
|
reader.Dispose();
|
||||||
|
stream.Dispose();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Globalization;
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Debugger
|
namespace Ryujinx.HLE.Debugger
|
||||||
{
|
{
|
||||||
|
@ -60,6 +61,39 @@ namespace Ryujinx.HLE.Debugger
|
||||||
return ulong.Parse(ReadLength(len), NumberStyles.HexNumber);
|
return ulong.Parse(ReadLength(len), NumberStyles.HexNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ulong ReadLengthAsLEHex(int len)
|
||||||
|
{
|
||||||
|
Debug.Assert(len % 2 == 0);
|
||||||
|
|
||||||
|
ulong result = 0;
|
||||||
|
int pos = 0;
|
||||||
|
while (pos < len)
|
||||||
|
{
|
||||||
|
result += ReadLengthAsHex(2) << (4 * pos);
|
||||||
|
pos += 2;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public bool ConsumePrefix(string prefix)
|
||||||
|
{
|
||||||
|
if (Data.Substring(Position).StartsWith(prefix))
|
||||||
|
{
|
||||||
|
Position += prefix.Length;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ConsumeRemaining(string match)
|
||||||
|
{
|
||||||
|
if (Data.Substring(Position) == match)
|
||||||
|
{
|
||||||
|
Position += match.Length;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsEmpty()
|
public bool IsEmpty()
|
||||||
{
|
{
|
||||||
return Position >= Data.Length;
|
return Position >= Data.Length;
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Remove="Debugger\GdbXml\aarch64-core.xml" />
|
||||||
|
<None Remove="Debugger\GdbXml\aarch64-fpu.xml" />
|
||||||
|
<None Remove="Debugger\GdbXml\target.xml" />
|
||||||
<None Remove="Homebrew.npdm" />
|
<None Remove="Homebrew.npdm" />
|
||||||
<None Remove="HOS\Applets\SoftwareKeyboard\Resources\Logo_Ryujinx.png" />
|
<None Remove="HOS\Applets\SoftwareKeyboard\Resources\Logo_Ryujinx.png" />
|
||||||
<None Remove="HOS\Applets\SoftwareKeyboard\Resources\Icon_BtnA.png" />
|
<None Remove="HOS\Applets\SoftwareKeyboard\Resources\Icon_BtnA.png" />
|
||||||
|
@ -39,6 +42,9 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Debugger\GdbXml\aarch64-core.xml" />
|
||||||
|
<EmbeddedResource Include="Debugger\GdbXml\aarch64-fpu.xml" />
|
||||||
|
<EmbeddedResource Include="Debugger\GdbXml\target.xml" />
|
||||||
<EmbeddedResource Include="Homebrew.npdm" />
|
<EmbeddedResource Include="Homebrew.npdm" />
|
||||||
<EmbeddedResource Include="HOS\Applets\SoftwareKeyboard\Resources\Logo_Ryujinx.png" />
|
<EmbeddedResource Include="HOS\Applets\SoftwareKeyboard\Resources\Logo_Ryujinx.png" />
|
||||||
<EmbeddedResource Include="HOS\Applets\SoftwareKeyboard\Resources\Icon_BtnA.png" />
|
<EmbeddedResource Include="HOS\Applets\SoftwareKeyboard\Resources\Icon_BtnA.png" />
|
||||||
|
|
Loading…
Reference in a new issue