mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-09-05 19:28:58 +00:00
Windows memory allocators
This commit is contained in:
parent
7533cac203
commit
347f7ce77b
@ -27,7 +27,11 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
// TODO: Win32 VMs ?
|
||||
#ifdef HAVE_WIN32_VM
|
||||
#define WIN32_LEAN_AND_MEAN /* avoid including junk */
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -173,6 +177,40 @@ static int translate_map_flags(int vm_flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Align ADDR and SIZE to 64K boundaries. */
|
||||
|
||||
#ifdef HAVE_WIN32_VM
|
||||
static inline LPVOID align_addr_segment(LPVOID addr)
|
||||
{
|
||||
return (LPVOID)(((DWORD)addr) & -65536);
|
||||
}
|
||||
|
||||
static inline DWORD align_size_segment(LPVOID addr, DWORD size)
|
||||
{
|
||||
return size + ((DWORD)addr - (DWORD)align_addr_segment(addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Translate generic VM prot flags to host values. */
|
||||
|
||||
#ifdef HAVE_WIN32_VM
|
||||
static int translate_prot_flags(int prot_flags)
|
||||
{
|
||||
int prot = PAGE_READWRITE;
|
||||
if (prot_flags == (VM_PAGE_EXECUTE | VM_PAGE_READ | VM_PAGE_WRITE))
|
||||
prot = PAGE_EXECUTE_READWRITE;
|
||||
else if (prot_flags == (VM_PAGE_EXECUTE | VM_PAGE_READ))
|
||||
prot = PAGE_EXECUTE_READ;
|
||||
else if (prot_flags == (VM_PAGE_READ | VM_PAGE_WRITE))
|
||||
prot = PAGE_READWRITE;
|
||||
else if (prot_flags == VM_PAGE_READ)
|
||||
prot = PAGE_READONLY;
|
||||
else if (prot_flags == 0)
|
||||
prot = PAGE_NOACCESS;
|
||||
return prot;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the VM system. Returns 0 if successful, -1 for errors. */
|
||||
|
||||
int vm_init(void)
|
||||
@ -262,6 +300,14 @@ void * vm_acquire(size_t size, int options)
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_WIN32_VM
|
||||
if ((addr = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL)
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
// Zero newly allocated memory
|
||||
if (memset(addr, 0, size) != addr)
|
||||
return VM_MAP_FAILED;
|
||||
#else
|
||||
if ((addr = calloc(size, 1)) == 0)
|
||||
return VM_MAP_FAILED;
|
||||
@ -269,6 +315,7 @@ void * vm_acquire(size_t size, int options)
|
||||
// Omit changes for protections because they are not supported in this mode
|
||||
return addr;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Explicitely protect the newly mapped region here because on some systems,
|
||||
@ -302,10 +349,27 @@ int vm_acquire_fixed(void * addr, size_t size, int options)
|
||||
// Since I don't know the standard behavior of mmap(), zero-fill here
|
||||
if (memset(addr, 0, size) != addr)
|
||||
return -1;
|
||||
#else
|
||||
#ifdef HAVE_WIN32_VM
|
||||
// Windows cannot allocate Low Memory
|
||||
if (addr == NULL)
|
||||
return -1;
|
||||
|
||||
// Allocate a possibly offset region to align on 64K boundaries
|
||||
LPVOID req_addr = align_addr_segment(addr);
|
||||
DWORD req_size = align_size_segment(addr, size);
|
||||
LPVOID ret_addr = VirtualAlloc(req_addr, req_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
if (ret_addr != req_addr)
|
||||
return -1;
|
||||
|
||||
// Zero newly allocated memory
|
||||
if (memset(addr, 0, size) != addr)
|
||||
return -1;
|
||||
#else
|
||||
// Unsupported
|
||||
return -1;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Explicitely protect the newly mapped region here because on some systems,
|
||||
@ -347,9 +411,14 @@ int vm_release(void * addr, size_t size)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_WIN32_VM
|
||||
if (VirtualFree(align_addr_segment(addr), 0, MEM_RELEASE) == 0)
|
||||
return -1;
|
||||
#else
|
||||
free(addr);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@ -367,11 +436,17 @@ int vm_protect(void * addr, size_t size, int prot)
|
||||
#ifdef HAVE_MMAP_VM
|
||||
int ret_code = mprotect((caddr_t)addr, size, prot);
|
||||
return ret_code == 0 ? 0 : -1;
|
||||
#else
|
||||
#ifdef HAVE_WIN32_VM
|
||||
DWORD old_prot;
|
||||
int ret_code = VirtualProtect(addr, size, translate_prot_flags(prot), &old_prot);
|
||||
return ret_code != 0 ? 0 : -1;
|
||||
#else
|
||||
// Unsupported
|
||||
return -1;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIGURE_TEST_VM_MAP
|
||||
@ -384,7 +459,11 @@ int main(void)
|
||||
vm_init();
|
||||
|
||||
#define page_align(address) ((char *)((unsigned long)(address) & -page_size))
|
||||
#ifdef _WIN32
|
||||
const unsigned long page_size = 4096;
|
||||
#else
|
||||
unsigned long page_size = getpagesize();
|
||||
#endif
|
||||
|
||||
const int area_size = 6 * page_size;
|
||||
volatile char * area = (volatile char *) vm_acquire(area_size);
|
||||
|
Loading…
Reference in New Issue
Block a user