From b4ed5b152505ed1dc46d2af083acb19053661787 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 28 Jun 2015 10:12:37 -0700 Subject: Use mmap with a hint rather than sbrk for allocating executable memory within 32-bit displacement range of compiled code --- mem.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) (limited to 'mem.c') diff --git a/mem.c b/mem.c index d019c6f..cb3a047 100644 --- a/mem.c +++ b/mem.c @@ -8,33 +8,20 @@ #include #include #include + #include "mem.h" +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif -/* void * alloc_code(size_t *size) { + //start at the 1GB mark to allow plenty of room for sbrk based malloc implementations + //while still keeping well within 32-bit displacement range for calling code compiled into the executable + static uint8_t *next = (uint8_t *)0x40000000; *size += PAGE_SIZE - (*size & (PAGE_SIZE - 1)); - return mmap(NULL, *size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -} -*/ - -/* -void * alloc_code(size_t *size) -{ - char * ret = malloc(*size); - char * base = (char *)(((intptr_t)ret) & (~(PAGE_SIZE-1))); - mprotect(base, (ret + *size) - base, PROT_EXEC | PROT_READ | PROT_WRITE); + uint8_t *ret = mmap(NULL, *size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + next = ret + *size; return ret; } -*/ -void * alloc_code(size_t *size) -{ - *size += PAGE_SIZE - (*size & (PAGE_SIZE - 1)); - void * ret = sbrk(*size); - if (ret == ((void *)-1)) { - return NULL; - } - mprotect(ret, *size, PROT_EXEC | PROT_READ | PROT_WRITE); - return ret; -} -- cgit v1.2.3 From f345f5d118a45778f46b478f438eb47fc31d6705 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 28 Jun 2015 10:21:51 -0700 Subject: Use MAP_32BIT on Linux since my hint seems to be ignored --- mem.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'mem.c') diff --git a/mem.c b/mem.c index cb3a047..048f751 100644 --- a/mem.c +++ b/mem.c @@ -14,13 +14,17 @@ #define MAP_ANONYMOUS MAP_ANON #endif +#ifndef MAP_32BIT +#define MAP_32BIT 0 +#endif + void * alloc_code(size_t *size) { //start at the 1GB mark to allow plenty of room for sbrk based malloc implementations //while still keeping well within 32-bit displacement range for calling code compiled into the executable static uint8_t *next = (uint8_t *)0x40000000; *size += PAGE_SIZE - (*size & (PAGE_SIZE - 1)); - uint8_t *ret = mmap(NULL, *size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + uint8_t *ret = mmap(NULL, *size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); next = ret + *size; return ret; } -- cgit v1.2.3 From 5aa414e068c120a74a1f42e8e7de8692e8c1a55a Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Tue, 21 Jul 2015 21:29:43 -0700 Subject: Better error handling in alloc_code --- mem.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'mem.c') diff --git a/mem.c b/mem.c index 048f751..c9bb75a 100644 --- a/mem.c +++ b/mem.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "mem.h" #ifndef MAP_ANONYMOUS @@ -25,6 +27,10 @@ void * alloc_code(size_t *size) static uint8_t *next = (uint8_t *)0x40000000; *size += PAGE_SIZE - (*size & (PAGE_SIZE - 1)); uint8_t *ret = mmap(NULL, *size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + if (ret == MAP_FAILED) { + perror("alloc_code"); + return NULL; + } next = ret + *size; return ret; } -- cgit v1.2.3