Skip to content

Commit 42c5f6e

Browse files
committed
Add FFI class and cdef guards
1 parent 2e24b19 commit 42c5f6e

File tree

3 files changed

+75
-11
lines changed

3 files changed

+75
-11
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,15 @@
4545
#if HAVE_FFI
4646
# include "ext/ffi/php_ffi.h"
4747

48-
# define FFI_TYPE_GUARD (1<<0)
48+
# define FFI_TYPE_GUARD (1<<0)
49+
# define FFI_SYMBOLS_GUARD (1<<1)
4950

5051
typedef struct zend_jit_ffi_info {
51-
zend_ffi_type *type;
52-
uint32_t info;
52+
union {
53+
zend_ffi_type *type;
54+
HashTable *symbols;
55+
};
56+
uint32_t info;
5357
} zend_jit_ffi_info;
5458

5559
static bool zend_jit_ffi_supported_type(zend_ffi_type *type) {

ext/opcache/jit/zend_jit_ir.c

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12616,6 +12616,63 @@ static int zend_jit_ffi_guard(zend_jit_ctx *jit,
1261612616
return 1;
1261712617
}
1261812618

12619+
static int zend_jit_ffi_symbols_guard(zend_jit_ctx *jit,
12620+
const zend_op *opline,
12621+
zend_ssa *ssa,
12622+
int use,
12623+
int def,
12624+
zend_jit_addr addr,
12625+
HashTable *ffi_symbols,
12626+
zend_jit_ffi_info *ffi_info)
12627+
{
12628+
ir_ref ref = IR_UNUSED;
12629+
12630+
if (ssa->var_info
12631+
&& use >= 0
12632+
&& ssa->var_info[use].ce != zend_ffi_ce) {
12633+
ref = jit_Z_PTR(jit, addr);
12634+
if (!zend_jit_class_guard(jit, opline, ref, zend_ffi_ce)) {
12635+
return 0;
12636+
}
12637+
ssa->var_info[use].type |= MAY_BE_CLASS_GUARD;
12638+
ssa->var_info[use].ce = zend_ffi_ce;
12639+
ssa->var_info[use].is_instanceof = 0;
12640+
if (def >= 0) {
12641+
ssa->var_info[def].type |= MAY_BE_CLASS_GUARD;
12642+
ssa->var_info[def].ce = zend_ffi_ce;
12643+
ssa->var_info[def].is_instanceof = 0;
12644+
}
12645+
}
12646+
12647+
if (ffi_info
12648+
&& use >= 0
12649+
&& (ffi_info[use].symbols != ffi_symbols
12650+
|| (ffi_info[use].info & FFI_SYMBOLS_GUARD))) {
12651+
if (!ref) {
12652+
ref = jit_Z_PTR(jit, addr);
12653+
}
12654+
12655+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
12656+
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
12657+
12658+
if (!exit_addr) {
12659+
return 0;
12660+
}
12661+
12662+
ir_GUARD(ir_EQ(ir_LOAD_A(ir_ADD_OFFSET(ref, offsetof(zend_ffi, symbols))), ir_CONST_ADDR(ffi_symbols)),
12663+
ir_CONST_ADDR(exit_addr));
12664+
12665+
ffi_info[use].info &= ~FFI_SYMBOLS_GUARD;
12666+
ffi_info[use].symbols = ffi_symbols;
12667+
if (def >= 0) {
12668+
ffi_info[def].info &= ~FFI_SYMBOLS_GUARD;
12669+
ffi_info[def].symbols = ffi_symbols;
12670+
}
12671+
}
12672+
12673+
return 1;
12674+
}
12675+
1261912676
static ir_ref jit_FFI_CDATA_PTR(zend_jit_ctx *jit, ir_ref obj_ref)
1262012677
{
1262112678
return ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
@@ -14435,17 +14492,16 @@ static int zend_jit_ffi_fetch_sym(zend_jit_ctx *jit,
1443514492
bool delayed_fetch_this,
1443614493
bool op1_avoid_refcounting,
1443714494
zend_ffi_symbol *sym,
14438-
zend_jit_addr res_addr/*???,
14439-
zend_ffi_type *op1_ffi_type,
14440-
zend_jit_ffi_info *ffi_info*/)
14495+
zend_jit_addr res_addr,
14496+
HashTable *op1_ffi_symbols,
14497+
zend_jit_ffi_info *ffi_info)
1444114498
{
1444214499
uint32_t res_info = RES_INFO();
1444314500
zend_ffi_type *sym_type = ZEND_FFI_TYPE(sym->type);
14444-
//??? ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
1444514501

14446-
//??? if (!zend_jit_ffi_guard(jit, opline, ssa, ssa_op->op1_use, -1, obj_ref, op1_ffi_type, ffi_info)) {
14447-
//??? return 0;
14448-
//??? }
14502+
if (!zend_jit_ffi_symbols_guard(jit, opline, ssa, ssa_op->op1_use, -1, op1_addr, op1_ffi_symbols, ffi_info)) {
14503+
return 0;
14504+
}
1444914505

1445014506
ir_ref ptr = ir_CONST_ADDR(sym->addr);
1445114507
if (!zend_jit_ffi_read(jit, sym_type, ptr, res_addr)) {

ext/opcache/jit/zend_jit_trace.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6179,10 +6179,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
61796179
&& ZEND_FFI_TYPE(sym->type)->kind < ZEND_FFI_TYPE_POINTER
61806180
&& ZEND_FFI_TYPE(sym->type)->kind != ZEND_FFI_TYPE_VOID
61816181
&& zend_jit_ffi_supported_type(ZEND_FFI_TYPE(sym->type))) {
6182+
if (!ffi_info) {
6183+
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
6184+
}
61826185
if (!zend_jit_ffi_fetch_sym(&ctx, opline, op_array, ssa, ssa_op,
61836186
op1_info, op1_addr, op1_indirect,
61846187
on_this, delayed_fetch_this, avoid_refcounting, sym,
6185-
RES_REG_ADDR())) {
6188+
RES_REG_ADDR(),
6189+
op1_ffi_symbols, ffi_info)) {
61866190
goto jit_failure;
61876191
}
61886192
goto done;

0 commit comments

Comments
 (0)