/** * mono_valloc: * @addr: memory address * @length: memory area size * @flags: protection flags * * Allocates @length bytes of virtual memory with the @flags * protection. @addr can be a preferred memory address or a * mandatory one if MONO_MMAP_FIXED is set in @flags. * @addr must be pagesize aligned and can be NULL. * @length must be a multiple of pagesize. * * Returns: NULL on failure, the address of the memory area otherwise */ void* mono_valloc (void *addr, size_t length, int flags) { void *ptr; int mflags = 0; int prot = prot_from_flags (flags); /* translate the flags */ if (flags & MONO_MMAP_FIXED) mflags |= MAP_FIXED; if (flags & MONO_MMAP_32BIT) mflags |= MAP_32BIT; mflags |= MAP_ANONYMOUS; mflags |= MAP_PRIVATE; ptr = mmap (addr, length, prot, mflags, -1, 0); if (ptr == (void*)-1) { int fd = open ("/dev/zero", O_RDONLY); if (fd != -1) { ptr = mmap (addr, length, prot, mflags, fd, 0); close (fd); } if (ptr == (void*)-1) return NULL; } return ptr; }
void* mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle) { void *ptr; int mflags = 0; HANDLE file, mapping; int prot = prot_from_flags (flags); /* translate the flags */ /*if (flags & MONO_MMAP_PRIVATE) mflags |= MAP_PRIVATE; if (flags & MONO_MMAP_SHARED) mflags |= MAP_SHARED; if (flags & MONO_MMAP_ANON) mflags |= MAP_ANONYMOUS; if (flags & MONO_MMAP_FIXED) mflags |= MAP_FIXED; if (flags & MONO_MMAP_32BIT) mflags |= MAP_32BIT;*/ mflags = FILE_MAP_READ; if (flags & MONO_MMAP_WRITE) mflags = FILE_MAP_COPY; file = (HANDLE) _get_osfhandle (fd); mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL); if (mapping == NULL) return NULL; ptr = MapViewOfFile (mapping, mflags, 0, offset, length); if (ptr == NULL) { CloseHandle (mapping); return NULL; } *ret_handle = (void*)mapping; return ptr; }
/** * mono_valloc: * @addr: memory address * @length: memory area size * @flags: protection flags * * Allocates @length bytes of virtual memory with the @flags * protection. @addr can be a preferred memory address or a * mandatory one if MONO_MMAP_FIXED is set in @flags. * @addr must be pagesize aligned and can be NULL. * @length must be a multiple of pagesize. * * Returns: NULL on failure, the address of the memory area otherwise */ void* mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type) { void *ptr; int mflags = 0; int prot = prot_from_flags (flags); /* translate the flags */ if (flags & MONO_MMAP_FIXED) mflags |= MAP_FIXED; if (flags & MONO_MMAP_32BIT) mflags |= MAP_32BIT; mflags |= MAP_ANONYMOUS; mflags |= MAP_PRIVATE; BEGIN_CRITICAL_SECTION; ptr = mmap (addr, length, prot, mflags, -1, 0); if (ptr == MAP_FAILED) { int fd = open ("/dev/zero", O_RDONLY); if (fd != -1) { ptr = mmap (addr, length, prot, mflags, fd, 0); close (fd); } } END_CRITICAL_SECTION; if (ptr == MAP_FAILED) return NULL; account_mem (type, (ssize_t)length); return ptr; }
void* mono_valloc (void *addr, size_t length, int flags) { void *ptr; int mflags = MEM_COMMIT; int prot = prot_from_flags (flags); /* translate the flags */ ptr = VirtualAlloc (addr, length, mflags, prot); return ptr; }
int mono_mprotect (void *addr, size_t length, int flags) { int prot = prot_from_flags (flags); void *new_addr; if (flags & MONO_MMAP_DISCARD) memset (addr, 0, length); new_addr = mmap(addr, length, prot, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0); if (new_addr == addr) return 0; return -1; }
int mono_mprotect (void *addr, size_t length, int flags) { DWORD oldprot; int prot = prot_from_flags (flags); if (flags & MONO_MMAP_DISCARD) { VirtualFree (addr, length, MEM_DECOMMIT); VirtualAlloc (addr, length, MEM_COMMIT, prot); return 0; } return VirtualProtect (addr, length, prot, &oldprot) == 0; }
void* mono_valloc_aligned (size_t length, size_t alignment, int flags) { int prot = prot_from_flags (flags); char *mem = VirtualAlloc (NULL, length + alignment, MEM_RESERVE, prot); char *aligned; if (!mem) return NULL; aligned = aligned_address (mem, length, alignment); aligned = VirtualAlloc (aligned, length, MEM_COMMIT, prot); g_assert (aligned); return aligned; }
int mono_mprotect (void *addr, size_t length, int flags) { int prot = prot_from_flags (flags); if (flags & MONO_MMAP_DISCARD) { /* on non-linux the pages are not guaranteed to be zeroed (*bsd, osx at least) */ #if defined(__linux__) if (madvise (addr, length, MADV_DONTNEED)) memset (addr, 0, length); #else memset (addr, 0, length); #ifdef HAVE_MADVISE madvise (addr, length, MADV_DONTNEED); madvise (addr, length, MADV_FREE); #else posix_madvise (addr, length, POSIX_MADV_DONTNEED); #endif #endif } return mprotect (addr, length, prot); }
/** * mono_file_map: * @length: size of data to map * @flags: protection flags * @fd: file descriptor * @offset: offset in the file * @ret_handle: pointer to storage for returning a handle for the map * * Map the area of the file pointed to by the file descriptor @fd, at offset * @offset and of size @length in memory according to the protection flags * @flags. * @offset and @length must be multiples of the page size. * @ret_handle must point to a void*: this value must be used when unmapping * the memory area using mono_file_unmap (). * */ void* mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle) { void *ptr; int mflags = 0; int prot = prot_from_flags (flags); /* translate the flags */ if (flags & MONO_MMAP_PRIVATE) mflags |= MAP_PRIVATE; if (flags & MONO_MMAP_SHARED) mflags |= MAP_SHARED; if (flags & MONO_MMAP_FIXED) mflags |= MAP_FIXED; if (flags & MONO_MMAP_32BIT) mflags |= MAP_32BIT; ptr = mmap (0, length, prot, mflags, fd, offset); if (ptr == (void*)-1) return NULL; *ret_handle = (void*)length; return ptr; }