mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-25 21:27:14 +02:00
Add GDB Stub
Author: merry, svc64
This commit is contained in:
parent
5d136980a3
commit
4a8463c2f7
53 changed files with 2428 additions and 21 deletions
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue