1 /* ===-- enable_execute_stack.c - Implement __enable_execute_stack ---------=== 2 * 3 * The LLVM Compiler Infrastructure 4 * 5 * This file is distributed under the University of Illinois Open Source 6 * License. See LICENSE.TXT for details. 7 * 8 * ===----------------------------------------------------------------------=== 9 */ 10 11 #include <stdint.h> 12 #include <sys/mman.h> 13 14 /* #include "config.h" 15 * FIXME: CMake - include when cmake system is ready. 16 * Remove #define HAVE_SYSCONF 1 line. 17 */ 18 #define HAVE_SYSCONF 1 19 20 #ifndef __APPLE__ 21 #include <unistd.h> 22 #endif /* __APPLE__ */ 23 24 25 /* 26 * The compiler generates calls to __enable_execute_stack() when creating 27 * trampoline functions on the stack for use with nested functions. 28 * It is expected to mark the page(s) containing the address 29 * and the next 48 bytes as executable. Since the stack is normally rw- 30 * that means changing the protection on those page(s) to rwx. 31 */ 32 __enable_execute_stack(void * addr)33void __enable_execute_stack(void* addr) 34 { 35 36 #if __APPLE__ 37 /* On Darwin, pagesize is always 4096 bytes */ 38 const uintptr_t pageSize = 4096; 39 #elif !defined(HAVE_SYSCONF) 40 #error "HAVE_SYSCONF not defined! See enable_execute_stack.c" 41 #else 42 const uintptr_t pageSize = sysconf(_SC_PAGESIZE); 43 #endif /* __APPLE__ */ 44 45 const uintptr_t pageAlignMask = ~(pageSize-1); 46 uintptr_t p = (uintptr_t)addr; 47 unsigned char* startPage = (unsigned char*)(p & pageAlignMask); 48 unsigned char* endPage = (unsigned char*)((p+48+pageSize) & pageAlignMask); 49 size_t length = endPage - startPage; 50 (void) mprotect((void *)startPage, length, PROT_READ | PROT_WRITE | PROT_EXEC); 51 } 52 53 54