diff options
-rw-r--r-- | orc/orccodemem.c | 80 | ||||
-rw-r--r-- | orc/orccompiler.c | 32 | ||||
-rw-r--r-- | orc/orccpu-arm.c | 5 | ||||
-rw-r--r-- | orc/orcexecutor.c | 18 | ||||
-rw-r--r-- | orc/orcinternal.h | 5 | ||||
-rw-r--r-- | orc/orcprogram-avx.c | 4 | ||||
-rw-r--r-- | orc/orctarget.c | 3 |
7 files changed, 111 insertions, 36 deletions
diff --git a/orc/orccodemem.c b/orc/orccodemem.c index ca1f7e0..566a699 100644 --- a/orc/orccodemem.c +++ b/orc/orccodemem.c @@ -37,8 +37,6 @@ /* See _orc_compiler_init() */ extern int _orc_codemem_alignment; -typedef struct _OrcCodeRegion OrcCodeRegion; - struct _OrcCodeRegion { orc_uint8 *write_ptr; orc_uint8 *exec_ptr; @@ -59,22 +57,39 @@ struct _OrcCodeChunk { }; -static void orc_code_region_allocate_codemem (OrcCodeRegion *region); +static int orc_code_region_allocate_codemem (OrcCodeRegion *region); static OrcCodeRegion **orc_code_regions; static int orc_code_n_regions; +OrcCodeRegion * +orc_code_region_alloc (void) +{ + OrcCodeRegion *region; + + region = malloc(sizeof(OrcCodeRegion)); + memset (region, 0, sizeof(OrcCodeRegion)); + + if (!orc_code_region_allocate_codemem (region)) { + free(region); + return NULL; + } + + return region; +} + static OrcCodeRegion * orc_code_region_new (void) { OrcCodeRegion *region; OrcCodeChunk *chunk; - region = malloc(sizeof(OrcCodeRegion)); - memset (region, 0, sizeof(OrcCodeRegion)); + region = orc_code_region_alloc(); - orc_code_region_allocate_codemem (region); + if (!region) { + return NULL; + } chunk = malloc(sizeof(OrcCodeChunk)); memset (chunk, 0, sizeof(OrcCodeChunk)); @@ -143,13 +158,18 @@ orc_code_region_get_free_chunk (int size) } } + region = orc_code_region_new (); + if (!region) + return NULL; + orc_code_regions = realloc (orc_code_regions, sizeof(void *)*(orc_code_n_regions+1)); - if (!orc_code_regions) + if (!orc_code_regions) { + free(region); return NULL; + } - orc_code_regions[orc_code_n_regions] = orc_code_region_new (); - region = orc_code_regions[orc_code_n_regions]; + orc_code_regions[orc_code_n_regions] = region; orc_code_n_regions++; for(chunk = region->chunks; chunk; chunk = chunk->next) { @@ -301,61 +321,77 @@ orc_code_region_allocate_codemem_anon_map (OrcCodeRegion *region) return TRUE; } -static void +int orc_code_region_allocate_codemem (OrcCodeRegion *region) { const char *tmpdir; tmpdir = getenv ("XDG_RUNTIME_DIR"); if (tmpdir && orc_code_region_allocate_codemem_dual_map (region, - tmpdir, FALSE)) return; + tmpdir, FALSE)) return TRUE; tmpdir = getenv ("HOME"); if (tmpdir && orc_code_region_allocate_codemem_dual_map (region, - tmpdir, FALSE)) return; + tmpdir, FALSE)) return TRUE; tmpdir = getenv ("TMPDIR"); if (tmpdir && orc_code_region_allocate_codemem_dual_map (region, - tmpdir, FALSE)) return; + tmpdir, FALSE)) return TRUE; if (orc_code_region_allocate_codemem_dual_map (region, - "/tmp", FALSE)) return; + "/tmp", FALSE)) return TRUE; - if (orc_code_region_allocate_codemem_anon_map (region)) return; + if (orc_code_region_allocate_codemem_anon_map (region)) return TRUE; #ifdef __APPLE__ ORC_ERROR("Failed to create write and exec mmap regions. This " "is probably because the Hardened Runtime is enabled without " "the com.apple.security.cs.allow-jit entitlement."); #else - 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)."); + ORC_ERROR( + "Failed to create write+exec mappings. This " + "is probably because SELinux execmem check is enabled (good), " + "$XDG_RUNTIME_DIR, $HOME, $TMPDIR, $HOME and /tmp are mounted noexec (good), " + "and anonymous mappings cannot be created (really bad)." + ); #endif + return FALSE; } #endif #ifdef HAVE_CODEMEM_VIRTUALALLOC -void +int orc_code_region_allocate_codemem (OrcCodeRegion *region) { /* On UWP, we can't allocate memory as executable from the start. We can only * set that later after compiling and copying the code over. This is a good * idea in general to avoid security issues, so we do it on win32 too. */ - region->write_ptr = _virtualalloc (NULL, SIZE, MEM_COMMIT, PAGE_READWRITE); + void *write_ptr; + write_ptr = _virtualalloc (NULL, SIZE, MEM_COMMIT, PAGE_READWRITE); + if (!write_ptr) + return FALSE; + + region->write_ptr = write_ptr; region->exec_ptr = region->write_ptr; region->size = SIZE; + return TRUE; } #endif #ifdef HAVE_CODEMEM_MALLOC -void +int orc_code_region_allocate_codemem (OrcCodeRegion *region) { - region->write_ptr = malloc(SIZE); + void *write_ptr; + write_ptr = malloc(SIZE); + if (!write_ptr) + return FALSE; + + region->write_ptr = write_ptr; region->exec_ptr = region->write_ptr; region->size = SIZE; + return TRUE; } #endif diff --git a/orc/orccompiler.c b/orc/orccompiler.c index 7591858..b3e29e0 100644 --- a/orc/orccompiler.c +++ b/orc/orccompiler.c @@ -112,16 +112,18 @@ _orc_compiler_init (void) _orc_codemem_alignment = 15; #endif -#ifdef ORC_WINAPI_ONLY_APP - if (!_orc_compiler_flag_backup && !_orc_compiler_flag_emulate) { - int can_jit = FALSE; + int can_jit = TRUE; + if (!_orc_compiler_flag_backup && !_orc_compiler_flag_emulate) { /* If backup code is not enabled and emulation is not enabled, that means * we will do JIT compilation and call orc_code_region_allocate_codemem(). - * When targeting Windows Store apps, the codeGeneration capability must + */ +#if defined(HAVE_CODEMEM_VIRTUALALLOC) && defined(ORC_WINAPI_ONLY_APP) + /* When targeting Windows Store apps, the codeGeneration capability must * be enabled in the app manifest, or passing PAGE_EXECUTE to * VirtualProtectFromApp will return NULL. In this case, we must force * backup C code, and if that's not available, we must emulate. */ + can_jit = FALSE; void *mem = VirtualAllocFromApp (NULL, page_size, MEM_COMMIT, PAGE_READWRITE); if (mem) { @@ -129,16 +131,32 @@ _orc_compiler_init (void) if (VirtualProtectFromApp (mem, page_size, PAGE_EXECUTE, &old_protect) > 0) can_jit = TRUE; VirtualFree (mem, 0, MEM_RELEASE); + } else { + ORC_WARNING ("Unable to allocate executable pages: using backup code or " + "emulation: codeGeneration capability isn't set in the app manifest?"); } +#elif defined(HAVE_CODEMEM_MMAP) + /* In this case, we need to check that we can mmap pages as executable. + * This is not the case under the combination of SELinux and sandboxing + * profiles. + */ + can_jit = FALSE; + OrcCodeRegion *region = orc_code_region_alloc(); + if (region) { + can_jit = TRUE; + // FIXME: the file descriptor should be kept somewhere + // Currently the underlying mmap'd pages are leaked + free(region); + } else { + ORC_WARNING ("Unable to allocate executable pages: using backup code or emulation"); + } +#endif if (!can_jit) { - ORC_WARNING ("Unable to allocate executable pages: using backup code or " - "emulation: codeGeneration capability isn't set in the app manifest?"); _orc_compiler_flag_backup = TRUE; _orc_compiler_flag_emulate = TRUE; } } -#endif } int diff --git a/orc/orccpu-arm.c b/orc/orccpu-arm.c index 865df59..8e65cee 100644 --- a/orc/orccpu-arm.c +++ b/orc/orccpu-arm.c @@ -47,6 +47,9 @@ #if defined(__linux__) #include <linux/auxvec.h> #endif +#ifdef __APPLE__ +#include <TargetConditionals.h> +#endif /***** arm *****/ @@ -120,7 +123,7 @@ orc_cpu_arm_getflags_cpuinfo () #if defined (_WIN32) && defined (_M_ARM64) /* On Windows, for desktop applications, we are on always on ARMv8 (aarch64)*/ ret = ORC_TARGET_ARM_EDSP | ORC_TARGET_NEON_NEON; -#elif defined (__APPLE__) && defined (__arm64__) +#elif defined (__APPLE__) && defined (__arm64__) && TARGET_OS_OSX ret = ORC_TARGET_ARM_EDSP | ORC_TARGET_NEON_NEON; #else char *cpuinfo; diff --git a/orc/orcexecutor.c b/orc/orcexecutor.c index 0f95700..43bb7b7 100644 --- a/orc/orcexecutor.c +++ b/orc/orcexecutor.c @@ -236,12 +236,22 @@ orc_executor_emulate (OrcExecutor *ex) OrcInstruction *insn; OrcStaticOpcode *opcode; OrcOpcodeExecutor *opcode_ex; - void *tmpspace[ORC_N_COMPILER_VARIABLES] = { 0 }; + char name_placeholder[40]; + const char* name = name_placeholder; + void *tmpspace[ORC_N_COMPILER_VARIABLES] = {0}; + + memset(name_placeholder, '\0', sizeof(name_placeholder)); if (ex->program) { code = ex->program->orccode; + if (ex->program->name == NULL) { + sprintf(name_placeholder, "<unnamed program @ %p>", ex->program); + } else { + name = ex->program->name; + } } else { code = (OrcCode *)ex->arrays[ORC_VAR_A2]; + sprintf(name_placeholder, "<unnamed source @ %p>", ex); } ex->accumulators[0] = 0; @@ -312,13 +322,13 @@ orc_executor_emulate (OrcExecutor *ex) } else if (var->vartype == ORC_VAR_TYPE_SRC) { if (ORC_PTR_TO_INT(ex->arrays[insn->src_args[k]]) & (var->size - 1)) { ORC_ERROR("Unaligned array for src%d, program %s", - (insn->src_args[k]-ORC_VAR_S1), ex->program->name); + (insn->src_args[k]-ORC_VAR_S1), name); } opcode_ex[j].src_ptrs[k] = ex->arrays[insn->src_args[k]]; } else if (var->vartype == ORC_VAR_TYPE_DEST) { if (ORC_PTR_TO_INT(ex->arrays[insn->src_args[k]]) & (var->size - 1)) { ORC_ERROR("Unaligned array for dest%d, program %s", - (insn->src_args[k]-ORC_VAR_D1), ex->program->name); + (insn->src_args[k]-ORC_VAR_D1), name); } opcode_ex[j].src_ptrs[k] = ex->arrays[insn->src_args[k]]; } @@ -336,7 +346,7 @@ orc_executor_emulate (OrcExecutor *ex) } else if (var->vartype == ORC_VAR_TYPE_DEST) { if (ORC_PTR_TO_INT(ex->arrays[insn->dest_args[k]]) & (var->size - 1)) { ORC_ERROR("Unaligned array for dest%d, program %s", - (insn->dest_args[k]-ORC_VAR_D1), ex->program->name); + (insn->dest_args[k]-ORC_VAR_D1), name); } opcode_ex[j].dest_ptrs[k] = ex->arrays[insn->dest_args[k]]; } diff --git a/orc/orcinternal.h b/orc/orcinternal.h index d1355a0..f7374a4 100644 --- a/orc/orcinternal.h +++ b/orc/orcinternal.h @@ -21,9 +21,12 @@ void orc_c64x_init (void); void orc_c64x_c_init (void); void orc_mips_init (void); +typedef struct _OrcCodeRegion OrcCodeRegion; typedef struct _OrcCodeChunk OrcCodeChunk; -/* This is internal API, nothing in the public headers returns an OrcCodeChunk */ +/* This is internal API, nothing in the public headers returns an OrcCodeChunk + */ +OrcCodeRegion * orc_code_region_alloc (void); void orc_code_chunk_free (OrcCodeChunk *chunk); extern int _orc_data_cache_size_level1; diff --git a/orc/orcprogram-avx.c b/orc/orcprogram-avx.c index 90f0e31..34a416c 100644 --- a/orc/orcprogram-avx.c +++ b/orc/orcprogram-avx.c @@ -46,11 +46,13 @@ avx_get_flag_name (const int shift) "ssse3", "sse41", "sse42", + "sse4a", + "sse5", "frame_pointer", "short_jumps", "64bit", "avx", - "avx2", + "avx2" }; if (shift >= 0 && shift < sizeof (flags) / sizeof (flags[0])) { diff --git a/orc/orctarget.c b/orc/orctarget.c index 86f4fb2..cd22613 100644 --- a/orc/orctarget.c +++ b/orc/orctarget.c @@ -1,7 +1,10 @@ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <orc/orctarget.h> #include <orc/orcinternal.h> |