Build mono runtime under none desktop Windows API family, adjustments and cleanup.
[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-internals.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.dwPageSize;
31         return saved_pagesize;
32 }
33
34 int
35 mono_valloc_granule (void)
36 {
37         SYSTEM_INFO info;
38         static int saved_valloc_granule = 0;
39         if (saved_valloc_granule)
40                 return saved_valloc_granule;
41         GetSystemInfo (&info);
42         saved_valloc_granule = info.dwAllocationGranularity;
43         return saved_valloc_granule;
44 }
45
46 int
47 mono_mmap_win_prot_from_flags (int flags)
48 {
49         int prot = flags & (MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC);
50         switch (prot) {
51         case 0: prot = PAGE_NOACCESS; break;
52         case MONO_MMAP_READ: prot = PAGE_READONLY; break;
53         case MONO_MMAP_READ|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READ; break;
54         case MONO_MMAP_READ|MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
55         case MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
56         case MONO_MMAP_WRITE: prot = PAGE_READWRITE; break;
57         case MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break;
58         case MONO_MMAP_EXEC: prot = PAGE_EXECUTE; break;
59         default:
60                 g_assert_not_reached ();
61         }
62         return prot;
63 }
64
65 void*
66 mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
67 {
68         void *ptr;
69         int mflags = MEM_RESERVE|MEM_COMMIT;
70         int prot = mono_mmap_win_prot_from_flags (flags);
71         /* translate the flags */
72
73         ptr = VirtualAlloc (addr, length, mflags, prot);
74
75         account_mem (type, (ssize_t)length);
76
77         return ptr;
78 }
79
80 void*
81 mono_valloc_aligned (size_t length, size_t alignment, int flags, MonoMemAccountType type)
82 {
83         int prot = mono_mmap_win_prot_from_flags (flags);
84         char *mem = VirtualAlloc (NULL, length + alignment, MEM_RESERVE, prot);
85         char *aligned;
86
87         if (!mem)
88                 return NULL;
89
90         aligned = aligned_address (mem, length, alignment);
91
92         aligned = VirtualAlloc (aligned, length, MEM_COMMIT, prot);
93         g_assert (aligned);
94
95         account_mem (type, (ssize_t)length);
96
97         return aligned;
98 }
99
100 int
101 mono_vfree (void *addr, size_t length, MonoMemAccountType type)
102 {
103         MEMORY_BASIC_INFORMATION mbi;
104         SIZE_T query_result = VirtualQuery (addr, &mbi, sizeof (mbi));
105         BOOL res;
106
107         g_assert (query_result);
108
109         res = VirtualFree (mbi.AllocationBase, 0, MEM_RELEASE);
110
111         g_assert (res);
112
113         account_mem (type, -(ssize_t)length);
114
115         return 0;
116 }
117
118 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
119 void*
120 mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle)
121 {
122         void *ptr;
123         int mflags = 0;
124         HANDLE file, mapping;
125         int prot = mono_mmap_win_prot_from_flags (flags);
126         /* translate the flags */
127         /*if (flags & MONO_MMAP_PRIVATE)
128                 mflags |= MAP_PRIVATE;
129         if (flags & MONO_MMAP_SHARED)
130                 mflags |= MAP_SHARED;
131         if (flags & MONO_MMAP_ANON)
132                 mflags |= MAP_ANONYMOUS;
133         if (flags & MONO_MMAP_FIXED)
134                 mflags |= MAP_FIXED;
135         if (flags & MONO_MMAP_32BIT)
136                 mflags |= MAP_32BIT;*/
137
138         mflags = FILE_MAP_READ;
139         if (flags & MONO_MMAP_WRITE)
140                 mflags = FILE_MAP_COPY;
141
142         file = (HANDLE) _get_osfhandle (fd);
143
144         mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL);
145
146         if (mapping == NULL)
147                 return NULL;
148
149         ptr = MapViewOfFile (mapping, mflags, 0, offset, length);
150
151         if (ptr == NULL) {
152                 CloseHandle (mapping);
153                 return NULL;
154         }
155         *ret_handle = (void*)mapping;
156         return ptr;
157 }
158
159 int
160 mono_file_unmap (void *addr, void *handle)
161 {
162         UnmapViewOfFile (addr);
163         CloseHandle ((HANDLE)handle);
164         return 0;
165 }
166 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
167
168 int
169 mono_mprotect (void *addr, size_t length, int flags)
170 {
171         DWORD oldprot;
172         int prot = mono_mmap_win_prot_from_flags (flags);
173
174         if (flags & MONO_MMAP_DISCARD) {
175                 VirtualFree (addr, length, MEM_DECOMMIT);
176                 VirtualAlloc (addr, length, MEM_COMMIT, prot);
177                 return 0;
178         }
179         return VirtualProtect (addr, length, prot, &oldprot) == 0;
180 }
181
182 void*
183 mono_shared_area (void)
184 {
185         if (!malloced_shared_area)
186                 malloced_shared_area = malloc_shared_area (0);
187         /* get the pid here */
188         return malloced_shared_area;
189 }
190
191 void
192 mono_shared_area_remove (void)
193 {
194         if (malloced_shared_area)
195                 g_free (malloced_shared_area);
196         malloced_shared_area = NULL;
197 }
198
199 void*
200 mono_shared_area_for_pid (void *pid)
201 {
202         return NULL;
203 }
204
205 void
206 mono_shared_area_unload (void *area)
207 {
208 }
209
210 int
211 mono_shared_area_instances (void **array, int count)
212 {
213         return 0;
214 }
215
216 #endif