/* Memory segment handling. Copyright (C) 2006 Tristan Gingold. GHDL is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GHDL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef WINNT #define _GNU_SOURCE #include #include /* #include */ /* TODO: init (get pagesize) round size, set rights. */ #ifdef __APPLE__ #define MAP_ANONYMOUS MAP_ANON #else #define HAVE_MREMAP #endif #ifndef HAVE_MREMAP #include #endif void * mmap_malloc (int size) { void *res; res = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); /* printf ("mmap (%d) = %p\n", size, res); */ if (res == MAP_FAILED) return NULL; return res; } void * mmap_realloc (void *ptr, int old_size, int size) { void *res; #ifdef HAVE_MREMAP res = mremap (ptr, old_size, size, MREMAP_MAYMOVE); #else res = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (res == MAP_FAILED) return NULL; memcpy (res, ptr, old_size); munmap (ptr, old_size); #endif /* printf ("mremap (%p, %d, %d) = %p\n", ptr, old_size, size, res); */ #if 0 if (res == MAP_FAILED) return NULL; #endif return res; } void mmap_free (void * ptr, int size) { munmap (ptr, size); } void mmap_rx (void *ptr, int size) { mprotect (ptr, size, PROT_READ | PROT_EXEC); } #else #include void * mmap_malloc (int size) { void *res; res = VirtualAlloc (NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); return res; } void * mmap_realloc (void *ptr, int old_size, int size) { void *res; res = VirtualAlloc (NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (ptr != NULL) { CopyMemory (res, ptr, size > old_size ? old_size : size); VirtualFree (ptr, old_size, MEM_RELEASE); } return res; } void mmap_free (void * ptr, int size) { VirtualFree (ptr, size, MEM_RELEASE); } void mmap_rx (void *ptr, int size) { DWORD old; /* This is not supported on every version. In case of failure, this should still work. */ VirtualProtect (ptr, size, PAGE_EXECUTE_READ, &old); } #endif