|
47 | 47 |
|
48 | 48 | #include "jit/zend_jit_internal.h"
|
49 | 49 |
|
| 50 | +#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP |
| 51 | +#include <pthread.h> |
| 52 | +#endif |
| 53 | + |
50 | 54 | #ifdef ZTS
|
51 | 55 | int jit_globals_id;
|
52 | 56 | #else
|
@@ -106,6 +110,9 @@ int16_t zend_jit_hot_counters[ZEND_HOT_COUNTERS_COUNT];
|
106 | 110 |
|
107 | 111 | const zend_op *zend_jit_halt_op = NULL;
|
108 | 112 | static int zend_jit_vm_kind = 0;
|
| 113 | +#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP |
| 114 | +static int zend_write_protect = 1; |
| 115 | +#endif |
109 | 116 |
|
110 | 117 | static void *dasm_buf = NULL;
|
111 | 118 | static void *dasm_end = NULL;
|
@@ -4601,12 +4608,13 @@ ZEND_EXT_API void zend_jit_unprotect(void)
|
4601 | 4608 | if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) {
|
4602 | 4609 | int opts = PROT_READ | PROT_WRITE;
|
4603 | 4610 | #ifdef ZTS
|
4604 |
| - /* TODO: EXEC+WRITE is not supported in macOS. Removing EXEC is still buggy as |
4605 |
| - * other threads, which are executing the JITed code, would crash anyway. */ |
4606 |
| -# ifndef __APPLE__ |
4607 |
| - /* Another thread may be executing JITed code. */ |
| 4611 | +#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP |
| 4612 | + if (zend_write_protect) { |
| 4613 | + pthread_jit_write_protect_np(0); |
| 4614 | + return; |
| 4615 | + } |
| 4616 | +#endif |
4608 | 4617 | opts |= PROT_EXEC;
|
4609 |
| -# endif |
4610 | 4618 | #endif
|
4611 | 4619 | if (mprotect(dasm_buf, dasm_size, opts) != 0) {
|
4612 | 4620 | fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno));
|
@@ -4634,6 +4642,12 @@ ZEND_EXT_API void zend_jit_protect(void)
|
4634 | 4642 | {
|
4635 | 4643 | #ifdef HAVE_MPROTECT
|
4636 | 4644 | if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) {
|
| 4645 | +#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP |
| 4646 | + if (zend_write_protect) { |
| 4647 | + pthread_jit_write_protect_np(1); |
| 4648 | + return; |
| 4649 | + } |
| 4650 | +#endif |
4637 | 4651 | if (mprotect(dasm_buf, dasm_size, PROT_READ | PROT_EXEC) != 0) {
|
4638 | 4652 | fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno));
|
4639 | 4653 | }
|
@@ -4889,11 +4903,19 @@ ZEND_EXT_API int zend_jit_startup(void *buf, size_t size, bool reattached)
|
4889 | 4903 | }
|
4890 | 4904 | }
|
4891 | 4905 | #endif
|
| 4906 | +#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP |
| 4907 | + zend_write_protect = pthread_jit_write_protect_supported_np(); |
| 4908 | +#endif |
4892 | 4909 |
|
4893 | 4910 | dasm_buf = buf;
|
4894 | 4911 | dasm_size = size;
|
4895 | 4912 |
|
4896 | 4913 | #ifdef HAVE_MPROTECT
|
| 4914 | +#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP |
| 4915 | + if (zend_write_protect) { |
| 4916 | + pthread_jit_write_protect_np(1); |
| 4917 | + } |
| 4918 | +#endif |
4897 | 4919 | if (JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP)) {
|
4898 | 4920 | if (mprotect(dasm_buf, dasm_size, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) {
|
4899 | 4921 | fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno));
|
|
0 commit comments