summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sljit/sljitConfigInternal.h2
-rw-r--r--src/sljit/sljitExecAllocator.c113
-rw-r--r--src/sljit/sljitNativeS390X.c43
3 files changed, 87 insertions, 71 deletions
diff --git a/src/sljit/sljitConfigInternal.h b/src/sljit/sljitConfigInternal.h
index eb1132d..ff36e5b 100644
--- a/src/sljit/sljitConfigInternal.h
+++ b/src/sljit/sljitConfigInternal.h
@@ -158,6 +158,8 @@ extern "C" {
#define SLJIT_CONFIG_MIPS_64 1
#elif defined(__sparc__) || defined(__sparc)
#define SLJIT_CONFIG_SPARC_32 1
+#elif defined(__s390x__)
+#define SLJIT_CONFIG_S390X 1
#else
/* Unsupported architecture */
#define SLJIT_CONFIG_UNSUPPORTED 1
diff --git a/src/sljit/sljitExecAllocator.c b/src/sljit/sljitExecAllocator.c
index 61a32f2..2e1c138 100644
--- a/src/sljit/sljitExecAllocator.c
+++ b/src/sljit/sljitExecAllocator.c
@@ -79,6 +79,7 @@
*/
#ifdef _WIN32
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
{
@@ -91,65 +92,76 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
VirtualFree(chunk, 0, MEM_RELEASE);
}
-#else
-
-#ifdef __APPLE__
-#ifdef MAP_ANON
-/* Configures TARGET_OS_OSX when appropriate */
-#include <TargetConditionals.h>
-
-#if TARGET_OS_OSX && defined(MAP_JIT)
-#include <sys/utsname.h>
-#endif /* TARGET_OS_OSX && MAP_JIT */
-
-#ifdef MAP_JIT
+#else /* POSIX */
+#if defined(__APPLE__) && defined(MAP_JIT)
/*
On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a
- version where it's OK to have more than one JIT block.
+ version where it's OK to have more than one JIT block or where MAP_JIT is
+ required.
On non-macOS systems, returns MAP_JIT if it is defined.
*/
+#include <TargetConditionals.h>
+#if TARGET_OS_OSX
+#if defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86
+#ifdef MAP_ANON
+#include <sys/utsname.h>
+#include <stdlib.h>
+
+#define SLJIT_MAP_JIT (get_map_jit_flag())
+
static SLJIT_INLINE int get_map_jit_flag()
{
-#if TARGET_OS_OSX
- sljit_sw page_size = get_page_alignment() + 1;
+ sljit_sw page_size;
void *ptr;
+ struct utsname name;
static int map_jit_flag = -1;
- /*
- The following code is thread safe because multiple initialization
- sets map_jit_flag to the same value and the code has no side-effects.
- Changing the kernel version witout system restart is (very) unlikely.
- */
- if (map_jit_flag == -1) {
- struct utsname name;
-
+ if (map_jit_flag < 0) {
map_jit_flag = 0;
uname(&name);
- /* Kernel version for 10.14.0 (Mojave) */
+ /* Kernel version for 10.14.0 (Mojave) or later */
if (atoi(name.release) >= 18) {
+ page_size = get_page_alignment() + 1;
/* Only use MAP_JIT if a hardened runtime is used */
+ ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
- ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
-
- if (ptr == MAP_FAILED) {
- map_jit_flag = MAP_JIT;
- } else {
+ if (ptr != MAP_FAILED)
munmap(ptr, page_size);
- }
+ else
+ map_jit_flag = MAP_JIT;
}
}
-
return map_jit_flag;
-#else /* !TARGET_OS_OSX */
- return MAP_JIT;
-#endif /* TARGET_OS_OSX */
}
-
-#endif /* MAP_JIT */
#endif /* MAP_ANON */
-#endif /* __APPLE__ */
+#else /* !SLJIT_CONFIG_X86 */
+#if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
+#error Unsupported architecture
+#endif /* SLJIT_CONFIG_ARM */
+#include <pthread.h>
+
+#define SLJIT_MAP_JIT (MAP_JIT)
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
+ apple_update_wx_flags(enable_exec)
+
+static SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec)
+{
+ pthread_jit_write_protect_np(enable_exec);
+}
+#endif /* SLJIT_CONFIG_X86 */
+#else /* !TARGET_OS_OSX */
+#define SLJIT_MAP_JIT (MAP_JIT)
+#endif /* TARGET_OS_OSX */
+#endif /* __APPLE__ && MAP_JIT */
+#ifndef SLJIT_UPDATE_WX_FLAGS
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
+#endif /* !SLJIT_UPDATE_WX_FLAGS */
+#ifndef SLJIT_MAP_JIT
+#define SLJIT_MAP_JIT (0)
+#endif /* !SLJIT_MAP_JIT */
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
{
@@ -157,12 +169,7 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
const int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
#ifdef MAP_ANON
-
- int flags = MAP_PRIVATE | MAP_ANON;
-
-#ifdef MAP_JIT
- flags |= get_map_jit_flag();
-#endif
+ int flags = MAP_PRIVATE | MAP_ANON | SLJIT_MAP_JIT;
retval = mmap(NULL, size, prot, flags, -1, 0);
#else /* !MAP_ANON */
@@ -173,14 +180,15 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
#endif /* MAP_ANON */
if (retval == MAP_FAILED)
- retval = NULL;
- else {
- if (mprotect(retval, size, prot) < 0) {
- munmap(retval, size);
- retval = NULL;
- }
+ return NULL;
+
+ if (mprotect(retval, size, prot) < 0) {
+ munmap(retval, size);
+ return NULL;
}
+ SLJIT_UPDATE_WX_FLAGS(retval, (uint8_t *)retval + size, 0);
+
return retval;
}
@@ -189,7 +197,7 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
munmap(chunk, size);
}
-#endif
+#endif /* windows */
/* --------------------------------------------------------------------- */
/* Common functions */
@@ -261,6 +269,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
while (free_block) {
if (free_block->size >= size) {
chunk_size = free_block->size;
+ SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
if (chunk_size > size + 64) {
/* We just cut a block from the end of the free block. */
chunk_size -= size;
@@ -326,6 +335,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
allocated_size -= header->size;
/* Connecting free blocks together if possible. */
+ SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
/* If header->prev_size == 0, free_block will equal to header.
In this case, free_block->header.size will be > 0. */
@@ -358,6 +368,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
}
}
+ SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
SLJIT_ALLOCATOR_UNLOCK();
}
@@ -367,6 +378,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
struct free_block* next_free_block;
SLJIT_ALLOCATOR_LOCK();
+ SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
free_block = free_blocks;
while (free_block) {
@@ -381,5 +393,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
}
SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
+ SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
SLJIT_ALLOCATOR_UNLOCK();
}
diff --git a/src/sljit/sljitNativeS390X.c b/src/sljit/sljitNativeS390X.c
index a8b6511..3d007fe 100644
--- a/src/sljit/sljitNativeS390X.c
+++ b/src/sljit/sljitNativeS390X.c
@@ -42,7 +42,7 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
typedef sljit_uw sljit_ins;
/* Instruction tags (most significant halfword). */
-const sljit_ins sljit_ins_const = (sljit_ins)1 << 48;
+static const sljit_ins sljit_ins_const = (sljit_ins)1 << 48;
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1
@@ -66,22 +66,22 @@ typedef sljit_uw sljit_gpr;
* will be retired ASAP (TODO: carenas)
*/
-const sljit_gpr r0 = 0; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */
-const sljit_gpr r1 = 1; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */
-const sljit_gpr r2 = 2; /* reg_map[1]: 1st argument */
-const sljit_gpr r3 = 3; /* reg_map[2]: 2nd argument */
-const sljit_gpr r4 = 4; /* reg_map[3]: 3rd argument */
-const sljit_gpr r5 = 5; /* reg_map[4]: 4th argument */
-const sljit_gpr r6 = 6; /* reg_map[5]: 5th argument; 1st saved register */
-const sljit_gpr r7 = 7; /* reg_map[6] */
-const sljit_gpr r8 = 8; /* reg_map[7] */
-const sljit_gpr r9 = 9; /* reg_map[8] */
-const sljit_gpr r10 = 10; /* reg_map[9] */
-const sljit_gpr r11 = 11; /* reg_map[10] */
-const sljit_gpr r12 = 12; /* reg_map[11]: GOT */
-const sljit_gpr r13 = 13; /* reg_map[12]: Literal Pool pointer */
-const sljit_gpr r14 = 14; /* reg_map[0]: return address and flag register */
-const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */
+static const sljit_gpr r0 = 0; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */
+static const sljit_gpr r1 = 1; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */
+static const sljit_gpr r2 = 2; /* reg_map[1]: 1st argument */
+static const sljit_gpr r3 = 3; /* reg_map[2]: 2nd argument */
+static const sljit_gpr r4 = 4; /* reg_map[3]: 3rd argument */
+static const sljit_gpr r5 = 5; /* reg_map[4]: 4th argument */
+static const sljit_gpr r6 = 6; /* reg_map[5]: 5th argument; 1st saved register */
+static const sljit_gpr r7 = 7; /* reg_map[6] */
+static const sljit_gpr r8 = 8; /* reg_map[7] */
+static const sljit_gpr r9 = 9; /* reg_map[8] */
+static const sljit_gpr r10 = 10; /* reg_map[9] */
+static const sljit_gpr r11 = 11; /* reg_map[10] */
+static const sljit_gpr r12 = 12; /* reg_map[11]: GOT */
+static const sljit_gpr r13 = 13; /* reg_map[12]: Literal Pool pointer */
+static const sljit_gpr r14 = 14; /* reg_map[0]: return address and flag register */
+static const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */
/* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */
/* TODO(carenas): r12 might conflict in PIC code, reserve? */
@@ -100,8 +100,8 @@ const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack point
/* Link registers. The normal link register is r14, but since
we use that for flags we need to use r0 instead to do fast
calls so that flags are preserved. */
-const sljit_gpr link_r = 14; /* r14 */
-const sljit_gpr fast_link_r = 0; /* r0 */
+static const sljit_gpr link_r = 14; /* r14 */
+static const sljit_gpr fast_link_r = 0; /* r0 */
/* Flag register layout:
@@ -110,7 +110,7 @@ const sljit_gpr fast_link_r = 0; /* r0 */
| ZERO | 0 | 0 | C C |///////|
+---------------+---+---+-------+-------+
*/
-const sljit_gpr flag_r = 14; /* r14 */
+static const sljit_gpr flag_r = 14; /* r14 */
struct sljit_s390x_const {
struct sljit_const const_; /* must be first */
@@ -1465,7 +1465,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
op = GET_OPCODE(op) | (op & SLJIT_I32_OP);
switch (op) {
case SLJIT_BREAKPOINT:
- /* TODO(mundaym): insert real breakpoint? */
+ /* The following invalid instruction is emitted by gdb. */
+ return push_inst(compiler, 0x0001 /* 2-byte trap */);
case SLJIT_NOP:
return push_inst(compiler, 0x0700 /* 2-byte nop */);
case SLJIT_LMUL_UW: