% % (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 # endif # ifdef HAVE_SYS_MMAN_H # include # 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 # if defined(linux_TARGET_OS) || defined(linuxaout_TARGET_OS) # /* it has it, but it is in BSD land; easier to just say so */ # define GETPAGESIZE() getpagesize() # else # error getpagesize # endif # endif # endif #if defined(sunos4_TARGET_OS) int getpagesize PROTO((void)); int mprotect PROTO((caddr_t, size_t, int)); #endif /* Needed for FreeBSD (SDM, 96/03) */ #ifndef PROT_NONE #define PROT_NONE 0 #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(EXIT_FAILURE); } 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}