make JIT pages executable in Windows (where DEP is enabled)

svn: r3325
This commit is contained in:
Matthew Flatt 2006-06-11 13:48:51 +00:00
parent 41c7c4ca42
commit 66cb396047
2 changed files with 28 additions and 7 deletions

View File

@ -588,6 +588,7 @@
# define NO_MBTOWC_FUNCTIONS # define NO_MBTOWC_FUNCTIONS
# define MZ_USE_JIT_I386 # define MZ_USE_JIT_I386
# define MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC
# define FLAGS_ALREADY_SET # define FLAGS_ALREADY_SET
@ -1330,6 +1331,9 @@
/* MZ_JIT_USE_MPROTECT uses mprotect on x86 platforms to make code /* MZ_JIT_USE_MPROTECT uses mprotect on x86 platforms to make code
pages executable */ pages executable */
/* MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC uses VirtualAlloc to make
code pages executable. */
/***********************/ /***********************/
/* Heap Images */ /* Heap Images */
/***********************/ /***********************/

View File

@ -35,8 +35,11 @@
#define __lightning_funcs_h #define __lightning_funcs_h
#ifdef MZ_JIT_USE_MPROTECT #ifdef MZ_JIT_USE_MPROTECT
#include <unistd.h> # include <unistd.h>
#include <sys/mman.h> # include <sys/mman.h>
#endif
#ifdef MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC
# include <windows.h>
#endif #endif
static void static void
@ -51,16 +54,23 @@ jit_flush_code(void *dest, void *end)
execution of the data and stack segment are becoming more execution of the data and stack segment are becoming more
and more common (Fedora, for example), so we implement our and more common (Fedora, for example), so we implement our
jit_flush_code as an mprotect. */ jit_flush_code as an mprotect. */
#ifdef MZ_JIT_USE_MPROTECT #if defined(MZ_JIT_USE_MPROTECT) || defined(MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC)
static unsigned long prev_page = 0, prev_length = 0; static unsigned long prev_page = 0, prev_length = 0;
long page, length; long page, length;
#ifdef PAGESIZE # ifdef PAGESIZE
const long page_size = PAGESIZE; const long page_size = PAGESIZE;
#else # else
static long page_size = -1; static long page_size = -1;
if (page_size == -1) if (page_size == -1) {
# ifdef MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC
SYSTEM_INFO info;
GetSystemInfo(&info);
page_size = info.dwPageSize;
# else
page_size = sysconf (_SC_PAGESIZE); page_size = sysconf (_SC_PAGESIZE);
#endif # endif
}
# endif
page = (long) dest & ~(page_size - 1); page = (long) dest & ~(page_size - 1);
length = ((char *) end - (char *) page + page_size - 1) & ~(page_size - 1); length = ((char *) end - (char *) page + page_size - 1) & ~(page_size - 1);
@ -70,7 +80,14 @@ jit_flush_code(void *dest, void *end)
if (page >= prev_page && page + length <= prev_page + prev_length) if (page >= prev_page && page + length <= prev_page + prev_length)
return; return;
# ifdef MZ_JIT_USE_WINDOWS_VIRTUAL_ALLOC
{
DWORD old;
VirtualProtect((void *)page, length, PAGE_EXECUTE_READWRITE, &old);
}
# else
mprotect ((void *) page, length, PROT_READ | PROT_WRITE | PROT_EXEC); mprotect ((void *) page, length, PROT_READ | PROT_WRITE | PROT_EXEC);
# endif
/* See if we can extend the previously mprotect'ed memory area towards /* See if we can extend the previously mprotect'ed memory area towards
higher addresses: the starting address remains the same as before. */ higher addresses: the starting address remains the same as before. */