Przeglądaj źródła

Implement PM GetProcessInfo atmosphere extension (partially) (#2966)

gdkchan 4 lat temu
rodzic
commit
556be08c4e

+ 10 - 6
Ryujinx.HLE/HOS/ApplicationLoader.cs

@@ -86,8 +86,8 @@ namespace Ryujinx.HLE.HOS
             MetaLoader metaData = ReadNpdm(codeFs);
 
             _device.Configuration.VirtualFileSystem.ModLoader.CollectMods(
-                new[] { TitleId }, 
-                _device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath(), 
+                new[] { TitleId },
+                _device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath(),
                 _device.Configuration.VirtualFileSystem.ModLoader.GetSdModsBasePath());
 
             if (TitleId != 0)
@@ -393,8 +393,8 @@ namespace Ryujinx.HLE.HOS
             MetaLoader metaData = ReadNpdm(codeFs);
 
             _device.Configuration.VirtualFileSystem.ModLoader.CollectMods(
-                _device.Configuration.ContentManager.GetAocTitleIds().Prepend(TitleId), 
-                _device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath(), 
+                _device.Configuration.ContentManager.GetAocTitleIds().Prepend(TitleId),
+                _device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath(),
                 _device.Configuration.VirtualFileSystem.ModLoader.GetSdModsBasePath());
 
             if (controlNca != null)
@@ -571,8 +571,12 @@ namespace Ryujinx.HLE.HOS
 
             Ptc.Initialize(TitleIdText, DisplayVersion, usePtc, memoryManagerMode);
 
+            // We allow it for nx-hbloader because it can be used to launch homebrew.
+            bool allowCodeMemoryForJit = TitleId == 0x010000000000100DUL;
+
             metaData.GetNpdm(out Npdm npdm).ThrowIfFailure();
-            ProgramLoader.LoadNsos(_device.System.KernelContext, out ProcessTamperInfo tamperInfo, metaData, new ProgramInfo(in npdm), executables: programs);
+            ProgramInfo programInfo = new ProgramInfo(in npdm, allowCodeMemoryForJit);
+            ProgramLoader.LoadNsos(_device.System.KernelContext, out ProcessTamperInfo tamperInfo, metaData, programInfo, executables: programs);
 
             _device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, tamperInfo, _device.TamperMachine);
         }
@@ -581,7 +585,7 @@ namespace Ryujinx.HLE.HOS
         {
             MetaLoader metaData = GetDefaultNpdm();
             metaData.GetNpdm(out Npdm npdm).ThrowIfFailure();
-            ProgramInfo programInfo = new ProgramInfo(in npdm);
+            ProgramInfo programInfo = new ProgramInfo(in npdm, allowCodeMemoryForJit: true);
 
             bool isNro = Path.GetExtension(filePath).ToLower() == ".nro";
 

+ 10 - 0
Ryujinx.HLE/HOS/Kernel/KernelStatic.cs

@@ -59,5 +59,15 @@ namespace Ryujinx.HLE.HOS.Kernel
         {
             return GetCurrentThread().Owner;
         }
+
+        internal static KProcess GetProcessByPid(ulong pid)
+        {
+            if (Context.Processes.TryGetValue(pid, out KProcess process))
+            {
+                return process;
+            }
+
+            return null;
+        }
     }
 }

+ 5 - 1
Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs

@@ -60,6 +60,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
 
         public KProcessCapabilities Capabilities { get; private set; }
 
+        public bool AllowCodeMemoryForJit { get; private set; }
+
         public ulong TitleId { get; private set; }
         public bool IsApplication { get; private set; }
         public ulong Pid { get; private set; }
@@ -90,7 +92,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
 
         public HleProcessDebugger Debugger { get; private set; }
 
-        public KProcess(KernelContext context) : base(context)
+        public KProcess(KernelContext context, bool allowCodeMemoryForJit = false) : base(context)
         {
             _processLock = new object();
             _threadingLock = new object();
@@ -102,6 +104,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
 
             Capabilities = new KProcessCapabilities();
 
+            AllowCodeMemoryForJit = allowCodeMemoryForJit;
+
             RandomEntropy = new ulong[KScheduler.CpuCoresCount];
             PinnedThreads = new KThread[KScheduler.CpuCoresCount];
 

+ 3 - 4
Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs

@@ -7,7 +7,6 @@ using Ryujinx.HLE.HOS.Kernel.Ipc;
 using Ryujinx.HLE.HOS.Kernel.Memory;
 using Ryujinx.HLE.HOS.Kernel.Process;
 using Ryujinx.HLE.HOS.Kernel.Threading;
-using Ryujinx.Memory;
 using System;
 using System.Threading;
 
@@ -1363,10 +1362,10 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
 
             KCodeMemory codeMemory = currentProcess.HandleTable.GetObject<KCodeMemory>(handle);
 
-            // Newer versions of the return also returns an error here if the owner and process
+            // Newer versions of the kernel also returns an error here if the owner and process
             // where the operation will happen are the same. We do not return an error here
-            // because some homebrew requires this to be patched out to work (for JIT).
-            if (codeMemory == null /* || codeMemory.Owner == currentProcess */)
+            // for homebrew because some of them requires this to be patched out to work (for JIT).
+            if (codeMemory == null || (!currentProcess.AllowCodeMemoryForJit && codeMemory.Owner == currentProcess))
             {
                 return KernelResult.InvalidHandle;
             }

+ 11 - 3
Ryujinx.HLE/HOS/ProgramLoader.cs

@@ -20,11 +20,13 @@ namespace Ryujinx.HLE.HOS
     {
         public string Name;
         public ulong ProgramId;
+        public bool AllowCodeMemoryForJit;
 
-        public ProgramInfo(in Npdm npdm)
+        public ProgramInfo(in Npdm npdm, bool allowCodeMemoryForJit)
         {
             Name = StringUtils.Utf8ZToString(npdm.Meta.Value.ProgramName);
             ProgramId = npdm.Aci.Value.ProgramId.Value;
+            AllowCodeMemoryForJit = allowCodeMemoryForJit;
         }
     }
 
@@ -141,7 +143,13 @@ namespace Ryujinx.HLE.HOS
             return true;
         }
 
-        public static bool LoadNsos(KernelContext context, out ProcessTamperInfo tamperInfo, MetaLoader metaData, ProgramInfo programInfo, byte[] arguments = null, params IExecutable[] executables)
+        public static bool LoadNsos(
+            KernelContext context,
+            out ProcessTamperInfo tamperInfo,
+            MetaLoader metaData,
+            ProgramInfo programInfo,
+            byte[] arguments = null,
+            params IExecutable[] executables)
         {
             LibHac.Result rc = metaData.GetNpdm(out var npdm);
 
@@ -243,7 +251,7 @@ namespace Ryujinx.HLE.HOS
                 return false;
             }
 
-            KProcess process = new KProcess(context);
+            KProcess process = new KProcess(context, programInfo.AllowCodeMemoryForJit);
 
             MemoryRegion memoryRegion = (MemoryRegion)((npdm.Acid.Value.Flags >> 2) & 0xf);
 

+ 24 - 1
Ryujinx.HLE/HOS/Services/Pm/IDebugMonitorInterface.cs

@@ -1,8 +1,31 @@
-namespace Ryujinx.HLE.HOS.Services.Pm
+using Ryujinx.HLE.HOS.Ipc;
+using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Process;
+
+namespace Ryujinx.HLE.HOS.Services.Pm
 {
     [Service("pm:dmnt")]
     class IDebugMonitorInterface : IpcService
     {
         public IDebugMonitorInterface(ServiceCtx context) { }
+
+        [CommandHipc(65000)]
+        // AtmosphereGetProcessInfo(os::ProcessId process_id) -> sf::OutCopyHandle out_process_handle, sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status
+        public ResultCode GetProcessInfo(ServiceCtx context)
+        {
+            ulong pid = context.RequestData.ReadUInt64();
+
+            KProcess process = KernelStatic.GetProcessByPid(pid);
+
+            if (context.Process.HandleTable.GenerateHandle(process, out int processHandle) != KernelResult.Success)
+            {
+                throw new System.Exception("Out of handles!");
+            }
+
+            context.Response.HandleDesc = IpcHandleDesc.MakeCopy(processHandle);
+
+            return ResultCode.Success;
+        }
     }
 }