From 9d4f5f0762400326463b2433181362723745f693 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 5 Dec 2024 18:32:02 +0300 Subject: [PATCH] Backport fix for GH-9011 (#17052) * Backport fix for GH-9011 * Fix build --- ext/opcache/jit/zend_jit_x86.dasc | 64 ++++++++++++++++++++++++------- ext/opcache/tests/jit/gh9011.phpt | 27 +++++++++++++ 2 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 ext/opcache/tests/jit/gh9011.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 3f17817992a2b..aff19300cd749 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -9240,19 +9240,11 @@ static int zend_jit_init_fcall_guard(dasm_State **Dst, uint32_t level, const zen int32_t exit_point; const void *exit_addr; - if (func->type == ZEND_INTERNAL_FUNCTION) { -#ifdef ZEND_WIN32 - // TODO: ASLR may cause different addresses in different workers ??? - return 0; -#endif - } else if (func->type == ZEND_USER_FUNCTION) { + if (func->type == ZEND_USER_FUNCTION) { if (!zend_accel_in_shm(func->op_array.opcodes)) { /* op_array and op_array->opcodes are not persistent. We can't link. */ return 0; } - } else { - ZEND_UNREACHABLE(); - return 0; } exit_point = zend_jit_trace_get_exit_point(to_opline, ZEND_JIT_EXIT_POLYMORPHISM); @@ -9286,6 +9278,22 @@ static int zend_jit_init_fcall_guard(dasm_State **Dst, uint32_t level, const zen | cmp aword [r1 + offsetof(zend_op_array, opcodes)], opcodes | .endif | jne &exit_addr +#ifdef _WIN32 + } else if (func->type == ZEND_INTERNAL_FUNCTION) { + const zif_handler handler = func->internal_function.handler; + + | .if X64 + || if (!IS_SIGNED_32BIT(handler)) { + | mov64 r2, ((ptrdiff_t)handler) + | cmp aword [r1 + offsetof(zend_internal_function, handler)], r2 + || } else { + | cmp aword [r1 + offsetof(zend_internal_function, handler)], handler + || } + | .else + | cmp aword [r1 + offsetof(zend_internal_function, handler)], handler + | .endif + | jne &exit_addr +#endif } else { | .if X64 || if (!IS_SIGNED_32BIT(func)) { @@ -9432,6 +9440,22 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t | cmp aword [r0 + offsetof(zend_op_array, opcodes)], opcodes | .endif | jz >3 +#ifdef _WIN32 + } else if (func->type == ZEND_INTERNAL_FUNCTION) { + const zif_handler handler = func->internal_function.handler; + + | .if X64 + || if (!IS_SIGNED_32BIT(handler)) { + | mov64 r1, ((ptrdiff_t)handler) + | cmp aword [r0 + offsetof(zend_internal_function, handler)], r1 + || } else { + | cmp aword [r0 + offsetof(zend_internal_function, handler)], handler + || } + | .else + | cmp aword [r0 + offsetof(zend_internal_function, handler)], handler + | .endif + | jz >3 +#endif } else { | .if X64 || if (!IS_SIGNED_32BIT(func)) { @@ -9618,11 +9642,7 @@ static int zend_jit_init_method_call(dasm_State **Dst, if ((!func || zend_jit_may_be_modified(func, op_array)) && trace && trace->op == ZEND_JIT_TRACE_INIT_CALL - && trace->func -#ifdef _WIN32 - && trace->func->type != ZEND_INTERNAL_FUNCTION -#endif - ) { + && trace->func) { int32_t exit_point; const void *exit_addr; @@ -9651,6 +9671,22 @@ static int zend_jit_init_method_call(dasm_State **Dst, | cmp aword [r0 + offsetof(zend_op_array, opcodes)], opcodes | .endif | jne &exit_addr +#ifdef _WIN32 + } else if (func->type == ZEND_INTERNAL_FUNCTION) { + const zif_handler handler = func->internal_function.handler; + + | .if X64 + || if (!IS_SIGNED_32BIT(handler)) { + | mov64 r1, ((ptrdiff_t)handler) + | cmp aword [r0 + offsetof(zend_internal_function, handler)], r1 + || } else { + | cmp aword [r0 + offsetof(zend_internal_function, handler)], handler + || } + | .else + | cmp aword [r0 + offsetof(zend_internal_function, handler)], handler + | .endif + | jne &exit_addr +#endif } else { | .if X64 || if (!IS_SIGNED_32BIT(func)) { diff --git a/ext/opcache/tests/jit/gh9011.phpt b/ext/opcache/tests/jit/gh9011.phpt new file mode 100644 index 0000000000000..3ffefe2ce29be --- /dev/null +++ b/ext/opcache/tests/jit/gh9011.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-9011: Assertion failure with tracing JIT +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +--FILE-- +__toString(); + } +} +?> +DONE +--EXPECT-- +DONE \ No newline at end of file