early-access version 2238
This commit is contained in:
		| @@ -1,7 +1,7 @@ | ||||
| yuzu emulator early access | ||||
| ============= | ||||
|  | ||||
| This is the source code for early-access 2237. | ||||
| This is the source code for early-access 2238. | ||||
|  | ||||
| ## Legal Notice | ||||
|  | ||||
|   | ||||
| @@ -685,8 +685,8 @@ ResultCode KPageTable::UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, | ||||
|     return ResultSuccess; | ||||
| } | ||||
|  | ||||
| ResultCode KPageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, | ||||
|                                                KMemoryPermission perm) { | ||||
| ResultCode KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size, | ||||
|                                                   KMemoryPermission perm) { | ||||
|  | ||||
|     std::lock_guard lock{page_table_lock}; | ||||
|  | ||||
|   | ||||
| @@ -41,7 +41,7 @@ public: | ||||
|     ResultCode MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state, | ||||
|                         KMemoryPermission perm); | ||||
|     ResultCode UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state); | ||||
|     ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm); | ||||
|     ResultCode SetProcessMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm); | ||||
|     KMemoryInfo QueryInfo(VAddr addr); | ||||
|     ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm); | ||||
|     ResultCode ResetTransferMemory(VAddr addr, std::size_t size); | ||||
|   | ||||
| @@ -528,7 +528,7 @@ void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { | ||||
|     std::lock_guard lock{HLE::g_hle_lock}; | ||||
|     const auto ReprotectSegment = [&](const CodeSet::Segment& segment, | ||||
|                                       KMemoryPermission permission) { | ||||
|         page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); | ||||
|         page_table->SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); | ||||
|     }; | ||||
|  | ||||
|     kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(), | ||||
|   | ||||
| @@ -1169,6 +1169,8 @@ static u32 GetCurrentProcessorNumber32(Core::System& system) { | ||||
|     return GetCurrentProcessorNumber(system); | ||||
| } | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| constexpr bool IsValidSharedMemoryPermission(Svc::MemoryPermission perm) { | ||||
|     switch (perm) { | ||||
|     case Svc::MemoryPermission::Read: | ||||
| @@ -1179,10 +1181,24 @@ constexpr bool IsValidSharedMemoryPermission(Svc::MemoryPermission perm) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| constexpr bool IsValidRemoteSharedMemoryPermission(Svc::MemoryPermission perm) { | ||||
| [[maybe_unused]] constexpr bool IsValidRemoteSharedMemoryPermission(Svc::MemoryPermission perm) { | ||||
|     return IsValidSharedMemoryPermission(perm) || perm == Svc::MemoryPermission::DontCare; | ||||
| } | ||||
|  | ||||
| constexpr bool IsValidProcessMemoryPermission(Svc::MemoryPermission perm) { | ||||
|     switch (perm) { | ||||
|     case Svc::MemoryPermission::None: | ||||
|     case Svc::MemoryPermission::Read: | ||||
|     case Svc::MemoryPermission::ReadWrite: | ||||
|     case Svc::MemoryPermission::ReadExecute: | ||||
|         return true; | ||||
|     default: | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| } // Anonymous namespace | ||||
|  | ||||
| static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, | ||||
|                                   u64 size, Svc::MemoryPermission map_perm) { | ||||
|     LOG_TRACE(Kernel_SVC, | ||||
| @@ -1262,6 +1278,34 @@ static ResultCode UnmapSharedMemory32(Core::System& system, Handle shmem_handle, | ||||
|     return UnmapSharedMemory(system, shmem_handle, address, size); | ||||
| } | ||||
|  | ||||
| static ResultCode SetProcessMemoryPermission(Core::System& system, Handle process_handle, | ||||
|                                              VAddr address, u64 size, Svc::MemoryPermission perm) { | ||||
|     LOG_TRACE(Kernel_SVC, | ||||
|               "called, process_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", | ||||
|               process_handle, address, size, perm); | ||||
|  | ||||
|     // Validate the address/size. | ||||
|     R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); | ||||
|     R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); | ||||
|     R_UNLESS(size > 0, ResultInvalidSize); | ||||
|     R_UNLESS((address < address + size), ResultInvalidCurrentMemory); | ||||
|  | ||||
|     // Validate the memory permission. | ||||
|     R_UNLESS(IsValidProcessMemoryPermission(perm), ResultInvalidNewMemoryPermission); | ||||
|  | ||||
|     // Get the process from its handle. | ||||
|     KScopedAutoObject process = | ||||
|         system.CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle); | ||||
|     R_UNLESS(process.IsNotNull(), ResultInvalidHandle); | ||||
|  | ||||
|     // Validate that the address is in range. | ||||
|     auto& page_table = process->PageTable(); | ||||
|     R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); | ||||
|  | ||||
|     // Set the memory permission. | ||||
|     return page_table.SetProcessMemoryPermission(address, size, ConvertToKMemoryPermission(perm)); | ||||
| } | ||||
|  | ||||
| static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, | ||||
|                                      VAddr page_info_address, Handle process_handle, | ||||
|                                      VAddr address) { | ||||
| @@ -1459,10 +1503,14 @@ static void ExitProcess32(Core::System& system) { | ||||
|     ExitProcess(system); | ||||
| } | ||||
|  | ||||
| static constexpr bool IsValidVirtualCoreId(int32_t core_id) { | ||||
| namespace { | ||||
|  | ||||
| constexpr bool IsValidVirtualCoreId(int32_t core_id) { | ||||
|     return (0 <= core_id && core_id < static_cast<int32_t>(Core::Hardware::NUM_CPU_CORES)); | ||||
| } | ||||
|  | ||||
| } // Anonymous namespace | ||||
|  | ||||
| /// Creates a new thread | ||||
| static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, | ||||
|                                VAddr stack_bottom, u32 priority, s32 core_id) { | ||||
| @@ -1846,7 +1894,9 @@ static ResultCode ResetSignal32(Core::System& system, Handle handle) { | ||||
|     return ResetSignal(system, handle); | ||||
| } | ||||
|  | ||||
| static constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { | ||||
| namespace { | ||||
|  | ||||
| constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { | ||||
|     switch (perm) { | ||||
|     case MemoryPermission::None: | ||||
|     case MemoryPermission::Read: | ||||
| @@ -1857,6 +1907,8 @@ static constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| } // Anonymous namespace | ||||
|  | ||||
| /// Creates a TransferMemory object | ||||
| static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, | ||||
|                                        MemoryPermission map_perm) { | ||||
| @@ -2588,7 +2640,7 @@ static const FunctionDef SVC_Table_64[] = { | ||||
|     {0x70, nullptr, "CreatePort"}, | ||||
|     {0x71, nullptr, "ManageNamedPort"}, | ||||
|     {0x72, nullptr, "ConnectToPort"}, | ||||
|     {0x73, nullptr, "SetProcessMemoryPermission"}, | ||||
|     {0x73, SvcWrap64<SetProcessMemoryPermission>, "SetProcessMemoryPermission"}, | ||||
|     {0x74, nullptr, "MapProcessMemory"}, | ||||
|     {0x75, nullptr, "UnmapProcessMemory"}, | ||||
|     {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, | ||||
|   | ||||
| @@ -396,12 +396,12 @@ public: | ||||
|         CopyCode(nro_addr + nro_header.segment_headers[DATA_INDEX].memory_offset, data_start, | ||||
|                  nro_header.segment_headers[DATA_INDEX].memory_size); | ||||
|  | ||||
|         CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( | ||||
|         CASCADE_CODE(process->PageTable().SetProcessMemoryPermission( | ||||
|             text_start, ro_start - text_start, Kernel::KMemoryPermission::ReadAndExecute)); | ||||
|         CASCADE_CODE(process->PageTable().SetCodeMemoryPermission(ro_start, data_start - ro_start, | ||||
|                                                                   Kernel::KMemoryPermission::Read)); | ||||
|         CASCADE_CODE(process->PageTable().SetProcessMemoryPermission( | ||||
|             ro_start, data_start - ro_start, Kernel::KMemoryPermission::Read)); | ||||
|  | ||||
|         return process->PageTable().SetCodeMemoryPermission( | ||||
|         return process->PageTable().SetProcessMemoryPermission( | ||||
|             data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite); | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user