summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzherczeg <zherczeg@6239d852-aaf2-0410-a92c-79f79f948069>2020-04-14 05:04:32 +0000
committerzherczeg <zherczeg@6239d852-aaf2-0410-a92c-79f79f948069>2020-04-14 05:04:32 +0000
commitf06c10cc600da7eb164d85f7e143d9949d6c4b15 (patch)
tree22480e4e21de7117158a9566a827f46fff07aba1
parent68b6918b2c1c339295f76996af53697a4e9b0b57 (diff)
downloadpcre2-f06c10cc600da7eb164d85f7e143d9949d6c4b15.tar.gz
JIT compiler update.
git-svn-id: svn://vcs.exim.org/pcre2/code/trunk@1243 6239d852-aaf2-0410-a92c-79f79f948069
-rw-r--r--src/sljit/sljitNativeARM_32.c4
-rw-r--r--src/sljit/sljitNativeARM_64.c4
-rw-r--r--src/sljit/sljitNativeARM_T2_32.c2
-rw-r--r--src/sljit/sljitProtExecAllocator.c70
4 files changed, 62 insertions, 18 deletions
diff --git a/src/sljit/sljitNativeARM_32.c b/src/sljit/sljitNativeARM_32.c
index 24ef02a..5d180c2 100644
--- a/src/sljit/sljitNativeARM_32.c
+++ b/src/sljit/sljitNativeARM_32.c
@@ -2633,11 +2633,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
}
else {
if (is_type1_transfer) {
- if (memw > 4095 && memw < -4095)
+ if (memw > 4095 || memw < -4095)
return SLJIT_ERR_UNSUPPORTED;
}
else {
- if (memw > 255 && memw < -255)
+ if (memw > 255 || memw < -255)
return SLJIT_ERR_UNSUPPORTED;
}
}
diff --git a/src/sljit/sljitNativeARM_64.c b/src/sljit/sljitNativeARM_64.c
index b86fc64..eaca095 100644
--- a/src/sljit/sljitNativeARM_64.c
+++ b/src/sljit/sljitNativeARM_64.c
@@ -1878,7 +1878,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
CHECK_ERROR();
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
- if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256))
+ if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))
return SLJIT_ERR_UNSUPPORTED;
if (type & SLJIT_MEM_SUPP)
@@ -1928,7 +1928,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil
CHECK_ERROR();
CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
- if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256))
+ if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))
return SLJIT_ERR_UNSUPPORTED;
if (type & SLJIT_MEM_SUPP)
diff --git a/src/sljit/sljitNativeARM_T2_32.c b/src/sljit/sljitNativeARM_T2_32.c
index a26f48f..a81e008 100644
--- a/src/sljit/sljitNativeARM_T2_32.c
+++ b/src/sljit/sljitNativeARM_T2_32.c
@@ -2274,7 +2274,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
CHECK_ERROR();
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
- if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -255))
+ if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -255))
return SLJIT_ERR_UNSUPPORTED;
if (type & SLJIT_MEM_SUPP)
diff --git a/src/sljit/sljitProtExecAllocator.c b/src/sljit/sljitProtExecAllocator.c
index 8425a2e..3f412fe 100644
--- a/src/sljit/sljitProtExecAllocator.c
+++ b/src/sljit/sljitProtExecAllocator.c
@@ -70,7 +70,6 @@
struct chunk_header {
void *executable;
- int fd;
};
/*
@@ -96,8 +95,18 @@ struct chunk_header {
#endif
#endif
+#if !(defined(__NetBSD__) && defined(MAP_REMAPDUP))
int mkostemp(char *template, int flags);
-#if !defined(__NetBSD__)
+
+#ifdef __NetBSD__
+/*
+ * this is a workaround for NetBSD < 8 that lacks a system provided
+ * secure_getenv function.
+ * ideally this should never be used, as the standard allocator is
+ * a preferred option for those systems and should be used instead.
+ */
+#define secure_getenv(name) issetugid() ? NULL : getenv(name)
+#else
char *secure_getenv(const char *name);
#endif
@@ -110,6 +119,13 @@ static SLJIT_INLINE int create_tempfile(void)
char *dir;
size_t len;
+#ifdef HAVE_MEMFD_CREATE
+ /* this is a GNU extension, make sure to use -D_GNU_SOURCE */
+ fd = memfd_create("sljit", MFD_CLOEXEC);
+ if (fd != -1)
+ return fd;
+#endif
+
#ifdef P_tmpdir
len = (P_tmpdir != NULL) ? strlen(P_tmpdir) : 0;
@@ -126,11 +142,8 @@ static SLJIT_INLINE int create_tempfile(void)
tmp_name_len = 4;
#endif
-#if defined(__NetBSD__)
- dir = getenv("TMPDIR");
-#else
dir = secure_getenv("TMPDIR");
-#endif
+
if (dir) {
len = strlen(dir);
if (len > 0 && len < sizeof(tmp_name)) {
@@ -195,23 +208,50 @@ static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
if (retval->executable == MAP_FAILED) {
- munmap(retval, size);
+ munmap((void *)retval, size);
close(fd);
return NULL;
}
- retval->fd = fd;
+ close(fd);
return retval;
}
+#else
+static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
+{
+ struct chunk_header *retval;
+ void *maprx;
+
+ retval = (struct chunk_header *)mmap(NULL, size,
+ PROT_MPROTECT(PROT_EXEC|PROT_WRITE|PROT_READ),
+ MAP_ANON, -1, 0);
+
+ if (retval == MAP_FAILED)
+ return NULL;
+
+ maprx = mremap(retval, size, NULL, size, MAP_REMAPDUP);
+ if (maprx == MAP_FAILED) {
+ munmap((void *)retval, size);
+ return NULL;
+ }
+
+ if (mprotect(retval, size, PROT_READ | PROT_WRITE) == -1 ||
+ mprotect(maprx, size, PROT_READ | PROT_EXEC) == -1) {
+ munmap(maprx, size);
+ munmap((void *)retval, size);
+ return NULL;
+ }
+ retval->executable = maprx;
+ return retval;
+}
+#endif /* NetBSD >= 8 */
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
{
struct chunk_header *header = ((struct chunk_header *)chunk) - 1;
- int fd = header->fd;
munmap(header->executable, size);
- munmap(header, size);
- close(fd);
+ munmap((void *)header, size);
}
/* --------------------------------------------------------------------- */
@@ -391,7 +431,9 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
if (total_size - free_block->size > (allocated_size * 3 / 2)) {
total_size -= free_block->size;
sljit_remove_free_block(free_block);
- free_chunk(free_block, free_block->size + sizeof(struct block_header));
+ free_chunk(free_block, free_block->size +
+ sizeof(struct chunk_header) +
+ sizeof(struct block_header));
}
}
@@ -412,7 +454,9 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
total_size -= free_block->size;
sljit_remove_free_block(free_block);
- free_chunk(free_block, free_block->size + sizeof(struct block_header));
+ free_chunk(free_block, free_block->size +
+ sizeof(struct chunk_header) +
+ sizeof(struct block_header));
}
free_block = next_free_block;
}