@@ -8653,24 +8653,47 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co
86538653 return 1;
86548654}
86558655
8656+ static int zend_jit_func_guard(zend_jit_ctx *jit, ir_ref func_ref, const zend_function *func, const void *exit_addr)
8657+ {
8658+ if (func->type == ZEND_USER_FUNCTION &&
8659+ (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
8660+ (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
8661+ !func->common.function_name)) {
8662+ const zend_op *opcodes = func->op_array.opcodes;
8663+
8664+ // JIT: if (call->func.op_array.opcodes != opcodes) goto exit_addr;
8665+ ir_GUARD(
8666+ ir_EQ(
8667+ ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes))),
8668+ ir_CONST_ADDR(opcodes)),
8669+ ir_CONST_ADDR(exit_addr));
8670+ #ifdef ZEND_WIN32
8671+ } else if (func->type == ZEND_INTERNAL_FUNCTION) {
8672+ // ASLR may cause different addresses in different workers. Check for the internal function handler.
8673+ // JIT: if (call->func.internal_function.handler != handler) goto exit_addr;
8674+ ir_GUARD(
8675+ ir_EQ(
8676+ ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_internal_function, handler))),
8677+ ir_CONST_FC_FUNC(func->internal_function.handler)),
8678+ ir_CONST_ADDR(exit_addr));
8679+ #endif
8680+ } else {
8681+ // JIT: if (call->func != func) goto exit_addr;
8682+ ir_GUARD(ir_EQ(func_ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
8683+ }
8684+
8685+ return 1;
8686+ }
8687+
86568688static int zend_jit_init_fcall_guard(zend_jit_ctx *jit, uint32_t level, const zend_function *func, const zend_op *to_opline)
86578689{
86588690 int32_t exit_point;
86598691 const void *exit_addr;
86608692 ir_ref call;
86618693
8662- if (func->type == ZEND_INTERNAL_FUNCTION) {
8663- #ifdef ZEND_WIN32
8664- // TODO: ASLR may cause different addresses in different workers ???
8665- return 0;
8666- #endif
8667- } else if (func->type == ZEND_USER_FUNCTION) {
8668- if (!zend_accel_in_shm(func->op_array.opcodes)) {
8669- /* op_array and op_array->opcodes are not persistent. We can't link. */
8670- return 0;
8671- }
8672- } else {
8673- ZEND_UNREACHABLE();
8694+ if (func->type == ZEND_USER_FUNCTION
8695+ && !zend_accel_in_shm(func->op_array.opcodes)) {
8696+ /* op_array and op_array->opcodes are not persistent. We can't link. */
86748697 return 0;
86758698 }
86768699
@@ -8688,24 +8711,7 @@ static int zend_jit_init_fcall_guard(zend_jit_ctx *jit, uint32_t level, const ze
86888711 level--;
86898712 }
86908713
8691- if (func->type == ZEND_USER_FUNCTION &&
8692- (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
8693- (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
8694- !func->common.function_name)) {
8695- const zend_op *opcodes = func->op_array.opcodes;
8696-
8697- // JIT: if (call->func.op_array.opcodes != opcodes) goto exit_addr;
8698- ir_GUARD(
8699- ir_EQ(
8700- ir_LOAD_A(ir_ADD_OFFSET(ir_LOAD_A(jit_CALL(call, func)), offsetof(zend_op_array, opcodes))),
8701- ir_CONST_ADDR(opcodes)),
8702- ir_CONST_ADDR(exit_addr));
8703- } else {
8704- // JIT: if (call->func != func) goto exit_addr;
8705- ir_GUARD(ir_EQ(ir_LOAD_A(jit_CALL(call, func)), ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
8706- }
8707-
8708- return 1;
8714+ return zend_jit_func_guard(jit, ir_LOAD_A(jit_CALL(call, func)), func, exit_addr);
87098715}
87108716
87118717static int zend_jit_init_fcall(zend_jit_ctx *jit, const zend_op *opline, uint32_t b, const zend_op_array *op_array, zend_ssa *ssa, const zend_ssa_op *ssa_op, int call_level, zend_jit_trace_rec *trace, int checked_stack)
@@ -8812,17 +8818,8 @@ static int zend_jit_init_fcall(zend_jit_ctx *jit, const zend_op *opline, uint32_
88128818 }
88138819 if (!func || opline->opcode == ZEND_INIT_FCALL) {
88148820 ir_GUARD(ref, ir_CONST_ADDR(exit_addr));
8815- } else if (func->type == ZEND_USER_FUNCTION
8816- && !(func->common.fn_flags & ZEND_ACC_IMMUTABLE)) {
8817- const zend_op *opcodes = func->op_array.opcodes;
8818-
8819- ir_GUARD(
8820- ir_EQ(
8821- ir_LOAD_A(ir_ADD_OFFSET(ref, offsetof(zend_op_array, opcodes))),
8822- ir_CONST_ADDR(opcodes)),
8823- ir_CONST_ADDR(exit_addr));
8824- } else {
8825- ir_GUARD(ir_EQ(ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
8821+ } else if (!zend_jit_func_guard(jit, ref, func, exit_addr)) {
8822+ return 0;
88268823 }
88278824 } else {
88288825jit_SET_EX_OPLINE(jit, opline);
@@ -9028,11 +9025,7 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit,
90289025 if ((!func || zend_jit_may_be_modified(func, op_array))
90299026 && trace
90309027 && trace->op == ZEND_JIT_TRACE_INIT_CALL
9031- && trace->func
9032- #ifdef _WIN32
9033- && trace->func->type != ZEND_INTERNAL_FUNCTION
9034- #endif
9035- ) {
9028+ && trace->func) {
90369029 int32_t exit_point;
90379030 const void *exit_addr;
90389031
@@ -9047,19 +9040,8 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit,
90479040
90489041 func = (zend_function*)trace->func;
90499042
9050- if (func->type == ZEND_USER_FUNCTION &&
9051- (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
9052- (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
9053- !func->common.function_name)) {
9054- const zend_op *opcodes = func->op_array.opcodes;
9055-
9056- ir_GUARD(
9057- ir_EQ(
9058- ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes))),
9059- ir_CONST_ADDR(opcodes)),
9060- ir_CONST_ADDR(exit_addr));
9061- } else {
9062- ir_GUARD(ir_EQ(func_ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
9043+ if (!zend_jit_func_guard(jit, func_ref, func, exit_addr)) {
9044+ return 0;
90639045 }
90649046 }
90659047
@@ -9213,11 +9195,7 @@ static int zend_jit_init_static_method_call(zend_jit_ctx *jit,
92139195 if ((!func || zend_jit_may_be_modified(func, op_array))
92149196 && trace
92159197 && trace->op == ZEND_JIT_TRACE_INIT_CALL
9216- && trace->func
9217- #ifdef _WIN32
9218- && trace->func->type != ZEND_INTERNAL_FUNCTION
9219- #endif
9220- ) {
9198+ && trace->func) {
92219199 int32_t exit_point;
92229200 const void *exit_addr;
92239201
@@ -9232,19 +9210,8 @@ static int zend_jit_init_static_method_call(zend_jit_ctx *jit,
92329210
92339211 func = (zend_function*)trace->func;
92349212
9235- if (func->type == ZEND_USER_FUNCTION &&
9236- (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
9237- (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
9238- !func->common.function_name)) {
9239- const zend_op *opcodes = func->op_array.opcodes;
9240-
9241- ir_GUARD(
9242- ir_EQ(
9243- ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes))),
9244- ir_CONST_ADDR(opcodes)),
9245- ir_CONST_ADDR(exit_addr));
9246- } else {
9247- ir_GUARD(ir_EQ(func_ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
9213+ if (!zend_jit_func_guard(jit, func_ref, func, exit_addr)) {
9214+ return 0;
92489215 }
92499216 }
92509217
0 commit comments