diff --git a/rpcs3/util/vm_native.cpp b/rpcs3/util/vm_native.cpp index e4dd50999d..278c37899c 100644 --- a/rpcs3/util/vm_native.cpp +++ b/rpcs3/util/vm_native.cpp @@ -254,8 +254,32 @@ namespace utils return nullptr; #else - const u64 ptr64 = reinterpret_cast(ptr); - return static_cast(::mmap(reinterpret_cast(ptr64 & -0x10000), m_size, +prot, MAP_SHARED | (ptr ? MAP_FIXED : 0), m_file, 0)); + const u64 ptr64 = reinterpret_cast(ptr) & -0x10000; + + if (ptr64) + { + return reinterpret_cast(reinterpret_cast(::mmap(reinterpret_cast(ptr64), m_size, +prot, MAP_SHARED | MAP_FIXED, m_file, 0))); + } + else + { + const u64 res64 = reinterpret_cast(::mmap(reinterpret_cast(ptr64), m_size + 0xe000, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0)); + + const u64 aligned = ::align(res64, 0x10000); + const auto result = ::mmap(reinterpret_cast(aligned), m_size, +prot, MAP_SHARED | MAP_FIXED, m_file, 0); + + // Now cleanup remnants + if (aligned > res64) + { + verify(HERE), ::munmap(reinterpret_cast(res64), aligned - res64) == 0; + } + + if (aligned < res64 + 0xe000) + { + verify(HERE), ::munmap(reinterpret_cast(aligned + m_size), (res64 + 0xe000) - (aligned)) == 0; + } + + return reinterpret_cast(result); + } #endif }