4141#define  _LIBUNWIND_CHECK_LINUX_SIGRETURN  1 
4242#endif 
4343
44+ #if  defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)
45+ #include  < OS.h> 
46+ #include  < signal.h> 
47+ #define  _LIBUNWIND_CHECK_HAIKU_SIGRETURN  1 
48+ #endif 
49+ 
4450#include  " AddressSpace.hpp" 
4551#include  " CompactUnwinder.hpp" 
4652#include  " config.h" 
@@ -1015,7 +1021,7 @@ class UnwindCursor : public AbstractUnwindCursor{
10151021  template  <typename  Registers> int  stepThroughSigReturn (Registers &) {
10161022    return  UNW_STEP_END;
10171023  }
1018- #elif  defined(_LIBUNWIND_TARGET_HAIKU )
1024+ #elif  defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN )
10191025  bool  setInfoForSigReturn ();
10201026  int  stepThroughSigReturn ();
10211027#endif 
@@ -2559,7 +2565,7 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
25592565template  <typename  A, typename  R>
25602566void  UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool  isReturnAddress) {
25612567#if  defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) ||                               \
2562-     defined (_LIBUNWIND_TARGET_HAIKU )
2568+     defined (_LIBUNWIND_CHECK_HAIKU_SIGRETURN )
25632569  _isSigReturn = false ;
25642570#endif 
25652571
@@ -2684,7 +2690,7 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
26842690#endif  //  #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
26852691
26862692#if  defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) ||                               \
2687-     defined (_LIBUNWIND_TARGET_HAIKU )
2693+     defined (_LIBUNWIND_CHECK_HAIKU_SIGRETURN )
26882694  if  (setInfoForSigReturn ())
26892695    return ;
26902696#endif 
@@ -2760,63 +2766,6 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
27602766  _isSignalFrame = true ;
27612767  return  UNW_STEP_SUCCESS;
27622768}
2763- 
2764- #elif  defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)
2765- #include  < commpage_defs.h> 
2766- #include  < signal.h> 
2767- 
2768- extern  " C"   {
2769- extern  void  *__gCommPageAddress;
2770- }
2771- 
2772- template  <typename  A, typename  R>
2773- bool  UnwindCursor<A, R>::setInfoForSigReturn() {
2774- #if  defined(_LIBUNWIND_TARGET_X86_64)
2775-   addr_t  signal_handler =
2776-       (((addr_t  *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] +
2777-        (addr_t )__gCommPageAddress);
2778-   addr_t  signal_handler_ret = signal_handler + 45 ;
2779- #endif 
2780-   pint_t  pc = static_cast <pint_t >(this ->getReg (UNW_REG_IP));
2781-   if  (pc == signal_handler_ret) {
2782-     _info = {};
2783-     _info.start_ip  = signal_handler;
2784-     _info.end_ip  = signal_handler_ret;
2785-     _isSigReturn = true ;
2786-     return  true ;
2787-   }
2788-   return  false ;
2789- }
2790- 
2791- template  <typename  A, typename  R>
2792- int  UnwindCursor<A, R>::stepThroughSigReturn() {
2793-   _isSignalFrame = true ;
2794-   pint_t  sp = _registers.getSP ();
2795- #if  defined(_LIBUNWIND_TARGET_X86_64)
2796-   vregs *regs = (vregs *)(sp + 0x70 );
2797- 
2798-   _registers.setRegister (UNW_REG_IP, regs->rip );
2799-   _registers.setRegister (UNW_REG_SP, regs->rsp );
2800-   _registers.setRegister (UNW_X86_64_RAX, regs->rax );
2801-   _registers.setRegister (UNW_X86_64_RDX, regs->rdx );
2802-   _registers.setRegister (UNW_X86_64_RCX, regs->rcx );
2803-   _registers.setRegister (UNW_X86_64_RBX, regs->rbx );
2804-   _registers.setRegister (UNW_X86_64_RSI, regs->rsi );
2805-   _registers.setRegister (UNW_X86_64_RDI, regs->rdi );
2806-   _registers.setRegister (UNW_X86_64_RBP, regs->rbp );
2807-   _registers.setRegister (UNW_X86_64_R8, regs->r8 );
2808-   _registers.setRegister (UNW_X86_64_R9, regs->r9 );
2809-   _registers.setRegister (UNW_X86_64_R10, regs->r10 );
2810-   _registers.setRegister (UNW_X86_64_R11, regs->r11 );
2811-   _registers.setRegister (UNW_X86_64_R12, regs->r12 );
2812-   _registers.setRegister (UNW_X86_64_R13, regs->r13 );
2813-   _registers.setRegister (UNW_X86_64_R14, regs->r14 );
2814-   _registers.setRegister (UNW_X86_64_R15, regs->r15 );
2815-   //  TODO: XMM
2816- #endif 
2817- 
2818-   return  UNW_STEP_SUCCESS;
2819- }
28202769#endif  //  defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
28212770       //  defined(_LIBUNWIND_TARGET_AARCH64)
28222771
@@ -3032,6 +2981,96 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_s390x &) {
30322981#endif  //  defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
30332982       //  defined(_LIBUNWIND_TARGET_S390X)
30342983
2984+ #if  defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN)
2985+ template  <typename  A, typename  R>
2986+ bool  UnwindCursor<A, R>::setInfoForSigReturn() {
2987+   Dl_info dlinfo;
2988+   const  auto  isSignalHandler = [&](pint_t  addr) {
2989+     if  (!dladdr (reinterpret_cast <void  *>(addr), &dlinfo))
2990+       return  false ;
2991+     if  (strcmp (dlinfo.dli_fname , " commpage"  ))
2992+       return  false ;
2993+     if  (dlinfo.dli_sname  == NULL  ||
2994+         strcmp (dlinfo.dli_sname , " commpage_signal_handler"  ))
2995+       return  false ;
2996+     return  true ;
2997+   };
2998+ 
2999+   pint_t  pc = static_cast <pint_t >(this ->getReg (UNW_REG_IP));
3000+   if  (!isSignalHandler (pc))
3001+     return  false ;
3002+ 
3003+   pint_t  start = reinterpret_cast <pint_t >(dlinfo.dli_saddr );
3004+ 
3005+   static  size_t  signalHandlerSize = 0 ;
3006+   if  (signalHandlerSize == 0 ) {
3007+     size_t  boundLow = 0 ;
3008+     size_t  boundHigh = static_cast <size_t >(-1 );
3009+ 
3010+     area_info areaInfo;
3011+     if  (get_area_info (area_for (dlinfo.dli_saddr ), &areaInfo) == B_OK)
3012+       boundHigh = areaInfo.size ;
3013+ 
3014+     while  (boundLow < boundHigh) {
3015+       size_t  boundMid = boundLow + ((boundHigh - boundLow) / 2 );
3016+       pint_t  test = start + boundMid;
3017+       if  (test >= start && isSignalHandler (test))
3018+         boundLow = boundMid + 1 ;
3019+       else 
3020+         boundHigh = boundMid;
3021+     }
3022+ 
3023+     signalHandlerSize = boundHigh;
3024+   }
3025+ 
3026+   _info = {};
3027+   _info.start_ip  = start;
3028+   _info.end_ip  = start + signalHandlerSize;
3029+   _isSigReturn = true ;
3030+ 
3031+   return  true ;
3032+ }
3033+ 
3034+ template  <typename  A, typename  R>
3035+ int  UnwindCursor<A, R>::stepThroughSigReturn() {
3036+   _isSignalFrame = true ;
3037+ 
3038+ #if  defined(_LIBUNWIND_TARGET_X86_64)
3039+   //  Layout of the stack before function call:
3040+   //  - signal_frame_data
3041+   //    + siginfo_t    (public struct, fairly stable)
3042+   //    + ucontext_t   (public struct, fairly stable)
3043+   //      - mcontext_t -> Offset 0x70, this is what we want.
3044+   //  - frame->ip (8 bytes)
3045+   //  - frame->bp (8 bytes). Not written by the kernel,
3046+   //    but the signal handler has a "push %rbp" instruction.
3047+   pint_t  bp = this ->getReg (UNW_X86_64_RBP);
3048+   vregs *regs = (vregs *)(bp + 0x70 );
3049+ 
3050+   _registers.setRegister (UNW_REG_IP, regs->rip );
3051+   _registers.setRegister (UNW_REG_SP, regs->rsp );
3052+   _registers.setRegister (UNW_X86_64_RAX, regs->rax );
3053+   _registers.setRegister (UNW_X86_64_RDX, regs->rdx );
3054+   _registers.setRegister (UNW_X86_64_RCX, regs->rcx );
3055+   _registers.setRegister (UNW_X86_64_RBX, regs->rbx );
3056+   _registers.setRegister (UNW_X86_64_RSI, regs->rsi );
3057+   _registers.setRegister (UNW_X86_64_RDI, regs->rdi );
3058+   _registers.setRegister (UNW_X86_64_RBP, regs->rbp );
3059+   _registers.setRegister (UNW_X86_64_R8, regs->r8 );
3060+   _registers.setRegister (UNW_X86_64_R9, regs->r9 );
3061+   _registers.setRegister (UNW_X86_64_R10, regs->r10 );
3062+   _registers.setRegister (UNW_X86_64_R11, regs->r11 );
3063+   _registers.setRegister (UNW_X86_64_R12, regs->r12 );
3064+   _registers.setRegister (UNW_X86_64_R13, regs->r13 );
3065+   _registers.setRegister (UNW_X86_64_R14, regs->r14 );
3066+   _registers.setRegister (UNW_X86_64_R15, regs->r15 );
3067+   //  TODO: XMM
3068+ #endif  //  defined(_LIBUNWIND_TARGET_X86_64)
3069+ 
3070+   return  UNW_STEP_SUCCESS;
3071+ }
3072+ #endif  //  defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN)
3073+ 
30353074template  <typename  A, typename  R> int  UnwindCursor<A, R>::step(bool  stage2) {
30363075  (void )stage2;
30373076  //  Bottom of stack is defined is when unwind info cannot be found.
@@ -3041,7 +3080,7 @@ template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
30413080  //  Use unwinding info to modify register set as if function returned.
30423081  int  result;
30433082#if  defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) ||                               \
3044-     defined (_LIBUNWIND_TARGET_HAIKU )
3083+     defined (_LIBUNWIND_CHECK_HAIKU_SIGRETURN )
30453084  if  (_isSigReturn) {
30463085    result = this ->stepThroughSigReturn ();
30473086  } else 
0 commit comments