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