mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 21:05:36 +00:00
Bug 530598: If we can't get the preferred address for a poison page, take whatever the OS will give us, rather than giving up
This commit is contained in:
parent
78bf5c8cea
commit
f6b3144136
@ -180,33 +180,38 @@ ARENA_POISON_init()
|
||||
return PR_SUCCESS;
|
||||
|
||||
} else {
|
||||
// Probe 1024 pages (four megabytes, typically) in both directions from
|
||||
// the baseline address before giving up.
|
||||
// First see if we can allocate the preferred poison address from the OS.
|
||||
PRUword candidate = (0xF0DEAFFF & ~(rgnsize-1));
|
||||
PRUword step = rgnsize;
|
||||
int direction = +1;
|
||||
PRUword limit = candidate + 1024*rgnsize;
|
||||
while (candidate < limit) {
|
||||
void *result = ReserveRegion(candidate, rgnsize);
|
||||
if (result == (void *)candidate) {
|
||||
// success - inaccessible page allocated
|
||||
ARENA_POISON = candidate + rgnsize/2 - 1;
|
||||
return PR_SUCCESS;
|
||||
void *result = ReserveRegion(candidate, rgnsize);
|
||||
if (result == (void *)candidate) {
|
||||
// success - inaccessible page allocated
|
||||
ARENA_POISON = candidate + rgnsize/2 - 1;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (result != RESERVE_FAILED)
|
||||
ReleaseRegion(result, rgnsize);
|
||||
// That didn't work, so see if the preferred address is within a range
|
||||
// of permanently inacessible memory.
|
||||
if (ProbeRegion(candidate, rgnsize)) {
|
||||
// success - selected page cannot be usable memory
|
||||
ARENA_POISON = candidate + rgnsize/2 - 1;
|
||||
if (result != RESERVE_FAILED)
|
||||
ReleaseRegion(result, rgnsize);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
if (ProbeRegion(candidate, rgnsize)) {
|
||||
// success - selected page cannot be usable memory
|
||||
ARENA_POISON = candidate + rgnsize/2 - 1;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
// The preferred address is already in use. Did the OS give us a
|
||||
// consolation prize?
|
||||
if (result != RESERVE_FAILED) {
|
||||
ARENA_POISON = PRUword(result) + rgnsize/2 - 1;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
candidate += step*direction;
|
||||
step = step + rgnsize;
|
||||
direction = -direction;
|
||||
// It didn't, so try to allocate again, without any constraint on
|
||||
// the address.
|
||||
result = ReserveRegion(0, rgnsize);
|
||||
if (result != RESERVE_FAILED) {
|
||||
ARENA_POISON = PRUword(result) + rgnsize/2 - 1;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
NS_RUNTIMEABORT("no usable poison region identified");
|
||||
|
@ -303,35 +303,42 @@ ReservePoisonArea()
|
||||
printf("INFO | poison area assumed at 0x%.*"PRIxPTR"\n", SIZxPTR, result);
|
||||
return result;
|
||||
} else {
|
||||
// Probe 1024 pages (four megabytes, typically) in both directions from
|
||||
// the baseline address before giving up.
|
||||
uintptr_t candidate = (0xF0DEAFFF & ~(uintptr_t)(PAGESIZE-1));
|
||||
uintptr_t step = PAGESIZE;
|
||||
intptr_t direction = +1;
|
||||
uintptr_t limit = candidate + 1024*PAGESIZE;
|
||||
while (candidate < limit) {
|
||||
void *result = ReserveRegion(candidate, false);
|
||||
if (result == (void *)candidate) {
|
||||
// success - inaccessible page allocated
|
||||
printf("INFO | poison area allocated at 0x%.*"PRIxPTR"\n",
|
||||
SIZxPTR, (uintptr_t)result);
|
||||
return candidate;
|
||||
// First see if we can allocate the preferred poison address from the OS.
|
||||
uintptr_t candidate = (0xF0DEAFFF & ~(PAGESIZE-1));
|
||||
void *result = ReserveRegion(candidate, false);
|
||||
if (result == (void *)candidate) {
|
||||
// success - inaccessible page allocated
|
||||
printf("INFO | poison area allocated at 0x%.*"PRIxPTR
|
||||
" (preferred addr)\n", SIZxPTR, (uintptr_t)result);
|
||||
return candidate;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (result != MAP_FAILED)
|
||||
ReleaseRegion(result);
|
||||
// That didn't work, so see if the preferred address is within a range
|
||||
// of permanently inacessible memory.
|
||||
if (ProbeRegion(candidate)) {
|
||||
// success - selected page cannot be usable memory
|
||||
if (result != MAP_FAILED)
|
||||
ReleaseRegion(result);
|
||||
printf("INFO | poison area assumed at 0x%.*"PRIxPTR
|
||||
" (preferred addr)\n", SIZxPTR, candidate);
|
||||
return candidate;
|
||||
}
|
||||
|
||||
if (ProbeRegion(candidate)) {
|
||||
// success - selected page cannot be usable memory
|
||||
printf("INFO | poison area probed at 0x%.*"PRIxPTR" | %s\n",
|
||||
SIZxPTR, candidate, LastErrMsg());
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
// The preferred address is already in use. Did the OS give us a
|
||||
// consolation prize?
|
||||
if (result != MAP_FAILED) {
|
||||
printf("INFO | poison area allocated at 0x%.*"PRIxPTR
|
||||
" (consolation prize)\n", SIZxPTR, (uintptr_t)result);
|
||||
return (uintptr_t)result;
|
||||
}
|
||||
|
||||
candidate += step*direction;
|
||||
step = step + PAGESIZE;
|
||||
direction = -direction;
|
||||
// It didn't, so try to allocate again, without any constraint on
|
||||
// the address.
|
||||
result = ReserveRegion(0, false);
|
||||
if (result != MAP_FAILED) {
|
||||
printf("INFO | poison area allocated at 0x%.*"PRIxPTR
|
||||
" (fallback)\n", SIZxPTR, (uintptr_t)result);
|
||||
return (uintptr_t)result;
|
||||
}
|
||||
|
||||
printf("ERROR | no usable poison area found\n");
|
||||
|
Loading…
Reference in New Issue
Block a user