vm: implement B_RANDOMIZED_ANY_ADDRESS address specification
Randomized equivalent of B_ANY_ADDRESS. When a free space is found (as in B_ANY_ADDRESS) the base adress is then randomized using _RandomizeAddress pretty much like it is done in B_RANDOMIZED_BASE_ADDRESS.
This commit is contained in:
parent
f9bab525f6
commit
b3e4c67739
@ -79,7 +79,7 @@ typedef struct area_info {
|
||||
#define B_CLONE_ADDRESS 3
|
||||
#define B_ANY_KERNEL_ADDRESS 4
|
||||
/* B_ANY_KERNEL_BLOCK_ADDRESS 5 */
|
||||
/* B_RANDOMIZED_ANY_ADDRESS 6 */
|
||||
#define B_RANDOMIZED_ANY_ADDRESS 6
|
||||
#define B_RANDOMIZED_BASE_ADDRESS 7
|
||||
|
||||
/* area protection */
|
||||
|
@ -174,6 +174,7 @@ VMUserAddressSpace::InsertArea(VMArea* _area, size_t size,
|
||||
case B_ANY_ADDRESS:
|
||||
case B_ANY_KERNEL_ADDRESS:
|
||||
case B_ANY_KERNEL_BLOCK_ADDRESS:
|
||||
case B_RANDOMIZED_ANY_ADDRESS:
|
||||
searchBase = fBase;
|
||||
// TODO: remove this again when vm86 mode is moved into the kernel
|
||||
// completely (currently needs a userland address space!)
|
||||
@ -402,8 +403,11 @@ VMUserAddressSpace::Dump() const
|
||||
|
||||
|
||||
addr_t
|
||||
VMUserAddressSpace::_RandomizeAddress(addr_t start, addr_t end, bool initial)
|
||||
VMUserAddressSpace::_RandomizeAddress(addr_t start, addr_t end,
|
||||
size_t alignment, bool initial)
|
||||
{
|
||||
ASSERT((start & addr_t(alignment - 1)) == 0);
|
||||
|
||||
if (start == end)
|
||||
return start;
|
||||
|
||||
@ -430,7 +434,7 @@ VMUserAddressSpace::_RandomizeAddress(addr_t start, addr_t end, bool initial)
|
||||
range = min_c(range, kMaxRandomize);
|
||||
|
||||
random %= range;
|
||||
random &= ~addr_t(B_PAGE_SIZE - 1);
|
||||
random &= ~addr_t(alignment - 1);
|
||||
|
||||
return start + random;
|
||||
}
|
||||
@ -555,13 +559,13 @@ VMUserAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end,
|
||||
alignment <<= 1;
|
||||
}
|
||||
|
||||
if (addressSpec == B_RANDOMIZED_BASE_ADDRESS) {
|
||||
originalStart = start;
|
||||
start = _RandomizeAddress(start, end - size, true);
|
||||
}
|
||||
|
||||
start = ROUNDUP(start, alignment);
|
||||
|
||||
if (addressSpec == B_RANDOMIZED_BASE_ADDRESS) {
|
||||
originalStart = start;
|
||||
start = _RandomizeAddress(start, end - size, alignment, true);
|
||||
}
|
||||
|
||||
// walk up to the spot where we should start searching
|
||||
second_chance:
|
||||
VMUserAreaList::Iterator it = fAreas.GetIterator();
|
||||
@ -581,13 +585,20 @@ second_chance:
|
||||
case B_ANY_ADDRESS:
|
||||
case B_ANY_KERNEL_ADDRESS:
|
||||
case B_ANY_KERNEL_BLOCK_ADDRESS:
|
||||
case B_RANDOMIZED_ANY_ADDRESS:
|
||||
{
|
||||
// find a hole big enough for a new area
|
||||
if (last == NULL) {
|
||||
// see if we can build it at the beginning of the virtual map
|
||||
addr_t alignedBase = ROUNDUP(start, alignment);
|
||||
if (is_valid_spot(start, alignedBase, size,
|
||||
next == NULL ? end : next->Base())) {
|
||||
addr_t nextBase = next == NULL ? end : next->Base();
|
||||
if (is_valid_spot(start, alignedBase, size, nextBase)) {
|
||||
|
||||
if (addressSpec == B_RANDOMIZED_ANY_ADDRESS) {
|
||||
alignedBase = _RandomizeAddress(alignedBase,
|
||||
nextBase - size, alignment);
|
||||
}
|
||||
|
||||
foundSpot = true;
|
||||
area->SetBase(alignedBase);
|
||||
break;
|
||||
@ -603,6 +614,12 @@ second_chance:
|
||||
alignment);
|
||||
if (is_valid_spot(last->Base() + (last->Size() - 1),
|
||||
alignedBase, size, next->Base())) {
|
||||
|
||||
if (addressSpec == B_RANDOMIZED_ANY_ADDRESS) {
|
||||
alignedBase = _RandomizeAddress(alignedBase,
|
||||
next->Base() - size, alignment);
|
||||
}
|
||||
|
||||
foundSpot = true;
|
||||
area->SetBase(alignedBase);
|
||||
break;
|
||||
@ -619,6 +636,12 @@ second_chance:
|
||||
alignment);
|
||||
if (is_valid_spot(last->Base() + (last->Size() - 1), alignedBase,
|
||||
size, end)) {
|
||||
|
||||
if (addressSpec == B_RANDOMIZED_ANY_ADDRESS) {
|
||||
alignedBase = _RandomizeAddress(alignedBase, end - size,
|
||||
alignment);
|
||||
}
|
||||
|
||||
// got a spot
|
||||
foundSpot = true;
|
||||
area->SetBase(alignedBase);
|
||||
@ -653,12 +676,19 @@ second_chance:
|
||||
if ((next->protection & RESERVED_AVOID_BASE) == 0
|
||||
&& alignedBase == next->Base()
|
||||
&& next->Size() >= size) {
|
||||
|
||||
if (addressSpec == B_RANDOMIZED_ANY_ADDRESS) {
|
||||
alignedBase = _RandomizeAddress(next->Base(),
|
||||
next->Size() - size, alignment);
|
||||
}
|
||||
addr_t offset = alignedBase - next->Base();
|
||||
|
||||
// The new area will be placed at the beginning of the
|
||||
// reserved area and the reserved area will be offset
|
||||
// and resized
|
||||
foundSpot = true;
|
||||
next->SetBase(next->Base() + size);
|
||||
next->SetSize(next->Size() - size);
|
||||
next->SetBase(next->Base() + offset + size);
|
||||
next->SetSize(next->Size() - offset - size);
|
||||
area->SetBase(alignedBase);
|
||||
break;
|
||||
}
|
||||
@ -668,8 +698,23 @@ second_chance:
|
||||
// The new area will be placed at the end of the
|
||||
// reserved area, and the reserved area will be resized
|
||||
// to make space
|
||||
alignedBase = ROUNDDOWN(
|
||||
next->Base() + next->Size() - size, alignment);
|
||||
|
||||
if (addressSpec == B_RANDOMIZED_ANY_ADDRESS) {
|
||||
addr_t alignedNextBase = ROUNDUP(next->Base(),
|
||||
alignment);
|
||||
|
||||
addr_t startRange = next->Base() + next->Size();
|
||||
startRange -= size + kMaxRandomize;
|
||||
startRange = ROUNDDOWN(startRange, alignment);
|
||||
|
||||
startRange = max_c(startRange, alignedNextBase);
|
||||
|
||||
alignedBase = _RandomizeAddress(startRange,
|
||||
next->Base() + next->Size() - size, alignment);
|
||||
} else {
|
||||
alignedBase = ROUNDDOWN(
|
||||
next->Base() + next->Size() - size, alignment);
|
||||
}
|
||||
|
||||
foundSpot = true;
|
||||
next->SetSize(alignedBase - next->Base());
|
||||
@ -726,7 +771,7 @@ second_chance:
|
||||
spaceEnd = next->Base();
|
||||
|
||||
start = _RandomizeAddress(lastEnd + 1, spaceEnd - size,
|
||||
false);
|
||||
B_PAGE_SIZE);
|
||||
}
|
||||
|
||||
area->SetBase(start);
|
||||
@ -736,10 +781,12 @@ second_chance:
|
||||
|
||||
// we didn't find a free spot in the requested range, so we'll
|
||||
// try again without any restrictions
|
||||
if (addressSpec != B_RANDOMIZED_BASE_ADDRESS
|
||||
|| originalStart == 0) {
|
||||
if (addressSpec != B_RANDOMIZED_BASE_ADDRESS) {
|
||||
start = fBase;
|
||||
addressSpec = B_ANY_ADDRESS;
|
||||
} else if (originalStart == 0) {
|
||||
start = fBase;
|
||||
addressSpec = B_RANDOMIZED_ANY_ADDRESS;
|
||||
} else {
|
||||
start = originalStart;
|
||||
originalStart = 0;
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
|
||||
private:
|
||||
static addr_t _RandomizeAddress(addr_t start, addr_t end,
|
||||
bool initial);
|
||||
size_t alignment, bool initial = false);
|
||||
|
||||
status_t _InsertAreaIntoReservedRegion(addr_t start,
|
||||
size_t size, VMUserArea* area,
|
||||
|
@ -1219,6 +1219,7 @@ vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
||||
case B_BASE_ADDRESS:
|
||||
case B_ANY_KERNEL_ADDRESS:
|
||||
case B_ANY_KERNEL_BLOCK_ADDRESS:
|
||||
case B_RANDOMIZED_ANY_ADDRESS:
|
||||
case B_RANDOMIZED_BASE_ADDRESS:
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user