summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--orc/orccodemem.c80
-rw-r--r--orc/orccompiler.c32
-rw-r--r--orc/orccpu-arm.c5
-rw-r--r--orc/orcexecutor.c18
-rw-r--r--orc/orcinternal.h5
-rw-r--r--orc/orcprogram-avx.c4
-rw-r--r--orc/orctarget.c3
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>