From 31fd85ce1d23cc880c0be69b7af048cde6ea22e3 Mon Sep 17 00:00:00 2001 From: DH Date: Wed, 19 Jul 2023 15:00:58 +0300 Subject: [PATCH] [rpcsx-os] vm: add getPageProtection api --- rpcsx-os/vm.cpp | 36 +++++++++++++++++++++++++++++++++++- rpcsx-os/vm.hpp | 1 + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/rpcsx-os/vm.cpp b/rpcsx-os/vm.cpp index 7be84ebff..7e9d791c7 100644 --- a/rpcsx-os/vm.cpp +++ b/rpcsx-os/vm.cpp @@ -307,6 +307,28 @@ struct Block { modifyFlags(firstPage, pagesCount, 0, flags); } + unsigned getProtection(std::uint64_t page) const { + std::uint64_t groupIndex = page / kGroupSize; + auto mask = makePagesMask(page & kGroupMask, 1); + auto &group = groups[groupIndex]; + + if ((group.allocated & mask) == 0) { + return 0; + } + + unsigned result = 0; + + result |= (group.readable & mask) == mask ? kReadable : 0; + result |= (group.writable & mask) == mask ? kReadable | kWritable : 0; + + result |= (group.executable & mask) == mask ? kReadable | kExecutable : 0; + + result |= (group.gpuReadable & mask) == mask ? kGpuReadable : 0; + result |= (group.gpuWritable & mask) == mask ? kGpuWritable : 0; + + return result; + } + void modifyFlags(std::uint64_t firstPage, std::uint64_t pagesCount, std::uint32_t addFlags, std::uint32_t removeFlags) { std::uint64_t groupIndex = firstPage / kGroupSize; @@ -344,7 +366,7 @@ struct Block { count = pagesCount; } - auto mask = makePagesMask(firstPage, count); + auto mask = makePagesMask(firstPage & kGroupMask, count); pagesCount -= count; auto &group = groups[groupIndex++]; @@ -893,6 +915,18 @@ bool rx::vm::queryProtection(const void *addr, std::uint64_t *startAddress, return false; } +unsigned rx::vm::getPageProtection(std::uint64_t address) { + if (address < kMinAddress || address >= kMaxAddress) { + std::printf("Memory error: getPageProtection out of memory\n"); + return 0; + } + + std::lock_guard lock(g_mtx); + + return gBlocks[(address >> kBlockShift) - kFirstBlock].getProtection( + (address & kBlockMask) >> kPageShift); +} + bool rx::vm::virtualQuery(const void *addr, std::int32_t flags, VirtualQueryInfo *info) { std::lock_guard lock(g_mtx); diff --git a/rpcsx-os/vm.hpp b/rpcsx-os/vm.hpp index a7999e20e..f5184629e 100644 --- a/rpcsx-os/vm.hpp +++ b/rpcsx-os/vm.hpp @@ -76,4 +76,5 @@ bool protect(void *addr, std::uint64_t size, std::int32_t prot); bool virtualQuery(const void *addr, std::int32_t flags, VirtualQueryInfo *info); bool queryProtection(const void *addr, std::uint64_t *startAddress, std::uint64_t *endAddress, std::int64_t *prot); +unsigned getPageProtection(std::uint64_t address); } // namespace rx::vm