16 #include "mono-mmap.h"
19 #define MAP_ANONYMOUS MAP_ANON
32 static int saved_pagesize = 0;
34 return saved_pagesize;
35 GetSystemInfo (&info);
36 saved_pagesize = info.dwAllocationGranularity;
37 return saved_pagesize;
41 prot_from_flags (int flags)
43 int prot = flags & (MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC);
45 case 0: prot = PAGE_NOACCESS; break;
46 case MONO_MMAP_READ: prot = PAGE_READONLY; break;
47 case MONO_MMAP_READ|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READ; break;
48 case MONO_MMAP_READ|MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
49 case MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
50 case MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
51 case MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
52 case MONO_MMAP_EXEC: prot = PAGE_EXECUTE; break;
54 g_assert_not_reached ();
60 mono_valloc (void *addr, size_t length, int flags)
63 int mflags = MEM_COMMIT;
64 int prot = prot_from_flags (flags);
65 /* translate the flags */
67 ptr = VirtualAlloc (addr, length, mflags, prot);
72 mono_vfree (void *addr, size_t length)
74 int res = VirtualFree (addr, 0, MEM_RELEASE);
82 mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
87 int prot = prot_from_flags (flags);
88 /* translate the flags */
89 /*if (flags & MONO_MMAP_PRIVATE)
90 mflags |= MAP_PRIVATE;
91 if (flags & MONO_MMAP_SHARED)
93 if (flags & MONO_MMAP_ANON)
94 mflags |= MAP_ANONYMOUS;
95 if (flags & MONO_MMAP_FIXED)
97 if (flags & MONO_MMAP_32BIT)
98 mflags |= MAP_32BIT;*/
100 mflags = FILE_MAP_READ;
101 if (flags & MONO_MMAP_WRITE)
102 mflags = FILE_MAP_COPY;
104 file = (HANDLE) _get_osfhandle (fd);
105 mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL);
108 ptr = MapViewOfFile (mapping, mflags, 0, offset, length);
110 CloseHandle (mapping);
113 *ret_handle = (void*)mapping;
118 mono_file_unmap (void *addr, void *handle)
120 UnmapViewOfFile (addr);
121 CloseHandle ((HANDLE)handle);
126 mono_mprotect (void *addr, size_t length, int flags)
129 int prot = prot_from_flags (flags);
131 if (flags & MONO_MMAP_DISCARD) {
132 VirtualFree (addr, length, MEM_DECOMMIT);
133 VirtualAlloc (addr, length, MEM_COMMIT, prot);
136 return VirtualProtect (addr, length, prot, &oldprot) == 0;
139 #elif defined(HAVE_MMAP)
143 * Get the page size in use on the system. Addresses and sizes in the
144 * mono_mmap(), mono_munmap() and mono_mprotect() calls must be pagesize
147 * Returns: the page size in bytes.
152 static int saved_pagesize = 0;
154 return saved_pagesize;
155 saved_pagesize = getpagesize ();
156 return saved_pagesize;
160 prot_from_flags (int flags)
162 int prot = PROT_NONE;
163 /* translate the protection bits */
164 if (flags & MONO_MMAP_READ)
166 if (flags & MONO_MMAP_WRITE)
168 if (flags & MONO_MMAP_EXEC)
175 * @addr: memory address
176 * @length: memory area size
177 * @flags: protection flags
179 * Allocates @length bytes of virtual memory with the @flags
180 * protection. @addr can be a preferred memory address or a
181 * mandatory one if MONO_MMAP_FIXED is set in @flags.
182 * @addr must be pagesize aligned and can be NULL.
183 * @length must be a multiple of pagesize.
185 * Returns: NULL on failure, the address of the memory area otherwise
188 mono_valloc (void *addr, size_t length, int flags)
192 int prot = prot_from_flags (flags);
193 /* translate the flags */
194 if (flags & MONO_MMAP_FIXED)
196 if (flags & MONO_MMAP_32BIT)
199 mflags |= MAP_ANONYMOUS;
200 mflags |= MAP_PRIVATE;
202 ptr = mmap (addr, length, prot, mflags, -1, 0);
203 if (ptr == (void*)-1) {
204 int fd = open ("/dev/zero", O_RDONLY);
206 ptr = mmap (addr, length, prot, mflags, fd, 0);
209 if (ptr == (void*)-1)
217 * @addr: memory address returned by mono_valloc ()
218 * @length: size of memory area
220 * Remove the memory mapping at the address @addr.
222 * Returns: 0 on success.
225 mono_vfree (void *addr, size_t length)
227 return munmap (addr, length);
232 * @length: size of data to map
233 * @flags: protection flags
234 * @fd: file descriptor
235 * @offset: offset in the file
236 * @ret_handle: pointer to storage for returning a handle for the map
238 * Map the area of the file pointed to by the file descriptor @fd, at offset
239 * @offset and of size @length in memory according to the protection flags
241 * @offset and @length must be multiples of the page size.
242 * @ret_handle must point to a void*: this value must be used when unmapping
243 * the memory area using mono_file_unmap ().
247 mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
251 int prot = prot_from_flags (flags);
252 /* translate the flags */
253 if (flags & MONO_MMAP_PRIVATE)
254 mflags |= MAP_PRIVATE;
255 if (flags & MONO_MMAP_SHARED)
256 mflags |= MAP_SHARED;
257 if (flags & MONO_MMAP_FIXED)
259 if (flags & MONO_MMAP_32BIT)
262 ptr = mmap (0, length, prot, mflags, fd, offset);
263 if (ptr == (void*)-1)
265 *ret_handle = (void*)length;
271 * @addr: memory address returned by mono_file_map ()
272 * @handle: handle of memory map
274 * Remove the memory mapping at the address @addr.
275 * @handle must be the value returned in ret_handle by mono_file_map ().
277 * Returns: 0 on success.
280 mono_file_unmap (void *addr, void *handle)
282 return munmap (addr, (size_t)handle);
287 * @addr: memory address
288 * @length: size of memory area
289 * @flags: new protection flags
291 * Change the protection for the memory area at @addr for @length bytes
292 * to matche the supplied @flags.
293 * If @flags includes MON_MMAP_DISCARD the pages are discarded from memory
294 * and the area is cleared to zero.
295 * @addr must be aligned to the page size.
296 * @length must be a multiple of the page size.
298 * Returns: 0 on success.
301 mono_mprotect (void *addr, size_t length, int flags)
303 int prot = prot_from_flags (flags);
305 if (flags & MONO_MMAP_DISCARD) {
306 /* on non-linux the pages are not guaranteed to be zeroed (*bsd, osx at least) */
308 if (madvise (addr, length, MADV_DONTNEED))
309 memset (addr, 0, length);
311 memset (addr, 0, length);
312 madvise (addr, length, MADV_DONTNEED);
313 madvise (addr, length, MADV_FREE);
316 return mprotect (addr, length, prot);
321 /* dummy malloc-based implementation */
329 mono_valloc (void *addr, size_t length, int flags)
331 return malloc (length);
335 mono_vfree (void *addr, size_t length)
342 mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
346 void *ptr = malloc (length);
349 cur_offset = lseek (fd, 0, SEEK_CUR);
350 if (lseek (fd, offset, SEEK_SET) != offset) {
354 bytes_read = read (fd, ptr, length);
355 lseek (fd, cur_offset, SEEK_SET);
361 mono_file_unmap (void *addr, void *handle)
368 mono_mprotect (void *addr, size_t length, int flags)
370 if (flags & MONO_MMAP_DISCARD) {
371 memset (addr, 0, length);