diff --git a/rpcs3/util/vm.hpp b/rpcs3/util/vm.hpp index ab8aa20896..7486c28356 100644 --- a/rpcs3/util/vm.hpp +++ b/rpcs3/util/vm.hpp @@ -67,6 +67,9 @@ namespace utils // Map shared memory u8* map(void* ptr, protection prot = protection::rw) const; + // Attempt to map shared memory fix fixed pointer + u8* try_map(void* ptr, protection prot = protection::rw) const; + // Map shared memory over reserved memory region, which is unsafe (non-atomic) under Win32 u8* map_critical(void* ptr, protection prot = protection::rw); diff --git a/rpcs3/util/vm_native.cpp b/rpcs3/util/vm_native.cpp index a6f2fbd869..49df623ac2 100644 --- a/rpcs3/util/vm_native.cpp +++ b/rpcs3/util/vm_native.cpp @@ -120,7 +120,7 @@ namespace utils auto ptr = ::mmap(use_addr, size, PROT_NONE, MAP_ANON | MAP_PRIVATE | c_map_noreserve, -1, 0); - if (ptr == reinterpret_cast(-1)) + if (ptr == reinterpret_cast(UINT64_MAX)) { return nullptr; } @@ -179,7 +179,7 @@ namespace utils ensure(::VirtualFree(pointer, size, MEM_DECOMMIT)); #else const u64 ptr64 = reinterpret_cast(pointer); - ensure(::mmap(pointer, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE | c_map_noreserve, -1, 0) != reinterpret_cast(-1)); + ensure(::mmap(pointer, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE | c_map_noreserve, -1, 0) != reinterpret_cast(UINT64_MAX)); if constexpr (c_madv_no_dump != 0) { @@ -195,7 +195,7 @@ namespace utils memory_commit(pointer, size, prot); #else const u64 ptr64 = reinterpret_cast(pointer); - ensure(::mmap(pointer, size, +prot, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0) != reinterpret_cast(-1)); + ensure(::mmap(pointer, size, +prot, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0) != reinterpret_cast(UINT64_MAX)); if constexpr (c_madv_hugepage != 0) { @@ -376,6 +376,25 @@ namespace utils #endif } + u8* shm::try_map(void* ptr, protection prot) const + { + // Non-null pointer shall be specified + const auto target = ensure(reinterpret_cast(reinterpret_cast(ptr) & -0x10000)); + +#ifdef _WIN32 + return this->map(target, prot); +#else + const auto result = reinterpret_cast(::mmap(reinterpret_cast(target), m_size, +prot, MAP_SHARED, m_file, 0)); + + if (result == reinterpret_cast(UINT64_MAX)) + { + [[unlikely]] return nullptr; + } + + return result; +#endif + } + u8* shm::map_critical(void* ptr, protection prot) { const auto target = reinterpret_cast(reinterpret_cast(ptr) & -0x10000);