From 838296ccb63bb76b1d2d672f0794bab8e5678cd7 Mon Sep 17 00:00:00 2001
From: Coxxs <58-coxxs@users.noreply.git.ryujinx.app>
Date: Mon, 23 Jun 2025 07:00:48 +0800
Subject: [PATCH] gdb: Support precise tracking of PC value when GDB Stub is
enabled
---
src/ARMeilleure/State/ExecutionContext.cs | 10 ++++++++++
src/ARMeilleure/State/NativeContext.cs | 15 +++++++++++++++
src/ARMeilleure/Translation/Translator.cs | 18 ++++++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/src/ARMeilleure/State/ExecutionContext.cs b/src/ARMeilleure/State/ExecutionContext.cs
index cdf6f56c5..fa1a4a032 100644
--- a/src/ARMeilleure/State/ExecutionContext.cs
+++ b/src/ARMeilleure/State/ExecutionContext.cs
@@ -164,11 +164,21 @@ namespace ARMeilleure.State
internal void OnBreak(ulong address, int imm)
{
+ if (Optimizations.EnableDebugging)
+ {
+ DebugPc = Pc;
+ }
+
_breakCallback?.Invoke(this, address, imm);
}
internal void OnSupervisorCall(ulong address, int imm)
{
+ if (Optimizations.EnableDebugging)
+ {
+ DebugPc = Pc;
+ }
+
_supervisorCallback?.Invoke(this, address, imm);
}
diff --git a/src/ARMeilleure/State/NativeContext.cs b/src/ARMeilleure/State/NativeContext.cs
index c90e522a9..25b5e51c3 100644
--- a/src/ARMeilleure/State/NativeContext.cs
+++ b/src/ARMeilleure/State/NativeContext.cs
@@ -22,6 +22,11 @@ namespace ARMeilleure.State
public ulong ExclusiveValueHigh;
public int Running;
public long Tpidr2El0;
+
+ ///
+ /// This is only set when Optimizations.EnableDebugging is true.
+ ///
+ public ulong CurrentPc;
}
private static NativeCtxStorage _dummyStorage = new();
@@ -39,6 +44,11 @@ namespace ARMeilleure.State
public ulong GetPc()
{
+ if (Optimizations.EnableDebugging)
+ {
+ return GetStorage().CurrentPc;
+ }
+
// TODO: More precise tracking of PC value.
return GetStorage().DispatchAddress;
}
@@ -268,6 +278,11 @@ namespace ARMeilleure.State
return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running);
}
+ public static int GetCurrentPcOffset()
+ {
+ return StorageOffset(ref _dummyStorage, ref _dummyStorage.CurrentPc);
+ }
+
private static int StorageOffset(ref NativeCtxStorage storage, ref T target)
{
return (int)Unsafe.ByteOffset(ref Unsafe.As(ref storage), ref target);
diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs
index 343e361a5..351ee34f1 100644
--- a/src/ARMeilleure/Translation/Translator.cs
+++ b/src/ARMeilleure/Translation/Translator.cs
@@ -388,6 +388,11 @@ namespace ARMeilleure.Translation
// Return to managed rather than tail call.
bool useReturns = Optimizations.EnableDebugging;
+ if (Optimizations.EnableDebugging)
+ {
+ EmitPcUpdate(context, block.Address);
+ }
+
InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns);
}
else
@@ -410,6 +415,11 @@ namespace ARMeilleure.Translation
}
}
+ if (Optimizations.EnableDebugging)
+ {
+ EmitPcUpdate(context, opCode.Address);
+ }
+
Operand lblPredicateSkip = default;
if (context.IsInIfThenBlock && context.CurrentIfThenBlockCond != Condition.Al)
@@ -506,6 +516,14 @@ namespace ARMeilleure.Translation
context.MarkLabel(lblExit);
}
+ internal static void EmitPcUpdate(EmitterContext context, ulong address)
+ {
+ long currentPcOffs = NativeContext.GetCurrentPcOffset();
+
+ Operand currentPcAddr = context.Add(context.LoadArgument(OperandType.I64, 0), Const(currentPcOffs));
+ context.Store(currentPcAddr, Const(address));
+ }
+
public void InvalidateJitCacheRegion(ulong address, ulong size)
{
ulong[] overlapAddresses = [];