@@ -8638,24 +8638,47 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co
86388638 return 1;
86398639}
86408640
8641+ static int zend_jit_func_guard(zend_jit_ctx *jit, ir_ref func_ref, const zend_function *func, const void *exit_addr)
8642+ {
8643+ if (func->type == ZEND_USER_FUNCTION &&
8644+ (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
8645+ (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
8646+ !func->common.function_name)) {
8647+ const zend_op *opcodes = func->op_array.opcodes;
8648+
8649+ // JIT: if (call->func.op_array.opcodes != opcodes) goto exit_addr;
8650+ ir_GUARD(
8651+ ir_EQ(
8652+ ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes))),
8653+ ir_CONST_ADDR(opcodes)),
8654+ ir_CONST_ADDR(exit_addr));
8655+ #ifdef ZEND_WIN32
8656+ } else if (func->type == ZEND_INTERNAL_FUNCTION) {
8657+ // ASLR may cause different addresses in different workers. Check for the internal function handler.
8658+ // JIT: if (call->func.internal_function.handler != handler) goto exit_addr;
8659+ ir_GUARD(
8660+ ir_EQ(
8661+ ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_internal_function, handler))),
8662+ ir_CONST_FC_FUNC(func->internal_function.handler)),
8663+ ir_CONST_ADDR(exit_addr));
8664+ #endif
8665+ } else {
8666+ // JIT: if (call->func != func) goto exit_addr;
8667+ ir_GUARD(ir_EQ(func_ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
8668+ }
8669+
8670+ return 1;
8671+ }
8672+
86418673static int zend_jit_init_fcall_guard(zend_jit_ctx *jit, uint32_t level, const zend_function *func, const zend_op *to_opline)
86428674{
86438675 int32_t exit_point;
86448676 const void *exit_addr;
86458677 ir_ref call;
86468678
8647- if (func->type == ZEND_INTERNAL_FUNCTION) {
8648- #ifdef ZEND_WIN32
8649- // TODO: ASLR may cause different addresses in different workers ???
8650- return 0;
8651- #endif
8652- } else if (func->type == ZEND_USER_FUNCTION) {
8653- if (!zend_accel_in_shm(func->op_array.opcodes)) {
8654- /* op_array and op_array->opcodes are not persistent. We can't link. */
8655- return 0;
8656- }
8657- } else {
8658- ZEND_UNREACHABLE();
8679+ if (func->type == ZEND_USER_FUNCTION
8680+ && !zend_accel_in_shm(func->op_array.opcodes)) {
8681+ /* op_array and op_array->opcodes are not persistent. We can't link. */
86598682 return 0;
86608683 }
86618684
@@ -8673,24 +8696,7 @@ static int zend_jit_init_fcall_guard(zend_jit_ctx *jit, uint32_t level, const ze
86738696 level--;
86748697 }
86758698
8676- if (func->type == ZEND_USER_FUNCTION &&
8677- (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
8678- (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
8679- !func->common.function_name)) {
8680- const zend_op *opcodes = func->op_array.opcodes;
8681-
8682- // JIT: if (call->func.op_array.opcodes != opcodes) goto exit_addr;
8683- ir_GUARD(
8684- ir_EQ(
8685- ir_LOAD_A(ir_ADD_OFFSET(ir_LOAD_A(jit_CALL(call, func)), offsetof(zend_op_array, opcodes))),
8686- ir_CONST_ADDR(opcodes)),
8687- ir_CONST_ADDR(exit_addr));
8688- } else {
8689- // JIT: if (call->func != func) goto exit_addr;
8690- ir_GUARD(ir_EQ(ir_LOAD_A(jit_CALL(call, func)), ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
8691- }
8692-
8693- return 1;
8699+ return zend_jit_func_guard(jit, ir_LOAD_A(jit_CALL(call, func)), func, exit_addr);
86948700}
86958701
86968702static 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)
@@ -8797,17 +8803,8 @@ static int zend_jit_init_fcall(zend_jit_ctx *jit, const zend_op *opline, uint32_
87978803 }
87988804 if (!func || opline->opcode == ZEND_INIT_FCALL) {
87998805 ir_GUARD(ref, ir_CONST_ADDR(exit_addr));
8800- } else if (func->type == ZEND_USER_FUNCTION
8801- && !(func->common.fn_flags & ZEND_ACC_IMMUTABLE)) {
8802- const zend_op *opcodes = func->op_array.opcodes;
8803-
8804- ir_GUARD(
8805- ir_EQ(
8806- ir_LOAD_A(ir_ADD_OFFSET(ref, offsetof(zend_op_array, opcodes))),
8807- ir_CONST_ADDR(opcodes)),
8808- ir_CONST_ADDR(exit_addr));
8809- } else {
8810- ir_GUARD(ir_EQ(ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
8806+ } else if (!zend_jit_func_guard(jit, ref, func, exit_addr)) {
8807+ return 0;
88118808 }
88128809 } else {
88138810jit_SET_EX_OPLINE(jit, opline);
@@ -9013,11 +9010,7 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit,
90139010 if ((!func || zend_jit_may_be_modified(func, op_array))
90149011 && trace
90159012 && trace->op == ZEND_JIT_TRACE_INIT_CALL
9016- && trace->func
9017- #ifdef _WIN32
9018- && trace->func->type != ZEND_INTERNAL_FUNCTION
9019- #endif
9020- ) {
9013+ && trace->func) {
90219014 int32_t exit_point;
90229015 const void *exit_addr;
90239016
@@ -9032,19 +9025,8 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit,
90329025
90339026 func = (zend_function*)trace->func;
90349027
9035- if (func->type == ZEND_USER_FUNCTION &&
9036- (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
9037- (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
9038- !func->common.function_name)) {
9039- const zend_op *opcodes = func->op_array.opcodes;
9040-
9041- ir_GUARD(
9042- ir_EQ(
9043- ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes))),
9044- ir_CONST_ADDR(opcodes)),
9045- ir_CONST_ADDR(exit_addr));
9046- } else {
9047- ir_GUARD(ir_EQ(func_ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
9028+ if (!zend_jit_func_guard(jit, func_ref, func, exit_addr)) {
9029+ return 0;
90489030 }
90499031 }
90509032
0 commit comments