From 56ddb59b0000c490c44f76c3415f762f64106f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lindqvist?= Date: Mon, 24 Aug 2015 08:47:36 +0200 Subject: [PATCH] VM: new function set_memory_locked(true/false) it wraps the mprotect/VirtualProtect platform differences and makes it so you can unify some windows/unix code path forks --- vm/code_blocks.cpp | 2 +- vm/code_heap.cpp | 2 +- vm/code_heap.hpp | 4 ++-- vm/factor.hpp | 2 ++ vm/os-unix.cpp | 22 +++++++++++++--------- vm/os-windows.cpp | 26 ++++++++++++++------------ 6 files changed, 33 insertions(+), 25 deletions(-) diff --git a/vm/code_blocks.cpp b/vm/code_blocks.cpp index 9ebc46bcc8..ee59463568 100644 --- a/vm/code_blocks.cpp +++ b/vm/code_blocks.cpp @@ -212,7 +212,7 @@ cell factor_vm::lookup_external_address(relocation_type rel_type, case RT_INLINE_CACHE_MISS: return (cell)&factor::inline_cache_miss; case RT_SAFEPOINT: - return (cell)code->safepoint_page; + return code->safepoint_page; default: return -1; } diff --git a/vm/code_heap.cpp b/vm/code_heap.cpp index 20afd023d4..3dd4683bbe 100644 --- a/vm/code_heap.cpp +++ b/vm/code_heap.cpp @@ -14,7 +14,7 @@ code_heap::code_heap(cell size) { allocator = new free_list_allocator(seg->end - start, start); /* See os-windows-x86.64.cpp for seh_area usage */ - safepoint_page = (void*)seg->start; + safepoint_page = seg->start; seh_area = (char*)seg->start + getpagesize(); } diff --git a/vm/code_heap.hpp b/vm/code_heap.hpp index bf1237f818..dc74840990 100644 --- a/vm/code_heap.hpp +++ b/vm/code_heap.hpp @@ -11,7 +11,7 @@ struct code_heap { segment* seg; /* Memory area reserved for safepoint guard page */ - void* safepoint_page; + cell safepoint_page; /* Memory area reserved for SEH. Only used on Windows */ char* seh_area; @@ -51,7 +51,7 @@ struct code_heap { bool safepoint_p(cell addr) { cell page_mask = ~(getpagesize() - 1); - return (addr & page_mask) == (cell)safepoint_page; + return (addr & page_mask) == safepoint_page; } }; diff --git a/vm/factor.hpp b/vm/factor.hpp index 5c60258a01..a370d1e3ba 100644 --- a/vm/factor.hpp +++ b/vm/factor.hpp @@ -13,4 +13,6 @@ void unlock_console(); void ignore_ctrl_c(); void handle_ctrl_c(); +bool set_memory_locked(cell base, cell size, bool locked); + } diff --git a/vm/os-unix.cpp b/vm/os-unix.cpp index e1d4439485..6d4a04a7a6 100644 --- a/vm/os-unix.cpp +++ b/vm/os-unix.cpp @@ -2,6 +2,12 @@ namespace factor { +bool set_memory_locked(cell base, cell size, bool locked) { + int prot = locked ? PROT_NONE : PROT_READ | PROT_WRITE; + int status = mprotect((char*)base, size, prot); + return status != -1; +} + THREADHANDLE start_thread(void* (*start_routine)(void*), void* args) { pthread_attr_t attr; pthread_t thread; @@ -98,19 +104,17 @@ segment::segment(cell size_, bool executable_p) { } 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) { + if (!set_memory_locked(lo, pagesize, locked)) { check_ENOMEM("mprotect low"); fatal_error("Cannot (un)protect low guard page", lo); } cell hi = end; - if (mprotect((char*)hi, pagesize, prot) == -1) { + if (!set_memory_locked(hi, pagesize, locked)) { check_ENOMEM("mprotect high"); - fatal_error("Cannot protect high guard page", lo); + fatal_error("Cannot (un)protect high guard page", hi); } } @@ -122,13 +126,13 @@ segment::~segment() { } void code_heap::guard_safepoint() { - if (mprotect(safepoint_page, getpagesize(), PROT_NONE) == -1) - fatal_error("Cannot protect safepoint guard page", (cell)safepoint_page); + if (!set_memory_locked(safepoint_page, getpagesize(), true)) + fatal_error("Cannot protect safepoint guard page", safepoint_page); } void code_heap::unguard_safepoint() { - if (mprotect(safepoint_page, getpagesize(), PROT_WRITE) == -1) - fatal_error("Cannot unprotect safepoint guard page", (cell)safepoint_page); + if (!set_memory_locked(safepoint_page, getpagesize(), false)) + fatal_error("Cannot unprotect safepoint guard page", safepoint_page); } void factor_vm::dispatch_signal(void* uap, void(handler)()) { diff --git a/vm/os-windows.cpp b/vm/os-windows.cpp index 343acbe272..586849e0a5 100644 --- a/vm/os-windows.cpp +++ b/vm/os-windows.cpp @@ -4,6 +4,13 @@ namespace factor { HMODULE hFactorDll; +bool set_memory_locked(cell base, cell size, bool locked) { + int prot = locked ? PAGE_NOACCESS : PAGE_READWRITE; + DWORD ignore; + int status = VirtualProtect((char*)base, size, prot, &ignore); + return status != 0; +} + void factor_vm::init_ffi() { hFactorDll = GetModuleHandle(NULL); if (!hFactorDll) @@ -101,18 +108,15 @@ segment::segment(cell size_, bool executable_p) { } 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)) { + if (!set_memory_locked(lo, pagesize, locked)) { 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); + if (!set_memory_locked(hi, pagesize, locked)) { + fatal_error("Cannot (un)protect high guard page", hi); } } @@ -134,15 +138,13 @@ long getpagesize() { } void code_heap::guard_safepoint() { - DWORD ignore; - if (!VirtualProtect(safepoint_page, getpagesize(), PAGE_NOACCESS, &ignore)) - fatal_error("Cannot protect safepoint guard page", (cell)safepoint_page); + if (!set_memory_locked(safepoint_page, getpagesize(), true)) + fatal_error("Cannot protect safepoint guard page", safepoint_page); } void code_heap::unguard_safepoint() { - DWORD ignore; - if (!VirtualProtect(safepoint_page, getpagesize(), PAGE_READWRITE, &ignore)) - fatal_error("Cannot unprotect safepoint guard page", (cell)safepoint_page); + if (!set_memory_locked(safepoint_page, getpagesize(), false)) + fatal_error("Cannot unprotect safepoint guard page", safepoint_page); } void factor_vm::move_file(const vm_char* path1, const vm_char* path2) {