VM: new method set_border_locked() in segment, so that you can remove
the protection of the guard pagesdb4
parent
50822c1a8a
commit
b8aef640f9
|
@ -91,24 +91,33 @@ segment::segment(cell size_, bool executable_p) {
|
||||||
else
|
else
|
||||||
prot = PROT_READ | PROT_WRITE;
|
prot = PROT_READ | PROT_WRITE;
|
||||||
|
|
||||||
char* array = (char*)mmap(NULL, pagesize + size + pagesize, prot,
|
char* array = (char*)mmap(NULL, 2 * pagesize + size, prot,
|
||||||
MAP_ANON | MAP_PRIVATE, -1, 0);
|
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||||
|
|
||||||
if (array == (char*)- 1)
|
if (array == (char*)-1)
|
||||||
out_of_memory("mmap");
|
out_of_memory("mmap");
|
||||||
|
|
||||||
if (mprotect(array, pagesize, PROT_NONE) == -1) {
|
|
||||||
check_ENOMEM("mprotect low");
|
|
||||||
fatal_error("Cannot protect low guard page", (cell)array);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mprotect(array + pagesize + size, pagesize, PROT_NONE) == -1) {
|
|
||||||
check_ENOMEM("mprotect high");
|
|
||||||
fatal_error("Cannot protect high guard page", (cell)array);
|
|
||||||
}
|
|
||||||
|
|
||||||
start = (cell)(array + pagesize);
|
start = (cell)(array + pagesize);
|
||||||
end = start + size;
|
end = start + size;
|
||||||
|
|
||||||
|
set_border_locked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void segment::set_border_locked(bool locked) {
|
||||||
|
int prot = locked ? PROT_NONE : PROT_READ | PROT_WRITE;
|
||||||
|
int pagesize = getpagesize();
|
||||||
|
|
||||||
|
cell lo = start - pagesize;
|
||||||
|
if (mprotect((char*)lo, pagesize, prot) == -1) {
|
||||||
|
check_ENOMEM("mprotect low");
|
||||||
|
fatal_error("Cannot (un)protect low guard page", lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell hi = end;
|
||||||
|
if (mprotect((char*)hi, pagesize, prot) == -1) {
|
||||||
|
check_ENOMEM("mprotect high");
|
||||||
|
fatal_error("Cannot protect high guard page", lo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
segment::~segment() {
|
segment::~segment() {
|
||||||
|
@ -150,10 +159,13 @@ void factor_vm::end_sampling_profiler_timer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_signal_handler(int signal, siginfo_t* siginfo, void* uap) {
|
void memory_signal_handler(int signal, siginfo_t* siginfo, void* uap) {
|
||||||
|
|
||||||
|
cell fault_addr = (cell)siginfo->si_addr;
|
||||||
|
cell fault_pc = (cell)UAP_PROGRAM_COUNTER(uap);
|
||||||
factor_vm* vm = current_vm();
|
factor_vm* vm = current_vm();
|
||||||
vm->verify_memory_protection_error((cell)siginfo->si_addr);
|
vm->verify_memory_protection_error(fault_addr);
|
||||||
vm->signal_fault_addr = (cell)siginfo->si_addr;
|
vm->signal_fault_addr = fault_addr;
|
||||||
vm->signal_fault_pc = (cell)UAP_PROGRAM_COUNTER(uap);
|
vm->signal_fault_pc = fault_pc;
|
||||||
vm->dispatch_signal(uap, factor::memory_signal_handler_impl);
|
vm->dispatch_signal(uap, factor::memory_signal_handler_impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,23 +95,34 @@ segment::segment(cell size_, bool executable_p) {
|
||||||
size = size_;
|
size = size_;
|
||||||
|
|
||||||
char* mem;
|
char* mem;
|
||||||
DWORD ignore;
|
|
||||||
|
|
||||||
if ((mem = (char*)VirtualAlloc(
|
if ((mem = (char*)VirtualAlloc(
|
||||||
NULL, getpagesize() * 2 + size, MEM_COMMIT,
|
NULL, getpagesize() * 2 + size, MEM_COMMIT,
|
||||||
executable_p ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE)) ==
|
executable_p ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE)) ==
|
||||||
0)
|
0) {
|
||||||
out_of_memory("VirtualAlloc");
|
out_of_memory("VirtualAlloc");
|
||||||
|
}
|
||||||
if (!VirtualProtect(mem, getpagesize(), PAGE_NOACCESS, &ignore))
|
|
||||||
fatal_error("Cannot allocate low guard page", (cell)mem);
|
|
||||||
|
|
||||||
if (!VirtualProtect(mem + size + getpagesize(), getpagesize(), PAGE_NOACCESS,
|
|
||||||
&ignore))
|
|
||||||
fatal_error("Cannot allocate high guard page", (cell)mem);
|
|
||||||
|
|
||||||
start = (cell)mem + getpagesize();
|
start = (cell)mem + getpagesize();
|
||||||
end = start + size;
|
end = start + size;
|
||||||
|
|
||||||
|
set_border_locked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void segment::set_border_locked(bool locked) {
|
||||||
|
int prot = locked ? PAGE_NOACCESS : PAGE_READWRITE;
|
||||||
|
int pagesize = getpagesize();
|
||||||
|
DWORD ignore;
|
||||||
|
|
||||||
|
cell lo = start - pagesize;
|
||||||
|
if (!VirtualProtect((char*)lo, pagesize, prot, &ignore)) {
|
||||||
|
fatal_error("Cannot (un)protect low guard page", lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell hi = end;
|
||||||
|
if (!VirtualProtect((char*)hi, pagesize, prot, &ignore)) {
|
||||||
|
fatal_error("Cannot (un)protect high guard page", lo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
segment::~segment() {
|
segment::~segment() {
|
||||||
|
|
|
@ -13,14 +13,18 @@ struct segment {
|
||||||
~segment();
|
~segment();
|
||||||
|
|
||||||
bool underflow_p(cell addr) {
|
bool underflow_p(cell addr) {
|
||||||
return (addr >= start - getpagesize() && addr < start);
|
return addr >= (start - getpagesize()) && addr < start;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool overflow_p(cell addr) {
|
bool overflow_p(cell addr) {
|
||||||
return (addr >= end && addr < end + getpagesize());
|
return addr >= end && addr < (end + getpagesize());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool in_segment_p(cell addr) { return (addr >= start && addr < end); }
|
bool in_segment_p(cell addr) {
|
||||||
|
return addr >= start && addr < end;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_border_locked(bool locked);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue