Skip to content

Commit

Permalink
Add hard-coded SEH unwind data for EXITCALL
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Dec 11, 2024
1 parent 09da31a commit e92cd0d
Showing 1 changed file with 36 additions and 7 deletions.
43 changes: 36 additions & 7 deletions ext/opcache/jit/zend_jit_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -3233,7 +3233,7 @@ static void zend_jit_setup_unwinder(void)
static const unsigned char uw_data[] = {
0x01, // UBYTE: 3 Version , UBYTE: 5 Flags
0x10, // UBYTE Size of prolog
0x09, // UBYTE Count of unwind codes
0x0a, // UBYTE Count of unwind codes
0x00, // UBYTE: 4 Frame Register, UBYTE: 4 Frame Register offset (scaled)
// USHORT * n Unwind codes array
0x10, 0x82, // c: subq $0x48, %rsp
Expand All @@ -3245,15 +3245,44 @@ static void zend_jit_setup_unwinder(void)
0x03, 0x60, // 2: pushq %rsi
0x02, 0x50, // 1: pushq %rbp
0x01, 0x30, // 0: pushq %rbx
0x00, 0x00,
};
static const unsigned char uw_data_exitcall[] = {
0x01, // UBYTE: 3 Version , UBYTE: 5 Flags
0x10, // UBYTE Size of prolog
0x0a, // UBYTE Count of unwind codes
0x00, // UBYTE: 4 Frame Register, UBYTE: 4 Frame Register offset (scaled)
// USHORT * n Unwind codes array
0x10, 0x01, 0x2f, 0x00, // c: subq 376, %rsp ; 0x48 + 32+16*8+16*8+8+8
0x0c, 0xf0, // a: pushq %r15
0x0a, 0xe0, // 8: pushq %r14
0x08, 0xd0, // 6: pushq %r13
0x06, 0xc0, // 4: pushq %r12
0x04, 0x70, // 3: pushq %rdi
0x03, 0x60, // 2: pushq %rsi
0x02, 0x50, // 1: pushq %rbp
0x01, 0x30, // 0: pushq %rbx
};

zend_jit_uw_func = (PRUNTIME_FUNCTION)*dasm_ptr;
*dasm_ptr = (char*)*dasm_ptr + ZEND_MM_ALIGNED_SIZE_EX(sizeof(RUNTIME_FUNCTION) + sizeof(uw_data), 16);
*dasm_ptr = (char*)*dasm_ptr + ZEND_MM_ALIGNED_SIZE_EX(sizeof(RUNTIME_FUNCTION) * 4 +
sizeof(uw_data) + sizeof(uw_data_exitcall) + sizeof(uw_data), 16);

zend_jit_uw_func[0].BeginAddress = 0;
zend_jit_uw_func[1].BeginAddress = (uintptr_t)zend_jit_stub_handlers[jit_stub_trace_exit] - (uintptr_t)dasm_buf;
zend_jit_uw_func[2].BeginAddress = (uintptr_t)zend_jit_stub_handlers[jit_stub_undefined_offset] - (uintptr_t)dasm_buf;

zend_jit_uw_func[0].EndAddress = zend_jit_uw_func[1].BeginAddress;
zend_jit_uw_func[1].EndAddress = zend_jit_uw_func[2].BeginAddress;
zend_jit_uw_func[2].EndAddress = (uintptr_t)dasm_end - (uintptr_t)dasm_buf;

zend_jit_uw_func[0].UnwindData = (uintptr_t)zend_jit_uw_func - (uintptr_t)dasm_buf + sizeof(RUNTIME_FUNCTION) * 4;
zend_jit_uw_func[1].UnwindData = zend_jit_uw_func[0].UnwindData + sizeof(uw_data);
zend_jit_uw_func[2].UnwindData = zend_jit_uw_func[1].UnwindData + sizeof(uw_data_exitcall);

zend_jit_uw_func->BeginAddress = 0;
zend_jit_uw_func->EndAddress = (uintptr_t)dasm_end - (uintptr_t)dasm_buf;
zend_jit_uw_func->UnwindData = (uintptr_t)zend_jit_uw_func + sizeof(RUNTIME_FUNCTION) - (uintptr_t)dasm_buf;
memcpy((char*)zend_jit_uw_func + sizeof(RUNTIME_FUNCTION), uw_data, sizeof(uw_data));
memcpy((char*)dasm_buf + zend_jit_uw_func[0].UnwindData, uw_data, sizeof(uw_data));
memcpy((char*)dasm_buf + zend_jit_uw_func[1].UnwindData, uw_data_exitcall, sizeof(uw_data_exitcall));
memcpy((char*)dasm_buf + zend_jit_uw_func[2].UnwindData, uw_data, sizeof(uw_data));

#ifdef ZEND_JIT_RT_UNWINDER
RtlInstallFunctionTableCallback(
Expand All @@ -3264,7 +3293,7 @@ static void zend_jit_setup_unwinder(void)
NULL,
NULL);
#else
RtlAddFunctionTable(zend_jit_uw_func, 1, (uintptr_t)dasm_buf);
RtlAddFunctionTable(zend_jit_uw_func, 3, (uintptr_t)dasm_buf);
#endif
}
#endif
Expand Down

0 comments on commit e92cd0d

Please sign in to comment.