1214152Sed/* ===-- enable_execute_stack.c - Implement __enable_execute_stack ---------=== 2214152Sed * 3214152Sed * The LLVM Compiler Infrastructure 4214152Sed * 5222656Sed * This file is dual licensed under the MIT and the University of Illinois Open 6222656Sed * Source Licenses. See LICENSE.TXT for details. 7214152Sed * 8214152Sed * ===----------------------------------------------------------------------=== 9214152Sed */ 10214152Sed 11229135Sed#include "int_lib.h" 12229135Sed 13214152Sed#include <sys/mman.h> 14214152Sed 15214152Sed/* #include "config.h" 16214152Sed * FIXME: CMake - include when cmake system is ready. 17214152Sed * Remove #define HAVE_SYSCONF 1 line. 18214152Sed */ 19214152Sed#define HAVE_SYSCONF 1 20214152Sed 21214152Sed#ifndef __APPLE__ 22214152Sed#include <unistd.h> 23214152Sed#endif /* __APPLE__ */ 24214152Sed 25214152Sed#if __LP64__ 26214152Sed #define TRAMPOLINE_SIZE 48 27214152Sed#else 28214152Sed #define TRAMPOLINE_SIZE 40 29214152Sed#endif 30214152Sed 31214152Sed/* 32214152Sed * The compiler generates calls to __enable_execute_stack() when creating 33214152Sed * trampoline functions on the stack for use with nested functions. 34214152Sed * It is expected to mark the page(s) containing the address 35214152Sed * and the next 48 bytes as executable. Since the stack is normally rw- 36214152Sed * that means changing the protection on those page(s) to rwx. 37214152Sed */ 38214152Sed 39214152Sedvoid __enable_execute_stack(void* addr) 40214152Sed{ 41214152Sed 42214152Sed#if __APPLE__ 43214152Sed /* On Darwin, pagesize is always 4096 bytes */ 44214152Sed const uintptr_t pageSize = 4096; 45214152Sed#elif !defined(HAVE_SYSCONF) 46214152Sed#error "HAVE_SYSCONF not defined! See enable_execute_stack.c" 47214152Sed#else 48214152Sed const uintptr_t pageSize = sysconf(_SC_PAGESIZE); 49214152Sed#endif /* __APPLE__ */ 50214152Sed 51214152Sed const uintptr_t pageAlignMask = ~(pageSize-1); 52214152Sed uintptr_t p = (uintptr_t)addr; 53214152Sed unsigned char* startPage = (unsigned char*)(p & pageAlignMask); 54214152Sed unsigned char* endPage = (unsigned char*)((p+TRAMPOLINE_SIZE+pageSize) & pageAlignMask); 55214152Sed size_t length = endPage - startPage; 56214152Sed (void) mprotect((void *)startPage, length, PROT_READ | PROT_WRITE | PROT_EXEC); 57214152Sed} 58214152Sed 59214152Sed 60