~ubuntu-branches/debian/squeeze/ffcall/squeeze

« back to all changes in this revision

Viewing changes to callback/trampoline_r/protexec.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Egger
  • Date: 2010-06-26 15:29:30 UTC
  • mfrom: (5.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100626152930-c09y01gk3szcnykn
Tags: 1.10+cvs20100619-2
Ship to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is derived from the GCC sources.  */
 
2
 
 
3
/* Copyright (C) 1989-2006 Free Software Foundation, Inc.
 
4
 
 
5
This file is part of GNU CC.
 
6
 
 
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)
 
10
any later version.
 
11
 
 
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.
 
16
 
 
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.  */
 
20
 
 
21
 
 
22
/* Taken from gcc-4.1.0/gcc/config/alpha/osf.h.  */
 
23
 
 
24
#if defined (__alpha__)
 
25
 
 
26
void
 
27
__enable_execute_stack (void *addr)
 
28
{
 
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);
 
33
 
 
34
  /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */
 
35
  if (mprotect (page, end - page, 7) < 0)
 
36
    perror ("mprotect of trampoline code");
 
37
}
 
38
 
 
39
#endif
 
40
 
 
41
/* Taken from gcc-4.1.0/gcc/config/sparc/freebsd.h.  */
 
42
 
 
43
#if defined (__sparc__)
 
44
 
 
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)
 
49
{
 
50
  int prot = 0;
 
51
  size_t len = sizeof(prot);
 
52
 
 
53
  sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);
 
54
  if (prot != 7)
 
55
    need_enable_exec_stack = 1;
 
56
}
 
57
void __enable_execute_stack (void *addr)
 
58
{
 
59
  if (!need_enable_exec_stack)
 
60
    return;
 
61
  else {
 
62
    /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */
 
63
    if (mprotect (addr, TRAMPOLINE_SIZE, 7) < 0)
 
64
      perror ("mprotect of trampoline code");
 
65
  }
 
66
}
 
67
 
 
68
#endif
 
69
 
 
70
/* Taken from gcc-4.1.0/gcc/config/sol2.h.  */
 
71
 
 
72
#if (defined (__sparc__) || defined (__i386__)) && defined(__svr4__) && defined(__sun)
 
73
 
 
74
extern long sysconf(int);
 
75
 
 
76
static int need_enable_exec_stack;
 
77
 
 
78
static void check_enabling(void) __attribute__ ((constructor));
 
79
static void check_enabling(void)
 
80
{
 
81
  int prot = (int) sysconf(515 /* _SC_STACK_PROT */);
 
82
  if (prot != 7 /* STACK_PROT_RWX */)
 
83
    need_enable_exec_stack = 1;
 
84
}
 
85
 
 
86
void
 
87
__enable_execute_stack (void *addr)
 
88
{
 
89
  if (!need_enable_exec_stack)
 
90
    return;
 
91
  else {
 
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);
 
96
 
 
97
    if (mprotect (page, end - page, 7 /* STACK_PROT_RWX */) < 0)
 
98
      perror ("mprotect of trampoline code");
 
99
  }
 
100
}
 
101
 
 
102
#endif
 
103
 
 
104
/* Taken from gcc-4.1.0/gcc/config/openbsd.h.  */
 
105
 
 
106
#if defined (__OpenBSD__)
 
107
 
 
108
/* Stack is explicitly denied execution rights on OpenBSD platforms.  */
 
109
void
 
110
__enable_execute_stack (void *addr)
 
111
{
 
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);
 
116
 
 
117
  if (mprotect (page, end - page, PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
 
118
    perror ("mprotect of trampoline code");
 
119
}
 
120
 
 
121
#endif
 
122
 
 
123
/* Taken from gcc-4.1.0/gcc/config/netbsd.h.  */
 
124
 
 
125
#if defined (__NetBSD__)
 
126
 
 
127
extern int __sysctl (int *, unsigned int, void *, size_t *, void *, size_t);
 
128
 
 
129
void
 
130
__enable_execute_stack (void *addr)
 
131
{
 
132
  static int size;
 
133
  static long mask;
 
134
 
 
135
  char *page, *end;
 
136
 
 
137
  if (size == 0)
 
138
    {
 
139
      int mib[2];
 
140
      size_t len;
 
141
 
 
142
      mib[0] = 6; /* CTL_HW */
 
143
      mib[1] = 7; /* HW_PAGESIZE */
 
144
      len = sizeof (size);
 
145
      (void) __sysctl (mib, 2, &size, &len, NULL, 0);
 
146
      mask = ~((long) size - 1);
 
147
    }
 
148
 
 
149
  page = (char *) (((long) addr) & mask);
 
150
  end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);
 
151
 
 
152
  /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */
 
153
  (void) mprotect (page, end - page, 7);
 
154
}
 
155
 
 
156
#endif
 
157
 
 
158
/* The rest is taken from gcc-2.6.3/libgcc2.c.  */
 
159
 
 
160
#if defined (NeXT) && defined (__MACH__)
 
161
 
 
162
/* Make stack executable so we can call trampolines on stack.
 
163
   This is called from INITIALIZE_TRAMPOLINE in next.h.  */
 
164
#ifdef NeXTStep21
 
165
 #include <mach.h>
 
166
#else
 
167
 #include <mach/mach.h>
 
168
#endif
 
169
 
 
170
void
 
171
__enable_execute_stack (addr)
 
172
     char *addr;
 
173
{
 
174
  kern_return_t r;
 
175
  char *eaddr = addr + TRAMPOLINE_SIZE;
 
176
  vm_address_t a = (vm_address_t) addr;
 
177
 
 
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)
 
181
    {
 
182
      mach_error("vm_protect VM_PROT_ALL", r);
 
183
      exit(1);
 
184
    }
 
185
 
186
 
 
187
#endif /* defined (NeXT) && defined (__MACH__) */
 
188
 
 
189
#ifdef __convex__
 
190
 
 
191
/* Make stack executable so we can call trampolines on stack.
 
192
   This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
 
193
 
 
194
#include <sys/mman.h>
 
195
#include <sys/vmparam.h>
 
196
#include <machine/machparam.h>
 
197
 
 
198
void
 
199
__enable_execute_stack ()
 
200
{
 
201
  int fp;
 
202
  static unsigned lowest = USRSTACK;
 
203
  unsigned current = (unsigned) &fp & -NBPG;
 
204
 
 
205
  if (lowest > current)
 
206
    {
 
207
      unsigned len = lowest - current;
 
208
      mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
 
209
      lowest = current;
 
210
    }
 
211
}
 
212
#endif /* __convex__ */
 
213
 
 
214
#ifdef __DOLPHIN__
 
215
 
 
216
/* Modified from the convex -code above. */
 
217
 
 
218
#include <sys/param.h>
 
219
#include <errno.h>
 
220
#include <sys/m88kbcs.h>
 
221
 
 
222
void
 
223
__enable_execute_stack ()
 
224
{
 
225
  int save_errno;
 
226
  static unsigned long lowest = USRSTACK;
 
227
  unsigned long current = (unsigned long) &save_errno & -NBPC;
 
228
  
 
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.   */
 
231
 
 
232
  save_errno=errno;
 
233
  if (lowest > current)
 
234
    {
 
235
      unsigned len=lowest-current;
 
236
      memctl(current,len,MCT_TEXT);
 
237
      lowest = current;
 
238
    }
 
239
  else
 
240
    memctl(current,NBPC,MCT_TEXT);
 
241
  errno=save_errno;
 
242
}
 
243
 
 
244
#endif /* __DOLPHIN__ */
 
245
 
 
246
#ifdef __pyr__
 
247
 
 
248
#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
 
249
#include <stdio.h>
 
250
#include <sys/mman.h>
 
251
#include <sys/types.h>
 
252
#include <sys/param.h>
 
253
#include <sys/vmmac.h>
 
254
 
 
255
/* Modified from the convex -code above.
 
256
   mremap promises to clear the i-cache. */
 
257
 
 
258
void
 
259
__enable_execute_stack ()
 
260
{
 
261
  int fp;
 
262
  if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
 
263
                PROT_READ|PROT_WRITE|PROT_EXEC))
 
264
    {
 
265
      perror ("mprotect in __enable_execute_stack");
 
266
      fflush (stderr);
 
267
      abort ();
 
268
    }
 
269
}
 
270
#endif /* __pyr__ */