2018-02-04 23:08:20 +00:00
|
|
|
using ChocolArm64;
|
2018-02-26 01:14:58 +00:00
|
|
|
using ChocolArm64.Events;
|
2018-02-04 23:08:20 +00:00
|
|
|
using ChocolArm64.Memory;
|
2018-04-22 05:21:49 +01:00
|
|
|
using ChocolArm64.State;
|
2018-09-19 13:09:49 +01:00
|
|
|
using LibHac;
|
2018-10-17 18:15:50 +01:00
|
|
|
using Ryujinx.Common.Logging;
|
2018-08-17 00:47:36 +01:00
|
|
|
using Ryujinx.HLE.Exceptions;
|
2018-09-15 14:29:18 +01:00
|
|
|
using Ryujinx.HLE.HOS.Diagnostics.Demangler;
|
2018-08-17 00:47:36 +01:00
|
|
|
using Ryujinx.HLE.HOS.Kernel;
|
|
|
|
using Ryujinx.HLE.HOS.Services.Nv;
|
|
|
|
using Ryujinx.HLE.HOS.SystemState;
|
2018-06-11 01:46:42 +01:00
|
|
|
using Ryujinx.HLE.Loaders;
|
|
|
|
using Ryujinx.HLE.Loaders.Executables;
|
2018-08-02 21:14:49 +01:00
|
|
|
using Ryujinx.HLE.Loaders.Npdm;
|
2018-08-17 00:47:36 +01:00
|
|
|
using Ryujinx.HLE.Utilities;
|
2018-02-04 23:08:20 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
using System.Collections.Generic;
|
2018-07-17 20:14:27 +01:00
|
|
|
using System.IO;
|
2018-04-22 05:21:49 +01:00
|
|
|
using System.Text;
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-08-17 00:47:36 +01:00
|
|
|
namespace Ryujinx.HLE.HOS
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-03-12 04:04:52 +00:00
|
|
|
class Process : IDisposable
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-03-14 00:24:17 +00:00
|
|
|
private const int TickFreq = 19_200_000;
|
|
|
|
|
2018-08-17 00:47:36 +01:00
|
|
|
public Switch Device { get; private set; }
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-03-12 04:04:52 +00:00
|
|
|
public bool NeedsHbAbi { get; private set; }
|
|
|
|
|
|
|
|
public long HbAbiDataPosition { get; private set; }
|
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
public int ProcessId { get; private set; }
|
|
|
|
|
2018-02-27 23:45:07 +00:00
|
|
|
private ATranslator Translator;
|
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
public AMemory Memory { get; private set; }
|
|
|
|
|
2018-08-15 19:59:51 +01:00
|
|
|
public KMemoryManager MemoryManager { get; private set; }
|
|
|
|
|
|
|
|
private List<KTlsPageManager> TlsPages;
|
|
|
|
|
|
|
|
public Npdm MetaData { get; private set; }
|
|
|
|
|
2018-09-19 13:09:49 +01:00
|
|
|
public Nacp ControlData { get; set; }
|
|
|
|
|
2018-03-12 04:04:52 +00:00
|
|
|
public KProcessHandleTable HandleTable { get; private set; }
|
|
|
|
|
2018-03-19 18:58:46 +00:00
|
|
|
public AppletStateMgr AppletState { get; private set; }
|
|
|
|
|
2018-02-14 05:43:21 +00:00
|
|
|
private SvcHandler SvcHandler;
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-04-21 20:07:16 +01:00
|
|
|
private ConcurrentDictionary<long, KThread> Threads;
|
2018-02-14 02:43:08 +00:00
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
private List<Executable> Executables;
|
|
|
|
|
|
|
|
private long ImageBase;
|
|
|
|
|
2018-03-12 04:04:52 +00:00
|
|
|
private bool Disposed;
|
|
|
|
|
2018-09-19 00:36:43 +01:00
|
|
|
public Process(Switch Device, int ProcessId, Npdm MetaData)
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-08-17 00:47:36 +01:00
|
|
|
this.Device = Device;
|
2018-08-15 19:59:51 +01:00
|
|
|
this.MetaData = MetaData;
|
2018-02-04 23:08:20 +00:00
|
|
|
this.ProcessId = ProcessId;
|
|
|
|
|
2018-08-17 00:47:36 +01:00
|
|
|
Memory = new AMemory(Device.Memory.RamPointer);
|
2018-08-15 19:59:51 +01:00
|
|
|
|
|
|
|
MemoryManager = new KMemoryManager(this);
|
|
|
|
|
|
|
|
TlsPages = new List<KTlsPageManager>();
|
2018-02-14 02:43:08 +00:00
|
|
|
|
2018-09-23 19:11:46 +01:00
|
|
|
int HandleTableSize = 1024;
|
|
|
|
|
|
|
|
if (MetaData != null)
|
|
|
|
{
|
|
|
|
foreach (KernelAccessControlItem Item in MetaData.ACI0.KernelAccessControl.Items)
|
|
|
|
{
|
|
|
|
if (Item.HasHandleTableSize)
|
|
|
|
{
|
|
|
|
HandleTableSize = Item.HandleTableSize;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
HandleTable = new KProcessHandleTable(Device.System, HandleTableSize);
|
2018-03-12 04:04:52 +00:00
|
|
|
|
2018-09-19 00:36:43 +01:00
|
|
|
AppletState = new AppletStateMgr(Device.System);
|
2018-02-14 02:43:08 +00:00
|
|
|
|
2018-08-17 00:47:36 +01:00
|
|
|
SvcHandler = new SvcHandler(Device, this);
|
2018-02-14 02:43:08 +00:00
|
|
|
|
2018-04-21 20:07:16 +01:00
|
|
|
Threads = new ConcurrentDictionary<long, KThread>();
|
2018-02-14 02:43:08 +00:00
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
Executables = new List<Executable>();
|
|
|
|
|
2018-08-15 19:59:51 +01:00
|
|
|
ImageBase = MemoryManager.CodeRegionStart;
|
2018-02-04 23:08:20 +00:00
|
|
|
}
|
|
|
|
|
2018-02-06 23:28:32 +00:00
|
|
|
public void LoadProgram(IExecutable Program)
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-03-12 04:04:52 +00:00
|
|
|
if (Disposed)
|
|
|
|
{
|
|
|
|
throw new ObjectDisposedException(nameof(Process));
|
|
|
|
}
|
|
|
|
|
2018-10-10 00:01:49 +01:00
|
|
|
long ImageEnd = LoadProgram(Program, ImageBase);
|
2018-02-17 21:06:11 +00:00
|
|
|
|
2018-10-10 00:01:49 +01:00
|
|
|
ImageBase = IntUtils.AlignUp(ImageEnd, KMemoryManager.PageSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
public long LoadProgram(IExecutable Program, long ExecutableBase)
|
|
|
|
{
|
|
|
|
if (Disposed)
|
|
|
|
{
|
|
|
|
throw new ObjectDisposedException(nameof(Process));
|
|
|
|
}
|
|
|
|
|
2018-10-17 18:15:50 +01:00
|
|
|
Logger.PrintInfo(LogClass.Loader, $"Image base at 0x{ExecutableBase:x16}.");
|
2018-10-10 00:01:49 +01:00
|
|
|
|
|
|
|
Executable Executable = new Executable(Program, MemoryManager, Memory, ExecutableBase);
|
2018-02-04 23:08:20 +00:00
|
|
|
|
|
|
|
Executables.Add(Executable);
|
|
|
|
|
2018-10-10 00:01:49 +01:00
|
|
|
return Executable.ImageEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void RemoveProgram(long ExecutableBase)
|
|
|
|
{
|
|
|
|
foreach (Executable Executable in Executables)
|
|
|
|
{
|
|
|
|
if (Executable.ImageBase == ExecutableBase)
|
|
|
|
{
|
|
|
|
Executables.Remove(Executable);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-02-04 23:08:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void SetEmptyArgs()
|
|
|
|
{
|
2018-03-12 04:04:52 +00:00
|
|
|
//TODO: This should be part of Run.
|
2018-08-15 19:59:51 +01:00
|
|
|
ImageBase += KMemoryManager.PageSize;
|
2018-02-04 23:08:20 +00:00
|
|
|
}
|
|
|
|
|
2018-03-12 04:04:52 +00:00
|
|
|
public bool Run(bool NeedsHbAbi = false)
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-03-12 04:04:52 +00:00
|
|
|
if (Disposed)
|
|
|
|
{
|
|
|
|
throw new ObjectDisposedException(nameof(Process));
|
|
|
|
}
|
|
|
|
|
|
|
|
this.NeedsHbAbi = NeedsHbAbi;
|
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
if (Executables.Count == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-15 19:59:51 +01:00
|
|
|
long MainStackTop = MemoryManager.CodeRegionEnd - KMemoryManager.PageSize;
|
|
|
|
|
|
|
|
long MainStackSize = 1 * 1024 * 1024;
|
2018-04-04 23:29:34 +01:00
|
|
|
|
2018-08-15 19:59:51 +01:00
|
|
|
long MainStackBottom = MainStackTop - MainStackSize;
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-08-15 19:59:51 +01:00
|
|
|
MemoryManager.HleMapCustom(
|
|
|
|
MainStackBottom,
|
|
|
|
MainStackSize,
|
|
|
|
MemoryState.MappedMemory,
|
|
|
|
MemoryPermission.ReadAndWrite);
|
|
|
|
|
|
|
|
int Handle = MakeThread(Executables[0].ImageBase, MainStackTop, 0, 44, 0);
|
2018-02-04 23:08:20 +00:00
|
|
|
|
|
|
|
if (Handle == -1)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-09-23 19:11:46 +01:00
|
|
|
KThread MainThread = HandleTable.GetKThread(Handle);
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-03-12 04:04:52 +00:00
|
|
|
if (NeedsHbAbi)
|
2018-02-24 00:59:38 +00:00
|
|
|
{
|
2018-08-15 19:59:51 +01:00
|
|
|
HbAbiDataPosition = IntUtils.AlignUp(Executables[0].ImageEnd, KMemoryManager.PageSize);
|
|
|
|
|
|
|
|
const long HbAbiDataSize = KMemoryManager.PageSize;
|
|
|
|
|
|
|
|
MemoryManager.HleMapCustom(
|
|
|
|
HbAbiDataPosition,
|
|
|
|
HbAbiDataSize,
|
|
|
|
MemoryState.MappedMemory,
|
|
|
|
MemoryPermission.ReadAndWrite);
|
2018-02-24 00:59:38 +00:00
|
|
|
|
2018-08-17 00:47:36 +01:00
|
|
|
string SwitchPath = Device.FileSystem.SystemPathToSwitchPath(Executables[0].FilePath);
|
2018-07-17 20:14:27 +01:00
|
|
|
|
|
|
|
Homebrew.WriteHbAbiData(Memory, HbAbiDataPosition, Handle, SwitchPath);
|
2018-02-26 01:44:30 +00:00
|
|
|
|
2018-09-19 00:36:43 +01:00
|
|
|
MainThread.Context.ThreadState.X0 = (ulong)HbAbiDataPosition;
|
|
|
|
MainThread.Context.ThreadState.X1 = ulong.MaxValue;
|
2018-02-24 00:59:38 +00:00
|
|
|
}
|
|
|
|
|
2018-09-19 00:36:43 +01:00
|
|
|
MainThread.TimeUp();
|
2018-02-04 23:08:20 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-09-19 00:36:43 +01:00
|
|
|
private int ThreadIdCtr = 1;
|
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
public int MakeThread(
|
|
|
|
long EntryPoint,
|
|
|
|
long StackTop,
|
|
|
|
long ArgsPtr,
|
|
|
|
int Priority,
|
|
|
|
int ProcessorId)
|
|
|
|
{
|
2018-03-12 04:04:52 +00:00
|
|
|
if (Disposed)
|
2018-02-14 02:43:08 +00:00
|
|
|
{
|
2018-03-12 04:04:52 +00:00
|
|
|
throw new ObjectDisposedException(nameof(Process));
|
2018-02-14 02:43:08 +00:00
|
|
|
}
|
|
|
|
|
2018-04-21 20:07:16 +01:00
|
|
|
AThread CpuThread = new AThread(GetTranslator(), Memory, EntryPoint);
|
2018-04-19 03:52:23 +01:00
|
|
|
|
2018-08-17 00:47:36 +01:00
|
|
|
long Tpidr = GetFreeTls();
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-09-19 00:36:43 +01:00
|
|
|
int ThreadId = ThreadIdCtr++; //(int)((Tpidr - MemoryManager.TlsIoRegionStart) / 0x200) + 1;
|
2018-06-26 05:09:32 +01:00
|
|
|
|
2018-09-19 00:36:43 +01:00
|
|
|
KThread Thread = new KThread(CpuThread, this, Device.System, ProcessorId, Priority, ThreadId);
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-08-17 00:47:36 +01:00
|
|
|
Thread.LastPc = EntryPoint;
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-09-23 19:11:46 +01:00
|
|
|
HandleTable.GenerateHandle(Thread, out int Handle);
|
2018-02-27 23:45:07 +00:00
|
|
|
|
2018-04-21 20:07:16 +01:00
|
|
|
CpuThread.ThreadState.CntfrqEl0 = TickFreq;
|
|
|
|
CpuThread.ThreadState.Tpidr = Tpidr;
|
2018-04-19 03:52:23 +01:00
|
|
|
|
2018-04-21 20:07:16 +01:00
|
|
|
CpuThread.ThreadState.X0 = (ulong)ArgsPtr;
|
|
|
|
CpuThread.ThreadState.X1 = (ulong)Handle;
|
|
|
|
CpuThread.ThreadState.X31 = (ulong)StackTop;
|
2018-04-19 03:52:23 +01:00
|
|
|
|
2018-09-19 00:36:43 +01:00
|
|
|
CpuThread.ThreadState.Interrupt += InterruptHandler;
|
2018-04-21 20:07:16 +01:00
|
|
|
CpuThread.ThreadState.Break += BreakHandler;
|
|
|
|
CpuThread.ThreadState.SvcCall += SvcHandler.SvcCall;
|
|
|
|
CpuThread.ThreadState.Undefined += UndefinedHandler;
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-04-21 20:07:16 +01:00
|
|
|
CpuThread.WorkFinished += ThreadFinished;
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-04-21 20:07:16 +01:00
|
|
|
Threads.TryAdd(CpuThread.ThreadState.Tpidr, Thread);
|
2018-02-14 02:43:08 +00:00
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
return Handle;
|
|
|
|
}
|
|
|
|
|
2018-08-15 19:59:51 +01:00
|
|
|
private long GetFreeTls()
|
|
|
|
{
|
|
|
|
long Position;
|
|
|
|
|
|
|
|
lock (TlsPages)
|
|
|
|
{
|
|
|
|
for (int Index = 0; Index < TlsPages.Count; Index++)
|
|
|
|
{
|
|
|
|
if (TlsPages[Index].TryGetFreeTlsAddr(out Position))
|
|
|
|
{
|
|
|
|
return Position;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
long PagePosition = MemoryManager.HleMapTlsPage();
|
|
|
|
|
|
|
|
KTlsPageManager TlsPage = new KTlsPageManager(PagePosition);
|
|
|
|
|
|
|
|
TlsPages.Add(TlsPage);
|
|
|
|
|
|
|
|
TlsPage.TryGetFreeTlsAddr(out Position);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Position;
|
|
|
|
}
|
|
|
|
|
2018-09-19 00:36:43 +01:00
|
|
|
private void InterruptHandler(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
Device.System.Scheduler.ContextSwitch();
|
|
|
|
}
|
|
|
|
|
2018-02-26 01:14:58 +00:00
|
|
|
private void BreakHandler(object sender, AInstExceptionEventArgs e)
|
2018-02-10 13:24:16 +00:00
|
|
|
{
|
|
|
|
throw new GuestBrokeExecutionException();
|
|
|
|
}
|
|
|
|
|
2018-02-26 01:14:58 +00:00
|
|
|
private void UndefinedHandler(object sender, AInstUndefinedEventArgs e)
|
2018-02-10 17:20:46 +00:00
|
|
|
{
|
|
|
|
throw new UndefinedInstructionException(e.Position, e.RawOpCode);
|
|
|
|
}
|
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
public void EnableCpuTracing()
|
2018-02-26 01:14:58 +00:00
|
|
|
{
|
2018-09-19 21:07:56 +01:00
|
|
|
Translator.EnableCpuTrace = true;
|
|
|
|
}
|
2018-02-26 01:14:58 +00:00
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
public void DisableCpuTracing()
|
|
|
|
{
|
|
|
|
Translator.EnableCpuTrace = false;
|
2018-04-22 05:21:49 +01:00
|
|
|
}
|
2018-02-26 01:14:58 +00:00
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
private void CpuTraceHandler(object sender, ACpuTraceEventArgs e)
|
2018-04-22 05:21:49 +01:00
|
|
|
{
|
2018-09-19 21:07:56 +01:00
|
|
|
Executable Exe = GetExecutable(e.Position);
|
|
|
|
|
|
|
|
if (Exe == null)
|
2018-04-22 05:21:49 +01:00
|
|
|
{
|
2018-09-19 21:07:56 +01:00
|
|
|
return;
|
|
|
|
}
|
2018-02-26 01:14:58 +00:00
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
if (!TryGetSubName(Exe, e.Position, out string SubName))
|
|
|
|
{
|
|
|
|
SubName = string.Empty;
|
2018-02-26 01:14:58 +00:00
|
|
|
}
|
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
long Offset = e.Position - Exe.ImageBase;
|
2018-02-26 01:14:58 +00:00
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
string ExeNameWithAddr = $"{Exe.Name}:0x{Offset:x8}";
|
2018-04-22 05:21:49 +01:00
|
|
|
|
2018-10-17 18:15:50 +01:00
|
|
|
Logger.PrintDebug(LogClass.Cpu, ExeNameWithAddr + " " + SubName);
|
2018-04-22 05:21:49 +01:00
|
|
|
}
|
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
private ATranslator GetTranslator()
|
2018-02-26 01:14:58 +00:00
|
|
|
{
|
2018-09-19 21:07:56 +01:00
|
|
|
if (Translator == null)
|
2018-03-04 03:06:44 +00:00
|
|
|
{
|
2018-09-19 21:07:56 +01:00
|
|
|
Translator = new ATranslator();
|
2018-04-04 23:29:34 +01:00
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
Translator.CpuTrace += CpuTraceHandler;
|
2018-03-04 03:06:44 +00:00
|
|
|
}
|
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
return Translator;
|
2018-02-26 01:14:58 +00:00
|
|
|
}
|
|
|
|
|
2018-04-22 05:21:49 +01:00
|
|
|
public void PrintStackTrace(AThreadState ThreadState)
|
2018-03-03 01:49:17 +00:00
|
|
|
{
|
2018-04-22 05:21:49 +01:00
|
|
|
StringBuilder Trace = new StringBuilder();
|
|
|
|
|
|
|
|
Trace.AppendLine("Guest stack trace:");
|
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
void AppendTrace(long Position)
|
2018-04-22 05:21:49 +01:00
|
|
|
{
|
2018-09-19 21:07:56 +01:00
|
|
|
Executable Exe = GetExecutable(Position);
|
|
|
|
|
|
|
|
if (Exe == null)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!TryGetSubName(Exe, Position, out string SubName))
|
2018-04-22 05:21:49 +01:00
|
|
|
{
|
|
|
|
SubName = $"Sub{Position:x16}";
|
|
|
|
}
|
2018-05-22 21:40:02 +01:00
|
|
|
else if (SubName.StartsWith("_Z"))
|
|
|
|
{
|
|
|
|
SubName = Demangler.Parse(SubName);
|
|
|
|
}
|
2018-04-22 05:21:49 +01:00
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
long Offset = Position - Exe.ImageBase;
|
|
|
|
|
|
|
|
string ExeNameWithAddr = $"{Exe.Name}:0x{Offset:x8}";
|
|
|
|
|
|
|
|
Trace.AppendLine(" " + ExeNameWithAddr + " " + SubName);
|
|
|
|
}
|
|
|
|
|
|
|
|
long FramePointer = (long)ThreadState.X29;
|
|
|
|
|
|
|
|
while (FramePointer != 0)
|
|
|
|
{
|
|
|
|
AppendTrace(Memory.ReadInt64(FramePointer + 8));
|
|
|
|
|
|
|
|
FramePointer = Memory.ReadInt64(FramePointer);
|
2018-04-22 05:21:49 +01:00
|
|
|
}
|
|
|
|
|
2018-10-17 18:15:50 +01:00
|
|
|
Logger.PrintInfo(LogClass.Cpu, Trace.ToString());
|
2018-03-03 01:49:17 +00:00
|
|
|
}
|
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
private bool TryGetSubName(Executable Exe, long Position, out string Name)
|
2018-03-03 01:49:17 +00:00
|
|
|
{
|
2018-09-19 21:07:56 +01:00
|
|
|
Position -= Exe.ImageBase;
|
2018-04-22 05:21:49 +01:00
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
int Left = 0;
|
|
|
|
int Right = Exe.SymbolTable.Count - 1;
|
|
|
|
|
|
|
|
while (Left <= Right)
|
2018-04-22 05:21:49 +01:00
|
|
|
{
|
2018-09-19 21:07:56 +01:00
|
|
|
int Size = Right - Left;
|
|
|
|
|
|
|
|
int Middle = Left + (Size >> 1);
|
|
|
|
|
|
|
|
ElfSym Symbol = Exe.SymbolTable[Middle];
|
|
|
|
|
|
|
|
long EndPosition = Symbol.Value + Symbol.Size;
|
|
|
|
|
|
|
|
if ((ulong)Position >= (ulong)Symbol.Value && (ulong)Position < (ulong)EndPosition)
|
2018-04-22 05:21:49 +01:00
|
|
|
{
|
2018-09-19 21:07:56 +01:00
|
|
|
Name = Symbol.Name;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ulong)Position < (ulong)Symbol.Value)
|
|
|
|
{
|
|
|
|
Right = Middle - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Left = Middle + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Name = null;
|
2018-04-22 05:21:49 +01:00
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
return false;
|
|
|
|
}
|
2018-04-22 05:21:49 +01:00
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
private Executable GetExecutable(long Position)
|
|
|
|
{
|
|
|
|
string Name = string.Empty;
|
|
|
|
|
|
|
|
for (int Index = Executables.Count - 1; Index >= 0; Index--)
|
|
|
|
{
|
|
|
|
if ((ulong)Position >= (ulong)Executables[Index].ImageBase)
|
|
|
|
{
|
|
|
|
return Executables[Index];
|
2018-04-22 05:21:49 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-19 21:07:56 +01:00
|
|
|
return null;
|
2018-03-03 01:49:17 +00:00
|
|
|
}
|
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
private void ThreadFinished(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
if (sender is AThread Thread)
|
|
|
|
{
|
2018-09-19 16:16:20 +01:00
|
|
|
if (Threads.TryRemove(Thread.ThreadState.Tpidr, out KThread KernelThread))
|
|
|
|
{
|
|
|
|
Device.System.Scheduler.RemoveThread(KernelThread);
|
|
|
|
}
|
2018-03-12 04:04:52 +00:00
|
|
|
}
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-08-15 19:59:51 +01:00
|
|
|
if (Threads.Count == 0)
|
2018-03-12 04:04:52 +00:00
|
|
|
{
|
2018-08-17 00:47:36 +01:00
|
|
|
Device.System.ExitProcess(ProcessId);
|
2018-02-04 23:08:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-19 18:58:46 +00:00
|
|
|
public KThread GetThread(long Tpidr)
|
2018-02-14 02:43:08 +00:00
|
|
|
{
|
2018-04-21 20:07:16 +01:00
|
|
|
if (!Threads.TryGetValue(Tpidr, out KThread Thread))
|
2018-02-19 19:37:13 +00:00
|
|
|
{
|
2018-04-24 19:57:39 +01:00
|
|
|
throw new InvalidOperationException();
|
2018-02-19 19:37:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Thread;
|
2018-02-14 02:43:08 +00:00
|
|
|
}
|
|
|
|
|
2018-08-17 00:47:36 +01:00
|
|
|
private void Unload()
|
|
|
|
{
|
|
|
|
if (Disposed || Threads.Count > 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Disposed = true;
|
|
|
|
|
2018-09-23 19:11:46 +01:00
|
|
|
HandleTable.Destroy();
|
2018-08-17 00:47:36 +01:00
|
|
|
|
|
|
|
INvDrvServices.UnloadProcess(this);
|
|
|
|
|
|
|
|
if (NeedsHbAbi && Executables.Count > 0 && Executables[0].FilePath.EndsWith(Homebrew.TemporaryNroSuffix))
|
|
|
|
{
|
|
|
|
File.Delete(Executables[0].FilePath);
|
|
|
|
}
|
|
|
|
|
2018-10-17 18:15:50 +01:00
|
|
|
Logger.PrintInfo(LogClass.Loader, $"Process {ProcessId} exiting...");
|
2018-08-17 00:47:36 +01:00
|
|
|
}
|
|
|
|
|
2018-02-14 02:43:08 +00:00
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
Dispose(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual void Dispose(bool Disposing)
|
|
|
|
{
|
2018-08-17 00:47:36 +01:00
|
|
|
if (Disposing)
|
2018-02-14 02:43:08 +00:00
|
|
|
{
|
2018-08-15 19:59:51 +01:00
|
|
|
if (Threads.Count > 0)
|
2018-03-12 04:04:52 +00:00
|
|
|
{
|
2018-08-17 00:47:36 +01:00
|
|
|
foreach (KThread Thread in Threads.Values)
|
2018-03-19 18:58:46 +00:00
|
|
|
{
|
2018-09-19 00:36:43 +01:00
|
|
|
Device.System.Scheduler.StopThread(Thread);
|
2018-03-19 18:58:46 +00:00
|
|
|
}
|
|
|
|
}
|
2018-08-17 00:47:36 +01:00
|
|
|
else
|
2018-07-19 19:44:52 +01:00
|
|
|
{
|
2018-08-17 00:47:36 +01:00
|
|
|
Unload();
|
2018-07-19 19:44:52 +01:00
|
|
|
}
|
2018-02-14 02:43:08 +00:00
|
|
|
}
|
|
|
|
}
|
2018-02-04 23:08:20 +00:00
|
|
|
}
|
|
|
|
}
|