else
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);
- if (array == (char*)- 1)
+ if (array == (char*)-1)
out_of_memory("mmap");
- if (mprotect(array, pagesize, PROT_NONE) == -1) {
+ start = (cell)(array + pagesize);
+ 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 protect low guard page", (cell)array);
+ fatal_error("Cannot (un)protect low guard page", lo);
}
- if (mprotect(array + pagesize + size, pagesize, PROT_NONE) == -1) {
+ cell hi = end;
+ if (mprotect((char*)hi, pagesize, prot) == -1) {
check_ENOMEM("mprotect high");
- fatal_error("Cannot protect high guard page", (cell)array);
+ fatal_error("Cannot protect high guard page", lo);
}
-
- start = (cell)(array + pagesize);
- end = start + size;
}
segment::~segment() {
}
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();
- vm->verify_memory_protection_error((cell)siginfo->si_addr);
- vm->signal_fault_addr = (cell)siginfo->si_addr;
- vm->signal_fault_pc = (cell)UAP_PROGRAM_COUNTER(uap);
+ vm->verify_memory_protection_error(fault_addr);
+ vm->signal_fault_addr = fault_addr;
+ vm->signal_fault_pc = fault_pc;
vm->dispatch_signal(uap, factor::memory_signal_handler_impl);
}
size = size_;
char* mem;
- DWORD ignore;
if ((mem = (char*)VirtualAlloc(
NULL, getpagesize() * 2 + size, MEM_COMMIT,
executable_p ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE)) ==
- 0)
+ 0) {
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();
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();
bool underflow_p(cell addr) {
- return (addr >= start - getpagesize() && addr < start);
+ return addr >= (start - getpagesize()) && addr < start;
}
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);
};
}