Perform nested assembly loading. Use assembly loading instead of
[mono.git] / mono / metadata / rawbuffer.c
1 /*
2  * rawbuffer.c: Manages buffers that might have been mmapped or malloced
3  *
4  * Author:
5  *   Miguel de Icaza (miguel@ximian.com)
6  *
7  * (C) 2001 Ximian, Inc.
8  */
9 #include <config.h>
10 #include <unistd.h>
11 #include <sys/mman.h>
12 #include <sys/types.h>
13 #include <glib.h>
14 #include "rawbuffer.h"
15
16 #define PAGESIZE 8192
17
18 GHashTable *malloc_map;
19
20 void *
21 raw_buffer_load (int fd, int is_writable, guint32 base, size_t size)
22 {
23         size_t start, end;
24         int prot = PROT_READ;
25         int flags = 0;
26         void *ptr, *mmap_ptr;
27         
28         if (is_writable){
29                 prot |= PROT_WRITE;
30         }
31         flags = MAP_PRIVATE;
32
33         start = base & ~(PAGESIZE - 1);
34         end = (base + size + PAGESIZE - 1) & ~(PAGESIZE - 1);
35         
36         mmap_ptr = mmap (0, end - start, prot, flags, fd, start);
37         if (mmap_ptr == (void *) -1){
38                 ptr = g_malloc (size);
39                 if (ptr == NULL)
40                         return NULL;
41                 if (lseek (fd, base, 0) == (off_t) -1)
42                         return NULL;
43                 read (fd, ptr, size);
44                 return ptr;
45         }
46         if (malloc_map == NULL)
47                 malloc_map = g_hash_table_new (g_direct_hash, g_direct_equal);
48
49         g_hash_table_insert (malloc_map, mmap_ptr, GINT_TO_POINTER (size));
50
51         return ((char *)mmap_ptr) + (base - start);
52 }
53
54 void
55 raw_buffer_free (void *buffer)
56 {
57         int size, diff;
58         char *base;
59         
60         if (!malloc_map){
61                 g_free (buffer);
62                 return;
63         }
64
65         diff = ((unsigned int) buffer) & (PAGESIZE - 1);
66         base = ((char *)buffer) - diff;
67         
68         size = GPOINTER_TO_INT (g_hash_table_lookup (malloc_map, base));
69         munmap (base, size);
70 }