@@ -230,8 +230,8 @@ void DwarfFDECache<A>::iterateCacheEntries(void (*func)(
230
230
}
231
231
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
232
232
233
-
234
- # define arrayoffsetof ( type, index, field ) (( size_t )(&(( type *) 0 )[index]. field))
233
+ # define arrayoffsetof ( type, index, field ) \
234
+ ( sizeof ( type) * (index) + offsetof( type, field))
235
235
236
236
#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
237
237
template <typename A> class UnwindSectionHeader {
@@ -1010,6 +1010,9 @@ class UnwindCursor : public AbstractUnwindCursor{
1010
1010
template <typename Registers> int stepThroughSigReturn (Registers &) {
1011
1011
return UNW_STEP_END;
1012
1012
}
1013
+ #elif defined(_LIBUNWIND_TARGET_HAIKU)
1014
+ bool setInfoForSigReturn ();
1015
+ int stepThroughSigReturn ();
1013
1016
#endif
1014
1017
1015
1018
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
@@ -1313,7 +1316,8 @@ class UnwindCursor : public AbstractUnwindCursor{
1313
1316
unw_proc_info_t _info;
1314
1317
bool _unwindInfoMissing;
1315
1318
bool _isSignalFrame;
1316
- #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
1319
+ #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
1320
+ defined (_LIBUNWIND_TARGET_HAIKU)
1317
1321
bool _isSigReturn = false;
1318
1322
#endif
1319
1323
};
@@ -2033,7 +2037,6 @@ typedef _Unwind_Reason_Code __xlcxx_personality_v0_t(int, _Unwind_Action,
2033
2037
uint64_t ,
2034
2038
_Unwind_Exception *,
2035
2039
struct _Unwind_Context *);
2036
- __attribute__ ((__weak__)) __xlcxx_personality_v0_t __xlcxx_personality_v0;
2037
2040
}
2038
2041
2039
2042
static __xlcxx_personality_v0_t *xlcPersonalityV0;
@@ -2126,42 +2129,35 @@ bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, R ®isters) {
2126
2129
// function __xlcxx_personality_v0(), which is the personality for the state
2127
2130
// table and is exported from libc++abi, is directly assigned as the
2128
2131
// handler here. When a legacy XLC++ frame is encountered, the symbol
2129
- // is resolved dynamically using dlopen() to avoid hard dependency from
2130
- // libunwind on libc++abi.
2132
+ // is resolved dynamically using dlopen() to avoid a hard dependency of
2133
+ // libunwind on libc++abi in cases such as non-C++ applications .
2131
2134
2132
2135
// Resolve the function pointer to the state table personality if it has
2133
- // not already.
2136
+ // not already been done .
2134
2137
if (xlcPersonalityV0 == NULL ) {
2135
2138
xlcPersonalityV0InitLock.lock ();
2136
2139
if (xlcPersonalityV0 == NULL ) {
2137
- // If libc++abi is statically linked in, symbol __xlcxx_personality_v0
2138
- // has been resolved at the link time.
2139
- xlcPersonalityV0 = &__xlcxx_personality_v0;
2140
+ // Resolve __xlcxx_personality_v0 using dlopen().
2141
+ const char *libcxxabi = " libc++abi.a(libc++abi.so.1)" ;
2142
+ void *libHandle;
2143
+ // The AIX dlopen() sets errno to 0 when it is successful, which
2144
+ // clobbers the value of errno from the user code. This is an AIX
2145
+ // bug because according to POSIX it should not set errno to 0. To
2146
+ // workaround before AIX fixes the bug, errno is saved and restored.
2147
+ int saveErrno = errno;
2148
+ libHandle = dlopen (libcxxabi, RTLD_MEMBER | RTLD_NOW);
2149
+ if (libHandle == NULL ) {
2150
+ _LIBUNWIND_TRACE_UNWINDING (" dlopen() failed with errno=%d\n " , errno);
2151
+ assert (0 && " dlopen() failed" );
2152
+ }
2153
+ xlcPersonalityV0 = reinterpret_cast <__xlcxx_personality_v0_t *>(
2154
+ dlsym (libHandle, " __xlcxx_personality_v0" ));
2140
2155
if (xlcPersonalityV0 == NULL ) {
2141
- // libc++abi is dynamically linked. Resolve __xlcxx_personality_v0
2142
- // using dlopen().
2143
- const char libcxxabi[] = " libc++abi.a(libc++abi.so.1)" ;
2144
- void *libHandle;
2145
- // The AIX dlopen() sets errno to 0 when it is successful, which
2146
- // clobbers the value of errno from the user code. This is an AIX
2147
- // bug because according to POSIX it should not set errno to 0. To
2148
- // workaround before AIX fixes the bug, errno is saved and restored.
2149
- int saveErrno = errno;
2150
- libHandle = dlopen (libcxxabi, RTLD_MEMBER | RTLD_NOW);
2151
- if (libHandle == NULL ) {
2152
- _LIBUNWIND_TRACE_UNWINDING (" dlopen() failed with errno=%d\n " ,
2153
- errno);
2154
- assert (0 && " dlopen() failed" );
2155
- }
2156
- xlcPersonalityV0 = reinterpret_cast <__xlcxx_personality_v0_t *>(
2157
- dlsym (libHandle, " __xlcxx_personality_v0" ));
2158
- if (xlcPersonalityV0 == NULL ) {
2159
- _LIBUNWIND_TRACE_UNWINDING (" dlsym() failed with errno=%d\n " , errno);
2160
- assert (0 && " dlsym() failed" );
2161
- }
2156
+ _LIBUNWIND_TRACE_UNWINDING (" dlsym() failed with errno=%d\n " , errno);
2162
2157
dlclose (libHandle);
2163
- errno = saveErrno ;
2158
+ assert ( 0 && " dlsym() failed " ) ;
2164
2159
}
2160
+ errno = saveErrno;
2165
2161
}
2166
2162
xlcPersonalityV0InitLock.unlock ();
2167
2163
}
@@ -2557,7 +2553,8 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
2557
2553
2558
2554
template <typename A, typename R>
2559
2555
void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
2560
- #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2556
+ #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2557
+ defined (_LIBUNWIND_TARGET_HAIKU)
2561
2558
_isSigReturn = false ;
2562
2559
#endif
2563
2560
@@ -2681,7 +2678,8 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
2681
2678
}
2682
2679
#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
2683
2680
2684
- #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2681
+ #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2682
+ defined (_LIBUNWIND_TARGET_HAIKU)
2685
2683
if (setInfoForSigReturn ())
2686
2684
return ;
2687
2685
#endif
@@ -2757,6 +2755,63 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
2757
2755
_isSignalFrame = true ;
2758
2756
return UNW_STEP_SUCCESS;
2759
2757
}
2758
+
2759
+ #elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)
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 =
2771
+ (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] +
2772
+ (addr_t )__gCommPageAddress);
2773
+ addr_t signal_handler_ret = signal_handler + 45 ;
2774
+ #endif
2775
+ pint_t pc = static_cast <pint_t >(this ->getReg (UNW_REG_IP));
2776
+ if (pc == signal_handler_ret) {
2777
+ _info = {};
2778
+ _info.start_ip = signal_handler;
2779
+ _info.end_ip = signal_handler_ret;
2780
+ _isSigReturn = true ;
2781
+ return true ;
2782
+ }
2783
+ return false ;
2784
+ }
2785
+
2786
+ template <typename A, typename R>
2787
+ int UnwindCursor<A, R>::stepThroughSigReturn() {
2788
+ _isSignalFrame = true ;
2789
+ pint_t sp = _registers.getSP ();
2790
+ #if defined(_LIBUNWIND_TARGET_X86_64)
2791
+ vregs *regs = (vregs *)(sp + 0x70 );
2792
+
2793
+ _registers.setRegister (UNW_REG_IP, regs->rip );
2794
+ _registers.setRegister (UNW_REG_SP, regs->rsp );
2795
+ _registers.setRegister (UNW_X86_64_RAX, regs->rax );
2796
+ _registers.setRegister (UNW_X86_64_RDX, regs->rdx );
2797
+ _registers.setRegister (UNW_X86_64_RCX, regs->rcx );
2798
+ _registers.setRegister (UNW_X86_64_RBX, regs->rbx );
2799
+ _registers.setRegister (UNW_X86_64_RSI, regs->rsi );
2800
+ _registers.setRegister (UNW_X86_64_RDI, regs->rdi );
2801
+ _registers.setRegister (UNW_X86_64_RBP, regs->rbp );
2802
+ _registers.setRegister (UNW_X86_64_R8, regs->r8 );
2803
+ _registers.setRegister (UNW_X86_64_R9, regs->r9 );
2804
+ _registers.setRegister (UNW_X86_64_R10, regs->r10 );
2805
+ _registers.setRegister (UNW_X86_64_R11, regs->r11 );
2806
+ _registers.setRegister (UNW_X86_64_R12, regs->r12 );
2807
+ _registers.setRegister (UNW_X86_64_R13, regs->r13 );
2808
+ _registers.setRegister (UNW_X86_64_R14, regs->r14 );
2809
+ _registers.setRegister (UNW_X86_64_R15, regs->r15 );
2810
+ // TODO: XMM
2811
+ #endif
2812
+
2813
+ return UNW_STEP_SUCCESS;
2814
+ }
2760
2815
#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2761
2816
// defined(_LIBUNWIND_TARGET_AARCH64)
2762
2817
@@ -2925,7 +2980,8 @@ template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
2925
2980
2926
2981
// Use unwinding info to modify register set as if function returned.
2927
2982
int result;
2928
- #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2983
+ #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2984
+ defined (_LIBUNWIND_TARGET_HAIKU)
2929
2985
if (_isSigReturn) {
2930
2986
result = this ->stepThroughSigReturn ();
2931
2987
} else
0 commit comments