aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChocolArm64/AThread.cs6
-rw-r--r--ChocolArm64/ATranslator.cs82
-rw-r--r--ChocolArm64/Decoder/ADecoder.cs7
-rw-r--r--ChocolArm64/Events/ACpuTraceEventArgs.cs17
-rw-r--r--ChocolArm64/Events/AInstExceptionEventArgs.cs14
-rw-r--r--ChocolArm64/Events/AInstUndefinedEventArgs.cs (renamed from ChocolArm64/State/AInstUndEventArgs.cs)6
-rw-r--r--ChocolArm64/Instruction/AInstEmitCsel.cs5
-rw-r--r--ChocolArm64/State/AInstExceptEventArgs.cs14
-rw-r--r--ChocolArm64/State/AThreadState.cs13
-rw-r--r--ChocolArm64/Translation/AILBarrier.cs7
-rw-r--r--ChocolArm64/Translation/AILBlock.cs27
-rw-r--r--ChocolArm64/Translation/AILEmitterCtx.cs10
-rw-r--r--ChocolArm64/Translation/AILOpCodeLoad.cs6
-rw-r--r--ChocolArm64/Translation/AILOpCodeStore.cs4
-rw-r--r--ChocolArm64/Translation/ALocalAlloc.cs8
-rw-r--r--Ryujinx.Core/Loaders/ElfSym.cs9
-rw-r--r--Ryujinx.Core/Loaders/Executable.cs30
-rw-r--r--Ryujinx.Core/OsHle/Process.cs39
-rw-r--r--Ryujinx.Core/OsHle/Svc/SvcHandler.cs3
-rw-r--r--Ryujinx.Tests/Cpu/CpuTest.cs3
20 files changed, 217 insertions, 93 deletions
diff --git a/ChocolArm64/AThread.cs b/ChocolArm64/AThread.cs
index 5c032289..6e018db6 100644
--- a/ChocolArm64/AThread.cs
+++ b/ChocolArm64/AThread.cs
@@ -28,14 +28,14 @@ namespace ChocolArm64
private object ExecuteLock;
- public AThread(AMemory Memory, ThreadPriority Priority, long EntryPoint)
+ public AThread(ATranslator Translator, AMemory Memory, ThreadPriority Priority, long EntryPoint)
{
+ this.Translator = Translator;
this.Memory = Memory;
this.Priority = Priority;
this.EntryPoint = EntryPoint;
ThreadState = new AThreadState();
- Translator = new ATranslator(this);
ExecuteLock = new object();
}
@@ -55,7 +55,7 @@ namespace ChocolArm64
Work = new Thread(delegate()
{
- Translator.ExecuteSubroutine(EntryPoint);
+ Translator.ExecuteSubroutine(this, EntryPoint);
Memory.RemoveMonitor(ThreadId);
diff --git a/ChocolArm64/ATranslator.cs b/ChocolArm64/ATranslator.cs
index 96bbc89e..2daf7bbc 100644
--- a/ChocolArm64/ATranslator.cs
+++ b/ChocolArm64/ATranslator.cs
@@ -1,47 +1,70 @@
using ChocolArm64.Decoder;
+using ChocolArm64.Events;
using ChocolArm64.Instruction;
+using ChocolArm64.Memory;
using ChocolArm64.Translation;
+using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection.Emit;
namespace ChocolArm64
{
- class ATranslator
+ public class ATranslator
{
- public AThread Thread { get; private set; }
+ private ConcurrentDictionary<long, ATranslatedSub> CachedSubs;
- private Dictionary<long, ATranslatedSub> CachedSubs;
+ private ConcurrentDictionary<long, string> SymbolTable;
+
+ public event EventHandler<ACpuTraceEventArgs> CpuTrace;
+
+ public bool EnableCpuTrace { get; set; }
private bool KeepRunning;
- public ATranslator(AThread Parent)
+ public ATranslator(IReadOnlyDictionary<long, string> SymbolTable = null)
{
- this.Thread = Parent;
+ CachedSubs = new ConcurrentDictionary<long, ATranslatedSub>();
- CachedSubs = new Dictionary<long, ATranslatedSub>();
+ if (SymbolTable != null)
+ {
+ this.SymbolTable = new ConcurrentDictionary<long, string>(SymbolTable);
+ }
+ else
+ {
+ this.SymbolTable = new ConcurrentDictionary<long, string>();
+ }
KeepRunning = true;
}
public void StopExecution() => KeepRunning = false;
- public void ExecuteSubroutine(long Position)
+ public void ExecuteSubroutine(AThread Thread, long Position)
{
do
{
- if (CachedSubs.TryGetValue(Position, out ATranslatedSub Sub) && !Sub.NeedsReJit)
+ if (EnableCpuTrace)
{
- Position = Sub.Execute(Thread.ThreadState, Thread.Memory);
+ if (!SymbolTable.TryGetValue(Position, out string SubName))
+ {
+ SubName = string.Empty;
+ }
+
+ CpuTrace?.Invoke(this, new ACpuTraceEventArgs(Position, SubName));
}
- else
+
+ if (!CachedSubs.TryGetValue(Position, out ATranslatedSub Sub) || Sub.NeedsReJit)
{
- Position = TranslateSubroutine(Position).Execute(Thread.ThreadState, Thread.Memory);
+ Sub = TranslateSubroutine(Thread.Memory, Position);
}
+
+ Position = Sub.Execute(Thread.ThreadState, Thread.Memory);
}
while (Position != 0 && KeepRunning);
}
- public bool TryGetCachedSub(AOpCode OpCode, out ATranslatedSub Sub)
+ internal bool TryGetCachedSub(AOpCode OpCode, out ATranslatedSub Sub)
{
if (OpCode.Emitter != AInstEmit.Bl)
{
@@ -53,24 +76,29 @@ namespace ChocolArm64
return TryGetCachedSub(((AOpCodeBImmAl)OpCode).Imm, out Sub);
}
- public bool TryGetCachedSub(long Position, out ATranslatedSub Sub)
+ internal bool TryGetCachedSub(long Position, out ATranslatedSub Sub)
{
return CachedSubs.TryGetValue(Position, out Sub);
}
- public bool HasCachedSub(long Position)
+ internal bool HasCachedSub(long Position)
{
return CachedSubs.ContainsKey(Position);
}
- private ATranslatedSub TranslateSubroutine(long Position)
+ private ATranslatedSub TranslateSubroutine(AMemory Memory, long Position)
{
- (ABlock[] Graph, ABlock Root) Cfg = ADecoder.DecodeSubroutine(this, Position);
+ (ABlock[] Graph, ABlock Root) Cfg = ADecoder.DecodeSubroutine(this, Memory, Position);
+
+ string SubName = SymbolTable.GetOrAdd(Position, $"Sub{Position:x16}");
+
+ PropagateName(Cfg.Graph, SubName);
AILEmitterCtx Context = new AILEmitterCtx(
this,
Cfg.Graph,
- Cfg.Root);
+ Cfg.Root,
+ SubName);
if (Context.CurrBlock.Position != Position)
{
@@ -95,12 +123,24 @@ namespace ChocolArm64
ATranslatedSub Subroutine = Context.GetSubroutine();
- if (!CachedSubs.TryAdd(Position, Subroutine))
- {
- CachedSubs[Position] = Subroutine;
- }
+ CachedSubs.AddOrUpdate(Position, Subroutine, (Key, OldVal) => Subroutine);
return Subroutine;
}
+
+ private void PropagateName(ABlock[] Graph, string Name)
+ {
+ foreach (ABlock Block in Graph)
+ {
+ AOpCode LastOp = Block.GetLastOp();
+
+ if (LastOp != null &&
+ (LastOp.Emitter == AInstEmit.Bl ||
+ LastOp.Emitter == AInstEmit.Blr))
+ {
+ SymbolTable.TryAdd(LastOp.Position + 4, Name);
+ }
+ }
+ }
}
} \ No newline at end of file
diff --git a/ChocolArm64/Decoder/ADecoder.cs b/ChocolArm64/Decoder/ADecoder.cs
index a3f44e47..44302290 100644
--- a/ChocolArm64/Decoder/ADecoder.cs
+++ b/ChocolArm64/Decoder/ADecoder.cs
@@ -18,7 +18,10 @@ namespace ChocolArm64.Decoder
OpActivators = new ConcurrentDictionary<Type, OpActivator>();
}
- public static (ABlock[] Graph, ABlock Root) DecodeSubroutine(ATranslator Translator, long Start)
+ public static (ABlock[] Graph, ABlock Root) DecodeSubroutine(
+ ATranslator Translator,
+ AMemory Memory,
+ long Start)
{
Dictionary<long, ABlock> Visited = new Dictionary<long, ABlock>();
Dictionary<long, ABlock> VisitedEnd = new Dictionary<long, ABlock>();
@@ -45,7 +48,7 @@ namespace ChocolArm64.Decoder
{
ABlock Current = Blocks.Dequeue();
- FillBlock(Translator.Thread.Memory, Current);
+ FillBlock(Memory, Current);
//Set child blocks. "Branch" is the block the branch instruction
//points to (when taken), "Next" is the block at the next address,
diff --git a/ChocolArm64/Events/ACpuTraceEventArgs.cs b/ChocolArm64/Events/ACpuTraceEventArgs.cs
new file mode 100644
index 00000000..fedf3865
--- /dev/null
+++ b/ChocolArm64/Events/ACpuTraceEventArgs.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace ChocolArm64.Events
+{
+ public class ACpuTraceEventArgs : EventArgs
+ {
+ public long Position { get; private set; }
+
+ public string SubName { get; private set; }
+
+ public ACpuTraceEventArgs(long Position, string SubName)
+ {
+ this.Position = Position;
+ this.SubName = SubName;
+ }
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/Events/AInstExceptionEventArgs.cs b/ChocolArm64/Events/AInstExceptionEventArgs.cs
new file mode 100644
index 00000000..34f90c8e
--- /dev/null
+++ b/ChocolArm64/Events/AInstExceptionEventArgs.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace ChocolArm64.Events
+{
+ public class AInstExceptionEventArgs : EventArgs
+ {
+ public int Id { get; private set; }
+
+ public AInstExceptionEventArgs(int Id)
+ {
+ this.Id = Id;
+ }
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/State/AInstUndEventArgs.cs b/ChocolArm64/Events/AInstUndefinedEventArgs.cs
index 53de65a3..cdc1728b 100644
--- a/ChocolArm64/State/AInstUndEventArgs.cs
+++ b/ChocolArm64/Events/AInstUndefinedEventArgs.cs
@@ -1,13 +1,13 @@
using System;
-namespace ChocolArm64.State
+namespace ChocolArm64.Events
{
- public class AInstUndEventArgs : EventArgs
+ public class AInstUndefinedEventArgs : EventArgs
{
public long Position { get; private set; }
public int RawOpCode { get; private set; }
- public AInstUndEventArgs(long Position, int RawOpCode)
+ public AInstUndefinedEventArgs(long Position, int RawOpCode)
{
this.Position = Position;
this.RawOpCode = RawOpCode;
diff --git a/ChocolArm64/Instruction/AInstEmitCsel.cs b/ChocolArm64/Instruction/AInstEmitCsel.cs
index 33080980..21876752 100644
--- a/ChocolArm64/Instruction/AInstEmitCsel.cs
+++ b/ChocolArm64/Instruction/AInstEmitCsel.cs
@@ -44,16 +44,15 @@ namespace ChocolArm64.Instruction
Context.Emit(OpCodes.Neg);
}
- Context.EmitStintzr(Op.Rd);
-
Context.Emit(OpCodes.Br_S, LblEnd);
Context.MarkLabel(LblTrue);
Context.EmitLdintzr(Op.Rn);
- Context.EmitStintzr(Op.Rd);
Context.MarkLabel(LblEnd);
+
+ Context.EmitStintzr(Op.Rd);
}
}
} \ No newline at end of file
diff --git a/ChocolArm64/State/AInstExceptEventArgs.cs b/ChocolArm64/State/AInstExceptEventArgs.cs
deleted file mode 100644
index f2ee039b..00000000
--- a/ChocolArm64/State/AInstExceptEventArgs.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-
-namespace ChocolArm64.State
-{
- public class AInstExceptEventArgs : EventArgs
- {
- public int Id { get; private set; }
-
- public AInstExceptEventArgs(int Id)
- {
- this.Id = Id;
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/State/AThreadState.cs b/ChocolArm64/State/AThreadState.cs
index cdab4034..2d988a65 100644
--- a/ChocolArm64/State/AThreadState.cs
+++ b/ChocolArm64/State/AThreadState.cs
@@ -1,3 +1,4 @@
+using ChocolArm64.Events;
using System;
namespace ChocolArm64.State
@@ -42,23 +43,23 @@ namespace ChocolArm64.State
public long CntpctEl0 => Environment.TickCount * TicksPerMS;
- public event EventHandler<AInstExceptEventArgs> Break;
- public event EventHandler<AInstExceptEventArgs> SvcCall;
- public event EventHandler<AInstUndEventArgs> Undefined;
+ public event EventHandler<AInstExceptionEventArgs> Break;
+ public event EventHandler<AInstExceptionEventArgs> SvcCall;
+ public event EventHandler<AInstUndefinedEventArgs> Undefined;
internal void OnBreak(int Imm)
{
- Break?.Invoke(this, new AInstExceptEventArgs(Imm));
+ Break?.Invoke(this, new AInstExceptionEventArgs(Imm));
}
internal void OnSvcCall(int Imm)
{
- SvcCall?.Invoke(this, new AInstExceptEventArgs(Imm));
+ SvcCall?.Invoke(this, new AInstExceptionEventArgs(Imm));
}
internal void OnUndefined(long Position, int RawOpCode)
{
- Undefined?.Invoke(this, new AInstUndEventArgs(Position, RawOpCode));
+ Undefined?.Invoke(this, new AInstUndefinedEventArgs(Position, RawOpCode));
}
}
} \ No newline at end of file
diff --git a/ChocolArm64/Translation/AILBarrier.cs b/ChocolArm64/Translation/AILBarrier.cs
new file mode 100644
index 00000000..25b08de3
--- /dev/null
+++ b/ChocolArm64/Translation/AILBarrier.cs
@@ -0,0 +1,7 @@
+namespace ChocolArm64.Translation
+{
+ struct AILBarrier : IAILEmit
+ {
+ public void Emit(AILEmitter Context) { }
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/Translation/AILBlock.cs b/ChocolArm64/Translation/AILBlock.cs
index bed195aa..e580e09c 100644
--- a/ChocolArm64/Translation/AILBlock.cs
+++ b/ChocolArm64/Translation/AILBlock.cs
@@ -4,11 +4,13 @@ namespace ChocolArm64.Translation
{
class AILBlock : IAILEmit
{
- public long IntInputs { get; private set; }
- public long IntOutputs { get; private set; }
+ public long IntInputs { get; private set; }
+ public long IntOutputs { get; private set; }
+ public long IntAwOutputs { get; private set; }
- public long VecInputs { get; private set; }
- public long VecOutputs { get; private set; }
+ public long VecInputs { get; private set; }
+ public long VecOutputs { get; private set; }
+ public long VecAwOutputs { get; private set; }
public bool HasStateStore { get; private set; }
@@ -24,13 +26,22 @@ namespace ChocolArm64.Translation
public void Add(IAILEmit ILEmitter)
{
- if (ILEmitter is AILOpCodeLoad Ld && AILEmitter.IsRegIndex(Ld.Index))
+ if (ILEmitter is AILBarrier)
+ {
+ //Those barriers are used to separate the groups of CIL
+ //opcodes emitted by each ARM instruction.
+ //We can only consider the new outputs for doing input elimination
+ //after all the CIL opcodes used by the instruction being emitted.
+ IntAwOutputs = IntOutputs;
+ VecAwOutputs = VecOutputs;
+ }
+ else if (ILEmitter is AILOpCodeLoad Ld && AILEmitter.IsRegIndex(Ld.Index))
{
switch (Ld.IoType)
{
- case AIoType.Flag: IntInputs |= ((1L << Ld.Index) << 32) & ~IntOutputs; break;
- case AIoType.Int: IntInputs |= (1L << Ld.Index) & ~IntOutputs; break;
- case AIoType.Vector: VecInputs |= (1L << Ld.Index) & ~VecOutputs; break;
+ case AIoType.Flag: IntInputs |= ((1L << Ld.Index) << 32) & ~IntAwOutputs; break;
+ case AIoType.Int: IntInputs |= (1L << Ld.Index) & ~IntAwOutputs; break;
+ case AIoType.Vector: VecInputs |= (1L << Ld.Index) & ~VecAwOutputs; break;
}
}
else if (ILEmitter is AILOpCodeStore St)
diff --git a/ChocolArm64/Translation/AILEmitterCtx.cs b/ChocolArm64/Translation/AILEmitterCtx.cs
index 9199eddc..ffcfa851 100644
--- a/ChocolArm64/Translation/AILEmitterCtx.cs
+++ b/ChocolArm64/Translation/AILEmitterCtx.cs
@@ -39,14 +39,16 @@ namespace ChocolArm64.Translation
private const int Tmp4Index = -4;
private const int Tmp5Index = -5;
- public AILEmitterCtx(ATranslator Translator, ABlock[] Graph, ABlock Root)
+ public AILEmitterCtx(
+ ATranslator Translator,
+ ABlock[] Graph,
+ ABlock Root,
+ string SubName)
{
this.Translator = Translator;
this.Graph = Graph;
this.Root = Root;
- string SubName = $"Sub{Root.Position:X16}";
-
Labels = new Dictionary<long, AILLabel>();
Emitter = new AILEmitter(Graph, Root, SubName);
@@ -92,6 +94,8 @@ namespace ChocolArm64.Translation
}
CurrOp.Emitter(this);
+
+ ILBlock.Add(new AILBarrier());
}
public bool TryOptEmitSubroutineCall()
diff --git a/ChocolArm64/Translation/AILOpCodeLoad.cs b/ChocolArm64/Translation/AILOpCodeLoad.cs
index 7cb431e2..d60ce539 100644
--- a/ChocolArm64/Translation/AILOpCodeLoad.cs
+++ b/ChocolArm64/Translation/AILOpCodeLoad.cs
@@ -11,12 +11,10 @@ namespace ChocolArm64.Translation
public ARegisterSize RegisterSize { get; private set; }
- public AILOpCodeLoad(int Index, AIoType IoType) : this(Index, IoType, ARegisterSize.Int64) { }
-
- public AILOpCodeLoad(int Index, AIoType IoType, ARegisterSize RegisterSize)
+ public AILOpCodeLoad(int Index, AIoType IoType, ARegisterSize RegisterSize = 0)
{
- this.IoType = IoType;
this.Index = Index;
+ this.IoType = IoType;
this.RegisterSize = RegisterSize;
}
diff --git a/ChocolArm64/Translation/AILOpCodeStore.cs b/ChocolArm64/Translation/AILOpCodeStore.cs
index c4ea53ab..a0feb437 100644
--- a/ChocolArm64/Translation/AILOpCodeStore.cs
+++ b/ChocolArm64/Translation/AILOpCodeStore.cs
@@ -11,10 +11,10 @@ namespace ChocolArm64.Translation
public ARegisterSize RegisterSize { get; private set; }
- public AILOpCodeStore(int Index, AIoType IoType, ARegisterSize RegisterSize = ARegisterSize.Int64)
+ public AILOpCodeStore(int Index, AIoType IoType, ARegisterSize RegisterSize = 0)
{
- this.IoType = IoType;
this.Index = Index;
+ this.IoType = IoType;
this.RegisterSize = RegisterSize;
}
diff --git a/ChocolArm64/Translation/ALocalAlloc.cs b/ChocolArm64/Translation/ALocalAlloc.cs
index 0661ddc8..f23af9c7 100644
--- a/ChocolArm64/Translation/ALocalAlloc.cs
+++ b/ChocolArm64/Translation/ALocalAlloc.cs
@@ -67,7 +67,7 @@ namespace ChocolArm64.Translation
public long VecOutputs;
}
- private const int MaxOptGraphLength = 120;
+ private const int MaxOptGraphLength = 55;
public ALocalAlloc(AILBlock[] Graph, AILBlock Root)
{
@@ -149,11 +149,7 @@ namespace ChocolArm64.Translation
if (RetTarget)
{
- BlkIO.Entry = Block;
- BlkIO.IntInputs = 0;
- BlkIO.VecInputs = 0;
- BlkIO.IntOutputs = 0;
- BlkIO.VecOutputs = 0;
+ BlkIO.Entry = Block;
}
else
{
diff --git a/Ryujinx.Core/Loaders/ElfSym.cs b/Ryujinx.Core/Loaders/ElfSym.cs
index 35a45500..89e7c61f 100644
--- a/Ryujinx.Core/Loaders/ElfSym.cs
+++ b/Ryujinx.Core/Loaders/ElfSym.cs
@@ -16,17 +16,15 @@ namespace Ryujinx.Core.Loaders
Binding == ElfSymBinding.STB_GLOBAL ||
Binding == ElfSymBinding.STB_WEAK;
- public int SHIdx { get; private set; }
- public long ValueAbs { get; private set; }
- public long Value { get; private set; }
- public long Size { get; private set; }
+ public int SHIdx { get; private set; }
+ public long Value { get; private set; }
+ public long Size { get; private set; }
public ElfSym(
string Name,
int Info,
int Other,
int SHIdx,
- long ImageBase,
long Value,
long Size)
{
@@ -35,7 +33,6 @@ namespace Ryujinx.Core.Loaders
this.Binding = (ElfSymBinding)(Info >> 4);
this.Visibility = (ElfSymVisibility)Other;
this.SHIdx = SHIdx;
- this.ValueAbs = Value + ImageBase;
this.Value = Value;
this.Size = Size;
}
diff --git a/Ryujinx.Core/Loaders/Executable.cs b/Ryujinx.Core/Loaders/Executable.cs
index e2660838..c6770c7b 100644
--- a/Ryujinx.Core/Loaders/Executable.cs
+++ b/Ryujinx.Core/Loaders/Executable.cs
@@ -9,13 +9,21 @@ namespace Ryujinx.Core.Loaders
{
private AMemory Memory;
- private ElfDyn[] Dynamic;
+ private List<ElfDyn> Dynamic;
+
+ private Dictionary<long, string> m_SymbolTable;
+
+ public IReadOnlyDictionary<long, string> SymbolTable => m_SymbolTable;
public long ImageBase { get; private set; }
public long ImageEnd { get; private set; }
public Executable(IExecutable Exe, AMemory Memory, long ImageBase)
{
+ Dynamic = new List<ElfDyn>();
+
+ m_SymbolTable = new Dictionary<long, string>();
+
this.Memory = Memory;
this.ImageBase = ImageBase;
this.ImageEnd = ImageBase;
@@ -48,9 +56,7 @@ namespace Ryujinx.Core.Loaders
MapBss(BssStartOffset, BssEndOffset - BssStartOffset);
- ImageEnd = BssEndOffset;
-
- List<ElfDyn> Dynamic = new List<ElfDyn>();
+ ImageEnd = ImageBase + BssEndOffset;
while (true)
{
@@ -69,7 +75,19 @@ namespace Ryujinx.Core.Loaders
Dynamic.Add(new ElfDyn(Tag, Value));
}
- this.Dynamic = Dynamic.ToArray();
+ long StrTblAddr = ImageBase + GetFirstValue(ElfDynTag.DT_STRTAB);
+ long SymTblAddr = ImageBase + GetFirstValue(ElfDynTag.DT_SYMTAB);
+
+ long SymEntSize = GetFirstValue(ElfDynTag.DT_SYMENT);
+
+ while ((ulong)SymTblAddr < (ulong)StrTblAddr)
+ {
+ ElfSym Sym = GetSymbol(SymTblAddr, StrTblAddr);
+
+ m_SymbolTable.TryAdd(Sym.Value, Sym.Name);
+
+ SymTblAddr += SymEntSize;
+ }
}
private void WriteData(
@@ -135,7 +153,7 @@ namespace Ryujinx.Core.Loaders
Name += (char)Chr;
}
- return new ElfSym(Name, Info, Other, SHIdx, ImageBase, Value, Size);
+ return new ElfSym(Name, Info, Other, SHIdx, Value, Size);
}
private long GetFirstValue(ElfDynTag Tag)
diff --git a/Ryujinx.Core/OsHle/Process.cs b/Ryujinx.Core/OsHle/Process.cs
index 3e265ed3..60e71ee9 100644
--- a/Ryujinx.Core/OsHle/Process.cs
+++ b/Ryujinx.Core/OsHle/Process.cs
@@ -1,6 +1,6 @@
using ChocolArm64;
+using ChocolArm64.Events;
using ChocolArm64.Memory;
-using ChocolArm64.State;
using Ryujinx.Core.Loaders;
using Ryujinx.Core.Loaders.Executables;
using Ryujinx.Core.OsHle.Exceptions;
@@ -24,6 +24,8 @@ namespace Ryujinx.Core.OsHle
private Switch Ns;
+ private ATranslator Translator;
+
public int ProcessId { get; private set; }
public AMemory Memory { get; private set; }
@@ -171,7 +173,7 @@ namespace Ryujinx.Core.OsHle
ThreadPrio = ThreadPriority.Lowest;
}
- AThread Thread = new AThread(Memory, ThreadPrio, EntryPoint);
+ AThread Thread = new AThread(GetTranslator(), Memory, ThreadPrio, EntryPoint);
HThread ThreadHnd = new HThread(Thread, ProcessorId, Priority);
@@ -201,16 +203,45 @@ namespace Ryujinx.Core.OsHle
return Handle;
}
- private void BreakHandler(object sender, AInstExceptEventArgs e)
+ private void BreakHandler(object sender, AInstExceptionEventArgs e)
{
throw new GuestBrokeExecutionException();
}
- private void UndefinedHandler(object sender, AInstUndEventArgs e)
+ private void UndefinedHandler(object sender, AInstUndefinedEventArgs e)
{
throw new UndefinedInstructionException(e.Position, e.RawOpCode);
}
+ private ATranslator GetTranslator()
+ {
+ if (Translator == null)
+ {
+ Dictionary<long, string> SymbolTable = new Dictionary<long, string>();
+
+ foreach (Executable Exe in Executables)
+ {
+ foreach (KeyValuePair<long, string> KV in Exe.SymbolTable)
+ {
+ SymbolTable.Add(Exe.ImageBase + KV.Key, KV.Value);
+ }
+ }
+
+ Translator = new ATranslator(SymbolTable);
+
+
+
+ Translator.CpuTrace += CpuTraceHandler;
+ }
+
+ return Translator;
+ }
+
+ private void CpuTraceHandler(object sender, ACpuTraceEventArgs e)
+ {
+ Logging.Info($"Executing at 0x{e.Position:x16} {e.SubName}");
+ }
+
private int GetFreeTlsSlot(AThread Thread)
{
for (int Index = 1; Index < TotalTlsSlots; Index++)
diff --git a/Ryujinx.Core/OsHle/Svc/SvcHandler.cs b/Ryujinx.Core/OsHle/Svc/SvcHandler.cs
index c5b6da04..ec53f47f 100644
--- a/Ryujinx.Core/OsHle/Svc/SvcHandler.cs
+++ b/Ryujinx.Core/OsHle/Svc/SvcHandler.cs
@@ -1,3 +1,4 @@
+using ChocolArm64.Events;
using ChocolArm64.Memory;
using ChocolArm64.State;
using System;
@@ -62,7 +63,7 @@ namespace Ryujinx.Core.OsHle.Svc
Rng = new Random();
}
- public void SvcCall(object sender, AInstExceptEventArgs e)
+ public void SvcCall(object sender, AInstExceptionEventArgs e)
{
AThreadState ThreadState = (AThreadState)sender;
diff --git a/Ryujinx.Tests/Cpu/CpuTest.cs b/Ryujinx.Tests/Cpu/CpuTest.cs
index 7af2d55d..bf9d90e3 100644
--- a/Ryujinx.Tests/Cpu/CpuTest.cs
+++ b/Ryujinx.Tests/Cpu/CpuTest.cs
@@ -30,10 +30,11 @@ namespace Ryujinx.Tests.Cpu
EntryPoint = Position;
Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
+ ATranslator Translator = new ATranslator();
Allocator = new AMemoryAlloc();
Memory = new AMemory(Ram, Allocator);
Memory.Manager.MapPhys(Position, Size, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
- Thread = new AThread(Memory, ThreadPriority.Normal, EntryPoint);
+ Thread = new AThread(Translator, Memory, ThreadPriority.Normal, EntryPoint);
}
[TearDown]