1*fdc4107cSJohn Marino /* Implement __enable_execute_stack using mprotect(2). 2*fdc4107cSJohn Marino Copyright (C) 2011, 2012 Free Software Foundation, Inc. 3*fdc4107cSJohn Marino 4*fdc4107cSJohn Marino This file is part of GCC. 5*fdc4107cSJohn Marino 6*fdc4107cSJohn Marino GCC is free software; you can redistribute it and/or modify it under 7*fdc4107cSJohn Marino the terms of the GNU General Public License as published by the Free 8*fdc4107cSJohn Marino Software Foundation; either version 3, or (at your option) any later 9*fdc4107cSJohn Marino version. 10*fdc4107cSJohn Marino 11*fdc4107cSJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12*fdc4107cSJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or 13*fdc4107cSJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14*fdc4107cSJohn Marino for more details. 15*fdc4107cSJohn Marino 16*fdc4107cSJohn Marino Under Section 7 of GPL version 3, you are granted additional 17*fdc4107cSJohn Marino permissions described in the GCC Runtime Library Exception, version 18*fdc4107cSJohn Marino 3.1, as published by the Free Software Foundation. 19*fdc4107cSJohn Marino 20*fdc4107cSJohn Marino You should have received a copy of the GNU General Public License and 21*fdc4107cSJohn Marino a copy of the GCC Runtime Library Exception along with this program; 22*fdc4107cSJohn Marino see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*fdc4107cSJohn Marino <http://www.gnu.org/licenses/>. */ 24*fdc4107cSJohn Marino 25*fdc4107cSJohn Marino #include <sys/mman.h> 26*fdc4107cSJohn Marino #include <unistd.h> 27*fdc4107cSJohn Marino #include <stdlib.h> 28*fdc4107cSJohn Marino 29*fdc4107cSJohn Marino #define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC) 30*fdc4107cSJohn Marino 31*fdc4107cSJohn Marino extern void __enable_execute_stack (void *); 32*fdc4107cSJohn Marino 33*fdc4107cSJohn Marino void 34*fdc4107cSJohn Marino __enable_execute_stack (void *addr) 35*fdc4107cSJohn Marino { 36*fdc4107cSJohn Marino static int size; 37*fdc4107cSJohn Marino static long mask; 38*fdc4107cSJohn Marino char *page, *ends; 39*fdc4107cSJohn Marino long page_addr, ends_addr; 40*fdc4107cSJohn Marino 41*fdc4107cSJohn Marino if (size == 0) 42*fdc4107cSJohn Marino { 43*fdc4107cSJohn Marino size = getpagesize (); 44*fdc4107cSJohn Marino mask = ~((long) size - 1); 45*fdc4107cSJohn Marino } 46*fdc4107cSJohn Marino page_addr = (long) addr; 47*fdc4107cSJohn Marino ends_addr = (long) (addr + __LIBGCC_TRAMPOLINE_SIZE__); 48*fdc4107cSJohn Marino 49*fdc4107cSJohn Marino page = (char *) (page_addr & mask); 50*fdc4107cSJohn Marino ends = (char *) ((ends_addr & mask) + size); 51*fdc4107cSJohn Marino 52*fdc4107cSJohn Marino /* 53*fdc4107cSJohn Marino * Note that no errors should be emitted by mprotect; it is considered 54*fdc4107cSJohn Marino * dangerous for library calls to send messages to stdout/stderr. 55*fdc4107cSJohn Marino */ 56*fdc4107cSJohn Marino if (mprotect (page, ends - page, STACK_PROT_RWX) < 0) 57*fdc4107cSJohn Marino abort (); 58*fdc4107cSJohn Marino } 59