From 5e901ea3b185f9e39ab3bbce6fa8a3aac4c5a752 Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 28 Dec 2025 19:21:26 +0300 Subject: [PATCH] rx/mem: fix query address alignment for win32, allow 0 alignment for reserve --- rx/include/rx/mem.hpp | 2 ++ rx/src/mem.cpp | 29 +++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/rx/include/rx/mem.hpp b/rx/include/rx/mem.hpp index efd733d0b..7c36b41ef 100644 --- a/rx/include/rx/mem.hpp +++ b/rx/include/rx/mem.hpp @@ -24,6 +24,8 @@ struct VirtualQueryEntry : rx::AddressRange { }; extern const std::size_t pageSize; +extern const std::size_t allocationPageSize; + std::errc reserve(rx::AddressRange range); std::errc release(rx::AddressRange range, std::size_t alignment); std::errc protect(rx::AddressRange range, rx::EnumBitSet prot); diff --git a/rx/src/mem.cpp b/rx/src/mem.cpp index 5c35db33e..45c01cc4e 100644 --- a/rx/src/mem.cpp +++ b/rx/src/mem.cpp @@ -1,5 +1,6 @@ #include "mem.hpp" #include "die.hpp" +#include "print.hpp" #ifdef _WIN32 #define NTDDI_VERSION NTDDI_WIN10_NI @@ -17,8 +18,15 @@ const std::size_t rx::mem::pageSize = [] { ::GetSystemInfo(&info); return info.dwPageSize; }(); +const std::size_t rx::mem::allocationPageSize = [] { + SYSTEM_INFO info; + ::GetSystemInfo(&info); + return info.dwAllocationGranularity; +}(); + #else const std::size_t rx::mem::pageSize = sysconf(_SC_PAGE_SIZE); +const std::size_t rx::mem::allocationPageSize = rx::mem::pageSize; #endif std::errc rx::mem::reserve(rx::AddressRange range) { @@ -53,6 +61,16 @@ std::errc rx::mem::release(rx::AddressRange range, [[maybe_unused]] std::size_t alignment) { #ifdef _WIN32 // simple and stupid implementation + if (alignment == 0) { + auto pointer = std::bit_cast(range.beginAddress()); + if (!UnmapViewOfFileEx(pointer, MEM_PRESERVE_PLACEHOLDER)) { + VirtualFree(pointer, range.size(), + MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); + } + + return {}; + } + for (std::uintptr_t address = range.beginAddress(); address < range.endAddress(); address += alignment) { auto pointer = std::bit_cast(address); @@ -118,8 +136,15 @@ std::vector rx::mem::query(rx::AddressRange range) { } auto region = rx::AddressRange::fromBeginSize( - (std::uintptr_t)info.BaseAddress, info.RegionSize) - .intersection(range); + (std::uintptr_t)info.BaseAddress, info.RegionSize); + + if (info.State != MEM_FREE) { + region = rx::AddressRange::fromBeginEnd( + rx::alignDown(region.beginAddress(), allocationPageSize), + rx::alignUp(region.endAddress(), allocationPageSize)); + } + + region = region.intersection(range); address = region.endAddress();