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.
This commit is contained in:
@@ -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)
|
VMUserAddressSpace::VMUserAddressSpace(team_id id, addr_t base, size_t size)
|
||||||
:
|
:
|
||||||
VMAddressSpace(id, base, size, "address space"),
|
VMAddressSpace(id, base, size, "address space"),
|
||||||
@@ -591,9 +619,10 @@ second_chance:
|
|||||||
|
|
||||||
// keep walking
|
// keep walking
|
||||||
while (next != NULL && next->Base() + next->Size() - 1 <= end) {
|
while (next != NULL && next->Base() + next->Size() - 1 <= end) {
|
||||||
addr_t alignedBase = ROUNDUP(last->Base() + last->Size(),
|
addr_t alignedBase = align_address(last->Base() + last->Size(),
|
||||||
alignment);
|
alignment, addressSpec, start);
|
||||||
addr_t nextBase = std::min(end, next->Base() - 1);
|
addr_t nextBase = std::min(end, next->Base() - 1);
|
||||||
|
|
||||||
if (is_valid_spot(last->Base() + (last->Size() - 1),
|
if (is_valid_spot(last->Base() + (last->Size() - 1),
|
||||||
alignedBase, size, nextBase)) {
|
alignedBase, size, nextBase)) {
|
||||||
addr_t rangeEnd = std::min(nextBase - size + 1, end);
|
addr_t rangeEnd = std::min(nextBase - size + 1, end);
|
||||||
@@ -614,8 +643,9 @@ second_chance:
|
|||||||
if (foundSpot)
|
if (foundSpot)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
addr_t alignedBase = ROUNDUP(last->Base() + last->Size(),
|
addr_t alignedBase = align_address(last->Base() + last->Size(),
|
||||||
alignment);
|
alignment, addressSpec, start);
|
||||||
|
|
||||||
if (next == NULL && is_valid_spot(last->Base() + (last->Size() - 1),
|
if (next == NULL && is_valid_spot(last->Base() + (last->Size() - 1),
|
||||||
alignedBase, size, end)) {
|
alignedBase, size, end)) {
|
||||||
if (is_randomized(addressSpec)) {
|
if (is_randomized(addressSpec)) {
|
||||||
@@ -627,8 +657,7 @@ second_chance:
|
|||||||
foundSpot = true;
|
foundSpot = true;
|
||||||
area->SetBase(alignedBase);
|
area->SetBase(alignedBase);
|
||||||
break;
|
break;
|
||||||
} else if (addressSpec == B_BASE_ADDRESS
|
} else if (is_base_address_spec(addressSpec)) {
|
||||||
|| addressSpec == B_RANDOMIZED_BASE_ADDRESS) {
|
|
||||||
// we didn't find a free spot in the requested range, so we'll
|
// we didn't find a free spot in the requested range, so we'll
|
||||||
// try again without any restrictions
|
// try again without any restrictions
|
||||||
if (!is_randomized(addressSpec)) {
|
if (!is_randomized(addressSpec)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user