@@ -8638,24 +8638,47 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co
8638
8638
return 1;
8639
8639
}
8640
8640
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
+
8641
8673
static int zend_jit_init_fcall_guard(zend_jit_ctx *jit, uint32_t level, const zend_function *func, const zend_op *to_opline)
8642
8674
{
8643
8675
int32_t exit_point;
8644
8676
const void *exit_addr;
8645
8677
ir_ref call;
8646
8678
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. */
8659
8682
return 0;
8660
8683
}
8661
8684
@@ -8673,24 +8696,7 @@ static int zend_jit_init_fcall_guard(zend_jit_ctx *jit, uint32_t level, const ze
8673
8696
level--;
8674
8697
}
8675
8698
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);
8694
8700
}
8695
8701
8696
8702
static 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_
8797
8803
}
8798
8804
if (!func || opline->opcode == ZEND_INIT_FCALL) {
8799
8805
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;
8811
8808
}
8812
8809
} else {
8813
8810
jit_SET_EX_OPLINE(jit, opline);
@@ -9013,11 +9010,7 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit,
9013
9010
if ((!func || zend_jit_may_be_modified(func, op_array))
9014
9011
&& trace
9015
9012
&& 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) {
9021
9014
int32_t exit_point;
9022
9015
const void *exit_addr;
9023
9016
@@ -9032,19 +9025,8 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit,
9032
9025
9033
9026
func = (zend_function*)trace->func;
9034
9027
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;
9048
9030
}
9049
9031
}
9050
9032
0 commit comments