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