00001 #include "efence.h"
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <fcntl.h>
00005 #include <sys/mman.h>
00006 #include <stdio.h>
00007 #include <errno.h>
00008 #include <string.h>
00009
00010
00011
00012
00013 #ifndef PROT_NONE
00014 #define PROT_NONE 0
00015 #endif
00016
00017
00018
00019
00020 #if ( !defined(MAP_ANONYMOUS) && defined(MAP_ANON) )
00021 #define MAP_ANONYMOUS MAP_ANON
00022 #endif
00023
00024
00025
00026
00027
00028
00029
00030 static caddr_t startAddr = (caddr_t) 0;
00031
00032 #if ( !defined(sgi) && !defined(_AIX) && !defined(__linux__) )
00033 extern int sys_nerr;
00034 extern char * sys_errlist[];
00035 #endif
00036
00037 static const char *
00038 stringErrorReport(void)
00039 {
00040 #if ( defined(sgi) )
00041 return strerror(oserror());
00042 #elif ( defined(_AIX) )
00043 return strerror(errno);
00044 #else
00045 if ( errno > 0 && errno < sys_nerr )
00046 return sys_errlist[errno];
00047 else
00048 return "Unknown error.\n";
00049 #endif
00050 }
00051
00052
00053
00054
00055 #if defined(MAP_ANONYMOUS)
00056 void *
00057 Page_Create(size_t size)
00058 {
00059 caddr_t allocation;
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 allocation = (caddr_t) mmap(
00072 startAddr
00073 ,(int)size
00074 ,PROT_READ|PROT_WRITE
00075 ,MAP_PRIVATE|MAP_ANONYMOUS
00076 ,-1
00077 ,0);
00078
00079 #ifndef __hpux
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 startAddr = allocation + size;
00091 #endif
00092
00093 if ( allocation == (caddr_t)-1 )
00094 EF_Exit("mmap() failed: %s", stringErrorReport());
00095
00096 return (void *)allocation;
00097 }
00098 #else
00099 void *
00100 Page_Create(size_t size)
00101 {
00102 static int devZeroFd = -1;
00103 caddr_t allocation;
00104
00105 if ( devZeroFd == -1 ) {
00106 devZeroFd = open("/dev/zero", O_RDWR);
00107 if ( devZeroFd < 0 )
00108 EF_Exit(
00109 "open() on /dev/zero failed: %s"
00110 ,stringErrorReport());
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 allocation = (caddr_t) mmap(
00124 startAddr
00125 ,(int)size
00126 ,PROT_READ|PROT_WRITE
00127 ,MAP_PRIVATE
00128 ,devZeroFd
00129 ,0);
00130
00131 startAddr = allocation + size;
00132
00133 if ( allocation == (caddr_t)-1 )
00134 EF_Exit("mmap() failed: %s", stringErrorReport());
00135
00136 return (void *)allocation;
00137 }
00138 #endif
00139
00140 static void
00141 mprotectFailed(void)
00142 {
00143 EF_Exit("mprotect() failed: %s", stringErrorReport());
00144 }
00145
00146 void
00147 Page_AllowAccess(void * address, size_t size)
00148 {
00149 if ( mprotect((caddr_t)address, size, PROT_READ|PROT_WRITE) < 0 )
00150 mprotectFailed();
00151 }
00152
00153 void
00154 Page_DenyAccess(void * address, size_t size)
00155 {
00156 if ( mprotect((caddr_t)address, size, PROT_NONE) < 0 )
00157 mprotectFailed();
00158 }
00159
00160 void
00161 Page_Delete(void * address, size_t size)
00162 {
00163 if ( munmap((caddr_t)address, size) < 0 )
00164 Page_DenyAccess(address, size);
00165 }
00166
00167 #if defined(_SC_PAGESIZE)
00168 size_t
00169 Page_Size(void)
00170 {
00171 return (size_t)sysconf(_SC_PAGESIZE);
00172 }
00173 #elif defined(_SC_PAGE_SIZE)
00174 size_t
00175 Page_Size(void)
00176 {
00177 return (size_t)sysconf(_SC_PAGE_SIZE);
00178 }
00179 #else
00180
00181 size_t
00182 Page_Size(void)
00183 {
00184 return getpagesize();
00185 }
00186 #endif