@@ -3213,6 +3213,63 @@ static zend_never_inline void zend_jit_set_sp_adj_vm(void)
32133213}
32143214#endif
32153215
3216+ #ifdef _WIN64
3217+ /*
3218+ * We use a single unwind entry for the whole JIT buffer.
3219+ * This works, because all the JIT-ed PHP functions have the same "fixed stack frame".
3220+ */
3221+ static PRUNTIME_FUNCTION zend_jit_uw_func = NULL;
3222+
3223+ #ifdef ZEND_JIT_RT_UNWINDER
3224+ static PRUNTIME_FUNCTION zend_jit_unwind_callback(DWORD64 pc, PVOID context)
3225+ {
3226+ return zend_jit_uw_func;
3227+ }
3228+ #endif
3229+
3230+ static void zend_jit_setup_unwinder(void)
3231+ {
3232+ /* Hardcoded SEH unwinf data for JIT-ed PHP functions with "fixed stack frame" */
3233+ static const unsigned char uw_data[] = {
3234+ 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags
3235+ 0x10, // UBYTE Size of prolog
3236+ 0x09, // UBYTE Count of unwind codes
3237+ 0x00, // UBYTE: 4 Frame Register, UBYTE: 4 Frame Register offset (scaled)
3238+ // USHORT * n Unwind codes array
3239+ 0x10, 0x82, // c: subq $0x48, %rsp
3240+ 0x0c, 0xf0, // a: pushq %r15
3241+ 0x0a, 0xe0, // 8: pushq %r14
3242+ 0x08, 0xd0, // 6: pushq %r13
3243+ 0x06, 0xc0, // 4: pushq %r12
3244+ 0x04, 0x70, // 3: pushq %rdi
3245+ 0x03, 0x60, // 2: pushq %rsi
3246+ 0x02, 0x50, // 1: pushq %rbp
3247+ 0x01, 0x30, // 0: pushq %rbx
3248+ };
3249+
3250+ zend_jit_uw_func = (PRUNTIME_FUNCTION)*dasm_ptr;
3251+ *dasm_ptr = (char*)*dasm_ptr + ZEND_MM_ALIGNED_SIZE_EX(sizeof(RUNTIME_FUNCTION) + sizeof(uw_data), 16);
3252+
3253+ zend_jit_uw_func->BeginAddress = 0;
3254+ zend_jit_uw_func->EndAddress = (uintptr_t)dasm_end - (uintptr_t)dasm_buf;
3255+ zend_jit_uw_func->UnwindData = (uintptr_t)zend_jit_uw_func + sizeof(RUNTIME_FUNCTION) - (uintptr_t)dasm_buf;
3256+ memcpy((char*)zend_jit_uw_func + sizeof(RUNTIME_FUNCTION), uw_data, sizeof(uw_data));
3257+
3258+ #ifdef ZEND_JIT_RT_UNWINDER
3259+ RtlInstallFunctionTableCallback(
3260+ (uintptr_t)dasm_buf | 3,
3261+ (uintptr_t) dasm_buf,
3262+ (uintptr_t)dasm_end - (uintptr_t)dasm_buf,
3263+ zend_jit_unwind_callback,
3264+ NULL,
3265+ NULL);
3266+ #else
3267+ RtlAddFunctionTable(zend_jit_uw_func, 1, (uintptr_t)dasm_buf);
3268+ #endif
3269+ }
3270+ #endif
3271+
3272+
32163273static void zend_jit_setup(void)
32173274{
32183275#if defined(IR_TARGET_X86)
@@ -3420,6 +3477,10 @@ static void zend_jit_setup(void)
34203477 zend_jit_calc_trace_prologue_size();
34213478 zend_jit_setup_stubs();
34223479 JIT_G(debug) = debug;
3480+
3481+ #ifdef _WIN64
3482+ zend_jit_setup_unwinder();
3483+ #endif
34233484}
34243485
34253486static void zend_jit_shutdown_ir(void)
0 commit comments