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
__enable_execute_stack(void * addr)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