2 * rawbuffer.c: Manages buffers that might have been mmapped or malloced
5 * Miguel de Icaza (miguel@ximian.com)
7 * (C) 2001 Ximian, Inc.
10 #if defined(PLATFORM_WIN32)
11 #define USE_WIN32_API 1
22 #include <sys/types.h>
24 #include "rawbuffer.h"
26 #include <mono/io-layer/io-layer.h>
28 #define ROUND_DOWN(VALUE,SIZE) ((VALUE) & ~((SIZE) - 1))
29 #define ROUND_UP(VALUE,SIZE) (ROUND_DOWN((VALUE) + (SIZE) - 1, (SIZE)))
30 #if SIZEOF_VOID_P == 8
31 #define UINTPTR_TYPE guint64
33 #define UINTPTR_TYPE guint32
36 static GHashTable *mmap_map = NULL;
37 static size_t alignment = 0;
38 static CRITICAL_SECTION mmap_mutex;
46 GetSystemInfo (&info);
47 alignment = info.dwAllocationGranularity;
49 alignment = getpagesize ();
54 mono_raw_buffer_load_malloc (int fd, int is_writable, guint32 base, size_t size)
58 ptr = g_malloc (size);
62 if (lseek (fd, base, 0) == (off_t) -1) {
72 mono_raw_buffer_free_malloc (void *base)
78 mono_raw_buffer_init (void)
80 InitializeCriticalSection (&mmap_mutex);
84 mmap_map = g_hash_table_new (NULL, NULL);
88 mono_raw_buffer_load_mmap (int fd, int is_writable, guint32 base, size_t size)
91 /* FileMapping implementation */
98 start = ROUND_DOWN (base, alignment);
102 prot = PAGE_WRITECOPY;
103 access = FILE_MAP_COPY;
106 prot = PAGE_READONLY;
107 access = FILE_MAP_READ;
110 file = (HANDLE) _get_osfhandle (fd);
111 mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL);
115 ptr = MapViewOfFile (mapping, access, 0, start, end - start);
117 CloseHandle (mapping);
121 EnterCriticalSection (&mmap_mutex);
122 g_hash_table_insert (mmap_map, ptr, GINT_TO_POINTER (mapping));
123 LeaveCriticalSection (&mmap_mutex);
125 return ((char *)ptr) + (base - start);
128 /* mmap implementation */
132 int prot = PROT_READ;
136 start = ROUND_DOWN (base, alignment);
137 end = ROUND_UP (base + size, alignment);
146 ptr = mmap (0, end - start, prot, flags, fd, start);
148 if (ptr == (void *) -1)
152 * This seems to prevent segmentation faults on Fedora Linux, no
154 * http://bugzilla.ximian.com/show_bug.cgi?id=49499
157 if (mprotect (ptr, end - start, prot | PROT_EXEC) != 0)
158 g_warning (G_GNUC_PRETTY_FUNCTION
159 ": mprotect failed: %s", g_strerror (errno));
161 EnterCriticalSection (&mmap_mutex);
162 g_hash_table_insert (mmap_map, ptr, GINT_TO_POINTER (size));
163 LeaveCriticalSection (&mmap_mutex);
165 return ((char *)ptr) + (base - start);
170 mono_raw_buffer_free_mmap (void *base)
174 EnterCriticalSection (&mmap_mutex);
175 value = GPOINTER_TO_INT (g_hash_table_lookup (mmap_map, base));
176 LeaveCriticalSection (&mmap_mutex);
179 UnmapViewOfFile (base);
180 CloseHandle ((HANDLE) value);
182 munmap (base, value);
187 mono_raw_buffer_update_mmap (void *base, size_t size)
190 FlushViewOfFile (base, size);
192 msync (base, size, MS_SYNC);
197 mono_raw_buffer_load (int fd, int is_writable, guint32 base, size_t size)
201 ptr = mono_raw_buffer_load_mmap (fd, is_writable, base, size);
203 ptr = mono_raw_buffer_load_malloc (fd, is_writable, base, size);
209 mono_raw_buffer_update (void *buffer, size_t size)
214 mmap_base = (gpointer)(ROUND_DOWN ((UINTPTR_TYPE) (buffer), alignment));
216 EnterCriticalSection (&mmap_mutex);
217 exists = g_hash_table_lookup (mmap_map, mmap_base) != NULL;
218 LeaveCriticalSection (&mmap_mutex);
220 mono_raw_buffer_update_mmap (mmap_base, size);
224 mono_raw_buffer_free (void *buffer)
229 mmap_base = (gpointer)(ROUND_DOWN ((UINTPTR_TYPE) (buffer), alignment));
231 exists = g_hash_table_lookup (mmap_map, mmap_base) != NULL;
233 mono_raw_buffer_free_mmap (mmap_base);
235 mono_raw_buffer_free_malloc (buffer);