From c6c679ca0c771ffe5d7bf4d449a2505bee571755 Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 5 Aug 2024 00:41:42 -0400 Subject: [PATCH 01/23] Fixed ORBIS_KERNEL_MAP_OP_TYPE_PROTECT for batchmap2 --- src/core/address_space.cpp | 24 +++++++++ src/core/address_space.h | 2 + .../libraries/kernel/memory_management.cpp | 36 ++++++++++++- src/core/memory.cpp | 54 +++++++++++++++++++ src/core/memory.h | 2 + 5 files changed, 116 insertions(+), 2 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index c3e0d77a..16344211 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -14,6 +14,7 @@ #include #include #endif +#include "libraries/error_codes.h" #ifdef __APPLE__ // Reserve space for the system address space using a zerofill section. @@ -240,6 +241,8 @@ struct AddressSpace::Impl { } } + + HANDLE process{}; HANDLE backing_handle{}; u8* backing_base{}; @@ -462,4 +465,25 @@ void AddressSpace::Protect(VAddr virtual_addr, size_t size, MemoryPermission per return impl->Protect(virtual_addr, size, true, true, true); } +int AddressSpace::MProtect(VAddr addr, size_t size, int prot) { + + // Use conditional compilation to switch between mprotect and VirtualProtect + int result; +#ifdef _WIN32 + // Windows-specific API call + result = VirtualProtect(reinterpret_cast(addr), size, prot, nullptr); +#else + // POSIX-specific API call + result = ::mprotect(reinterpret_cast(addr), size, prot); +#endif + + if (result != 0) { + LOG_ERROR(Core, "Failed to change memory protection: {}", strerror(errno)); + return ORBIS_KERNEL_ERROR_EACCES; + } + + LOG_INFO(Core, "Changed protection on range {:#x}-{:#x} to {:#x}", addr, addr + size, prot); + return ORBIS_OK; +} + } // namespace Core diff --git a/src/core/address_space.h b/src/core/address_space.h index e2515902..1d2c67da 100644 --- a/src/core/address_space.h +++ b/src/core/address_space.h @@ -98,6 +98,8 @@ public: void Protect(VAddr virtual_addr, size_t size, MemoryPermission perms); + int MProtect(VAddr addr, size_t size, int prot); + private: struct Impl; std::unique_ptr impl; diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index e0509fb4..81874c1f 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -10,6 +10,8 @@ #include "core/libraries/kernel/memory_management.h" #include "core/linker.h" #include "core/memory.h" +#include "core/address_space.h" + namespace Libraries::Kernel { @@ -198,6 +200,22 @@ int PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void** return memory->QueryProtection(std::bit_cast(addr), start, end, prot); } +int PS4_SYSV_ABI sceKernelMProtect(void* addr, size_t size, int prot) { + LOG_INFO(Kernel_Vmm, "called addr = {}, size = {:#x}, prot = {:#x}", fmt::ptr(addr), size, + prot); + Core::MemoryManager* memory_manager = Core::Memory::Instance(); + if (!memory_manager) { + LOG_ERROR(Kernel_Vmm, "Failed to get MemoryManager instance"); + return ORBIS_KERNEL_ERROR_EINVAL; + } + + int result = memory_manager->MProtect(std::bit_cast(addr), size, prot); + if (result != ORBIS_OK) { + LOG_ERROR(Kernel_Vmm, "MProtect failed with result {}", result); + } + return result; +} + int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info, size_t infoSize) { LOG_WARNING(Kernel_Vmm, "called offset = {:#x}, flags = {:#x}", offset, flags); @@ -256,14 +274,28 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn if (result == 0) processed++; - } else if (entries[i].operation == 1) { + } else if (entries[i].operation == 1) { // UNMAP result = sceKernelMunmap(entries[i].start, entries[i].length); LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", i, entries[i].operation, entries[i].length, result); if (result == 0) processed++; - } else { + } else if (entries[i].operation == 4) { // MPROTECT + result = + sceKernelMProtect(entries[i].start, entries[i].length, entries[i].protection); + LOG_INFO(Kernel_Vmm, + "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", i, + entries[i].operation, entries[i].length, result); + if (result != ORBIS_OK) { + LOG_ERROR(Kernel_Vmm, "BatchMap: MProtect failed on entry {} with result {}", i, + result); + } + if (result == 0) { + processed++; + } + } + else { UNREACHABLE_MSG("called: Unimplemented Operation = {}", entries[i].operation); } } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index f2607bff..ba6c6f6a 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -8,6 +8,11 @@ #include "core/libraries/kernel/memory_management.h" #include "core/memory.h" #include "video_core/renderer_vulkan/vk_instance.h" +#ifdef _WIN32 +#include +#else +#include +#endif namespace Core { @@ -261,6 +266,55 @@ int MemoryManager::QueryProtection(VAddr addr, void** start, void** end, u32* pr return ORBIS_OK; } +int MemoryManager::MProtect(VAddr addr, size_t size, int prot) { + std::scoped_lock lk{mutex}; + + // Find the virtual memory area that contains the specified address range. + auto it = FindVMA(addr); + if (it == vma_map.end() || !it->second.Contains(addr, size)) { + LOG_ERROR(Core, "Address range not mapped"); + return ORBIS_KERNEL_ERROR_EINVAL; + } + + VirtualMemoryArea& vma = it->second; + if (vma.type == VMAType::Free) { + LOG_ERROR(Core, "Cannot change protection on free memory region"); + return ORBIS_KERNEL_ERROR_EINVAL; + } + +// Check if the new protection flags are valid. + if ((static_cast(prot) & + ~(static_cast(MemoryProt::NoAccess) | static_cast(MemoryProt::CpuRead) | + static_cast(MemoryProt::CpuReadWrite) | static_cast(MemoryProt::GpuRead) | + static_cast(MemoryProt::GpuWrite) | static_cast(MemoryProt::GpuReadWrite))) != + 0) { + LOG_ERROR(Core, "Invalid protection flags, prot: {:#x}, GpuWrite: {:#x}", + static_cast(prot), static_cast(MemoryProt::GpuWrite)); + return ORBIS_KERNEL_ERROR_EINVAL; + } + + // Change the protection on the specified address range. + vma.prot = static_cast(prot); + + // Use the Protect function from the AddressSpace class. + Core::MemoryPermission perms; + if ((static_cast(prot) & static_cast(MemoryProt::CpuRead)) != 0) + perms |= Core::MemoryPermission::Read; + if ((static_cast(prot) & static_cast(MemoryProt::CpuReadWrite)) != 0) + perms |= Core::MemoryPermission::ReadWrite; + if ((static_cast(prot) & static_cast(MemoryProt::GpuRead)) != 0) + perms |= Core::MemoryPermission::Read; + if ((static_cast(prot) & static_cast(MemoryProt::GpuWrite)) != 0) + perms |= Core::MemoryPermission::Write; + if ((static_cast(prot) & static_cast(MemoryProt::GpuReadWrite)) != 0) + perms |= Core::MemoryPermission::ReadWrite; // Add this line + impl.Protect(addr, size, perms); + + LOG_INFO(Core, "Changed protection on range {:#x}-{:#x} to {:#x}", addr, addr + size, prot); + return ORBIS_OK; +} + + int MemoryManager::VirtualQuery(VAddr addr, int flags, Libraries::Kernel::OrbisVirtualQueryInfo* info) { std::scoped_lock lk{mutex}; diff --git a/src/core/memory.h b/src/core/memory.h index ff4af5cd..0122deed 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -165,6 +165,8 @@ public: int QueryProtection(VAddr addr, void** start, void** end, u32* prot); + int MProtect(VAddr addr, size_t size, int prot); + int VirtualQuery(VAddr addr, int flags, Libraries::Kernel::OrbisVirtualQueryInfo* info); int DirectMemoryQuery(PAddr addr, bool find_next, Libraries::Kernel::OrbisQueryInfo* out_info); From b967f373127fe5aebbaaa9c0981e558614387113 Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 5 Aug 2024 01:17:49 -0400 Subject: [PATCH 02/23] Fix merge --- src/core/libraries/kernel/memory_management.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index f0d71c5f..c411072c 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -275,11 +275,7 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn if (result == 0) processed++; -<<<<<<< HEAD - } else if (entries[i].operation == 1) { // UNMAP -======= } else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_UNMAP) { ->>>>>>> cdff4af38da1d832e35d8c057d698f38c64b2932 result = sceKernelMunmap(entries[i].start, entries[i].length); LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", i, entries[i].operation, entries[i].length, result); @@ -300,9 +296,6 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn if (result == 0) { processed++; } - } - else { -======= } else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_FLEXIBLE) { result = sceKernelMapNamedFlexibleMemory(&entries[i].start, entries[i].length, entries[i].protection, flags, ""); @@ -314,7 +307,6 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn if (result == 0) processed++; } else { ->>>>>>> cdff4af38da1d832e35d8c057d698f38c64b2932 UNREACHABLE_MSG("called: Unimplemented Operation = {}", entries[i].operation); } } From 1a84804100f3a455904f975fb2a981065a950dfa Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 5 Aug 2024 01:20:29 -0400 Subject: [PATCH 03/23] Changed 4 to ORBIS_KERNEL_MAP_OP_TYPE_PROTECT --- src/core/libraries/kernel/memory_management.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index c411072c..02978177 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -282,8 +282,8 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn if (result == 0) processed++; -<<<<<<< HEAD - } else if (entries[i].operation == 4) { // MPROTECT + } else if (entries[i].operation == + MemoryOpTypes::ORBIS_KERNEL_MAP_OP_TYPE_PROTECT) { // MPROTECT result = sceKernelMProtect(entries[i].start, entries[i].length, entries[i].protection); LOG_INFO(Kernel_Vmm, From 491480967254c8b4218880e2063c4a163022c72f Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 5 Aug 2024 01:27:01 -0400 Subject: [PATCH 04/23] Removed MProtect from AddressSpace --- src/core/address_space.cpp | 21 --------------------- src/core/address_space.h | 2 -- 2 files changed, 23 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 16344211..741cd4fe 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -465,25 +465,4 @@ void AddressSpace::Protect(VAddr virtual_addr, size_t size, MemoryPermission per return impl->Protect(virtual_addr, size, true, true, true); } -int AddressSpace::MProtect(VAddr addr, size_t size, int prot) { - - // Use conditional compilation to switch between mprotect and VirtualProtect - int result; -#ifdef _WIN32 - // Windows-specific API call - result = VirtualProtect(reinterpret_cast(addr), size, prot, nullptr); -#else - // POSIX-specific API call - result = ::mprotect(reinterpret_cast(addr), size, prot); -#endif - - if (result != 0) { - LOG_ERROR(Core, "Failed to change memory protection: {}", strerror(errno)); - return ORBIS_KERNEL_ERROR_EACCES; - } - - LOG_INFO(Core, "Changed protection on range {:#x}-{:#x} to {:#x}", addr, addr + size, prot); - return ORBIS_OK; -} - } // namespace Core diff --git a/src/core/address_space.h b/src/core/address_space.h index 311310f2..29f74f56 100644 --- a/src/core/address_space.h +++ b/src/core/address_space.h @@ -95,8 +95,6 @@ public: void Protect(VAddr virtual_addr, size_t size, MemoryPermission perms); - int MProtect(VAddr addr, size_t size, int prot); - private: struct Impl; std::unique_ptr impl; From 9ad6317f0140b554d443d08481cbe9c69d5154ca Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 5 Aug 2024 03:00:49 -0400 Subject: [PATCH 05/23] Added Mtyprotect and moved Mprotect to ORBIS_KERNEL_MAP_OP_PROTECT --- .../libraries/kernel/memory_management.cpp | 34 +++++++++++- src/core/libraries/kernel/memory_management.h | 4 ++ src/core/memory.cpp | 52 +++++++++++++++++++ src/core/memory.h | 2 + 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index 02978177..f544b8a4 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -216,6 +216,23 @@ int PS4_SYSV_ABI sceKernelMProtect(void* addr, size_t size, int prot) { return result; } +int PS4_SYSV_ABI sceKernelMTypeProtect(void* addr, size_t size, int mtype, int prot) { + LOG_INFO(Kernel_Vmm, "called addr = {}, size = {:#x}, mtype = {:#x}, prot = {:#x}", + fmt::ptr(addr), size, mtype, prot); + Core::MemoryManager* memory_manager = Core::Memory::Instance(); + if (!memory_manager) { + LOG_ERROR(Kernel_Vmm, "Failed to get MemoryManager instance"); + return ORBIS_KERNEL_ERROR_EINVAL; + } + + int result = memory_manager->MTypeProtect(std::bit_cast(addr), size, + static_cast(mtype), prot); + if (result != ORBIS_OK) { + LOG_ERROR(Kernel_Vmm, "MTypeProtect failed with result {}", result); + } + return result; +} + int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info, size_t infoSize) { LOG_WARNING(Kernel_Vmm, "called offset = {:#x}, flags = {:#x}", offset, flags); @@ -284,8 +301,8 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn processed++; } else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_TYPE_PROTECT) { // MPROTECT - result = - sceKernelMProtect(entries[i].start, entries[i].length, entries[i].protection); + result = sceKernelMTypeProtect(entries[i].start, entries[i].length, entries[i].type, + entries[i].protection); LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", i, entries[i].operation, entries[i].length, result); @@ -296,6 +313,19 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn if (result == 0) { processed++; } + } else if (entries[i].operation == + MemoryOpTypes::ORBIS_KERNEL_MAP_OP_PROTECT) { // MPROTECT + result = sceKernelMProtect(entries[i].start, entries[i].length, + entries[i].protection); + LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", + i, entries[i].operation, entries[i].length, result); + if (result != ORBIS_OK) { + LOG_ERROR(Kernel_Vmm, "BatchMap: MProtect failed on entry {} with result {}", i, + result); + } + if (result == 0) { + processed++; + } } else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_FLEXIBLE) { result = sceKernelMapNamedFlexibleMemory(&entries[i].start, entries[i].length, entries[i].protection, flags, ""); diff --git a/src/core/libraries/kernel/memory_management.h b/src/core/libraries/kernel/memory_management.h index 25a4a9f0..301a1ef5 100644 --- a/src/core/libraries/kernel/memory_management.h +++ b/src/core/libraries/kernel/memory_management.h @@ -95,6 +95,10 @@ s32 PS4_SYSV_ABI sceKernelMapFlexibleMemory(void** addr_in_out, std::size_t len, int flags); int PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void** end, u32* prot); +int PS4_SYSV_ABI sceKernelMProtect(void* addr, size_t size, int prot); + +int PS4_SYSV_ABI sceKernelMTypeProtect(void* addr, size_t size, int mtype, int prot); + int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info, size_t infoSize); s32 PS4_SYSV_ABI sceKernelAvailableFlexibleMemorySize(size_t* sizeOut); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 28a348d4..0d49ce98 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -315,6 +315,58 @@ int MemoryManager::MProtect(VAddr addr, size_t size, int prot) { return ORBIS_OK; } +int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot) { + std::scoped_lock lk{mutex}; + + // Find the virtual memory area that contains the specified address range. + auto it = FindVMA(addr); + if (it == vma_map.end() || !it->second.Contains(addr, size)) { + LOG_ERROR(Core, "Address range not mapped"); + return ORBIS_KERNEL_ERROR_EINVAL; + } + + VirtualMemoryArea& vma = it->second; + if (vma.type == VMAType::Free) { + LOG_ERROR(Core, "Cannot change protection on free memory region"); + return ORBIS_KERNEL_ERROR_EINVAL; + } + + // Check if the new protection flags are valid. + if ((static_cast(prot) & + ~(static_cast(MemoryProt::NoAccess) | static_cast(MemoryProt::CpuRead) | + static_cast(MemoryProt::CpuReadWrite) | static_cast(MemoryProt::GpuRead) | + static_cast(MemoryProt::GpuWrite) | static_cast(MemoryProt::GpuReadWrite))) != + 0) { + LOG_ERROR(Core, "Invalid protection flags, prot: {:#x}, GpuWrite: {:#x}", + static_cast(prot), static_cast(MemoryProt::GpuWrite)); + return ORBIS_KERNEL_ERROR_EINVAL; + } + + // Change the type and protection on the specified address range. + vma.type = mtype; + vma.prot = static_cast(prot); + + // Use the Protect function from the AddressSpace class. + Core::MemoryPermission perms; + if ((static_cast(prot) & static_cast(MemoryProt::CpuRead)) != 0) + perms |= Core::MemoryPermission::Read; + if ((static_cast(prot) & static_cast(MemoryProt::CpuReadWrite)) != 0) + perms |= Core::MemoryPermission::ReadWrite; + if ((static_cast(prot) & static_cast(MemoryProt::GpuRead)) != 0) + perms |= Core::MemoryPermission::Read; + if ((static_cast(prot) & static_cast(MemoryProt::GpuWrite)) != 0) + perms |= Core::MemoryPermission::Write; + if ((static_cast(prot) & static_cast(MemoryProt::GpuReadWrite)) != 0) + perms |= Core::MemoryPermission::ReadWrite; + impl.Protect(addr, size, perms); + + LOG_INFO(Core, "Changed type and protection on range {:#x}-{:#x} to {:#x} {:#x}", addr, + addr + size, mtype, prot); + return ORBIS_OK; +} + + + int MemoryManager::VirtualQuery(VAddr addr, int flags, Libraries::Kernel::OrbisVirtualQueryInfo* info) { diff --git a/src/core/memory.h b/src/core/memory.h index 0a9641d3..3e8b5021 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -167,6 +167,8 @@ public: int MProtect(VAddr addr, size_t size, int prot); + int MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot); + int VirtualQuery(VAddr addr, int flags, Libraries::Kernel::OrbisVirtualQueryInfo* info); int DirectMemoryQuery(PAddr addr, bool find_next, Libraries::Kernel::OrbisQueryInfo* out_info); From fc4c96b8c0b7a0fffa45e24c6f45e83b8b4941ea Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 5 Aug 2024 22:31:01 -0400 Subject: [PATCH 06/23] Changed Protect for Windows --- src/core/address_space.cpp | 57 +++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 741cd4fe..d5d35157 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -217,29 +217,36 @@ struct AddressSpace::Impl { } void Protect(VAddr virtual_addr, size_t size, bool read, bool write, bool execute) { - DWORD new_flags{}; - if (read && write) { - new_flags = PAGE_READWRITE; - } else if (read && !write) { - new_flags = PAGE_READONLY; - } else if (!read && !write) { - new_flags = PAGE_NOACCESS; - } else { - UNIMPLEMENTED_MSG("Protection flag combination read={} write={}", read, write); - } - - const VAddr virtual_end = virtual_addr + size; - auto [it, end] = placeholders.equal_range({virtual_addr, virtual_end}); - while (it != end) { - const size_t offset = std::max(it->lower(), virtual_addr); - const size_t protect_length = std::min(it->upper(), virtual_end) - offset; - DWORD old_flags{}; - if (!VirtualProtect(virtual_base + offset, protect_length, new_flags, &old_flags)) { - LOG_CRITICAL(Common_Memory, "Failed to change virtual memory protect rules"); + DWORD new_flags{}; + if (read && write) { + new_flags = PAGE_READWRITE; + } else if (read && !write) { + new_flags = PAGE_READONLY; + } else if (!read && !write) { + new_flags = PAGE_NOACCESS; + } else { + UNIMPLEMENTED_MSG("Protection flag combination read={} write={}", read, write); } - ++it; - } - } + + MEMORY_BASIC_INFORMATION info; + VirtualQuery(reinterpret_cast(virtual_addr), &info, sizeof(info)); + LOG_INFO(Common_Memory, "Current protection flags: {}", info.Protect); + + if (info.Protect == new_flags) { + LOG_INFO(Common_Memory, "Protection flags already match, skipping VirtualProtect"); + return; + } + + + + if (!VirtualProtect(reinterpret_cast(virtual_addr), size, new_flags, nullptr)) { + DWORD error = GetLastError(); + LOG_CRITICAL( + Common_Memory, + "Failed to change virtual memory protect rules: error {}, new_flags = {:#x}", error, + new_flags); + } + } @@ -462,7 +469,11 @@ void AddressSpace::Unmap(VAddr virtual_addr, size_t size, bool has_backing) { } void AddressSpace::Protect(VAddr virtual_addr, size_t size, MemoryPermission perms) { - return impl->Protect(virtual_addr, size, true, true, true); + bool read = static_cast(perms & MemoryPermission::Read) != 0; + bool write = static_cast(perms & MemoryPermission::Write) != 0; + bool execute = static_cast(perms & MemoryPermission::Execute) != 0; // Assuming you have an Execute permission + + return impl->Protect(virtual_addr, size, read, write, execute); } } // namespace Core From 88cbf4128ae36175d626be887cc871c6e93cce7d Mon Sep 17 00:00:00 2001 From: Antonio Date: Tue, 6 Aug 2024 21:37:31 -0400 Subject: [PATCH 07/23] reverted the previous function --- src/core/address_space.cpp | 55 ++++++++++++++++++-------------------- src/core/memory.cpp | 8 ++++++ 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index d5d35157..4ea9ca43 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -217,36 +217,33 @@ struct AddressSpace::Impl { } void Protect(VAddr virtual_addr, size_t size, bool read, bool write, bool execute) { - DWORD new_flags{}; - if (read && write) { - new_flags = PAGE_READWRITE; - } else if (read && !write) { - new_flags = PAGE_READONLY; - } else if (!read && !write) { - new_flags = PAGE_NOACCESS; - } else { - UNIMPLEMENTED_MSG("Protection flag combination read={} write={}", read, write); + DWORD new_flags{}; + if (read && write && execute) { + new_flags = PAGE_EXECUTE_READWRITE; + } else if (read && write) { + new_flags = PAGE_READWRITE; + } else if (read && !write) { + new_flags = PAGE_READONLY; + } else if (execute && !read && !write) { + new_flags = PAGE_EXECUTE; + } else if (!read && !write && !execute) { + new_flags = PAGE_NOACCESS; + } else { + LOG_CRITICAL(Common_Memory, "Unsupported protection flag combination"); + } + + const VAddr virtual_end = virtual_addr + size; + auto [it, end] = placeholders.equal_range({virtual_addr, virtual_end}); + while (it != end) { + const size_t offset = std::max(it->lower(), virtual_addr); + const size_t protect_length = std::min(it->upper(), virtual_end) - offset; + DWORD old_flags{}; + if (!VirtualProtect(virtual_base + offset, protect_length, new_flags, &old_flags)) { + LOG_CRITICAL(Common_Memory, "Failed to change virtual memory protect rules"); } - - MEMORY_BASIC_INFORMATION info; - VirtualQuery(reinterpret_cast(virtual_addr), &info, sizeof(info)); - LOG_INFO(Common_Memory, "Current protection flags: {}", info.Protect); - - if (info.Protect == new_flags) { - LOG_INFO(Common_Memory, "Protection flags already match, skipping VirtualProtect"); - return; - } - - - - if (!VirtualProtect(reinterpret_cast(virtual_addr), size, new_flags, nullptr)) { - DWORD error = GetLastError(); - LOG_CRITICAL( - Common_Memory, - "Failed to change virtual memory protect rules: error {}, new_flags = {:#x}", error, - new_flags); - } - } + ++it; + } + } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 0d49ce98..11043b19 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -318,6 +318,9 @@ int MemoryManager::MProtect(VAddr addr, size_t size, int prot) { int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot) { std::scoped_lock lk{mutex}; + LOG_INFO(Core, "MTypeProtect called: addr = {:#x}, size = {:#x}, mtype = {:#x}, prot = {:#x}", + addr, size, mtype, prot); + // Find the virtual memory area that contains the specified address range. auto it = FindVMA(addr); if (it == vma_map.end() || !it->second.Contains(addr, size)) { @@ -326,6 +329,9 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot } VirtualMemoryArea& vma = it->second; + LOG_INFO(Core, "VMA found: base = {:#x}, size = {:#x}, prot = {:#x}, type = {}", vma.base, + vma.size, vma.prot, vma.type); + if (vma.type == VMAType::Free) { LOG_ERROR(Core, "Cannot change protection on free memory region"); return ORBIS_KERNEL_ERROR_EINVAL; @@ -346,6 +352,8 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot vma.type = mtype; vma.prot = static_cast(prot); + LOG_INFO(Core, "Changed VMA type and protection: type = {:#x}, prot = {:#x}", mtype, prot); + // Use the Protect function from the AddressSpace class. Core::MemoryPermission perms; if ((static_cast(prot) & static_cast(MemoryProt::CpuRead)) != 0) From 61c4096ae180784be81d5290eef504940454588b Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 8 Aug 2024 18:03:09 -0400 Subject: [PATCH 08/23] Fixed Mtypeprotect and MProtect --- .../libraries/kernel/memory_management.cpp | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index f544b8a4..aba81fbd 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -300,22 +300,8 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn if (result == 0) processed++; } else if (entries[i].operation == - MemoryOpTypes::ORBIS_KERNEL_MAP_OP_TYPE_PROTECT) { // MPROTECT - result = sceKernelMTypeProtect(entries[i].start, entries[i].length, entries[i].type, - entries[i].protection); - LOG_INFO(Kernel_Vmm, - "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", i, - entries[i].operation, entries[i].length, result); - if (result != ORBIS_OK) { - LOG_ERROR(Kernel_Vmm, "BatchMap: MProtect failed on entry {} with result {}", i, - result); - } - if (result == 0) { - processed++; - } - } else if (entries[i].operation == - MemoryOpTypes::ORBIS_KERNEL_MAP_OP_PROTECT) { // MPROTECT - result = sceKernelMProtect(entries[i].start, entries[i].length, + MemoryOpTypes::ORBIS_KERNEL_MAP_OP_TYPE_PROTECT) { // MTYPEPROTECT + result = sceKernelMTypeProtect(entries[i].start, entries[i].length, entries[i].type, entries[i].protection); LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", i, entries[i].operation, entries[i].length, result); @@ -326,6 +312,17 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn if (result == 0) { processed++; } + } else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_PROTECT) { // MPROTECT + result = sceKernelMProtect(entries[i].start, entries[i].length, entries[i].protection); + LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", + i, entries[i].operation, entries[i].length, result); + if (result != ORBIS_OK) { + LOG_ERROR(Kernel_Vmm, "BatchMap: MProtect failed on entry {} with result {}", i, + result); + } + if (result == 0) { + processed++; + } } else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_FLEXIBLE) { result = sceKernelMapNamedFlexibleMemory(&entries[i].start, entries[i].length, entries[i].protection, flags, ""); @@ -340,6 +337,8 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn UNREACHABLE_MSG("called: Unimplemented Operation = {}", entries[i].operation); } } + LOG_INFO(Kernel_Vmm, "sceKernelBatchMap2 finished: processed = {}, result = {}", processed, + result); if (numEntriesOut != NULL) { // can be zero. do not return an error code. *numEntriesOut = processed; } From e1e892782357a26f61ae4c28ec53963d495df70f Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 8 Aug 2024 18:03:22 -0400 Subject: [PATCH 09/23] '' --- src/core/address_space.cpp | 46 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 4ea9ca43..05aa6cbb 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -217,32 +217,32 @@ struct AddressSpace::Impl { } void Protect(VAddr virtual_addr, size_t size, bool read, bool write, bool execute) { - DWORD new_flags{}; - if (read && write && execute) { - new_flags = PAGE_EXECUTE_READWRITE; - } else if (read && write) { - new_flags = PAGE_READWRITE; - } else if (read && !write) { - new_flags = PAGE_READONLY; - } else if (execute && !read && !write) { - new_flags = PAGE_EXECUTE; - } else if (!read && !write && !execute) { - new_flags = PAGE_NOACCESS; - } else { - LOG_CRITICAL(Common_Memory, "Unsupported protection flag combination"); - } + DWORD new_flags{}; + if (read && write && execute) { + new_flags = PAGE_EXECUTE_READWRITE; + } else if (read && write) { + new_flags = PAGE_READWRITE; + } else if (read && !write) { + new_flags = PAGE_READONLY; + } else if (execute && !read && !write) { + new_flags = PAGE_EXECUTE; + } else if (!read && !write && !execute) { + new_flags = PAGE_NOACCESS; + } else { + LOG_CRITICAL(Common_Memory, "Unsupported protection flag combination"); + } const VAddr virtual_end = virtual_addr + size; - auto [it, end] = placeholders.equal_range({virtual_addr, virtual_end}); - while (it != end) { - const size_t offset = std::max(it->lower(), virtual_addr); - const size_t protect_length = std::min(it->upper(), virtual_end) - offset; - DWORD old_flags{}; - if (!VirtualProtect(virtual_base + offset, protect_length, new_flags, &old_flags)) { - LOG_CRITICAL(Common_Memory, "Failed to change virtual memory protect rules"); + auto [it, end] = placeholders.equal_range({virtual_addr, virtual_end}); + while (it != end) { + const size_t offset = std::max(it->lower(), virtual_addr); + const size_t protect_length = std::min(it->upper(), virtual_end) - offset; + DWORD old_flags{}; + if (!VirtualProtect(virtual_base + offset, protect_length, new_flags, &old_flags)) { + LOG_CRITICAL(Common_Memory, "Failed to change virtual memory protect rules"); + } + ++it; } - ++it; - } } From 5da085aa24c9cec79d2049c8aa0dabd3021e3833 Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 8 Aug 2024 18:46:27 -0400 Subject: [PATCH 10/23] '' --- src/core/libraries/kernel/libkernel.cpp | 3 +++ src/core/memory.cpp | 1 + 2 files changed, 4 insertions(+) diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index e2625819..3e2c4f86 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -424,6 +424,9 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("F6e0kwo4cnk", "libkernel", 1, "libkernel", 1, 1, sceKernelTriggerUserEvent); LIB_FUNCTION("LJDwdSNTnDg", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteUserEvent); LIB_FUNCTION("mJ7aghmgvfc", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventId); + LIB_FUNCTION("9bfdLIyuwCY", "libkernel", 1, "libkernel", 1, 1, sceKernelMTypeProtect); + LIB_FUNCTION("vSMAm3cxYTY", "libkernel", 1, "libkernel", 1, 1, sceKernelMProtect); + // misc LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", 1, 1, sceKernelIsNeoMode); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 12830e02..46e604e0 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -8,6 +8,7 @@ #include "core/libraries/kernel/memory_management.h" #include "core/memory.h" #include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_rasterizer.h" namespace Core { From ed2b29524cad76b3b3c35d62c803891fe0abdb0f Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 8 Aug 2024 21:24:13 -0400 Subject: [PATCH 11/23] Took out logs stopping build --- src/core/libraries/kernel/memory_management.cpp | 6 ++---- src/core/memory.cpp | 10 +--------- src/core/memory.h | 4 ++-- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index aba81fbd..0433e2fb 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -201,8 +201,7 @@ int PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void** } int PS4_SYSV_ABI sceKernelMProtect(void* addr, size_t size, int prot) { - LOG_INFO(Kernel_Vmm, "called addr = {}, size = {:#x}, prot = {:#x}", fmt::ptr(addr), size, - prot); + Core::MemoryManager* memory_manager = Core::Memory::Instance(); if (!memory_manager) { LOG_ERROR(Kernel_Vmm, "Failed to get MemoryManager instance"); @@ -217,8 +216,7 @@ int PS4_SYSV_ABI sceKernelMProtect(void* addr, size_t size, int prot) { } int PS4_SYSV_ABI sceKernelMTypeProtect(void* addr, size_t size, int mtype, int prot) { - LOG_INFO(Kernel_Vmm, "called addr = {}, size = {:#x}, mtype = {:#x}, prot = {:#x}", - fmt::ptr(addr), size, mtype, prot); + Core::MemoryManager* memory_manager = Core::Memory::Instance(); if (!memory_manager) { LOG_ERROR(Kernel_Vmm, "Failed to get MemoryManager instance"); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 46e604e0..f321d898 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -307,15 +307,12 @@ int MemoryManager::MProtect(VAddr addr, size_t size, int prot) { perms |= Core::MemoryPermission::ReadWrite; // Add this line impl.Protect(addr, size, perms); - LOG_INFO(Core, "Changed protection on range {:#x}-{:#x} to {:#x}", addr, addr + size, prot); return ORBIS_OK; } int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot) { std::scoped_lock lk{mutex}; - LOG_INFO(Core, "MTypeProtect called: addr = {:#x}, size = {:#x}, mtype = {:#x}, prot = {:#x}", - addr, size, mtype, prot); // Find the virtual memory area that contains the specified address range. auto it = FindVMA(addr); @@ -325,8 +322,7 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot } VirtualMemoryArea& vma = it->second; - LOG_INFO(Core, "VMA found: base = {:#x}, size = {:#x}, prot = {:#x}, type = {}", vma.base, - vma.size, vma.prot, vma.type); + if (vma.type == VMAType::Free) { LOG_ERROR(Core, "Cannot change protection on free memory region"); @@ -348,8 +344,6 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot vma.type = mtype; vma.prot = static_cast(prot); - LOG_INFO(Core, "Changed VMA type and protection: type = {:#x}, prot = {:#x}", mtype, prot); - // Use the Protect function from the AddressSpace class. Core::MemoryPermission perms; if ((static_cast(prot) & static_cast(MemoryProt::CpuRead)) != 0) @@ -364,8 +358,6 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot perms |= Core::MemoryPermission::ReadWrite; impl.Protect(addr, size, perms); - LOG_INFO(Core, "Changed type and protection on range {:#x}-{:#x} to {:#x} {:#x}", addr, - addr + size, mtype, prot); return ORBIS_OK; } diff --git a/src/core/memory.h b/src/core/memory.h index 9f217e0f..5163f024 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -164,9 +164,9 @@ public: int MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot); - int VirtualQuery(VAddr addr, int flags, Libraries::Kernel::OrbisVirtualQueryInfo* info); + int VirtualQuery(VAddr addr, int flags, ::Libraries::Kernel::OrbisVirtualQueryInfo* info); - int DirectMemoryQuery(PAddr addr, bool find_next, Libraries::Kernel::OrbisQueryInfo* out_info); + int DirectMemoryQuery(PAddr addr, bool find_next, ::Libraries::Kernel::OrbisQueryInfo* out_info); int DirectQueryAvailable(PAddr search_start, PAddr search_end, size_t alignment, PAddr* phys_addr_out, size_t* size_out); From 153362f13efd4cf53456518854331219ad89ef80 Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 8 Aug 2024 21:38:53 -0400 Subject: [PATCH 12/23] clang-format issues --- src/core/address_space.cpp | 51 +++++++++---------- src/core/libraries/kernel/libkernel.cpp | 1 - .../libraries/kernel/memory_management.cpp | 3 +- src/core/memory.cpp | 7 +-- src/core/memory.h | 3 +- 5 files changed, 29 insertions(+), 36 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 05aa6cbb..4dd06e99 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -217,36 +217,34 @@ struct AddressSpace::Impl { } void Protect(VAddr virtual_addr, size_t size, bool read, bool write, bool execute) { - DWORD new_flags{}; - if (read && write && execute) { - new_flags = PAGE_EXECUTE_READWRITE; - } else if (read && write) { - new_flags = PAGE_READWRITE; - } else if (read && !write) { - new_flags = PAGE_READONLY; - } else if (execute && !read && !write) { - new_flags = PAGE_EXECUTE; - } else if (!read && !write && !execute) { - new_flags = PAGE_NOACCESS; - } else { - LOG_CRITICAL(Common_Memory, "Unsupported protection flag combination"); - } + DWORD new_flags{}; + if (read && write && execute) { + new_flags = PAGE_EXECUTE_READWRITE; + } else if (read && write) { + new_flags = PAGE_READWRITE; + } else if (read && !write) { + new_flags = PAGE_READONLY; + } else if (execute && !read && !write) { + new_flags = PAGE_EXECUTE; + } else if (!read && !write && !execute) { + new_flags = PAGE_NOACCESS; + } else { + LOG_CRITICAL(Common_Memory, "Unsupported protection flag combination"); + } const VAddr virtual_end = virtual_addr + size; - auto [it, end] = placeholders.equal_range({virtual_addr, virtual_end}); - while (it != end) { - const size_t offset = std::max(it->lower(), virtual_addr); - const size_t protect_length = std::min(it->upper(), virtual_end) - offset; - DWORD old_flags{}; - if (!VirtualProtect(virtual_base + offset, protect_length, new_flags, &old_flags)) { - LOG_CRITICAL(Common_Memory, "Failed to change virtual memory protect rules"); - } - ++it; + auto [it, end] = placeholders.equal_range({virtual_addr, virtual_end}); + while (it != end) { + const size_t offset = std::max(it->lower(), virtual_addr); + const size_t protect_length = std::min(it->upper(), virtual_end) - offset; + DWORD old_flags{}; + if (!VirtualProtect(virtual_base + offset, protect_length, new_flags, &old_flags)) { + LOG_CRITICAL(Common_Memory, "Failed to change virtual memory protect rules"); } + ++it; + } } - - HANDLE process{}; HANDLE backing_handle{}; u8* backing_base{}; @@ -468,7 +466,8 @@ void AddressSpace::Unmap(VAddr virtual_addr, size_t size, bool has_backing) { void AddressSpace::Protect(VAddr virtual_addr, size_t size, MemoryPermission perms) { bool read = static_cast(perms & MemoryPermission::Read) != 0; bool write = static_cast(perms & MemoryPermission::Write) != 0; - bool execute = static_cast(perms & MemoryPermission::Execute) != 0; // Assuming you have an Execute permission + bool execute = static_cast(perms & MemoryPermission::Execute) != + 0; // Assuming you have an Execute permission return impl->Protect(virtual_addr, size, read, write, execute); } diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index 3e2c4f86..4b9565b6 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -427,7 +427,6 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("9bfdLIyuwCY", "libkernel", 1, "libkernel", 1, 1, sceKernelMTypeProtect); LIB_FUNCTION("vSMAm3cxYTY", "libkernel", 1, "libkernel", 1, 1, sceKernelMProtect); - // misc LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", 1, 1, sceKernelIsNeoMode); LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail); diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index 0433e2fb..db8a4a52 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -6,12 +6,11 @@ #include "common/assert.h" #include "common/logging/log.h" #include "common/singleton.h" +#include "core/address_space.h" #include "core/libraries/error_codes.h" #include "core/libraries/kernel/memory_management.h" #include "core/linker.h" #include "core/memory.h" -#include "core/address_space.h" - namespace Libraries::Kernel { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index f321d898..41bb60e3 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -279,7 +279,7 @@ int MemoryManager::MProtect(VAddr addr, size_t size, int prot) { return ORBIS_KERNEL_ERROR_EINVAL; } -// Check if the new protection flags are valid. + // Check if the new protection flags are valid. if ((static_cast(prot) & ~(static_cast(MemoryProt::NoAccess) | static_cast(MemoryProt::CpuRead) | static_cast(MemoryProt::CpuReadWrite) | static_cast(MemoryProt::GpuRead) | @@ -313,7 +313,6 @@ int MemoryManager::MProtect(VAddr addr, size_t size, int prot) { int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot) { std::scoped_lock lk{mutex}; - // Find the virtual memory area that contains the specified address range. auto it = FindVMA(addr); if (it == vma_map.end() || !it->second.Contains(addr, size)) { @@ -323,7 +322,6 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot VirtualMemoryArea& vma = it->second; - if (vma.type == VMAType::Free) { LOG_ERROR(Core, "Cannot change protection on free memory region"); return ORBIS_KERNEL_ERROR_EINVAL; @@ -361,9 +359,6 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot return ORBIS_OK; } - - - int MemoryManager::VirtualQuery(VAddr addr, int flags, ::Libraries::Kernel::OrbisVirtualQueryInfo* info) { std::scoped_lock lk{mutex}; diff --git a/src/core/memory.h b/src/core/memory.h index 5163f024..17902897 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -166,7 +166,8 @@ public: int VirtualQuery(VAddr addr, int flags, ::Libraries::Kernel::OrbisVirtualQueryInfo* info); - int DirectMemoryQuery(PAddr addr, bool find_next, ::Libraries::Kernel::OrbisQueryInfo* out_info); + int DirectMemoryQuery(PAddr addr, bool find_next, + ::Libraries::Kernel::OrbisQueryInfo* out_info); int DirectQueryAvailable(PAddr search_start, PAddr search_end, size_t alignment, PAddr* phys_addr_out, size_t* size_out); From 4098d57cabba1037493d518a428bc124b953d621 Mon Sep 17 00:00:00 2001 From: Antonio Date: Fri, 9 Aug 2024 19:59:31 -0400 Subject: [PATCH 13/23] Fixed the order of mtypeprotect and mprotect in batchmap2 --- src/core/libraries/kernel/memory_management.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index db8a4a52..11e8a74c 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -296,10 +296,8 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn if (result == 0) processed++; - } else if (entries[i].operation == - MemoryOpTypes::ORBIS_KERNEL_MAP_OP_TYPE_PROTECT) { // MTYPEPROTECT - result = sceKernelMTypeProtect(entries[i].start, entries[i].length, entries[i].type, - entries[i].protection); + } else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_PROTECT) { + result = sceKernelMProtect(entries[i].start, entries[i].length, entries[i].protection); LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", i, entries[i].operation, entries[i].length, result); if (result != ORBIS_OK) { @@ -309,8 +307,9 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn if (result == 0) { processed++; } - } else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_PROTECT) { // MPROTECT - result = sceKernelMProtect(entries[i].start, entries[i].length, entries[i].protection); + } else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_TYPE_PROTECT) { + result = sceKernelMTypeProtect(entries[i].start, entries[i].length, entries[i].type, + entries[i].protection); LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", i, entries[i].operation, entries[i].length, result); if (result != ORBIS_OK) { From 434b20509f5a2b5dd2bb33af88fcaade1f30d090 Mon Sep 17 00:00:00 2001 From: Antonio Date: Fri, 9 Aug 2024 19:59:53 -0400 Subject: [PATCH 14/23] '' --- externals/fmt | 2 +- externals/glslang | 2 +- externals/magic_enum | 2 +- externals/sdl3 | 2 +- externals/toml11 | 2 +- externals/vulkan-headers | 2 +- externals/xxhash | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/externals/fmt b/externals/fmt index c9851835..bc8d32e9 160000 --- a/externals/fmt +++ b/externals/fmt @@ -1 +1 @@ -Subproject commit c98518351efd5a46f5d448e947e0b7242d197d07 +Subproject commit bc8d32e9643d2be5fc070abf2a50bc021544545d diff --git a/externals/glslang b/externals/glslang index 7c4d91e7..52f68dc6 160000 --- a/externals/glslang +++ b/externals/glslang @@ -1 +1 @@ -Subproject commit 7c4d91e7819a1d27213aa3499953d54ae1a00e8f +Subproject commit 52f68dc6b2a9d017b43161f31f13a6f44636ee7c diff --git a/externals/magic_enum b/externals/magic_enum index dae6bbf1..664ee62c 160000 --- a/externals/magic_enum +++ b/externals/magic_enum @@ -1 +1 @@ -Subproject commit dae6bbf16c363e9ead4e628a47fdb02956a634f3 +Subproject commit 664ee62c12570948b0e025d15b42d641fba8d54a diff --git a/externals/sdl3 b/externals/sdl3 index 4cc3410d..f9a06c20 160000 --- a/externals/sdl3 +++ b/externals/sdl3 @@ -1 +1 @@ -Subproject commit 4cc3410dce50cefce98d3cf3cf1bc8eca83b862a +Subproject commit f9a06c20ed85fb1d6754fc2280d6183382217910 diff --git a/externals/toml11 b/externals/toml11 index fcb1d3d7..b389bbc4 160000 --- a/externals/toml11 +++ b/externals/toml11 @@ -1 +1 @@ -Subproject commit fcb1d3d7e5885edfadbbe9572991dc4b3248af58 +Subproject commit b389bbc4ebf90fa2fe7651de3046fb19f661ba3c diff --git a/externals/vulkan-headers b/externals/vulkan-headers index 595c8d47..b379292b 160000 --- a/externals/vulkan-headers +++ b/externals/vulkan-headers @@ -1 +1 @@ -Subproject commit 595c8d4794410a4e64b98dc58d27c0310d7ea2fd +Subproject commit b379292b2ab6df5771ba9870d53cf8b2c9295daf diff --git a/externals/xxhash b/externals/xxhash index ee65ff98..a57f6cce 160000 --- a/externals/xxhash +++ b/externals/xxhash @@ -1 +1 @@ -Subproject commit ee65ff988bab34a184c700e2fbe1e1c5bc27485d +Subproject commit a57f6cce2698049863af8c25787084ae0489d849 From 671667228b9f7d0432c29c8d2949eedb77dee1e3 Mon Sep 17 00:00:00 2001 From: Antonio Date: Wed, 14 Aug 2024 18:38:54 -0400 Subject: [PATCH 15/23] update branch --- externals/ext-boost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/ext-boost b/externals/ext-boost index a04136ad..147b2de7 160000 --- a/externals/ext-boost +++ b/externals/ext-boost @@ -1 +1 @@ -Subproject commit a04136add1e469f46d8ae8d3e8307779240a5c53 +Subproject commit 147b2de7734f5dc3b9aeb1f4135ae15fcd44b9d7 From ef16a1b758e91765960ce114bc54ec84ad5bd824 Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 15 Aug 2024 08:53:23 -0400 Subject: [PATCH 16/23] '' --- externals/ext-boost | 2 +- externals/fmt | 2 +- externals/glslang | 2 +- externals/magic_enum | 2 +- externals/sdl3 | 2 +- externals/toml11 | 2 +- externals/vma | 2 +- externals/vulkan-headers | 2 +- externals/xxhash | 2 +- externals/zydis | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/externals/ext-boost b/externals/ext-boost index 147b2de7..a04136ad 160000 --- a/externals/ext-boost +++ b/externals/ext-boost @@ -1 +1 @@ -Subproject commit 147b2de7734f5dc3b9aeb1f4135ae15fcd44b9d7 +Subproject commit a04136add1e469f46d8ae8d3e8307779240a5c53 diff --git a/externals/fmt b/externals/fmt index bc8d32e9..c9851835 160000 --- a/externals/fmt +++ b/externals/fmt @@ -1 +1 @@ -Subproject commit bc8d32e9643d2be5fc070abf2a50bc021544545d +Subproject commit c98518351efd5a46f5d448e947e0b7242d197d07 diff --git a/externals/glslang b/externals/glslang index 52f68dc6..0dc6711e 160000 --- a/externals/glslang +++ b/externals/glslang @@ -1 +1 @@ -Subproject commit 52f68dc6b2a9d017b43161f31f13a6f44636ee7c +Subproject commit 0dc6711e5a178e4d5643437af688c6b48f829f5c diff --git a/externals/magic_enum b/externals/magic_enum index 664ee62c..dae6bbf1 160000 --- a/externals/magic_enum +++ b/externals/magic_enum @@ -1 +1 @@ -Subproject commit 664ee62c12570948b0e025d15b42d641fba8d54a +Subproject commit dae6bbf16c363e9ead4e628a47fdb02956a634f3 diff --git a/externals/sdl3 b/externals/sdl3 index f9a06c20..4cc3410d 160000 --- a/externals/sdl3 +++ b/externals/sdl3 @@ -1 +1 @@ -Subproject commit f9a06c20ed85fb1d6754fc2280d6183382217910 +Subproject commit 4cc3410dce50cefce98d3cf3cf1bc8eca83b862a diff --git a/externals/toml11 b/externals/toml11 index b389bbc4..cc0bee4f 160000 --- a/externals/toml11 +++ b/externals/toml11 @@ -1 +1 @@ -Subproject commit b389bbc4ebf90fa2fe7651de3046fb19f661ba3c +Subproject commit cc0bee4fd46ea1f5db147d63ea545208cc9e8405 diff --git a/externals/vma b/externals/vma index 871913da..e1bdbca9 160000 --- a/externals/vma +++ b/externals/vma @@ -1 +1 @@ -Subproject commit 871913da6a4b132b567d7b65c509600363c0041e +Subproject commit e1bdbca9baf4d682fb6066b380f4aa4a7bdbb58a diff --git a/externals/vulkan-headers b/externals/vulkan-headers index b379292b..595c8d47 160000 --- a/externals/vulkan-headers +++ b/externals/vulkan-headers @@ -1 +1 @@ -Subproject commit b379292b2ab6df5771ba9870d53cf8b2c9295daf +Subproject commit 595c8d4794410a4e64b98dc58d27c0310d7ea2fd diff --git a/externals/xxhash b/externals/xxhash index a57f6cce..54c14fe6 160000 --- a/externals/xxhash +++ b/externals/xxhash @@ -1 +1 @@ -Subproject commit a57f6cce2698049863af8c25787084ae0489d849 +Subproject commit 54c14fe6a6654abf12d315a45a68005586cb7610 diff --git a/externals/zydis b/externals/zydis index 16c6a369..bd73bc03 160000 --- a/externals/zydis +++ b/externals/zydis @@ -1 +1 @@ -Subproject commit 16c6a369c193981e9cf314126589eaa8763f92c3 +Subproject commit bd73bc03b0aacaa89c9c203b9b43cd08f1b1843b From dbb9a45af34e522e0b7eb224ad3aef8517971bef Mon Sep 17 00:00:00 2001 From: Antonio Date: Sat, 17 Aug 2024 14:49:23 -0400 Subject: [PATCH 17/23] Fixed nits --- .../libraries/kernel/memory_management.cpp | 22 +++--- src/core/libraries/kernel/memory_management.h | 4 +- src/core/memory.cpp | 78 +++++++++++-------- src/core/memory.h | 5 +- 4 files changed, 60 insertions(+), 49 deletions(-) diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index 189c7387..55f37e34 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -208,31 +208,29 @@ int PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void** return memory->QueryProtection(std::bit_cast(addr), start, end, prot); } -int PS4_SYSV_ABI sceKernelMProtect(void* addr, size_t size, int prot) { +int PS4_SYSV_ABI sceKernelMProtect(const void* addr, size_t size, int prot) { Core::MemoryManager* memory_manager = Core::Memory::Instance(); - if (!memory_manager) { - LOG_ERROR(Kernel_Vmm, "Failed to get MemoryManager instance"); - return ORBIS_KERNEL_ERROR_EINVAL; - } - int result = memory_manager->MProtect(std::bit_cast(addr), size, prot); + // Cast the 'prot' integer to 'MemoryProt' enum type + Core::MemoryProt protection_flags = static_cast(prot); + + int result = memory_manager->Protect(std::bit_cast(addr), size, protection_flags); if (result != ORBIS_OK) { LOG_ERROR(Kernel_Vmm, "MProtect failed with result {}", result); } return result; } -int PS4_SYSV_ABI sceKernelMTypeProtect(void* addr, size_t size, int mtype, int prot) { +int PS4_SYSV_ABI sceKernelMTypeProtect(const void* addr, size_t size, int mtype, int prot) { Core::MemoryManager* memory_manager = Core::Memory::Instance(); - if (!memory_manager) { - LOG_ERROR(Kernel_Vmm, "Failed to get MemoryManager instance"); - return ORBIS_KERNEL_ERROR_EINVAL; - } + + // Cast the 'prot' integer to 'MemoryProt' enum type + Core::MemoryProt protection_flags = static_cast(prot); int result = memory_manager->MTypeProtect(std::bit_cast(addr), size, - static_cast(mtype), prot); + static_cast(mtype), protection_flags); if (result != ORBIS_OK) { LOG_ERROR(Kernel_Vmm, "MTypeProtect failed with result {}", result); } diff --git a/src/core/libraries/kernel/memory_management.h b/src/core/libraries/kernel/memory_management.h index 440685c3..97018e43 100644 --- a/src/core/libraries/kernel/memory_management.h +++ b/src/core/libraries/kernel/memory_management.h @@ -95,9 +95,9 @@ s32 PS4_SYSV_ABI sceKernelMapFlexibleMemory(void** addr_in_out, std::size_t len, int flags); int PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void** end, u32* prot); -int PS4_SYSV_ABI sceKernelMProtect(void* addr, size_t size, int prot); +int PS4_SYSV_ABI sceKernelMProtect(const void* addr, size_t size, int prot); -int PS4_SYSV_ABI sceKernelMTypeProtect(void* addr, size_t size, int mtype, int prot); +int PS4_SYSV_ABI sceKernelMTypeProtect(const void* addr, size_t size, int mtype, int prot); int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info, size_t infoSize); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 931009e2..c06ad832 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -269,7 +269,7 @@ int MemoryManager::QueryProtection(VAddr addr, void** start, void** end, u32* pr return ORBIS_OK; } -int MemoryManager::MProtect(VAddr addr, size_t size, int prot) { +int MemoryManager::Protect(VAddr addr, size_t size, MemoryProt prot) { std::scoped_lock lk{mutex}; // Find the virtual memory area that contains the specified address range. @@ -285,38 +285,44 @@ int MemoryManager::MProtect(VAddr addr, size_t size, int prot) { return ORBIS_KERNEL_ERROR_EINVAL; } - // Check if the new protection flags are valid. - if ((static_cast(prot) & - ~(static_cast(MemoryProt::NoAccess) | static_cast(MemoryProt::CpuRead) | - static_cast(MemoryProt::CpuReadWrite) | static_cast(MemoryProt::GpuRead) | - static_cast(MemoryProt::GpuWrite) | static_cast(MemoryProt::GpuReadWrite))) != - 0) { + // Validate protection flags + MemoryProt valid_flags = MemoryProt::NoAccess | MemoryProt::CpuRead | MemoryProt::CpuReadWrite | + MemoryProt::GpuRead | MemoryProt::GpuWrite | MemoryProt::GpuReadWrite; + + if ((prot & ~valid_flags) != MemoryProt::NoAccess) { LOG_ERROR(Core, "Invalid protection flags, prot: {:#x}, GpuWrite: {:#x}", static_cast(prot), static_cast(MemoryProt::GpuWrite)); return ORBIS_KERNEL_ERROR_EINVAL; } - // Change the protection on the specified address range. - vma.prot = static_cast(prot); + // Change protection + vma.prot = prot; - // Use the Protect function from the AddressSpace class. - Core::MemoryPermission perms; - if ((static_cast(prot) & static_cast(MemoryProt::CpuRead)) != 0) + // Set permissions + Core::MemoryPermission perms{}; + + if ((prot & MemoryProt::CpuRead) != MemoryProt::NoAccess) { perms |= Core::MemoryPermission::Read; - if ((static_cast(prot) & static_cast(MemoryProt::CpuReadWrite)) != 0) + } + if ((prot & MemoryProt::CpuReadWrite) != MemoryProt::NoAccess) { perms |= Core::MemoryPermission::ReadWrite; - if ((static_cast(prot) & static_cast(MemoryProt::GpuRead)) != 0) + } + if ((prot & MemoryProt::GpuRead) != MemoryProt::NoAccess) { perms |= Core::MemoryPermission::Read; - if ((static_cast(prot) & static_cast(MemoryProt::GpuWrite)) != 0) + } + if ((prot & MemoryProt::GpuWrite) != MemoryProt::NoAccess) { perms |= Core::MemoryPermission::Write; - if ((static_cast(prot) & static_cast(MemoryProt::GpuReadWrite)) != 0) - perms |= Core::MemoryPermission::ReadWrite; // Add this line + } + if ((prot & MemoryProt::GpuReadWrite) != MemoryProt::NoAccess) { + perms |= Core::MemoryPermission::ReadWrite; + } + impl.Protect(addr, size, perms); return ORBIS_OK; } -int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot) { +int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, MemoryProt prot) { std::scoped_lock lk{mutex}; // Find the virtual memory area that contains the specified address range. @@ -333,33 +339,39 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot return ORBIS_KERNEL_ERROR_EINVAL; } - // Check if the new protection flags are valid. - if ((static_cast(prot) & - ~(static_cast(MemoryProt::NoAccess) | static_cast(MemoryProt::CpuRead) | - static_cast(MemoryProt::CpuReadWrite) | static_cast(MemoryProt::GpuRead) | - static_cast(MemoryProt::GpuWrite) | static_cast(MemoryProt::GpuReadWrite))) != - 0) { + // Validate protection flags + MemoryProt valid_flags = MemoryProt::NoAccess | MemoryProt::CpuRead | MemoryProt::CpuReadWrite | + MemoryProt::GpuRead | MemoryProt::GpuWrite | MemoryProt::GpuReadWrite; + + if ((prot & ~valid_flags) != MemoryProt::NoAccess) { LOG_ERROR(Core, "Invalid protection flags, prot: {:#x}, GpuWrite: {:#x}", static_cast(prot), static_cast(MemoryProt::GpuWrite)); return ORBIS_KERNEL_ERROR_EINVAL; } - // Change the type and protection on the specified address range. + // Change type and protection vma.type = mtype; - vma.prot = static_cast(prot); + vma.prot = prot; - // Use the Protect function from the AddressSpace class. - Core::MemoryPermission perms; - if ((static_cast(prot) & static_cast(MemoryProt::CpuRead)) != 0) + // Set permissions + Core::MemoryPermission perms{}; + + if ((prot & MemoryProt::CpuRead) != MemoryProt::NoAccess) { perms |= Core::MemoryPermission::Read; - if ((static_cast(prot) & static_cast(MemoryProt::CpuReadWrite)) != 0) + } + if ((prot & MemoryProt::CpuReadWrite) != MemoryProt::NoAccess) { perms |= Core::MemoryPermission::ReadWrite; - if ((static_cast(prot) & static_cast(MemoryProt::GpuRead)) != 0) + } + if ((prot & MemoryProt::GpuRead) != MemoryProt::NoAccess) { perms |= Core::MemoryPermission::Read; - if ((static_cast(prot) & static_cast(MemoryProt::GpuWrite)) != 0) + } + if ((prot & MemoryProt::GpuWrite) != MemoryProt::NoAccess) { perms |= Core::MemoryPermission::Write; - if ((static_cast(prot) & static_cast(MemoryProt::GpuReadWrite)) != 0) + } + if ((prot & MemoryProt::GpuReadWrite) != MemoryProt::NoAccess) { perms |= Core::MemoryPermission::ReadWrite; + } + impl.Protect(addr, size, perms); return ORBIS_OK; diff --git a/src/core/memory.h b/src/core/memory.h index 9c046c25..6502829b 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -30,6 +30,7 @@ enum class MemoryProt : u32 { GpuWrite = 32, GpuReadWrite = 38, }; +DECLARE_ENUM_FLAG_OPERATORS(MemoryProt) enum class MemoryMapFlags : u32 { NoFlags = 0, @@ -161,9 +162,9 @@ public: int QueryProtection(VAddr addr, void** start, void** end, u32* prot); - int MProtect(VAddr addr, size_t size, int prot); + int Protect(VAddr addr, size_t size, MemoryProt prot); - int MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot); + int MTypeProtect(VAddr addr, size_t size, VMAType mtype, MemoryProt prot); int VirtualQuery(VAddr addr, int flags, ::Libraries::Kernel::OrbisVirtualQueryInfo* info); From 66c709b4938101bfc018d6d6e13d89e8fc60d923 Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 19 Aug 2024 15:05:53 -0400 Subject: [PATCH 18/23] '' --- externals/glslang | 2 +- externals/vulkan-headers | 2 +- externals/xxhash | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/externals/glslang b/externals/glslang index d59c84d3..0dc6711e 160000 --- a/externals/glslang +++ b/externals/glslang @@ -1 +1 @@ -Subproject commit d59c84d388c805022e2bddea08aa41cbe7e43e55 +Subproject commit 0dc6711e5a178e4d5643437af688c6b48f829f5c diff --git a/externals/vulkan-headers b/externals/vulkan-headers index d205aff4..595c8d47 160000 --- a/externals/vulkan-headers +++ b/externals/vulkan-headers @@ -1 +1 @@ -Subproject commit d205aff40b4e15d4c568523ee6a26f85138126d9 +Subproject commit 595c8d4794410a4e64b98dc58d27c0310d7ea2fd diff --git a/externals/xxhash b/externals/xxhash index dbea33e4..54c14fe6 160000 --- a/externals/xxhash +++ b/externals/xxhash @@ -1 +1 @@ -Subproject commit dbea33e47e7c0fe0b7c8592cd931c7430c1f130d +Subproject commit 54c14fe6a6654abf12d315a45a68005586cb7610 From 7fe9efce5c4f580e8b14d2cf5b60c0fed0285a6b Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 19 Aug 2024 15:12:29 -0400 Subject: [PATCH 19/23] Update submodules to latest commits --- externals/ffmpeg-core | 2 +- externals/glslang | 2 +- externals/toml11 | 2 +- externals/vulkan-headers | 2 +- externals/xxhash | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/externals/ffmpeg-core b/externals/ffmpeg-core index e30b7d7f..63b5fa6a 160000 --- a/externals/ffmpeg-core +++ b/externals/ffmpeg-core @@ -1 +1 @@ -Subproject commit e30b7d7fe228bfb3f6e41ce1040b44a15eb7d5e0 +Subproject commit 63b5fa6a522a923a1f94f7431ba6d32a292cfac0 diff --git a/externals/glslang b/externals/glslang index 0dc6711e..4422273e 160000 --- a/externals/glslang +++ b/externals/glslang @@ -1 +1 @@ -Subproject commit 0dc6711e5a178e4d5643437af688c6b48f829f5c +Subproject commit 4422273e8464d20b9d8dd403cbfc3049e09a5f23 diff --git a/externals/toml11 b/externals/toml11 index cc0bee4f..26d403e4 160000 --- a/externals/toml11 +++ b/externals/toml11 @@ -1 +1 @@ -Subproject commit cc0bee4fd46ea1f5db147d63ea545208cc9e8405 +Subproject commit 26d403e46102269e5314199cd313e82e4e17d99a diff --git a/externals/vulkan-headers b/externals/vulkan-headers index 595c8d47..d205aff4 160000 --- a/externals/vulkan-headers +++ b/externals/vulkan-headers @@ -1 +1 @@ -Subproject commit 595c8d4794410a4e64b98dc58d27c0310d7ea2fd +Subproject commit d205aff40b4e15d4c568523ee6a26f85138126d9 diff --git a/externals/xxhash b/externals/xxhash index 54c14fe6..dbea33e4 160000 --- a/externals/xxhash +++ b/externals/xxhash @@ -1 +1 @@ -Subproject commit 54c14fe6a6654abf12d315a45a68005586cb7610 +Subproject commit dbea33e47e7c0fe0b7c8592cd931c7430c1f130d From 15b917f268a51d31f70034192dff1d03d390e424 Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 19 Aug 2024 15:23:21 -0400 Subject: [PATCH 20/23] '' --- externals/xbyak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/xbyak b/externals/xbyak index aabb091a..a78d6bac 160000 --- a/externals/xbyak +++ b/externals/xbyak @@ -1 +1 @@ -Subproject commit aabb091ae37068498751fd58202a9854408ecb0e +Subproject commit a78d6bac84bc9f7c1ec3a797a84c4e9d1381a492 From 169aec5d4c7ea3710fd8891cbeae275982236dd6 Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 19 Aug 2024 15:56:50 -0400 Subject: [PATCH 21/23] reverted ffmpeg --- externals/ffmpeg-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/ffmpeg-core b/externals/ffmpeg-core index 63b5fa6a..e30b7d7f 160000 --- a/externals/ffmpeg-core +++ b/externals/ffmpeg-core @@ -1 +1 @@ -Subproject commit 63b5fa6a522a923a1f94f7431ba6d32a292cfac0 +Subproject commit e30b7d7fe228bfb3f6e41ce1040b44a15eb7d5e0 From d768714a4acca69e852eb41483d0d0c7ee82f72a Mon Sep 17 00:00:00 2001 From: Antonio Date: Tue, 20 Aug 2024 14:33:59 -0400 Subject: [PATCH 22/23] '' --- src/core/address_space.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 410759fc..3c65010e 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -232,16 +232,9 @@ struct AddressSpace::Impl { LOG_CRITICAL(Common_Memory, "Unsupported protection flag combination"); } - const VAddr virtual_end = virtual_addr + size; - auto [it, end] = placeholders.equal_range({virtual_addr, virtual_end}); - while (it != end) { - const size_t offset = std::max(it->lower(), virtual_addr); - const size_t protect_length = std::min(it->upper(), virtual_end) - offset; - DWORD old_flags{}; - if (!VirtualProtect(virtual_base + offset, protect_length, new_flags, &old_flags)) { - LOG_CRITICAL(Common_Memory, "Failed to change virtual memory protect rules"); - } - ++it; + DWORD old_flags{}; + if (!VirtualProtect(reinterpret_cast(virtual_addr), size, new_flags, &old_flags)) { + LOG_CRITICAL(Common_Memory, "Failed to change virtual memory protection"); } } From 258e5f0ad97c5cab7ec40bb20b85259510170a31 Mon Sep 17 00:00:00 2001 From: Antonio Date: Tue, 20 Aug 2024 16:04:43 -0400 Subject: [PATCH 23/23] Fixed the nits --- src/core/address_space.cpp | 29 ++++++++---- .../libraries/kernel/memory_management.cpp | 22 ++-------- src/core/memory.cpp | 44 ++++++++++--------- 3 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 3c65010e..dec761ba 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -218,24 +218,36 @@ struct AddressSpace::Impl { void Protect(VAddr virtual_addr, size_t size, bool read, bool write, bool execute) { DWORD new_flags{}; + if (read && write && execute) { new_flags = PAGE_EXECUTE_READWRITE; } else if (read && write) { new_flags = PAGE_READWRITE; } else if (read && !write) { new_flags = PAGE_READONLY; - } else if (execute && !read && !write) { + } else if (execute && !read && not write) { new_flags = PAGE_EXECUTE; } else if (!read && !write && !execute) { new_flags = PAGE_NOACCESS; } else { - LOG_CRITICAL(Common_Memory, "Unsupported protection flag combination"); + LOG_CRITICAL(Common_Memory, + "Unsupported protection flag combination for address {:#x}, size {}", + virtual_addr, size); + return; } DWORD old_flags{}; - if (!VirtualProtect(reinterpret_cast(virtual_addr), size, new_flags, &old_flags)) { - LOG_CRITICAL(Common_Memory, "Failed to change virtual memory protection"); + bool success = + VirtualProtect(reinterpret_cast(virtual_addr), size, new_flags, &old_flags); + + if (!success) { + LOG_ERROR(Common_Memory, + "Failed to change virtual memory protection for address {:#x}, size {}", + virtual_addr, size); } + + // Use assert to ensure success in debug builds + assert(success && "Failed to change virtual memory protection"); } HANDLE process{}; @@ -477,10 +489,11 @@ void AddressSpace::Unmap(VAddr virtual_addr, size_t size, VAddr start_in_vma, VA } void AddressSpace::Protect(VAddr virtual_addr, size_t size, MemoryPermission perms) { - bool read = static_cast(perms & MemoryPermission::Read) != 0; - bool write = static_cast(perms & MemoryPermission::Write) != 0; - bool execute = static_cast(perms & MemoryPermission::Execute) != - 0; // Assuming you have an Execute permission + const bool read = True(perms & MemoryPermission::Read); + + const bool write = True(perms & MemoryPermission::Write); + + const bool execute = True(perms & MemoryPermission::Execute); return impl->Protect(virtual_addr, size, read, write, execute); } diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index 55f37e34..fa3e1bc4 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -209,32 +209,16 @@ int PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void** } int PS4_SYSV_ABI sceKernelMProtect(const void* addr, size_t size, int prot) { - Core::MemoryManager* memory_manager = Core::Memory::Instance(); - - // Cast the 'prot' integer to 'MemoryProt' enum type Core::MemoryProt protection_flags = static_cast(prot); - - int result = memory_manager->Protect(std::bit_cast(addr), size, protection_flags); - if (result != ORBIS_OK) { - LOG_ERROR(Kernel_Vmm, "MProtect failed with result {}", result); - } - return result; + return memory_manager->Protect(std::bit_cast(addr), size, protection_flags); } int PS4_SYSV_ABI sceKernelMTypeProtect(const void* addr, size_t size, int mtype, int prot) { - Core::MemoryManager* memory_manager = Core::Memory::Instance(); - - // Cast the 'prot' integer to 'MemoryProt' enum type Core::MemoryProt protection_flags = static_cast(prot); - - int result = memory_manager->MTypeProtect(std::bit_cast(addr), size, - static_cast(mtype), protection_flags); - if (result != ORBIS_OK) { - LOG_ERROR(Kernel_Vmm, "MTypeProtect failed with result {}", result); - } - return result; + return memory_manager->MTypeProtect(std::bit_cast(addr), size, + static_cast(mtype), protection_flags); } int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info, diff --git a/src/core/memory.cpp b/src/core/memory.cpp index c06ad832..9280f63b 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -286,12 +286,14 @@ int MemoryManager::Protect(VAddr addr, size_t size, MemoryProt prot) { } // Validate protection flags - MemoryProt valid_flags = MemoryProt::NoAccess | MemoryProt::CpuRead | MemoryProt::CpuReadWrite | - MemoryProt::GpuRead | MemoryProt::GpuWrite | MemoryProt::GpuReadWrite; + constexpr static MemoryProt valid_flags = MemoryProt::NoAccess | MemoryProt::CpuRead | + MemoryProt::CpuReadWrite | MemoryProt::GpuRead | + MemoryProt::GpuWrite | MemoryProt::GpuReadWrite; - if ((prot & ~valid_flags) != MemoryProt::NoAccess) { - LOG_ERROR(Core, "Invalid protection flags, prot: {:#x}, GpuWrite: {:#x}", - static_cast(prot), static_cast(MemoryProt::GpuWrite)); + MemoryProt invalid_flags = prot & ~valid_flags; + if (u32(invalid_flags) != 0 && u32(invalid_flags) != u32(MemoryProt::NoAccess)) { + LOG_ERROR(Core, "Invalid protection flags: prot = {:#x}, invalid flags = {:#x}", u32(prot), + invalid_flags); return ORBIS_KERNEL_ERROR_EINVAL; } @@ -301,19 +303,19 @@ int MemoryManager::Protect(VAddr addr, size_t size, MemoryProt prot) { // Set permissions Core::MemoryPermission perms{}; - if ((prot & MemoryProt::CpuRead) != MemoryProt::NoAccess) { + if (True(prot & MemoryProt::CpuRead)) { perms |= Core::MemoryPermission::Read; } - if ((prot & MemoryProt::CpuReadWrite) != MemoryProt::NoAccess) { + if (True(prot & MemoryProt::CpuReadWrite)) { perms |= Core::MemoryPermission::ReadWrite; } - if ((prot & MemoryProt::GpuRead) != MemoryProt::NoAccess) { + if (True(prot & MemoryProt::GpuRead)) { perms |= Core::MemoryPermission::Read; } - if ((prot & MemoryProt::GpuWrite) != MemoryProt::NoAccess) { + if (True(prot & MemoryProt::GpuWrite)) { perms |= Core::MemoryPermission::Write; } - if ((prot & MemoryProt::GpuReadWrite) != MemoryProt::NoAccess) { + if (True(prot & MemoryProt::GpuReadWrite)) { perms |= Core::MemoryPermission::ReadWrite; } @@ -340,12 +342,14 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, MemoryPr } // Validate protection flags - MemoryProt valid_flags = MemoryProt::NoAccess | MemoryProt::CpuRead | MemoryProt::CpuReadWrite | - MemoryProt::GpuRead | MemoryProt::GpuWrite | MemoryProt::GpuReadWrite; + constexpr static MemoryProt valid_flags = MemoryProt::NoAccess | MemoryProt::CpuRead | + MemoryProt::CpuReadWrite | MemoryProt::GpuRead | + MemoryProt::GpuWrite | MemoryProt::GpuReadWrite; - if ((prot & ~valid_flags) != MemoryProt::NoAccess) { - LOG_ERROR(Core, "Invalid protection flags, prot: {:#x}, GpuWrite: {:#x}", - static_cast(prot), static_cast(MemoryProt::GpuWrite)); + MemoryProt invalid_flags = prot & ~valid_flags; + if (u32(invalid_flags) != 0 && u32(invalid_flags) != u32(MemoryProt::NoAccess)) { + LOG_ERROR(Core, "Invalid protection flags: prot = {:#x}, invalid flags = {:#x}", u32(prot), + invalid_flags); return ORBIS_KERNEL_ERROR_EINVAL; } @@ -356,19 +360,19 @@ int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, MemoryPr // Set permissions Core::MemoryPermission perms{}; - if ((prot & MemoryProt::CpuRead) != MemoryProt::NoAccess) { + if (True(prot & MemoryProt::CpuRead)) { perms |= Core::MemoryPermission::Read; } - if ((prot & MemoryProt::CpuReadWrite) != MemoryProt::NoAccess) { + if (True(prot & MemoryProt::CpuReadWrite)) { perms |= Core::MemoryPermission::ReadWrite; } - if ((prot & MemoryProt::GpuRead) != MemoryProt::NoAccess) { + if (True(prot & MemoryProt::GpuRead)) { perms |= Core::MemoryPermission::Read; } - if ((prot & MemoryProt::GpuWrite) != MemoryProt::NoAccess) { + if (True(prot & MemoryProt::GpuWrite)) { perms |= Core::MemoryPermission::Write; } - if ((prot & MemoryProt::GpuReadWrite) != MemoryProt::NoAccess) { + if (True(prot & MemoryProt::GpuReadWrite)) { perms |= Core::MemoryPermission::ReadWrite; }