diff options
Diffstat (limited to 'src/compile/compile.c')
-rw-r--r-- | src/compile/compile.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/src/compile/compile.c b/src/compile/compile.c index e741a0f..490bc43 100644 --- a/src/compile/compile.c +++ b/src/compile/compile.c @@ -19,10 +19,10 @@ struct reloc_helper { #define VEC_NAME addrs #include "../vec.h" -static void *alloc_arena(size_t size) +static void *alloc_arena(size_t size, bool im_scawed) { return mmap(NULL, size, - PROT_EXEC | PROT_READ | PROT_WRITE, + (!im_scawed ? PROT_EXEC : 0) | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } @@ -2414,7 +2414,15 @@ static void assign_fprs(struct ejit_func *f) } } -bool ejit_compile(struct ejit_func *f, bool use_64) +static size_t align_up(size_t a, size_t n) +{ + if (a % n == 0) + return a; + + return a + (a % n); +} + +bool ejit_compile(struct ejit_func *f, bool use_64, bool im_scawed) { (void)use_64; #if __WORDSIZE == 32 @@ -2436,10 +2444,11 @@ bool ejit_compile(struct ejit_func *f, bool use_64) assert(j); void *arena = NULL; - size_t size = 4096; + size_t pagesize = sysconf(_SC_PAGE_SIZE); + size_t size = pagesize; while (1) { - arena = alloc_arena(size); + arena = alloc_arena(size, im_scawed); if (arena == (void *)(-1)) { jit_destroy_state(j); return false; @@ -2450,10 +2459,16 @@ bool ejit_compile(struct ejit_func *f, bool use_64) break; free_arena(arena, size); - size = required_size + 4096; + size = align_up(required_size + pagesize, pagesize); } jit_destroy_state(j); + + if (im_scawed && mprotect(arena, size, PROT_EXEC | PROT_READ)) { + free_arena(arena, size); + return false; + } + f->arena = arena; f->size = size; return true; |