From 6c417556091c57c2cd7c9f3303519e700e051d87 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 1 Dec 2013 00:44:58 +0100 Subject: [PATCH] VMUserAddressSpace::_InsertAreaSlot(): Fix base address handling Unless a free range was found before the first area a specified base address was ignored. In the non-randomized case this could result in a range other than (i.e. starting before) the preferred one being chosen, although the preferred range was available. --- src/system/kernel/vm/VMUserAddressSpace.cpp | 41 ++++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/system/kernel/vm/VMUserAddressSpace.cpp b/src/system/kernel/vm/VMUserAddressSpace.cpp index 1d58d0fd05..fa0cac2189 100644 --- a/src/system/kernel/vm/VMUserAddressSpace.cpp +++ b/src/system/kernel/vm/VMUserAddressSpace.cpp @@ -60,6 +60,34 @@ is_randomized(uint32 addressSpec) } +static inline bool +is_base_address_spec(uint32 addressSpec) +{ + return addressSpec == B_BASE_ADDRESS + || addressSpec == B_RANDOMIZED_BASE_ADDRESS; +} + + +static inline addr_t +align_address(addr_t address, size_t alignment) +{ + return ROUNDUP(address, alignment); +} + + +static inline addr_t +align_address(addr_t address, size_t alignment, uint32 addressSpec, + addr_t baseAddress) +{ + if (is_base_address_spec(addressSpec)) + address = std::max(address, baseAddress); + return align_address(address, alignment); +} + + +// #pragma mark - VMUserAddressSpace + + VMUserAddressSpace::VMUserAddressSpace(team_id id, addr_t base, size_t size) : VMAddressSpace(id, base, size, "address space"), @@ -591,9 +619,10 @@ second_chance: // keep walking while (next != NULL && next->Base() + next->Size() - 1 <= end) { - addr_t alignedBase = ROUNDUP(last->Base() + last->Size(), - alignment); + addr_t alignedBase = align_address(last->Base() + last->Size(), + alignment, addressSpec, start); addr_t nextBase = std::min(end, next->Base() - 1); + if (is_valid_spot(last->Base() + (last->Size() - 1), alignedBase, size, nextBase)) { addr_t rangeEnd = std::min(nextBase - size + 1, end); @@ -614,8 +643,9 @@ second_chance: if (foundSpot) break; - addr_t alignedBase = ROUNDUP(last->Base() + last->Size(), - alignment); + addr_t alignedBase = align_address(last->Base() + last->Size(), + alignment, addressSpec, start); + if (next == NULL && is_valid_spot(last->Base() + (last->Size() - 1), alignedBase, size, end)) { if (is_randomized(addressSpec)) { @@ -627,8 +657,7 @@ second_chance: foundSpot = true; area->SetBase(alignedBase); break; - } else if (addressSpec == B_BASE_ADDRESS - || addressSpec == B_RANDOMIZED_BASE_ADDRESS) { + } else if (is_base_address_spec(addressSpec)) { // we didn't find a free spot in the requested range, so we'll // try again without any restrictions if (!is_randomized(addressSpec)) {