Skip to content

Commit e92cd0d

Browse files
committed
Add hard-coded SEH unwind data for EXITCALL
1 parent 09da31a commit e92cd0d

File tree

1 file changed

+36
-7
lines changed

1 file changed

+36
-7
lines changed

ext/opcache/jit/zend_jit_ir.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3233,7 +3233,7 @@ static void zend_jit_setup_unwinder(void)
32333233
static const unsigned char uw_data[] = {
32343234
0x01, // UBYTE: 3 Version , UBYTE: 5 Flags
32353235
0x10, // UBYTE Size of prolog
3236-
0x09, // UBYTE Count of unwind codes
3236+
0x0a, // UBYTE Count of unwind codes
32373237
0x00, // UBYTE: 4 Frame Register, UBYTE: 4 Frame Register offset (scaled)
32383238
// USHORT * n Unwind codes array
32393239
0x10, 0x82, // c: subq $0x48, %rsp
@@ -3245,15 +3245,44 @@ static void zend_jit_setup_unwinder(void)
32453245
0x03, 0x60, // 2: pushq %rsi
32463246
0x02, 0x50, // 1: pushq %rbp
32473247
0x01, 0x30, // 0: pushq %rbx
3248+
0x00, 0x00,
3249+
};
3250+
static const unsigned char uw_data_exitcall[] = {
3251+
0x01, // UBYTE: 3 Version , UBYTE: 5 Flags
3252+
0x10, // UBYTE Size of prolog
3253+
0x0a, // UBYTE Count of unwind codes
3254+
0x00, // UBYTE: 4 Frame Register, UBYTE: 4 Frame Register offset (scaled)
3255+
// USHORT * n Unwind codes array
3256+
0x10, 0x01, 0x2f, 0x00, // c: subq 376, %rsp ; 0x48 + 32+16*8+16*8+8+8
3257+
0x0c, 0xf0, // a: pushq %r15
3258+
0x0a, 0xe0, // 8: pushq %r14
3259+
0x08, 0xd0, // 6: pushq %r13
3260+
0x06, 0xc0, // 4: pushq %r12
3261+
0x04, 0x70, // 3: pushq %rdi
3262+
0x03, 0x60, // 2: pushq %rsi
3263+
0x02, 0x50, // 1: pushq %rbp
3264+
0x01, 0x30, // 0: pushq %rbx
32483265
};
32493266

32503267
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);
3268+
*dasm_ptr = (char*)*dasm_ptr + ZEND_MM_ALIGNED_SIZE_EX(sizeof(RUNTIME_FUNCTION) * 4 +
3269+
sizeof(uw_data) + sizeof(uw_data_exitcall) + sizeof(uw_data), 16);
3270+
3271+
zend_jit_uw_func[0].BeginAddress = 0;
3272+
zend_jit_uw_func[1].BeginAddress = (uintptr_t)zend_jit_stub_handlers[jit_stub_trace_exit] - (uintptr_t)dasm_buf;
3273+
zend_jit_uw_func[2].BeginAddress = (uintptr_t)zend_jit_stub_handlers[jit_stub_undefined_offset] - (uintptr_t)dasm_buf;
3274+
3275+
zend_jit_uw_func[0].EndAddress = zend_jit_uw_func[1].BeginAddress;
3276+
zend_jit_uw_func[1].EndAddress = zend_jit_uw_func[2].BeginAddress;
3277+
zend_jit_uw_func[2].EndAddress = (uintptr_t)dasm_end - (uintptr_t)dasm_buf;
3278+
3279+
zend_jit_uw_func[0].UnwindData = (uintptr_t)zend_jit_uw_func - (uintptr_t)dasm_buf + sizeof(RUNTIME_FUNCTION) * 4;
3280+
zend_jit_uw_func[1].UnwindData = zend_jit_uw_func[0].UnwindData + sizeof(uw_data);
3281+
zend_jit_uw_func[2].UnwindData = zend_jit_uw_func[1].UnwindData + sizeof(uw_data_exitcall);
32523282

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));
3283+
memcpy((char*)dasm_buf + zend_jit_uw_func[0].UnwindData, uw_data, sizeof(uw_data));
3284+
memcpy((char*)dasm_buf + zend_jit_uw_func[1].UnwindData, uw_data_exitcall, sizeof(uw_data_exitcall));
3285+
memcpy((char*)dasm_buf + zend_jit_uw_func[2].UnwindData, uw_data, sizeof(uw_data));
32573286

32583287
#ifdef ZEND_JIT_RT_UNWINDER
32593288
RtlInstallFunctionTableCallback(
@@ -3264,7 +3293,7 @@ static void zend_jit_setup_unwinder(void)
32643293
NULL,
32653294
NULL);
32663295
#else
3267-
RtlAddFunctionTable(zend_jit_uw_func, 1, (uintptr_t)dasm_buf);
3296+
RtlAddFunctionTable(zend_jit_uw_func, 3, (uintptr_t)dasm_buf);
32683297
#endif
32693298
}
32703299
#endif

0 commit comments

Comments
 (0)