diff options
author | David Schleef <ds@entropywave.com> | 2010-09-14 23:15:44 -0700 |
---|---|---|
committer | David Schleef <ds@entropywave.com> | 2010-09-14 23:16:56 -0700 |
commit | 68259b8d7bd4b706d75ecdd291148e884dfc282e (patch) | |
tree | c9d664b519fcda018de0ac729a80eaddc7624256 | |
parent | cf0a47086b6727ceb9eec9e79adb870eb26bc9bb (diff) |
Add various hacks to allocated codemem
First check $TMPDIR, then $HOME, then try an anonymous map.
-rw-r--r-- | orc/orccodemem.c | 84 |
1 files changed, 56 insertions, 28 deletions
diff --git a/orc/orccodemem.c b/orc/orccodemem.c index be7a262..b704ecf 100644 --- a/orc/orccodemem.c +++ b/orc/orccodemem.c @@ -187,58 +187,86 @@ orc_code_chunk_free (OrcCodeChunk *chunk) } #ifdef HAVE_CODEMEM_MMAP -void -orc_code_region_allocate_codemem (OrcCodeRegion *region) +int +orc_code_region_allocate_codemem_dual_map (OrcCodeRegion *region, + const char *dir, int force_unlink) { int fd; int n; - static char *tmpdir = NULL; char *filename; - if (tmpdir == NULL) { - tmpdir = getenv ("TMPDIR"); - if (tmpdir == NULL) { - tmpdir = "/tmp"; - } - } - -#if 0 - filename = malloc (strlen ("/orcexec..") + - strlen (tmpdir) + strlen (compiler->program->name) + 6 + 1); - sprintf(filename, "%s/orcexec.%s.XXXXXX", tmpdir, compiler->program->name); -#endif filename = malloc (strlen ("/orcexec..") + - strlen (tmpdir) + 6 + 1); - sprintf(filename, "%s/orcexec.XXXXXX", tmpdir); + strlen (dir) + 6 + 1); + sprintf(filename, "%s/orcexec.XXXXXX", dir); fd = mkstemp (filename); if (fd == -1) { - /* FIXME oh crap */ - ORC_ERROR ("failed to create temp file"); - return; + ORC_WARNING ("failed to create temp file"); + return FALSE; } - if (!_orc_compiler_flag_debug) { + if (force_unlink || !_orc_compiler_flag_debug) { unlink (filename); } free (filename); n = ftruncate (fd, SIZE); + region->exec_ptr = mmap (NULL, SIZE, PROT_READ|PROT_EXEC, + MAP_SHARED, fd, 0); + if (region->exec_ptr == MAP_FAILED) { + ORC_WARNING("failed to create exec map"); + close (fd); + return FALSE; + } region->write_ptr = mmap (NULL, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (region->write_ptr == MAP_FAILED) { - ORC_ERROR("failed to create write map"); - return; + ORC_WARNING ("failed to create write map"); + close (fd); + return FALSE; } - region->exec_ptr = mmap (NULL, SIZE, PROT_READ|PROT_EXEC, - MAP_SHARED, fd, 0); + region->size = SIZE; + + close (fd); + return TRUE; +} + +int +orc_code_region_allocate_codemem_anon_map (OrcCodeRegion *region) +{ + region->exec_ptr = mmap (NULL, SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (region->exec_ptr == MAP_FAILED) { - ORC_ERROR("failed to create exec map"); - return; + ORC_WARNING("failed to create write/exec map"); + return FALSE; } + region->write_ptr = region->exec_ptr; region->size = SIZE; + return TRUE; +} - close (fd); +void +orc_code_region_allocate_codemem (OrcCodeRegion *region) +{ + int ret; + const char *tmpdir; + + tmpdir = getenv ("TMPDIR"); + ret = orc_code_region_allocate_codemem_dual_map (region, + tmpdir ? tmpdir : "/tmp", FALSE); + if (!ret) { + ret = orc_code_region_allocate_codemem_dual_map (region, + getenv ("HOME"), TRUE); + } + if (!ret) { + ret = orc_code_region_allocate_codemem_anon_map (region); + } + if (!ret) { + ORC_ERROR("Failed to create write and exec mmap regions. This " + "is probably because SELinux execmem check is enabled (good) " + "and $TMPDIR and $HOME are mounted noexec (bad)."); + } } + #endif #ifdef HAVE_CODEMEM_VIRTUALALLOC |