/* does it make sense to use the mmap-like API? */ if (flags == CODE_FLAG_MALLOC) { ptr = malloc (chunk_size); if (!ptr) return NULL; } else { #ifndef FORCE_MALLOC ptr = mmap (0, chunk_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS|ARCH_MAP_FLAGS, -1, 0); if (ptr == (void*)-1) { int fd = open ("/dev/zero", O_RDONLY); if (fd != -1) { ptr = mmap (0, chunk_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|ARCH_MAP_FLAGS, fd, 0); close (fd); } if (ptr == (void*)-1) { ptr = malloc (chunk_size); if (!ptr) return NULL; flags = CODE_FLAG_MALLOC; } } #else return NULL; #endif } if (flags == CODE_FLAG_MALLOC) { /* * AMD64 processors maintain icache coherency only for pages which are * marked executable. */ #ifndef PLATFORM_WIN32 { char *page_start = (char *) (((gssize) (ptr)) & ~ (pagesize - 1)); int pages = ((char*)ptr + chunk_size - page_start + pagesize - 1) / pagesize; int err = mprotect (page_start, pages * pagesize, PROT_READ | PROT_WRITE | PROT_EXEC); >>>>line 257 assert (!err); } #else { DWORD oldp; int err = VirtualProtect (ptr, chunk_size, PAGE_EXECUTE_READWRITE, &oldp); assert (err); } #endif #ifdef BIND_ROOM /* Make sure the thunks area is zeroed */ memset (ptr, 0, bsize); #endif } chunk = malloc (sizeof (CodeChunk)); if (!chunk) { if (flags == CODE_FLAG_MALLOC) free (ptr); #ifndef FORCE_MALLOC else munmap (ptr, chunk_size); #endif return NULL; } chunk->next = NULL; chunk->size = chunk_size; chunk->data = ptr; chunk->flags = flags; chunk->pos = bsize; chunk->bsize = bsize; /*printf ("code chunk at: %p\n", ptr);*/ return chunk; }