27 |
|
#include <fcntl.h> |
28 |
|
#endif |
29 |
|
|
30 |
< |
// TODO: Win32 VMs ? |
30 |
> |
#ifdef HAVE_WIN32_VM |
31 |
> |
#define WIN32_LEAN_AND_MEAN /* avoid including junk */ |
32 |
> |
#include <windows.h> |
33 |
> |
#endif |
34 |
> |
|
35 |
|
#include <stdio.h> |
36 |
|
#include <stdlib.h> |
37 |
|
#include <string.h> |
177 |
|
} |
178 |
|
#endif |
179 |
|
|
180 |
+ |
/* Align ADDR and SIZE to 64K boundaries. */ |
181 |
+ |
|
182 |
+ |
#ifdef HAVE_WIN32_VM |
183 |
+ |
static inline LPVOID align_addr_segment(LPVOID addr) |
184 |
+ |
{ |
185 |
+ |
return (LPVOID)(((DWORD)addr) & -65536); |
186 |
+ |
} |
187 |
+ |
|
188 |
+ |
static inline DWORD align_size_segment(LPVOID addr, DWORD size) |
189 |
+ |
{ |
190 |
+ |
return size + ((DWORD)addr - (DWORD)align_addr_segment(addr)); |
191 |
+ |
} |
192 |
+ |
#endif |
193 |
+ |
|
194 |
+ |
/* Translate generic VM prot flags to host values. */ |
195 |
+ |
|
196 |
+ |
#ifdef HAVE_WIN32_VM |
197 |
+ |
static int translate_prot_flags(int prot_flags) |
198 |
+ |
{ |
199 |
+ |
int prot = PAGE_READWRITE; |
200 |
+ |
if (prot_flags == (VM_PAGE_EXECUTE | VM_PAGE_READ | VM_PAGE_WRITE)) |
201 |
+ |
prot = PAGE_EXECUTE_READWRITE; |
202 |
+ |
else if (prot_flags == (VM_PAGE_EXECUTE | VM_PAGE_READ)) |
203 |
+ |
prot = PAGE_EXECUTE_READ; |
204 |
+ |
else if (prot_flags == (VM_PAGE_READ | VM_PAGE_WRITE)) |
205 |
+ |
prot = PAGE_READWRITE; |
206 |
+ |
else if (prot_flags == VM_PAGE_READ) |
207 |
+ |
prot = PAGE_READONLY; |
208 |
+ |
else if (prot_flags == 0) |
209 |
+ |
prot = PAGE_NOACCESS; |
210 |
+ |
return prot; |
211 |
+ |
} |
212 |
+ |
#endif |
213 |
+ |
|
214 |
|
/* Initialize the VM system. Returns 0 if successful, -1 for errors. */ |
215 |
|
|
216 |
|
int vm_init(void) |
301 |
|
} |
302 |
|
#endif |
303 |
|
#else |
304 |
+ |
#ifdef HAVE_WIN32_VM |
305 |
+ |
if ((addr = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL) |
306 |
+ |
return VM_MAP_FAILED; |
307 |
+ |
|
308 |
+ |
// Zero newly allocated memory |
309 |
+ |
if (memset(addr, 0, size) != addr) |
310 |
+ |
return VM_MAP_FAILED; |
311 |
+ |
#else |
312 |
|
if ((addr = calloc(size, 1)) == 0) |
313 |
|
return VM_MAP_FAILED; |
314 |
|
|
316 |
|
return addr; |
317 |
|
#endif |
318 |
|
#endif |
319 |
+ |
#endif |
320 |
|
|
321 |
|
// Explicitely protect the newly mapped region here because on some systems, |
322 |
|
// say MacOS X, mmap() doesn't honour the requested protection flags. |
350 |
|
if (memset(addr, 0, size) != addr) |
351 |
|
return -1; |
352 |
|
#else |
353 |
+ |
#ifdef HAVE_WIN32_VM |
354 |
+ |
// Windows cannot allocate Low Memory |
355 |
+ |
if (addr == NULL) |
356 |
+ |
return -1; |
357 |
+ |
|
358 |
+ |
// Allocate a possibly offset region to align on 64K boundaries |
359 |
+ |
LPVOID req_addr = align_addr_segment(addr); |
360 |
+ |
DWORD req_size = align_size_segment(addr, size); |
361 |
+ |
LPVOID ret_addr = VirtualAlloc(req_addr, req_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); |
362 |
+ |
if (ret_addr != req_addr) |
363 |
+ |
return -1; |
364 |
+ |
|
365 |
+ |
// Zero newly allocated memory |
366 |
+ |
if (memset(addr, 0, size) != addr) |
367 |
+ |
return -1; |
368 |
+ |
#else |
369 |
|
// Unsupported |
370 |
|
return -1; |
371 |
|
#endif |
372 |
|
#endif |
373 |
+ |
#endif |
374 |
|
|
375 |
|
// Explicitely protect the newly mapped region here because on some systems, |
376 |
|
// say MacOS X, mmap() doesn't honour the requested protection flags. |
412 |
|
} |
413 |
|
#endif |
414 |
|
#else |
415 |
+ |
#ifdef HAVE_WIN32_VM |
416 |
+ |
if (VirtualFree(align_addr_segment(addr), 0, MEM_RELEASE) == 0) |
417 |
+ |
return -1; |
418 |
+ |
#else |
419 |
|
free(addr); |
420 |
|
#endif |
421 |
|
#endif |
422 |
+ |
#endif |
423 |
|
|
424 |
|
return 0; |
425 |
|
} |
437 |
|
int ret_code = mprotect((caddr_t)addr, size, prot); |
438 |
|
return ret_code == 0 ? 0 : -1; |
439 |
|
#else |
440 |
+ |
#ifdef HAVE_WIN32_VM |
441 |
+ |
DWORD old_prot; |
442 |
+ |
int ret_code = VirtualProtect(addr, size, translate_prot_flags(prot), &old_prot); |
443 |
+ |
return ret_code != 0 ? 0 : -1; |
444 |
+ |
#else |
445 |
|
// Unsupported |
446 |
|
return -1; |
447 |
|
#endif |
448 |
|
#endif |
449 |
+ |
#endif |
450 |
|
} |
451 |
|
|
452 |
|
#ifdef CONFIGURE_TEST_VM_MAP |
459 |
|
vm_init(); |
460 |
|
|
461 |
|
#define page_align(address) ((char *)((unsigned long)(address) & -page_size)) |
462 |
+ |
#ifdef _WIN32 |
463 |
+ |
const unsigned long page_size = 4096; |
464 |
+ |
#else |
465 |
|
unsigned long page_size = getpagesize(); |
466 |
+ |
#endif |
467 |
|
|
468 |
|
const int area_size = 6 * page_size; |
469 |
|
volatile char * area = (volatile char *) vm_acquire(area_size); |