diff options
| author | Thomas Guillemard <thog@protonmail.com> | 2019-02-14 01:44:39 +0100 |
|---|---|---|
| committer | jduncanator <1518948+jduncanator@users.noreply.github.com> | 2019-02-14 11:44:39 +1100 |
| commit | b126ea48c63a3de8da8f3b817860c0323f2621ef (patch) | |
| tree | eb58d7b31719050da390e2b79824d6e931b85da8 /Ryujinx.HLE/HOS/Kernel/SupervisorCall | |
| parent | 7e9f5555747315d142e1ae20266cb581647db0cd (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.cs | 126 | ||||
| -rw-r--r-- | Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs | 5 |
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]; |
