mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-08-12 06:25:32 +00:00
Windows memory allocators
This commit is contained in:
@@ -27,7 +27,11 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: Win32 VMs ?
|
#ifdef HAVE_WIN32_VM
|
||||||
|
#define WIN32_LEAN_AND_MEAN /* avoid including junk */
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -173,6 +177,40 @@ static int translate_map_flags(int vm_flags)
|
|||||||
}
|
}
|
||||||
#endif
|
#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. */
|
/* Initialize the VM system. Returns 0 if successful, -1 for errors. */
|
||||||
|
|
||||||
int vm_init(void)
|
int vm_init(void)
|
||||||
@@ -262,6 +300,14 @@ void * vm_acquire(size_t size, int options)
|
|||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#else
|
||||||
if ((addr = calloc(size, 1)) == 0)
|
if ((addr = calloc(size, 1)) == 0)
|
||||||
return VM_MAP_FAILED;
|
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
|
// Omit changes for protections because they are not supported in this mode
|
||||||
return addr;
|
return addr;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Explicitely protect the newly mapped region here because on some systems,
|
// 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
|
// Since I don't know the standard behavior of mmap(), zero-fill here
|
||||||
if (memset(addr, 0, size) != addr)
|
if (memset(addr, 0, size) != addr)
|
||||||
return -1;
|
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
|
#else
|
||||||
// Unsupported
|
// Unsupported
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Explicitely protect the newly mapped region here because on some systems,
|
// 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;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_WIN32_VM
|
||||||
|
if (VirtualFree(align_addr_segment(addr), 0, MEM_RELEASE) == 0)
|
||||||
|
return -1;
|
||||||
#else
|
#else
|
||||||
free(addr);
|
free(addr);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -367,11 +436,17 @@ int vm_protect(void * addr, size_t size, int prot)
|
|||||||
#ifdef HAVE_MMAP_VM
|
#ifdef HAVE_MMAP_VM
|
||||||
int ret_code = mprotect((caddr_t)addr, size, prot);
|
int ret_code = mprotect((caddr_t)addr, size, prot);
|
||||||
return ret_code == 0 ? 0 : -1;
|
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
|
#else
|
||||||
// Unsupported
|
// Unsupported
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIGURE_TEST_VM_MAP
|
#ifdef CONFIGURE_TEST_VM_MAP
|
||||||
@@ -384,7 +459,11 @@ int main(void)
|
|||||||
vm_init();
|
vm_init();
|
||||||
|
|
||||||
#define page_align(address) ((char *)((unsigned long)(address) & -page_size))
|
#define page_align(address) ((char *)((unsigned long)(address) & -page_size))
|
||||||
|
#ifdef _WIN32
|
||||||
|
const unsigned long page_size = 4096;
|
||||||
|
#else
|
||||||
unsigned long page_size = getpagesize();
|
unsigned long page_size = getpagesize();
|
||||||
|
#endif
|
||||||
|
|
||||||
const int area_size = 6 * page_size;
|
const int area_size = 6 * page_size;
|
||||||
volatile char * area = (volatile char *) vm_acquire(area_size);
|
volatile char * area = (volatile char *) vm_acquire(area_size);
|
||||||
|
Reference in New Issue
Block a user