aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Kernel/SupervisorCall
diff options
context:
space:
mode:
authorThomas Guillemard <thog@protonmail.com>2019-02-14 01:44:39 +0100
committerjduncanator <1518948+jduncanator@users.noreply.github.com>2019-02-14 11:44:39 +1100
commitb126ea48c63a3de8da8f3b817860c0323f2621ef (patch)
treeeb58d7b31719050da390e2b79824d6e931b85da8 /Ryujinx.HLE/HOS/Kernel/SupervisorCall
parent7e9f5555747315d142e1ae20266cb581647db0cd (diff)
Support HomeBrew Loader (#577)
* Make it possibles to load hb-loader and hb-menu One issue remains with hb-menu homebrew icons because of SIMD issues (libjpeg-turbo related) and netloader doesn't work. * Implement GetApplicationControlData * Fix shared fonts for NSO/NRO * Add homebrew NRO romfs support This readd the NRO support by parsing the ASET header * Address comments about HomebrewRomFs * override Dispose in homebrew romfs stream * Use a struct for file timestamp * Simplify positional increments in GetApplicationControlData * Address comments * improve readability of the memory permission check in SetProcessMemoryPermission * Fix previous broken check * Add address space checks in SetProcessMemoryPermission
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/SupervisorCall')
-rw-r--r--Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcMemory.cs126
-rw-r--r--Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs5
2 files changed, 130 insertions, 1 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcMemory.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcMemory.cs
index 388dcc21..6f8180c5 100644
--- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcMemory.cs
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcMemory.cs
@@ -386,6 +386,132 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return _process.MemoryManager.UnmapPhysicalMemory(address, size);
}
+ public KernelResult MapProcessCodeMemory64(int handle, ulong dst, ulong src, ulong size)
+ {
+ return MapProcessCodeMemory(handle, dst, src, size);
+ }
+
+ public KernelResult MapProcessCodeMemory(int handle, ulong dst, ulong src, ulong size)
+ {
+ if (!PageAligned(dst) || !PageAligned(src))
+ {
+ return KernelResult.InvalidAddress;
+ }
+
+ if (!PageAligned(size) || size == 0)
+ {
+ return KernelResult.InvalidSize;
+ }
+
+ KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+ KProcess targetProcess = currentProcess.HandleTable.GetObject<KProcess>(handle);
+
+ if (targetProcess == null)
+ {
+ return KernelResult.InvalidHandle;
+ }
+
+ if (targetProcess.MemoryManager.OutsideAddrSpace(dst, size) ||
+ targetProcess.MemoryManager.OutsideAddrSpace(src, size) ||
+ targetProcess.MemoryManager.InsideAliasRegion(dst, size) ||
+ targetProcess.MemoryManager.InsideHeapRegion(dst, size))
+ {
+ return KernelResult.InvalidMemRange;
+ }
+
+ if (size + dst <= dst || size + src <= src)
+ {
+ return KernelResult.InvalidMemState;
+ }
+
+ return targetProcess.MemoryManager.MapProcessCodeMemory(dst, src, size);
+ }
+
+ public KernelResult UnmapProcessCodeMemory64(int handle, ulong dst, ulong src, ulong size)
+ {
+ return UnmapProcessCodeMemory(handle, dst, src, size);
+ }
+
+ public KernelResult UnmapProcessCodeMemory(int handle, ulong dst, ulong src, ulong size)
+ {
+ if (!PageAligned(dst) || !PageAligned(src))
+ {
+ return KernelResult.InvalidAddress;
+ }
+
+ if (!PageAligned(size) || size == 0)
+ {
+ return KernelResult.InvalidSize;
+ }
+
+ KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+ KProcess targetProcess = currentProcess.HandleTable.GetObject<KProcess>(handle);
+
+ if (targetProcess == null)
+ {
+ return KernelResult.InvalidHandle;
+ }
+
+ if (targetProcess.MemoryManager.OutsideAddrSpace(dst, size) ||
+ targetProcess.MemoryManager.OutsideAddrSpace(src, size) ||
+ targetProcess.MemoryManager.InsideAliasRegion(dst, size) ||
+ targetProcess.MemoryManager.InsideHeapRegion(dst, size))
+ {
+ return KernelResult.InvalidMemRange;
+ }
+
+ if (size + dst <= dst || size + src <= src)
+ {
+ return KernelResult.InvalidMemState;
+ }
+
+ return targetProcess.MemoryManager.UnmapProcessCodeMemory(dst, src, size);
+ }
+
+ public KernelResult SetProcessMemoryPermission64(int handle, ulong src, ulong size, MemoryPermission permission)
+ {
+ return SetProcessMemoryPermission(handle, src, size, permission);
+ }
+
+ public KernelResult SetProcessMemoryPermission(int handle, ulong src, ulong size, MemoryPermission permission)
+ {
+ if (!PageAligned(src))
+ {
+ return KernelResult.InvalidAddress;
+ }
+
+ if (!PageAligned(size) || size == 0)
+ {
+ return KernelResult.InvalidSize;
+ }
+
+ if (permission != MemoryPermission.None &&
+ permission != MemoryPermission.Read &&
+ permission != MemoryPermission.ReadAndWrite &&
+ permission != MemoryPermission.ReadAndExecute)
+ {
+ return KernelResult.InvalidPermission;
+ }
+
+ KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+ KProcess targetProcess = currentProcess.HandleTable.GetObject<KProcess>(handle);
+
+ if (targetProcess == null)
+ {
+ return KernelResult.InvalidHandle;
+ }
+
+ if (targetProcess.MemoryManager.OutsideAddrSpace(src, size))
+ {
+ return KernelResult.InvalidMemState;
+ }
+
+ return targetProcess.MemoryManager.SetProcessMemoryPermission(src, size, permission);
+ }
+
private static bool PageAligned(ulong position)
{
return (position & (KMemoryManager.PageSize - 1)) == 0;
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs
index cbcb712f..dd98e8a0 100644
--- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs
@@ -71,7 +71,10 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{ 0x6f, nameof(SvcHandler.GetSystemInfo64) },
{ 0x70, nameof(SvcHandler.CreatePort64) },
{ 0x71, nameof(SvcHandler.ManageNamedPort64) },
- { 0x72, nameof(SvcHandler.ConnectToPort64) }
+ { 0x72, nameof(SvcHandler.ConnectToPort64) },
+ { 0x73, nameof(SvcHandler.SetProcessMemoryPermission64) },
+ { 0x77, nameof(SvcHandler.MapProcessCodeMemory64) },
+ { 0x78, nameof(SvcHandler.UnmapProcessCodeMemory64) }
};
_svcTable64 = new Action<SvcHandler, CpuThreadState>[0x80];