opcache JIT support improvements attempts on macOs.

for cases when shared segments switch b/w R/W/X and R/X bits.

Closes #8382.
This commit is contained in:
David CARLIER 2022-04-16 09:10:07 +01:00 committed by David Carlier
parent 180557dd9c
commit 1416961505
3 changed files with 30 additions and 5 deletions

2
NEWS
View file

@ -36,6 +36,8 @@ PHP NEWS
for macOs Instrument. (David Carlier)
. Fixed bug GH-8030 (Segfault with JIT and large match/switch statements).
(Arnaud)
. JIT support improvement for macOs for segments and executable permission
bit handling. (David Carlier)
- PCRE:
. Updated bundled libpcre to 10.40. (cmb)

View file

@ -597,6 +597,7 @@ mmap \
nice \
nl_langinfo \
poll \
pthread_jit_write_protect_np \
putenv \
scandir \
setitimer \

View file

@ -47,6 +47,10 @@
#include "jit/zend_jit_internal.h"
#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
#include <pthread.h>
#endif
#ifdef ZTS
int jit_globals_id;
#else
@ -106,6 +110,9 @@ int16_t zend_jit_hot_counters[ZEND_HOT_COUNTERS_COUNT];
const zend_op *zend_jit_halt_op = NULL;
static int zend_jit_vm_kind = 0;
#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
static int zend_write_protect = 1;
#endif
static void *dasm_buf = NULL;
static void *dasm_end = NULL;
@ -4601,12 +4608,13 @@ ZEND_EXT_API void zend_jit_unprotect(void)
if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) {
int opts = PROT_READ | PROT_WRITE;
#ifdef ZTS
/* TODO: EXEC+WRITE is not supported in macOS. Removing EXEC is still buggy as
* other threads, which are executing the JITed code, would crash anyway. */
# ifndef __APPLE__
/* Another thread may be executing JITed code. */
#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
if (zend_write_protect) {
pthread_jit_write_protect_np(0);
return;
}
#endif
opts |= PROT_EXEC;
# endif
#endif
if (mprotect(dasm_buf, dasm_size, opts) != 0) {
fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno));
@ -4634,6 +4642,12 @@ ZEND_EXT_API void zend_jit_protect(void)
{
#ifdef HAVE_MPROTECT
if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) {
#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
if (zend_write_protect) {
pthread_jit_write_protect_np(1);
return;
}
#endif
if (mprotect(dasm_buf, dasm_size, PROT_READ | PROT_EXEC) != 0) {
fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno));
}
@ -4889,11 +4903,19 @@ ZEND_EXT_API int zend_jit_startup(void *buf, size_t size, bool reattached)
}
}
#endif
#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
zend_write_protect = pthread_jit_write_protect_supported_np();
#endif
dasm_buf = buf;
dasm_size = size;
#ifdef HAVE_MPROTECT
#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
if (zend_write_protect) {
pthread_jit_write_protect_np(1);
}
#endif
if (JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP)) {
if (mprotect(dasm_buf, dasm_size, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) {
fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno));