[project @ 1996-01-08 20:28:12 by partain]
[ghc-hetmet.git] / ghc / runtime / storage / mprotect.lc
diff --git a/ghc/runtime/storage/mprotect.lc b/ghc/runtime/storage/mprotect.lc
new file mode 100644 (file)
index 0000000..8c50a6e
--- /dev/null
@@ -0,0 +1,78 @@
+%
+% (c) The AQUA Project, Glasgow University, 1995
+%
+%************************************************************************
+%*                                                                      *
+\section[mprotect.lc]{Memory Protection}
+%*                                                                     *
+%************************************************************************
+
+Is @mprotect@ POSIX now?
+
+\begin{code}
+
+#if STACK_CHECK_BY_PAGE_FAULT
+
+/* #define STK_CHK_DEBUG */
+
+#include "rtsdefs.h"
+
+# ifdef HAVE_SYS_TYPES_H
+#  include <sys/types.h>
+# endif
+
+# ifdef HAVE_SYS_MMAN_H
+#  include <sys/mman.h>
+# endif
+
+# if defined(_SC_PAGE_SIZE) && !defined(_SC_PAGESIZE)
+    /* Death to HP-UX.  What are standards for, anyway??? */
+#  define _SC_PAGESIZE _SC_PAGE_SIZE
+# endif
+
+# if defined(_SC_PAGESIZE)
+#  define GETPAGESIZE()        sysconf(_SC_PAGESIZE)
+# else
+#  if defined(HAVE_GETPAGESIZE)
+#   define GETPAGESIZE()    getpagesize()
+#  else
+#   error getpagesize
+#  endif
+# endif
+
+#if defined(sunos4_TARGET_OS)
+extern int getpagesize PROTO((void));
+extern int mprotect PROTO((caddr_t, size_t, int));
+#endif
+
+void 
+unmapMiddleStackPage(addr_, size)
+char * /*caddr_t*/ addr_;
+int size;
+{
+    int pagesize = GETPAGESIZE();
+    caddr_t addr = addr_;
+    caddr_t middle = (caddr_t) (((W_) (addr + size / 2)) / pagesize * pagesize);
+
+# ifdef STK_CHK_DEBUG
+    fprintf(stderr, "pagesize: %x\nstack start: %08lx\nstack size: %08lx\nstack middle: %08lx\n",
+      pagesize, addr, size, middle);
+# endif
+
+    if (middle < addr || middle + pagesize > addr + size) {
+       fprintf(stderr, "Stack too small; stack overflow trap disabled.\n");
+       return;
+    }
+    if (mprotect(middle, pagesize, PROT_NONE) == -1) {
+       perror("mprotect");
+       exit(1);
+    }
+    if (install_segv_handler()) {
+       fprintf(stderr, "Can't install SIGSEGV handler for stack overflow check.\n");
+       EXIT(EXIT_FAILURE);
+    }
+}
+
+#endif /* STACK_CHECK_BY_PAGE_FAULT */
+
+\end{code}