1
/* This file is derived from the GCC sources. */
3
/* Copyright (C) 1989-2006 Free Software Foundation, Inc.
5
This file is part of GNU CC.
7
GNU CC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
12
GNU CC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with GNU CC; see the file COPYING. If not, write to
19
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22
/* Taken from gcc-4.1.0/gcc/config/alpha/osf.h. */
24
#if defined (__alpha__)
27
__enable_execute_stack (void *addr)
29
long size = getpagesize ();
30
long mask = ~(size-1);
31
char *page = (char *) (((long) addr) & mask);
32
char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);
34
/* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */
35
if (mprotect (page, end - page, 7) < 0)
36
perror ("mprotect of trampoline code");
41
/* Taken from gcc-4.1.0/gcc/config/sparc/freebsd.h. */
43
#if defined (__sparc__)
45
extern int sysctlbyname(const char *, void *, size_t *, void *, size_t);
46
static int need_enable_exec_stack;
47
static void check_enabling(void) __attribute__ ((constructor));
48
static void check_enabling(void)
51
size_t len = sizeof(prot);
53
sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);
55
need_enable_exec_stack = 1;
57
void __enable_execute_stack (void *addr)
59
if (!need_enable_exec_stack)
62
/* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */
63
if (mprotect (addr, TRAMPOLINE_SIZE, 7) < 0)
64
perror ("mprotect of trampoline code");
70
/* Taken from gcc-4.1.0/gcc/config/sol2.h. */
72
#if (defined (__sparc__) || defined (__i386__)) && defined(__svr4__) && defined(__sun)
74
extern long sysconf(int);
76
static int need_enable_exec_stack;
78
static void check_enabling(void) __attribute__ ((constructor));
79
static void check_enabling(void)
81
int prot = (int) sysconf(515 /* _SC_STACK_PROT */);
82
if (prot != 7 /* STACK_PROT_RWX */)
83
need_enable_exec_stack = 1;
87
__enable_execute_stack (void *addr)
89
if (!need_enable_exec_stack)
92
long size = getpagesize ();
93
long mask = ~(size-1);
94
char *page = (char *) (((long) addr) & mask);
95
char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);
97
if (mprotect (page, end - page, 7 /* STACK_PROT_RWX */) < 0)
98
perror ("mprotect of trampoline code");
104
/* Taken from gcc-4.1.0/gcc/config/openbsd.h. */
106
#if defined (__OpenBSD__)
108
/* Stack is explicitly denied execution rights on OpenBSD platforms. */
110
__enable_execute_stack (void *addr)
112
long size = getpagesize ();
113
long mask = ~(size-1);
114
char *page = (char *) (((long) addr) & mask);
115
char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);
117
if (mprotect (page, end - page, PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
118
perror ("mprotect of trampoline code");
123
/* Taken from gcc-4.1.0/gcc/config/netbsd.h. */
125
#if defined (__NetBSD__)
127
extern int __sysctl (int *, unsigned int, void *, size_t *, void *, size_t);
130
__enable_execute_stack (void *addr)
142
mib[0] = 6; /* CTL_HW */
143
mib[1] = 7; /* HW_PAGESIZE */
145
(void) __sysctl (mib, 2, &size, &len, NULL, 0);
146
mask = ~((long) size - 1);
149
page = (char *) (((long) addr) & mask);
150
end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);
152
/* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */
153
(void) mprotect (page, end - page, 7);
158
/* The rest is taken from gcc-2.6.3/libgcc2.c. */
160
#if defined (NeXT) && defined (__MACH__)
162
/* Make stack executable so we can call trampolines on stack.
163
This is called from INITIALIZE_TRAMPOLINE in next.h. */
167
#include <mach/mach.h>
171
__enable_execute_stack (addr)
175
char *eaddr = addr + TRAMPOLINE_SIZE;
176
vm_address_t a = (vm_address_t) addr;
178
/* turn on execute access on stack */
179
r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
180
if (r != KERN_SUCCESS)
182
mach_error("vm_protect VM_PROT_ALL", r);
187
#endif /* defined (NeXT) && defined (__MACH__) */
191
/* Make stack executable so we can call trampolines on stack.
192
This is called from INITIALIZE_TRAMPOLINE in convex.h. */
194
#include <sys/mman.h>
195
#include <sys/vmparam.h>
196
#include <machine/machparam.h>
199
__enable_execute_stack ()
202
static unsigned lowest = USRSTACK;
203
unsigned current = (unsigned) &fp & -NBPG;
205
if (lowest > current)
207
unsigned len = lowest - current;
208
mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
212
#endif /* __convex__ */
216
/* Modified from the convex -code above. */
218
#include <sys/param.h>
220
#include <sys/m88kbcs.h>
223
__enable_execute_stack ()
226
static unsigned long lowest = USRSTACK;
227
unsigned long current = (unsigned long) &save_errno & -NBPC;
229
/* Ignore errno being set. memctl sets errno to EINVAL whenever the
230
address is seen as 'negative'. That is the case with the stack. */
233
if (lowest > current)
235
unsigned len=lowest-current;
236
memctl(current,len,MCT_TEXT);
240
memctl(current,NBPC,MCT_TEXT);
244
#endif /* __DOLPHIN__ */
248
#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
250
#include <sys/mman.h>
251
#include <sys/types.h>
252
#include <sys/param.h>
253
#include <sys/vmmac.h>
255
/* Modified from the convex -code above.
256
mremap promises to clear the i-cache. */
259
__enable_execute_stack ()
262
if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
263
PROT_READ|PROT_WRITE|PROT_EXEC))
265
perror ("mprotect in __enable_execute_stack");