@@ -1010,6 +1010,9 @@ class UnwindCursor : public AbstractUnwindCursor{
10101010 template <typename Registers> int stepThroughSigReturn (Registers &) {
10111011 return UNW_STEP_END;
10121012 }
1013+ #elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)
1014+ bool setInfoForSigReturn ();
1015+ int stepThroughSigReturn ();
10131016#endif
10141017
10151018#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
@@ -1313,7 +1316,8 @@ class UnwindCursor : public AbstractUnwindCursor{
13131316 unw_proc_info_t _info;
13141317 bool _unwindInfoMissing;
13151318 bool _isSignalFrame;
1316- #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
1319+ #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
1320+ (defined (_LIBUNWIND_TARGET_HAIKU) && defined (_LIBUNWIND_TARGET_X86_64))
13171321 bool _isSigReturn = false ;
13181322#endif
13191323};
@@ -2549,7 +2553,8 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
25492553
25502554template <typename A, typename R>
25512555void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
2552- #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2556+ #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2557+ (defined (_LIBUNWIND_TARGET_HAIKU) && defined (_LIBUNWIND_TARGET_X86_64))
25532558 _isSigReturn = false ;
25542559#endif
25552560
@@ -2673,7 +2678,8 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
26732678 }
26742679#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
26752680
2676- #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2681+ #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2682+ (defined (_LIBUNWIND_TARGET_HAIKU) && defined (_LIBUNWIND_TARGET_X86_64))
26772683 if (setInfoForSigReturn ())
26782684 return ;
26792685#endif
@@ -2749,6 +2755,62 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
27492755 _isSignalFrame = true ;
27502756 return UNW_STEP_SUCCESS;
27512757}
2758+ #elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)
2759+
2760+ #include < commpage_defs.h>
2761+ #include < signal.h>
2762+
2763+ extern " C" {
2764+ extern void *__gCommPageAddress;
2765+ }
2766+
2767+ template <typename A, typename R>
2768+ bool UnwindCursor<A, R>::setInfoForSigReturn() {
2769+ #if defined(_LIBUNWIND_TARGET_X86_64)
2770+ addr_t signal_handler = (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER]
2771+ + (addr_t )__gCommPageAddress);
2772+ addr_t signal_handler_ret = signal_handler + 45 ;
2773+ #endif
2774+ pint_t pc = static_cast <pint_t >(this ->getReg (UNW_REG_IP));
2775+ if (pc == signal_handler_ret) {
2776+ _info = {};
2777+ _info.start_ip = signal_handler;
2778+ _info.end_ip = signal_handler_ret;
2779+ _isSigReturn = true ;
2780+ return true ;
2781+ }
2782+ return false ;
2783+ }
2784+
2785+ template <typename A, typename R>
2786+ int UnwindCursor<A, R>::stepThroughSigReturn() {
2787+ _isSignalFrame = true ;
2788+ pint_t sp = _registers.getSP ();
2789+ #if defined(_LIBUNWIND_TARGET_X86_64)
2790+ vregs *regs = (vregs*)(sp + 0x70 );
2791+
2792+ _registers.setRegister (UNW_REG_IP, regs->rip );
2793+ _registers.setRegister (UNW_REG_SP, regs->rsp );
2794+ _registers.setRegister (UNW_X86_64_RAX, regs->rax );
2795+ _registers.setRegister (UNW_X86_64_RDX, regs->rdx );
2796+ _registers.setRegister (UNW_X86_64_RCX, regs->rcx );
2797+ _registers.setRegister (UNW_X86_64_RBX, regs->rbx );
2798+ _registers.setRegister (UNW_X86_64_RSI, regs->rsi );
2799+ _registers.setRegister (UNW_X86_64_RDI, regs->rdi );
2800+ _registers.setRegister (UNW_X86_64_RBP, regs->rbp );
2801+ _registers.setRegister (UNW_X86_64_R8, regs->r8 );
2802+ _registers.setRegister (UNW_X86_64_R9, regs->r9 );
2803+ _registers.setRegister (UNW_X86_64_R10, regs->r10 );
2804+ _registers.setRegister (UNW_X86_64_R11, regs->r11 );
2805+ _registers.setRegister (UNW_X86_64_R12, regs->r12 );
2806+ _registers.setRegister (UNW_X86_64_R13, regs->r13 );
2807+ _registers.setRegister (UNW_X86_64_R14, regs->r14 );
2808+ _registers.setRegister (UNW_X86_64_R15, regs->r15 );
2809+ // TODO: XMM
2810+ #endif
2811+
2812+ return UNW_STEP_SUCCESS;
2813+ }
27522814#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
27532815 // defined(_LIBUNWIND_TARGET_AARCH64)
27542816
@@ -2917,7 +2979,8 @@ template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
29172979
29182980 // Use unwinding info to modify register set as if function returned.
29192981 int result;
2920- #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2982+ #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2983+ (defined (_LIBUNWIND_TARGET_HAIKU) && defined (_LIBUNWIND_TARGET_X86_64))
29212984 if (_isSigReturn) {
29222985 result = this ->stepThroughSigReturn ();
29232986 } else
0 commit comments