diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index fd9d31fe56..f6f9dcf0db 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -1205,15 +1205,29 @@ namespace vm shm = std::make_shared(size); } + const u32 max = (this->addr + this->size - size) & (0 - align); + + u32 addr = utils::align(this->addr, align); + + if (this->addr > std::min(max, addr)) + { + return 0; + } + vm::writer_lock lock(0); // Search for an appropriate place (unoptimized) - for (u32 addr = utils::align(this->addr, align); u64{addr} + size <= u64{this->addr} + this->size; addr += align) + for (;; addr += align) { if (try_alloc(addr, pflags, size, std::move(shm))) { return addr + (flags & stack_guarded ? 0x1000 : 0); } + + if (addr == max) + { + break; + } } return 0; @@ -1417,12 +1431,24 @@ namespace vm static std::shared_ptr _find_map(u32 size, u32 align, u64 flags) { - for (u32 addr = utils::align(0x20000000, align); addr - 1 < 0xC0000000 - 1; addr += align) + const u32 max = (0xC0000000 - size) & (0 - align); + + if (size > 0xC0000000 - 0x20000000 || max < 0x20000000) + { + return nullptr; + } + + for (u32 addr = utils::align(0x20000000, align);; addr += align) { if (_test_map(addr, size)) { return std::make_shared(addr, size, flags); } + + if (addr == max) + { + break; + } } return nullptr;