| 232 | } |
| 233 | |
| 234 | void* OSAllocator_64Bit::Mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) { |
| 235 | if (addr != 0 && addr < reinterpret_cast<void*>(LOWER_BOUND)) { |
| 236 | // If we are asked to allocate something outside of the 64-bit space |
| 237 | // Then we need to just hand this to the OS |
| 238 | return ::mmap(addr, length, prot, flags, fd, offset); |
| 239 | } |
| 240 | |
| 241 | uint64_t Addr = reinterpret_cast<uint64_t>(addr); |
| 242 | // Addr must be page aligned |
| 243 | if (Addr & ~FEXCore::Utils::FEX_PAGE_MASK) { |
| 244 | return reinterpret_cast<void*>(-EINVAL); |
| 245 | } |
| 246 | |
| 247 | // If FD is provided then offset must also be page aligned |
| 248 | if (fd != -1 && offset & ~FEXCore::Utils::FEX_PAGE_MASK) { |
| 249 | return reinterpret_cast<void*>(-EINVAL); |
| 250 | } |
| 251 | |
| 252 | // 64bit address overflow |
| 253 | if (Addr + length < Addr) { |
| 254 | return reinterpret_cast<void*>(-EOVERFLOW); |
| 255 | } |
| 256 | |
| 257 | bool Fixed = (flags & MAP_FIXED) || (flags & MAP_FIXED_NOREPLACE); |
| 258 | length = FEXCore::AlignUp(length, FEXCore::Utils::FEX_PAGE_SIZE); |
| 259 | |
| 260 | uint64_t AddrEnd = Addr + length; |
| 261 | size_t NumberOfPages = length / FEXCore::Utils::FEX_PAGE_SIZE; |
| 262 | |
| 263 | // This needs a mutex to be thread safe |
| 264 | auto lk = FEXCore::GuardSignalDeferringSectionWithFallback(AllocationMutex, TLSThread); |
| 265 | |
| 266 | uint64_t AllocatedOffset {}; |
| 267 | LiveVMARegion* LiveRegion {}; |
| 268 | |
| 269 | if (Fixed || Addr != 0) { |
| 270 | LiveRegion = FindLiveRegionForAddress(Addr, AddrEnd); |
| 271 | } |
| 272 | |
| 273 | again: |
| 274 | |
| 275 | struct RangeResult final { |
| 276 | LiveVMARegion *RegionInsertedInto; |
| 277 | void *Ptr; |
| 278 | }; |
| 279 | |
| 280 | auto CheckIfRangeFits = [&AllocatedOffset](LiveVMARegion* Region, uint64_t length, int prot, int flags, int fd, off_t offset, |
| 281 | uint64_t StartingPosition = 0) -> RangeResult { |
| 282 | uint64_t AllocatedPage {~0ULL}; |
| 283 | uint64_t NumberOfPages = length >> FEXCore::Utils::FEX_PAGE_SHIFT; |
| 284 | |
| 285 | if (Region->FreeSpace >= length) { |
| 286 | uint64_t LastAllocation = |
| 287 | StartingPosition ? (StartingPosition - Region->SlabInfo->Base) >> FEXCore::Utils::FEX_PAGE_SHIFT : Region->LastPageAllocation; |
| 288 | size_t RegionNumberOfPages = Region->SlabInfo->RegionSize >> FEXCore::Utils::FEX_PAGE_SHIFT; |
| 289 | |
| 290 | |
| 291 | if (Region->HadMunmap) { |