Stub a few services, add support for generating call stacks on the CPU

This commit is contained in:
gdkchan 2018-04-22 01:21:49 -03:00
parent 4906acdde9
commit bd9b1e2c6b
20 changed files with 267 additions and 41 deletions

View file

@ -1,6 +1,7 @@
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;
@ -10,6 +11,7 @@ using Ryujinx.Core.OsHle.Services.Nv;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
namespace Ryujinx.Core.OsHle
{
@ -47,9 +49,11 @@ namespace Ryujinx.Core.OsHle
private ConcurrentDictionary<long, KThread> Threads;
private KThread MainThread;
private List<Executable> Executables;
private KThread MainThread;
private Dictionary<long, string> SymbolTable;
private long ImageBase;
@ -121,6 +125,8 @@ namespace Ryujinx.Core.OsHle
return false;
}
MakeSymbolTable();
MapRWMemRegion(
MemoryRegions.MainStackAddress,
MemoryRegions.MainStackSize,
@ -227,20 +233,23 @@ namespace Ryujinx.Core.OsHle
throw new UndefinedInstructionException(e.Position, e.RawOpCode);
}
private void MakeSymbolTable()
{
SymbolTable = new Dictionary<long, string>();
foreach (Executable Exe in Executables)
{
foreach (KeyValuePair<long, string> KV in Exe.SymbolTable)
{
SymbolTable.TryAdd(Exe.ImageBase + KV.Key, KV.Value);
}
}
}
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.TryAdd(Exe.ImageBase + KV.Key, KV.Value);
}
}
Translator = new ATranslator(SymbolTable);
Translator.CpuTrace += CpuTraceHandler;
@ -249,6 +258,16 @@ namespace Ryujinx.Core.OsHle
return Translator;
}
public void EnableCpuTracing()
{
Translator.EnableCpuTrace = true;
}
public void DisableCpuTracing()
{
Translator.EnableCpuTrace = false;
}
private void CpuTraceHandler(object sender, ACpuTraceEventArgs e)
{
string NsoName = string.Empty;
@ -263,17 +282,47 @@ namespace Ryujinx.Core.OsHle
}
}
Logging.Trace(LogClass.Loader, $"Executing at 0x{e.Position:x16} {e.SubName} {NsoName}");
Logging.Trace(LogClass.CPU, $"Executing at 0x{e.Position:x16} {e.SubName} {NsoName}");
}
public void EnableCpuTracing()
public void PrintStackTrace(AThreadState ThreadState)
{
Translator.EnableCpuTrace = true;
long[] Positions = ThreadState.GetCallStack();
StringBuilder Trace = new StringBuilder();
Trace.AppendLine("Guest stack trace:");
foreach (long Position in Positions)
{
if (!SymbolTable.TryGetValue(Position, out string SubName))
{
SubName = $"Sub{Position:x16}";
}
Trace.AppendLine(" " + SubName + " (" + GetNsoNameAndAddress(Position) + ")");
}
Logging.Trace(LogClass.CPU, Trace.ToString());
}
public void DisableCpuTracing()
private string GetNsoNameAndAddress(long Position)
{
Translator.EnableCpuTrace = false;
string Name = string.Empty;
for (int Index = Executables.Count - 1; Index >= 0; Index--)
{
if (Position >= Executables[Index].ImageBase)
{
long Offset = Position - Executables[Index].ImageBase;
Name = $"{Executables[Index].Name}:{Offset:x8}";
break;
}
}
return Name;
}
private int GetFreeTlsSlot(AThread Thread)