]> gitweb.factorcode.org Git - factor.git/commitdiff
VM: new method set_border_locked() in segment, so that you can remove
authorBjörn Lindqvist <bjourne@gmail.com>
Fri, 14 Aug 2015 22:06:59 +0000 (00:06 +0200)
committerJohn Benediktsson <mrjbq7@gmail.com>
Sat, 15 Aug 2015 03:19:56 +0000 (20:19 -0700)
the protection of the guard pages

vm/os-unix.cpp
vm/os-windows.cpp
vm/segments.hpp

index 206f1827bf9b3ff4dad5018d64ec3a10182f49e8..b9b1dcbef1fdf54c7094007fe662a9aaf09a9ffb 100644 (file)
@@ -91,24 +91,33 @@ segment::segment(cell size_, bool executable_p) {
   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() {
@@ -150,10 +159,13 @@ void factor_vm::end_sampling_profiler_timer() {
 }
 
 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);
 }
 
index 214b48ca29d4e59e72b1568fadb2571059733180..5ac44999d67f732abdc1679fc81c71ccf4c6070b 100644 (file)
@@ -95,23 +95,34 @@ segment::segment(cell size_, bool executable_p) {
   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() {
index 3e8a4b748fba4d3b45368da6f6c0341b4c6e1cfc..b136d9cd5e346830fc43bf628424161d9d143ef7 100644 (file)
@@ -13,14 +13,18 @@ struct 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);
 };
 
 }