xref: /dflybsd-src/contrib/gcc-4.7/libgcc/enable-execute-stack-freebsd.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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