diff --git a/zend_abstract_interface/jit_utils/jit_blacklist.c b/zend_abstract_interface/jit_utils/jit_blacklist.c index 059c5bba2bf..a9d065ebd01 100644 --- a/zend_abstract_interface/jit_utils/jit_blacklist.c +++ b/zend_abstract_interface/jit_utils/jit_blacklist.c @@ -88,10 +88,6 @@ typedef union _zend_op_trace_info { #define ZEND_OP_TRACE_INFO(opline, offset) \ ((zend_op_trace_info*)(((char*)opline) + offset)) - -#ifndef _WIN32 -static int dd_probe_pipes[2]; -#endif #endif #define ZEND_FUNC_INFO(op_array) \ @@ -107,9 +103,6 @@ static void zai_jit_find_opcache_handle(void *ext) { // opcache startup NULLs its handle. MINIT is executed before extension startup. void zai_jit_minit(void) { -#if PHP_VERSION_ID < 80400 && !defined(_WIN32) - pipe(dd_probe_pipes); -#endif zend_llist_apply(&zend_extensions, zai_jit_find_opcache_handle); } @@ -185,6 +178,42 @@ int zai_get_zend_func_rid(zend_op_array *op_array) { return zend_func_info_rid; } +#if defined(__linux__) && (defined(__x86_64__) || defined(__aarch64__)) && PHP_VERSION_ID < 80400 +static bool is_mapped(void *addr, size_t size) { + uintptr_t page_size = sysconf(_SC_PAGESIZE); + assert(size <= page_size); + uintptr_t page_addr = ((uintptr_t)addr & ~(page_size - 1)); + unsigned char vec; + + uintptr_t last_page_addr = ((uintptr_t)(addr + size - 1) & ~(page_size - 1)); + +#ifdef __x86_64__ +#define SYS_mincore 0x1B +#else // aarch64 +#define SYS_mincore 0xE8 +#endif + +again: + if (syscall(SYS_mincore, page_addr, page_size, &vec) == 0) { + if (page_addr == last_page_addr) { + return true; + } else { + page_addr = last_page_addr; + goto again; + } + } else if (errno == EFAULT || errno == ENOMEM) { + return false; + } else { + // we don't know... asume true +#ifdef ZEND_DEBUG + abort(); +#else + return true; +#endif + } +} +#endif + void zai_jit_blacklist_function_inlining(zend_op_array *op_array) { #if PHP_VERSION_ID >= 80400 if (opcache_handle) { @@ -210,14 +239,12 @@ void zai_jit_blacklist_function_inlining(zend_op_array *op_array) { size_t offset = jit_extension->offset; -#ifndef _WIN32 +#if defined(__linux__) && (defined(__x86_64__) || defined(__aarch64__)) // check whether the op_trace_info is actually readable or EFAULTing // we can't trust opcache too much here... - char dummy_buf[sizeof(zend_op_trace_info)]; - if (write(dd_probe_pipes[1], ZEND_OP_TRACE_INFO(opline, offset), sizeof(zend_op_trace_info)) < 0) { + if (!is_mapped(ZEND_OP_TRACE_INFO(opline, offset), sizeof(zend_op_trace_info))) { return; } - read(dd_probe_pipes[0], dummy_buf, sizeof(zend_op_trace_info)); #endif if (!(ZEND_OP_TRACE_INFO(opline, offset)->trace_flags & ZEND_JIT_TRACE_BLACKLISTED)) {