Merge pull request #3716 from vargaz/unbox-stobj-null
[mono.git] / mono / utils / mono-mmap-windows.c
1 /*
2  * mono-mmap-windows.c: Windows support for mapping code into the process address space
3  *
4  * Author:
5  *   Mono Team (mono-list@lists.ximian.com)
6  *
7  * Copyright 2001-2008 Novell, Inc.
8  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
9  */
10
11 #include <config.h>
12 #include <glib.h>
13
14 #if defined(HOST_WIN32)
15 #include <Windows.h>
16 #include "mono/utils/mono-mmap-windows.h"
17 #include <mono/utils/mono-counters.h>
18 #include <io.h>
19
20 static void *malloced_shared_area = NULL;
21
22 int
23 mono_pagesize (void)
24 {
25         SYSTEM_INFO info;
26         static int saved_pagesize = 0;
27         if (saved_pagesize)
28                 return saved_pagesize;
29         GetSystemInfo (&info);
30         saved_pagesize = info.dwAllocationGranularity;
31         return saved_pagesize;
32 }
33
34 int
35 mono_mmap_win_prot_from_flags (int flags)
36 {
37         int prot = flags & (MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC);
38         switch (prot) {
39         case 0: prot = PAGE_NOACCESS; break;
40         case MONO_MMAP_READ: prot = PAGE_READONLY; break;
41         case MONO_MMAP_READ|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READ; break;
42         case MONO_MMAP_READ|MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
43         case MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
44         case MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
45         case MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
46         case MONO_MMAP_EXEC: prot = PAGE_EXECUTE; break;
47         default:
48                 g_assert_not_reached ();
49         }
50         return prot;
51 }
52
53 void*
54 mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
55 {
56         void *ptr;
57         int mflags = MEM_RESERVE|MEM_COMMIT;
58         int prot = mono_mmap_win_prot_from_flags (flags);
59         /* translate the flags */
60
61         ptr = VirtualAlloc (addr, length, mflags, prot);
62
63         account_mem (type, (ssize_t)length);
64
65         return ptr;
66 }
67
68 void*
69 mono_valloc_aligned (size_t length, size_t alignment, int flags, MonoMemAccountType type)
70 {
71         int prot = mono_mmap_win_prot_from_flags (flags);
72         char *mem = VirtualAlloc (NULL, length + alignment, MEM_RESERVE, prot);
73         char *aligned;
74
75         if (!mem)
76                 return NULL;
77
78         aligned = aligned_address (mem, length, alignment);
79
80         aligned = VirtualAlloc (aligned, length, MEM_COMMIT, prot);
81         g_assert (aligned);
82
83         account_mem (type, (ssize_t)length);
84
85         return aligned;
86 }
87
88 int
89 mono_vfree (void *addr, size_t length, MonoMemAccountType type)
90 {
91         MEMORY_BASIC_INFORMATION mbi;
92         SIZE_T query_result = VirtualQuery (addr, &mbi, sizeof (mbi));
93         BOOL res;
94
95         g_assert (query_result);
96
97         res = VirtualFree (mbi.AllocationBase, 0, MEM_RELEASE);
98
99         g_assert (res);
100
101         account_mem (type, -(ssize_t)length);
102
103         return 0;
104 }
105
106 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
107 void*
108 mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
109 {
110         void *ptr;
111         int mflags = 0;
112         HANDLE file, mapping;
113         int prot = mono_mmap_win_prot_from_flags (flags);
114         /* translate the flags */
115         /*if (flags & MONO_MMAP_PRIVATE)
116                 mflags |= MAP_PRIVATE;
117         if (flags & MONO_MMAP_SHARED)
118                 mflags |= MAP_SHARED;
119         if (flags & MONO_MMAP_ANON)
120                 mflags |= MAP_ANONYMOUS;
121         if (flags & MONO_MMAP_FIXED)
122                 mflags |= MAP_FIXED;
123         if (flags & MONO_MMAP_32BIT)
124                 mflags |= MAP_32BIT;*/
125
126         mflags = FILE_MAP_READ;
127         if (flags & MONO_MMAP_WRITE)
128                 mflags = FILE_MAP_COPY;
129
130         file = (HANDLE) _get_osfhandle (fd);
131
132         mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL);
133
134         if (mapping == NULL)
135                 return NULL;
136
137         ptr = MapViewOfFile (mapping, mflags, 0, offset, length);
138
139         if (ptr == NULL) {
140                 CloseHandle (mapping);
141                 return NULL;
142         }
143         *ret_handle = (void*)mapping;
144         return ptr;
145 }
146
147 int
148 mono_file_unmap (void *addr, void *handle)
149 {
150         UnmapViewOfFile (addr);
151         CloseHandle ((HANDLE)handle);
152         return 0;
153 }
154 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
155
156 int
157 mono_mprotect (void *addr, size_t length, int flags)
158 {
159         DWORD oldprot;
160         int prot = mono_mmap_win_prot_from_flags (flags);
161
162         if (flags & MONO_MMAP_DISCARD) {
163                 VirtualFree (addr, length, MEM_DECOMMIT);
164                 VirtualAlloc (addr, length, MEM_COMMIT, prot);
165                 return 0;
166         }
167         return VirtualProtect (addr, length, prot, &oldprot) == 0;
168 }
169
170 void*
171 mono_shared_area (void)
172 {
173         if (!malloced_shared_area)
174                 malloced_shared_area = malloc_shared_area (0);
175         /* get the pid here */
176         return malloced_shared_area;
177 }
178
179 void
180 mono_shared_area_remove (void)
181 {
182         if (malloced_shared_area)
183                 g_free (malloced_shared_area);
184         malloced_shared_area = NULL;
185 }
186
187 void*
188 mono_shared_area_for_pid (void *pid)
189 {
190         return NULL;
191 }
192
193 void
194 mono_shared_area_unload (void *area)
195 {
196 }
197
198 int
199 mono_shared_area_instances (void **array, int count)
200 {
201         return 0;
202 }
203
204 #endif