예제 #1
0
int vm_release(void * addr, size_t size)
{
	// Safety check: don't try to release memory that was not allocated
	if (addr == VM_MAP_FAILED)
		return 0;

#ifdef HAVE_MACH_VM
	if (vm_deallocate(mach_task_self(), (vm_address_t)addr, size) != KERN_SUCCESS)
		return -1;
#else
#ifdef HAVE_MMAP_VM
	if (munmap((caddr_t)addr, size) != 0)
		return -1;
#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;
}
예제 #2
0
int vm_acquire_fixed(void * addr, size_t size, int options)
{
	errno = 0;

	// Fixed mappings are required to be private
	if (options & VM_MAP_SHARED)
		return -1;

#ifndef HAVE_VM_WRITE_WATCH
	if (options & VM_MAP_WRITE_WATCH)
		return -1;
#endif

#if defined(HAVE_MACH_VM)
	// vm_allocate() returns a zero-filled memory region
	kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, 0);
	if (ret_code != KERN_SUCCESS) {
		errno = vm_error(ret_code);
		return -1;
	}
#elif defined(HAVE_MMAP_VM)
	int fd = zero_fd;
	int the_map_flags = translate_map_flags(options) | map_flags | MAP_FIXED;

	if (mmap((caddr_t)addr, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0) == (void *)MAP_FAILED)
		return -1;
#elif defined(HAVE_WIN32_VM)
	// Windows cannot allocate Low Memory
	if (addr == NULL)
		return -1;

	int alloc_type = MEM_RESERVE | MEM_COMMIT;
	if (options & VM_MAP_WRITE_WATCH)
	  alloc_type |= MEM_WRITE_WATCH;

	// 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, alloc_type, PAGE_EXECUTE_READWRITE);
	if (ret_addr != req_addr)
		return -1;
#else
	// Unsupported
	return -1;
#endif

	// Explicitely protect the newly mapped region here because on some systems,
	// say MacOS X, mmap() doesn't honour the requested protection flags.
	if (vm_protect(addr, size, VM_PAGE_DEFAULT) != 0)
		return -1;

	return 0;
}
예제 #3
0
static inline DWORD align_size_segment(LPVOID addr, DWORD size)
{
	return size + ((vm_uintptr_t)addr - (vm_uintptr_t)align_addr_segment(addr));
}
예제 #4
0
static inline DWORD align_size_segment(LPVOID addr, DWORD size)
{
	D(bug("%s\n", __func__));
	return size + ((vm_uintptr_t)addr - (vm_uintptr_t)align_addr_segment(addr));
}