diff --git a/Utilities/VirtualMemory.cpp b/Utilities/VirtualMemory.cpp index f3f81ae734..ff6558a0eb 100644 --- a/Utilities/VirtualMemory.cpp +++ b/Utilities/VirtualMemory.cpp @@ -11,32 +11,62 @@ #include #endif -namespace memory_helper +namespace utils { - void* reserve_memory(std::size_t size) + void* memory_reserve(std::size_t size) { #ifdef _WIN32 - return verify("reserve_memory" HERE, VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS)); + return verify("reserve_memory" HERE, ::VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS)); #else return verify("reserve_memory" HERE, ::mmap(nullptr, size, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0)); #endif } - void commit_page_memory(void* pointer, std::size_t size) + void memory_commit(void* pointer, std::size_t size) { #ifdef _WIN32 - verify(HERE), VirtualAlloc(pointer, size, MEM_COMMIT, PAGE_READWRITE); + verify(HERE), ::VirtualAlloc(pointer, size, MEM_COMMIT, PAGE_READWRITE); #else verify(HERE), ::mprotect((void*)((u64)pointer & -4096), ::align(size, 4096), PROT_READ | PROT_WRITE) != -1; #endif } - void free_reserved_memory(void* pointer, std::size_t size) + void memory_decommit(void* pointer, std::size_t size) { #ifdef _WIN32 - verify(HERE), VirtualFree(pointer, 0, MEM_DECOMMIT); + verify(HERE), ::VirtualFree(pointer, 0, MEM_DECOMMIT); #else verify(HERE), ::mmap(pointer, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); +#endif + } + + void memory_protect(void* pointer, std::size_t size, protection prot) + { +#ifdef _WIN32 + DWORD _prot = PAGE_NOACCESS; + switch (prot) + { + case protection::rw: _prot = PAGE_READWRITE; break; + case protection::ro: _prot = PAGE_READONLY; break; + case protection::no: break; + case protection::wx: _prot = PAGE_EXECUTE_READWRITE; break; + case protection::rx: _prot = PAGE_EXECUTE_READ; break; + } + + DWORD old; + verify(HERE), ::VirtualProtect(pointer, size, _prot, &old); +#else + int _prot = PROT_NONE; + switch (prot) + { + case protection::rw: _prot = PROT_READ | PROT_WRITE; break; + case protection::ro: _prot = PROT_READ; break; + case protection::no: break; + case protection::wx: _prot = PROT_READ | PROT_WRITE | PROT_EXEC; break; + case protection::rx: _prot = PROT_READ | PROT_EXEC; break; + } + + verify(HERE), ::mprotect((void*)((u64)pointer & -4096), ::align(size, 4096), _prot) != -1; #endif } } diff --git a/Utilities/VirtualMemory.h b/Utilities/VirtualMemory.h index c63d75f659..e8381f8c8e 100644 --- a/Utilities/VirtualMemory.h +++ b/Utilities/VirtualMemory.h @@ -1,22 +1,34 @@ #pragma once -namespace memory_helper +namespace utils { /** * Reserve `size` bytes of virtual memory and returns it. * The memory should be commited before usage. */ - void* reserve_memory(std::size_t size); + void* memory_reserve(std::size_t size); /** * Commit `size` bytes of virtual memory starting at pointer. * That is, bake reserved memory with physical memory. * pointer should belong to a range of reserved memory. */ - void commit_page_memory(void* pointer, std::size_t size); + void memory_commit(void* pointer, std::size_t size); /** * Decommit all memory committed via commit_page_memory. */ - void free_reserved_memory(void* pointer, std::size_t size); + void memory_decommit(void* pointer, std::size_t size); + + // Memory protection type + enum class protection + { + rw, // Read + write (default) + ro, // Read only + no, // No access + wx, // Read + write + execute + rx, // Read + execute + }; + + void memory_protect(void* pointer, std::size_t size, protection prot); } diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index a1186b8a9e..93f1382c2d 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -100,11 +100,11 @@ extern void ppu_initialize(const ppu_module& info); extern void ppu_execute_syscall(ppu_thread& ppu, u64 code); extern void ppu_execute_function(ppu_thread& ppu, u32 index); -const auto s_ppu_compiled = static_cast(memory_helper::reserve_memory(0x100000000)); +const auto s_ppu_compiled = static_cast(utils::memory_reserve(0x100000000)); extern void ppu_finalize() { - memory_helper::free_reserved_memory(s_ppu_compiled, 0x100000000); + utils::memory_decommit(s_ppu_compiled, 0x100000000); } // Get interpreter cache value @@ -139,7 +139,7 @@ extern void ppu_register_range(u32 addr, u32 size) } // Register executable range at - memory_helper::commit_page_memory(s_ppu_compiled + addr / 4, size); + utils::memory_commit(s_ppu_compiled + addr / 4, size); const u32 fallback = ::narrow(reinterpret_cast(ppu_fallback)); diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 7e91eee080..3439b7af70 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -28,7 +28,7 @@ namespace vm { // Emulated virtual memory (4 GiB) - u8* const g_base_addr = static_cast(memory_helper::reserve_memory(0x100000000)); + u8* const g_base_addr = static_cast(utils::memory_reserve(0x100000000)); // Memory locations std::vector> g_locations; @@ -796,7 +796,7 @@ namespace vm { g_locations.clear(); - memory_helper::free_reserved_memory(g_base_addr, 0x100000000); + utils::memory_decommit(g_base_addr, 0x100000000); } }