% % (c) The AQUA Project, Glasgow University, 1995 % %************************************************************************ %* * \section[mprotect.lc]{Memory Protection} %* * %************************************************************************ Is @mprotect@ POSIX now? [Yup, POSIX.4 -- sof] \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 #if defined(aix_TARGET_OS) /* PROT_NONE doesn't work on aix, PROT_READ works and should suit the job */ #define PROT_NONE PROT_READ #endif /* Needed for FreeBSD (SDM, 96/03) */ #ifndef PROT_NONE #define PROT_NONE 0 #endif /* For VirtualProtect() and its flags */ #if defined(cygwin32_TARGET_OS) #include #endif void unmapMiddleStackPage(addr, size) char * /*caddr_t*/ addr; int size; { int pagesize = GETPAGESIZE(); char * middle = (caddr_t) (((W_) (addr + size / 2)) / pagesize * pagesize); #if defined(cygwin32_TARGET_OS) unsigned int old_prot; #endif # 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; } /* mprotect() is broken in beta18, so we use the native Win32 call instead */ #if defined(cygwin32_TARGET_OS) if (VirtualProtect(middle, pagesize, PAGE_NOACCESS, &old_prot) == 0) { #else if (mprotect(middle, pagesize, PROT_NONE) == -1) { #endif 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}