aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Kernel/SupervisorCall
diff options
context:
space:
mode:
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];