Skip to content

Commit 3c04ce4

Browse files
committed
Replace ZEND_ASSERT() by conditional compilation abort.
Prevent endless loop through ESCAPE code.
1 parent f5fe4c3 commit 3c04ce4

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

ext/opcache/jit/zend_jit_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ typedef struct _zend_jit_trace_info {
351351
uint32_t code_size; /* size of native code */
352352
uint32_t exit_counters; /* offset in exit counters array */
353353
uint32_t stack_map_size;
354+
const zend_op *opline; /* first opline */
354355
const void *code_start; /* address of native code */
355356
zend_jit_trace_exit_info *exit_info; /* info about side exits */
356357
zend_jit_trace_stack *stack_map;

ext/opcache/jit/zend_jit_trace.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,10 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
10561056
stack = frame->stack;
10571057
op_array = p->op_array;
10581058
level++;
1059-
ZEND_ASSERT(ssa_vars_count < 0xff);
1059+
// TODO: remove this restriction ???
1060+
if (ssa_vars_count >= 0xff) {
1061+
return NULL;
1062+
}
10601063
p->first_ssa_var = ssa_vars_count;
10611064
for (i = 0; i < op_array->last_var; i++) {
10621065
SET_STACK_VAR(stack, i, ssa_vars_count++);
@@ -1066,7 +1069,10 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
10661069
frame = zend_jit_trace_ret_frame(frame, op_array);
10671070
stack = frame->stack;
10681071
if (level == 0) {
1069-
ZEND_ASSERT(ssa_vars_count <= 0xff);
1072+
// TODO: remove this restriction ???
1073+
if (ssa_vars_count >= 0xff) {
1074+
return NULL;
1075+
}
10701076
p->first_ssa_var = ssa_vars_count;
10711077
for (i = 0; i < op_array->last_var + op_array->T; i++) {
10721078
SET_STACK_VAR(stack, i, ssa_vars_count++);
@@ -2456,6 +2462,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
24562462

24572463
ssa = zend_jit_trace_build_tssa(trace_buffer, parent_trace, exit_num, script, op_arrays, &num_op_arrays);
24582464

2465+
if (!ssa) {
2466+
zend_arena_release(&CG(arena), checkpoint);
2467+
JIT_G(current_trace) = NULL;
2468+
return NULL;
2469+
}
2470+
24592471
/* Register allocation */
24602472
if (zend_jit_reg_alloc && zend_jit_level >= ZEND_JIT_LEVEL_INLINE) {
24612473
ra = zend_jit_trace_allocate_registers(trace_buffer, ssa, parent_trace, exit_num);
@@ -3990,7 +4002,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
39904002
t->link = zend_jit_find_trace(p->opline->handler);
39914003
zend_jit_trace_link_to_root(&dasm_state, p->opline->handler);
39924004
} else if (p->stop == ZEND_JIT_TRACE_STOP_RETURN) {
3993-
zend_jit_trace_return(&dasm_state);
4005+
zend_jit_trace_return(&dasm_state, 0);
39944006
} else {
39954007
// TODO: not implemented ???
39964008
ZEND_ASSERT(0 && p->stop);
@@ -4053,6 +4065,7 @@ static const void *zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_n
40534065
const zend_op *opline;
40544066
uint32_t i, stack_size;
40554067
zend_jit_trace_stack *stack;
4068+
zend_bool original_handler = 0;
40564069

40574070
if (!zend_jit_trace_exit_needs_deoptimization(trace_num, exit_num)) {
40584071
return dasm_labels[zend_lbtrace_escape];
@@ -4084,9 +4097,13 @@ static const void *zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_n
40844097
opline = (const zend_op*)((uintptr_t)opline & ~(ZEND_JIT_EXIT_JITED|ZEND_JIT_EXIT_BLACKLISTED));
40854098
if (opline) {
40864099
zend_jit_set_ip(&dasm_state, opline);
4100+
if (opline == zend_jit_traces[zend_jit_traces[trace_num].root].opline) {
4101+
/* prevent endless loop */
4102+
original_handler = 1;
4103+
}
40874104
}
40884105

4089-
zend_jit_trace_return(&dasm_state);
4106+
zend_jit_trace_return(&dasm_state, original_handler);
40904107

40914108
handler = dasm_link_and_encode(&dasm_state, NULL, NULL, NULL, NULL, name, 1);
40924109

@@ -4123,6 +4140,7 @@ static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace
41234140
t->exit_count = 0;
41244141
t->child_count = 0;
41254142
t->stack_map_size = 0;
4143+
t->opline = ((zend_jit_trace_start_rec*)trace_buffer)->opline;
41264144
t->exit_info = exit_info;
41274145
t->stack_map = NULL;
41284146

@@ -4674,6 +4692,7 @@ static zend_jit_trace_stop zend_jit_compile_side_trace(zend_jit_trace_rec *trace
46744692
t->exit_count = 0;
46754693
t->child_count = 0;
46764694
t->stack_map_size = 0;
4695+
t->opline = NULL;
46774696
t->exit_info = exit_info;
46784697
t->stack_map = NULL;
46794698

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2995,23 +2995,38 @@ static int zend_jit_trace_link_to_root(dasm_State **Dst, const void *code)
29952995
return 1;
29962996
}
29972997

2998-
static int zend_jit_trace_return(dasm_State **Dst)
2998+
static int zend_jit_trace_return(dasm_State **Dst, zend_bool original_handler)
29992999
{
30003000
#if 0
30013001
| jmp ->trace_escape
30023002
#else
30033003
if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
30043004
| add r4, HYBRID_SPAD
3005-
| JMP_IP
3005+
if (!original_handler) {
3006+
| JMP_IP
3007+
} else {
3008+
| mov r0, EX->func
3009+
| mov r0, aword [r0 + offsetof(zend_op_array, reserved[zend_func_info_rid])]
3010+
| mov r0, aword [r0 + offsetof(zend_jit_op_array_trace_extension, offset)]
3011+
| jmp aword [IP + r0]
3012+
}
30063013
} else if (GCC_GLOBAL_REGS) {
30073014
| add r4, SPAD // stack alignment
3008-
| JMP_IP
3015+
if (!original_handler) {
3016+
| JMP_IP
3017+
} else {
3018+
| mov r0, EX->func
3019+
| mov r0, aword [r0 + offsetof(zend_op_array, reserved[zend_func_info_rid])]
3020+
| mov r0, aword [r0 + offsetof(zend_jit_op_array_trace_extension, offset)]
3021+
| jmp aword [IP + r0]
3022+
}
30093023
} else {
30103024
| mov FP, aword T2 // restore FP
30113025
| mov RX, aword T3 // restore IP
30123026
| add r4, NR_SPAD // stack alignment
30133027
| mov r0, 2 // ZEND_VM_LEAVE
30143028
| ret
3029+
// TODO: support for "original_handler" ????
30153030
}
30163031
#endif
30173032
return 1;

0 commit comments

Comments
 (0)