Add GDB Stub

Author: merry, svc64
This commit is contained in:
Coxxs 2025-06-20 16:14:12 +08:00
parent 5d136980a3
commit 4a8463c2f7
53 changed files with 2428 additions and 21 deletions

View file

@ -3,6 +3,8 @@ using ARMeilleure.State;
using ARMeilleure.Translation;
using System;
using System.Runtime.InteropServices;
using System.Threading;
using ExecutionContext = ARMeilleure.State.ExecutionContext;
namespace ARMeilleure.Instructions
{
@ -200,7 +202,11 @@ namespace ARMeilleure.Instructions
ExecutionContext context = GetContext();
context.CheckInterrupt();
// If debugging, we'll handle interrupts outside
if (!Optimizations.EnableDebugging)
{
context.CheckInterrupt();
}
Statistics.ResumeTimer();

View file

@ -12,6 +12,7 @@ namespace ARMeilleure
public static bool AllowLcqInFunctionTable { get; set; } = true;
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
public static bool EnableDebugging { get; set; } = false;
public static bool UseAdvSimdIfAvailable { get; set; } = true;
public static bool UseArm64AesIfAvailable { get; set; } = true;

View file

@ -1,4 +1,7 @@
using ARMeilleure.Memory;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading;
namespace ARMeilleure.State
{
@ -10,7 +13,7 @@ namespace ARMeilleure.State
internal nint NativeContextPtr => _nativeContext.BasePtr;
private bool _interrupted;
internal bool Interrupted { get; private set; }
private readonly ICounter _counter;
@ -65,6 +68,8 @@ namespace ARMeilleure.State
public bool IsAarch32 { get; set; }
public ulong ThreadUid { get; set; }
internal ExecutionMode ExecutionMode
{
get
@ -90,14 +95,19 @@ namespace ARMeilleure.State
private readonly ExceptionCallbackNoArgs _interruptCallback;
private readonly ExceptionCallback _breakCallback;
private readonly ExceptionCallbackNoArgs _stepCallback;
private readonly ExceptionCallback _supervisorCallback;
private readonly ExceptionCallback _undefinedCallback;
internal int ShouldStep;
public ulong DebugPc { get; set; }
public ExecutionContext(
IJitMemoryAllocator allocator,
ICounter counter,
ExceptionCallbackNoArgs interruptCallback = null,
ExceptionCallback breakCallback = null,
ExceptionCallbackNoArgs stepCallback = null,
ExceptionCallback supervisorCallback = null,
ExceptionCallback undefinedCallback = null)
{
@ -105,6 +115,7 @@ namespace ARMeilleure.State
_counter = counter;
_interruptCallback = interruptCallback;
_breakCallback = breakCallback;
_stepCallback = stepCallback;
_supervisorCallback = supervisorCallback;
_undefinedCallback = undefinedCallback;
@ -127,9 +138,9 @@ namespace ARMeilleure.State
internal void CheckInterrupt()
{
if (_interrupted)
if (Interrupted)
{
_interrupted = false;
Interrupted = false;
_interruptCallback?.Invoke(this);
}
@ -139,7 +150,18 @@ namespace ARMeilleure.State
public void RequestInterrupt()
{
_interrupted = true;
Interrupted = true;
}
public void StepHandler()
{
_stepCallback.Invoke(this);
}
public void RequestDebugStep()
{
Interlocked.Exchange(ref ShouldStep, 1);
RequestInterrupt();
}
internal void OnBreak(ulong address, int imm)

View file

@ -119,7 +119,25 @@ namespace ARMeilleure.Translation
NativeInterface.RegisterThread(context, Memory, this);
if (Optimizations.UseUnmanagedDispatchLoop)
if (Optimizations.EnableDebugging)
{
context.DebugPc = address;
do
{
if (Interlocked.CompareExchange(ref context.ShouldStep, 0, 1) == 1)
{
context.DebugPc = Step(context, context.DebugPc);
context.StepHandler();
}
else
{
context.DebugPc = ExecuteSingle(context, context.DebugPc);
}
context.CheckInterrupt();
}
while (context.Running && context.DebugPc != 0);
}
else if (Optimizations.UseUnmanagedDispatchLoop)
{
Stubs.DispatchLoop(context.NativeContextPtr, address);
}
@ -175,7 +193,7 @@ namespace ARMeilleure.Translation
return nextAddr;
}
public ulong Step(State.ExecutionContext context, ulong address)
private ulong Step(State.ExecutionContext context, ulong address)
{
TranslatedFunction func = Translate(address, context.ExecutionMode, highCq: false, singleStep: true);
@ -228,7 +246,7 @@ namespace ARMeilleure.Translation
Stubs,
address,
highCq,
_ptc.State != PtcState.Disabled,
_ptc.State != PtcState.Disabled && !Optimizations.EnableDebugging,
mode: Aarch32Mode.User);
Logger.StartPass(PassName.Decoding);
@ -367,9 +385,8 @@ namespace ARMeilleure.Translation
if (block.Exit)
{
// Left option here as it may be useful if we need to return to managed rather than tail call in
// future. (eg. for debug)
bool useReturns = false;
// Return to managed rather than tail call.
bool useReturns = Optimizations.EnableDebugging;
InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns);
}