Obtained from: https://github.com/derickr/vld/commit/df1c52c4cb62e5ff31e1b72e3f11df9a45ee567a https://github.com/derickr/vld/commit/dc56f73a25b0230745afb5523871f2e8dd33fccd --- srm_oparray.c.orig 2022-09-16 08:00:47 UTC +++ srm_oparray.c @@ -350,6 +350,16 @@ static const op_usage opcodes[] = { /* 200 */ { "FETCH_GLOBALS", ALL_USED }, /* 201 */ { "VERIFY_NEVER_TYPE", ALL_USED }, /* 202 */ { "ZEND_CALLABLE_CONVERT", ALL_USED }, +# if PHP_VERSION_ID >= 80300 + /* 203 */ { "ZEND_BIND_INIT_STATIC_OR_JMP", ALL_USED }, +# if PHP_VERSION_ID >= 80400 + /* 204 */ { "ZEND_FRAMELESS_ICALL_0", ALL_USED | EXT_VAL_FLF }, + /* 205 */ { "ZEND_FRAMELESS_ICALL_1", ALL_USED | EXT_VAL_FLF }, + /* 206 */ { "ZEND_FRAMELESS_ICALL_2", ALL_USED | EXT_VAL_FLF }, + /* 207 */ { "ZEND_FRAMELESS_ICALL_3", ALL_USED | EXT_VAL_FLF }, + /* 208 */ { "ZEND_JMP_FRAMELESS", ALL_USED | EXT_CACHED_PTR | OP2_OPNUM }, +# endif +# endif # endif # endif # else @@ -811,6 +821,12 @@ void vld_dump_op(int nr, zend_op * op_ptr, unsigned in last_lineno = op.lineno; } +#if PHP_VERSION_ID >= 80400 + if (flags & EXT_VAL_FLF) { + fetch_type = (char*) ZEND_FLF_FUNC(&op)->common.function_name->val; + } +#endif + if (op.opcode >= NUM_KNOWN_OPCODES) { if (VLD_G(format)) { vld_printf(stderr, "%5d %s %c %c %c %c %s <%03d>%-23s %s %-14s ", nr, VLD_G(col_sep), notdead ? ' ' : '*', entry ? 'E' : ' ', start ? '>' : ' ', end ? '>' : ' ', VLD_G(col_sep), op.opcode, VLD_G(col_sep), fetch_type); @@ -831,6 +847,11 @@ void vld_dump_op(int nr, zend_op * op_ptr, unsigned in } } +#if PHP_VERSION_ID >= 80400 + if (flags & EXT_CACHED_PTR) { + vld_printf(stderr, "s%-3d ", op.extended_value); + } else +#endif if (flags & EXT_VAL) { #if PHP_VERSION_ID >= 70300 if (op.opcode == ZEND_CATCH) { @@ -1082,9 +1103,19 @@ int vld_find_jumps(zend_op_array *opa, unsigned int po *jump_count = 1; return 1; +#if PHP_VERSION_ID >= 80400 + } else if (opcode.opcode == ZEND_JMP_FRAMELESS) { + jumps[0] = position + 1; + jumps[1] = VLD_ZNODE_JMP_LINE(opcode.op2, position, base_address); + *jump_count = 2; + return 1; +#endif + } else if ( opcode.opcode == ZEND_GENERATOR_RETURN || +#if PHP_VERSION_ID < 80400 opcode.opcode == ZEND_EXIT || +#endif opcode.opcode == ZEND_THROW || #if PHP_VERSION_ID >= 80000 opcode.opcode == ZEND_MATCH_ERROR || @@ -1094,6 +1125,49 @@ int vld_find_jumps(zend_op_array *opa, unsigned int po jumps[0] = VLD_JMP_EXIT; *jump_count = 1; return 1; +#if PHP_VERSION_ID >= 80200 + } else if ( + opcode.opcode == ZEND_INIT_FCALL + ) { + zval *func_name = RT_CONSTANT(&opa->opcodes[position], opcode.op2); + if (zend_string_equals_literal(Z_PTR_P(func_name), "exit")) { + int level = 0; + uint32_t start = position + 1; + + for (;;) { + switch (opa->opcodes[start].opcode) { + case ZEND_INIT_FCALL: + case ZEND_INIT_FCALL_BY_NAME: + case ZEND_INIT_NS_FCALL_BY_NAME: + case ZEND_INIT_DYNAMIC_CALL: + case ZEND_INIT_USER_CALL: + case ZEND_INIT_METHOD_CALL: + case ZEND_INIT_STATIC_METHOD_CALL: +#if PHP_VERSION_ID >= 80400 + case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL: +#endif + case ZEND_NEW: + level++; + break; + case ZEND_DO_FCALL: + case ZEND_DO_FCALL_BY_NAME: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + if (level == 0) { + goto done; + } + level--; + break; + } + start++; + } + done: + ZEND_ASSERT(opa->opcodes[start].opcode == ZEND_DO_ICALL); + jumps[0] = VLD_JMP_EXIT; + *jump_count = 1; + return 1; + } +# endif #if PHP_VERSION_ID >= 70200 } else if ( # if PHP_VERSION_ID >= 80000 @@ -1233,6 +1307,7 @@ void vld_analyse_branch(zend_op_array *opa, unsigned i break; } +#if PHP_VERSION_ID < 80400 /* See if we have an exit instruction */ if (opa->opcodes[position].opcode == ZEND_EXIT) { VLD_PRINT(1, "Exit found\n"); @@ -1240,6 +1315,7 @@ void vld_analyse_branch(zend_op_array *opa, unsigned i branch_info->branches[position].start_lineno = opa->opcodes[position].lineno; break; } +#endif /* See if we have a return instruction */ if ( opa->opcodes[position].opcode == ZEND_RETURN --- srm_oparray.h.orig 2022-09-16 08:00:47 UTC +++ srm_oparray.h @@ -57,6 +57,8 @@ #define EXT_VAL_JMP_ABS 1<<25 #define VLD_IS_JMP_ARRAY 1<<26 #define VLD_IS_INDEX 1<<27 +#define EXT_VAL_FLF 1<<28 +#define EXT_CACHED_PTR 1<<29 typedef struct _op_usage { const char *name; --- tests/jmp_frameless.inc.orig 2024-07-29 13:37:33 UTC +++ tests/jmp_frameless.inc @@ -0,0 +1,6 @@ +