[project @ 1996-06-27 16:13:29 by partain]
[ghc-hetmet.git] / ghc / runtime / storage / mprotect.lc
1 %
2 % (c) The AQUA Project, Glasgow University, 1995
3 %
4 %************************************************************************
5 %*                                                                      *
6 \section[mprotect.lc]{Memory Protection}
7 %*                                                                      *
8 %************************************************************************
9
10 Is @mprotect@ POSIX now?
11
12 \begin{code}
13 #if STACK_CHECK_BY_PAGE_FAULT
14
15 /* #define STK_CHK_DEBUG */
16
17 #include "rtsdefs.h"
18
19 # ifdef HAVE_SYS_TYPES_H
20 #  include <sys/types.h>
21 # endif
22
23 # ifdef HAVE_SYS_MMAN_H
24 #  include <sys/mman.h>
25 # endif
26
27 # if defined(_SC_PAGE_SIZE) && !defined(_SC_PAGESIZE)
28     /* Death to HP-UX.  What are standards for, anyway??? */
29 #  define _SC_PAGESIZE _SC_PAGE_SIZE
30 # endif
31
32 # if defined(_SC_PAGESIZE)
33 #  define GETPAGESIZE() sysconf(_SC_PAGESIZE)
34 # else
35 #  if defined(HAVE_GETPAGESIZE)
36 #   define GETPAGESIZE()    getpagesize()
37 #  else
38 #   if defined(linux_TARGET_OS) || defined(linuxaout_TARGET_OS)
39 #    /* it has it, but it is in BSD land; easier to just say so */
40 #    define GETPAGESIZE()   getpagesize()
41 #   else 
42 #    error getpagesize
43 #   endif
44 #  endif
45 # endif
46
47 #if defined(sunos4_TARGET_OS)
48 extern int getpagesize PROTO((void));
49 extern int mprotect PROTO((caddr_t, size_t, int));
50 #endif
51
52 /* Needed for FreeBSD (SDM, 96/03) */
53 #ifndef PROT_NONE
54 #define PROT_NONE 0
55 #endif
56
57 void 
58 unmapMiddleStackPage(addr_, size)
59 char * /*caddr_t*/ addr_;
60 int size;
61 {
62     int pagesize = GETPAGESIZE();
63     caddr_t addr = addr_;
64     caddr_t middle = (caddr_t) (((W_) (addr + size / 2)) / pagesize * pagesize);
65
66 # ifdef STK_CHK_DEBUG
67     fprintf(stderr, "pagesize: %x\nstack start: %08lx\nstack size: %08lx\nstack middle: %08lx\n",
68       pagesize, addr, size, middle);
69 # endif
70
71     if (middle < addr || middle + pagesize > addr + size) {
72         fprintf(stderr, "Stack too small; stack overflow trap disabled.\n");
73         return;
74     }
75     if (mprotect(middle, pagesize, PROT_NONE) == -1) {
76         perror("mprotect");
77         EXIT(EXIT_FAILURE);
78     }
79     if (install_segv_handler()) {
80         fprintf(stderr, "Can't install SIGSEGV handler for stack overflow check.\n");
81         EXIT(EXIT_FAILURE);
82     }
83 }
84
85 #endif /* STACK_CHECK_BY_PAGE_FAULT */
86 \end{code}