Skip to content

Commit 3b904ae

Browse files
korlitrungnt2910
andauthored
[libunwind][Haiku] Improve support (#115462)
* Signal frame unwinding on x86_64 from X512 * Header search for commpage_defs.h on non-standard paths Unwind supported tests pass on Haiku x86_64 --------- Co-authored-by: Trung Nguyen <[email protected]>
1 parent a608607 commit 3b904ae

File tree

2 files changed

+84
-4
lines changed

2 files changed

+84
-4
lines changed

libunwind/src/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,22 @@ if (HAIKU)
113113

114114
add_compile_flags("-D_DEFAULT_SOURCE")
115115
add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME")
116+
117+
find_path(LIBUNWIND_HAIKU_PRIVATE_HEADERS
118+
"commpage_defs.h"
119+
PATHS ${CMAKE_SYSTEM_INCLUDE_PATH}
120+
PATH_SUFFIXES "/private/system"
121+
NO_DEFAULT_PATH
122+
REQUIRED)
123+
124+
include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}")
125+
if (LIBUNWIND_TARGET_TRIPLE)
126+
if (${LIBUNWIND_TARGET_TRIPLE} MATCHES "^x86_64")
127+
include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/x86_64")
128+
endif()
129+
else()
130+
include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/${CMAKE_SYSTEM_PROCESSOR}")
131+
endif()
116132
endif ()
117133

118134
string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}")

libunwind/src/UnwindCursor.hpp

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
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)
13171321
bool _isSigReturn = false;
13181322
#endif
13191323
};
@@ -2549,7 +2553,8 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
25492553

25502554
template <typename A, typename R>
25512555
void 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)
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)
26772683
if (setInfoForSigReturn())
26782684
return;
26792685
#endif
@@ -2749,6 +2755,63 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
27492755
_isSignalFrame = true;
27502756
return UNW_STEP_SUCCESS;
27512757
}
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+
}
27522815
#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
27532816
// defined(_LIBUNWIND_TARGET_AARCH64)
27542817

@@ -2917,7 +2980,8 @@ template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
29172980

29182981
// Use unwinding info to modify register set as if function returned.
29192982
int result;
2920-
#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2983+
#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2984+
defined(_LIBUNWIND_TARGET_HAIKU)
29212985
if (_isSigReturn) {
29222986
result = this->stepThroughSigReturn();
29232987
} else

0 commit comments

Comments
 (0)