[libunwind] Fix signal frame unwinding (PR #135367)
https://github.com/trungnt2910 created https://github.com/llvm/llvm-project/pull/135367 The current unwinding implementation on Haiku is messy and broken. 1. It searches weird paths for private headers, which is breaking builds in consuming projects, such as dotnet/runtime. 2. It does not even work, due to relying on incorrect private offsets. This commit strips all references to private headers and ports a working signal frame implementation. It has been tested against `tests/signal_unwind.pass.cpp` and can go pass the signal frame. >From 9f9a3e70740331a7a4ac9f52e580d76f94b5e8fd Mon Sep 17 00:00:00 2001 From: Trung Nguyen <57174311+trungnt2...@users.noreply.github.com> Date: Fri, 11 Apr 2025 23:11:04 +1000 Subject: [PATCH] Fix signal frame unwinding The current unwinding implementation on Haiku is messy and broken. 1. It searches weird paths for private headers, which is breaking builds in consuming projects, such as dotnet/runtime. 2. It does not even work, due to relying on incorrect private offsets. This commit strips all references to private headers and ports a working signal frame implementation. It has been tested against `tests/signal_unwind.pass.cpp` and can go pass the signal frame. --- libunwind/src/CMakeLists.txt | 16 --- libunwind/src/UnwindCursor.hpp | 223 - 2 files changed, 163 insertions(+), 76 deletions(-) diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt index d69013e5dace1..70bd3a017cda7 100644 --- a/libunwind/src/CMakeLists.txt +++ b/libunwind/src/CMakeLists.txt @@ -118,22 +118,6 @@ if (HAIKU) add_compile_flags("-D_DEFAULT_SOURCE") add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME") - - find_path(LIBUNWIND_HAIKU_PRIVATE_HEADERS -"commpage_defs.h" -PATHS ${CMAKE_SYSTEM_INCLUDE_PATH} -PATH_SUFFIXES "/private/system" -NO_DEFAULT_PATH -REQUIRED) - - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}") - if (LIBUNWIND_TARGET_TRIPLE) -if (${LIBUNWIND_TARGET_TRIPLE} MATCHES "^x86_64") - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/x86_64") -endif() - else() -include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/${CMAKE_SYSTEM_PROCESSOR}") - endif() endif () string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}") diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index ca9927edc9990..fc1f8e91724b2 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -41,6 +41,14 @@ #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 #endif +#if defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) +#include +#include +#include +#include +#define _LIBUNWIND_CHECK_HAIKU_SIGRETURN 1 +#endif + #include "AddressSpace.hpp" #include "CompactUnwinder.hpp" #include "config.h" @@ -1015,7 +1023,7 @@ class UnwindCursor : public AbstractUnwindCursor{ template int stepThroughSigReturn(Registers &) { return UNW_STEP_END; } -#elif defined(_LIBUNWIND_TARGET_HAIKU) +#elif defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) bool setInfoForSigReturn(); int stepThroughSigReturn(); #endif @@ -2559,7 +2567,7 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, template void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) _isSigReturn = false; #endif @@ -2684,7 +2692,7 @@ void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) if (setInfoForSigReturn()) return; #endif @@ -2760,63 +2768,6 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { _isSignalFrame = true; return UNW_STEP_SUCCESS; } - -#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) -#include -#include - -extern "C" { -extern void *__gCommPageAddress; -} - -template -bool UnwindCursor::setInfoForSigReturn() { -#if defined(_LIBUNWIND_TARGET_X86_64) - addr_t signal_handler = - (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + - (addr_t)__gCommPageAddress); - addr_t signal_handler_ret = signal_handler + 45; -#endif - pint_t pc = static_cast(this->getReg(UNW_REG_IP)); - if (pc == signal_handler_ret) { -_info = {}; -_info.start_ip = signal_handler; -_info.end_ip = signal_handler_ret; -_isSigReturn = true; -return true; - } - return false; -} - -template -int UnwindCursor::stepThroughSigReturn() { - _isSignalFrame = true; - pint_t sp = _registers.getSP(); -#if defined(_LIBUNWIND_TARGET_X86_64) - vregs *regs = (vregs *
[libunwind] Fix signal frame unwinding (PR #135367)
https://github.com/trungnt2910 updated https://github.com/llvm/llvm-project/pull/135367 >From d213e68a98b5c92656122aa13bf853b77e6c0b7a Mon Sep 17 00:00:00 2001 From: Trung Nguyen <57174311+trungnt2...@users.noreply.github.com> Date: Fri, 11 Apr 2025 23:11:04 +1000 Subject: [PATCH] Fix signal frame unwinding The current unwinding implementation on Haiku is messy and broken. 1. It searches weird paths for private headers, which is breaking builds in consuming projects, such as dotnet/runtime. 2. It does not even work, due to relying on incorrect private offsets. This commit strips all references to private headers and ports a working signal frame implementation. It has been tested against `tests/signal_unwind.pass.cpp` and can go pass the signal frame. --- libunwind/src/CMakeLists.txt | 16 --- libunwind/src/UnwindCursor.hpp | 227 - 2 files changed, 167 insertions(+), 76 deletions(-) diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt index d69013e5dace1..70bd3a017cda7 100644 --- a/libunwind/src/CMakeLists.txt +++ b/libunwind/src/CMakeLists.txt @@ -118,22 +118,6 @@ if (HAIKU) add_compile_flags("-D_DEFAULT_SOURCE") add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME") - - find_path(LIBUNWIND_HAIKU_PRIVATE_HEADERS -"commpage_defs.h" -PATHS ${CMAKE_SYSTEM_INCLUDE_PATH} -PATH_SUFFIXES "/private/system" -NO_DEFAULT_PATH -REQUIRED) - - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}") - if (LIBUNWIND_TARGET_TRIPLE) -if (${LIBUNWIND_TARGET_TRIPLE} MATCHES "^x86_64") - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/x86_64") -endif() - else() -include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/${CMAKE_SYSTEM_PROCESSOR}") - endif() endif () string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}") diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index ca9927edc9990..1c545978673b4 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -41,6 +41,14 @@ #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 #endif +#if defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) +#include +#include +#include +#include +#define _LIBUNWIND_CHECK_HAIKU_SIGRETURN 1 +#endif + #include "AddressSpace.hpp" #include "CompactUnwinder.hpp" #include "config.h" @@ -1015,7 +1023,7 @@ class UnwindCursor : public AbstractUnwindCursor{ template int stepThroughSigReturn(Registers &) { return UNW_STEP_END; } -#elif defined(_LIBUNWIND_TARGET_HAIKU) +#elif defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) bool setInfoForSigReturn(); int stepThroughSigReturn(); #endif @@ -2559,7 +2567,7 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, template void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) _isSigReturn = false; #endif @@ -2684,7 +2692,7 @@ void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) if (setInfoForSigReturn()) return; #endif @@ -2760,63 +2768,6 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { _isSignalFrame = true; return UNW_STEP_SUCCESS; } - -#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) -#include -#include - -extern "C" { -extern void *__gCommPageAddress; -} - -template -bool UnwindCursor::setInfoForSigReturn() { -#if defined(_LIBUNWIND_TARGET_X86_64) - addr_t signal_handler = - (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + - (addr_t)__gCommPageAddress); - addr_t signal_handler_ret = signal_handler + 45; -#endif - pint_t pc = static_cast(this->getReg(UNW_REG_IP)); - if (pc == signal_handler_ret) { -_info = {}; -_info.start_ip = signal_handler; -_info.end_ip = signal_handler_ret; -_isSigReturn = true; -return true; - } - return false; -} - -template -int UnwindCursor::stepThroughSigReturn() { - _isSignalFrame = true; - pint_t sp = _registers.getSP(); -#if defined(_LIBUNWIND_TARGET_X86_64) - vregs *regs = (vregs *)(sp + 0x70); - - _registers.setRegister(UNW_REG_IP, regs->rip); - _registers.setRegister(UNW_REG_SP, regs->rsp); - _registers.setRegister(UNW_X86_64_RAX, regs->rax); - _registers.setRegister(UNW_X86_64_RDX, regs->rdx); - _registers.setRegister(UNW_X86_64_RCX, regs->rcx); - _registers.setRegister(UNW_X86_64_RBX, regs->rbx); - _registers.setRegister(UNW_X86_64_RSI, regs->rsi); - _registers.setRegister(UNW_X86_64_RDI, regs->rdi); - _registers.set
[libunwind] Fix signal frame unwinding (PR #135367)
https://github.com/trungnt2910 updated https://github.com/llvm/llvm-project/pull/135367 >From dd2b01926ad901836465c1aaf1bf142688cbb768 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Fri, 11 Apr 2025 23:49:36 +1000 Subject: [PATCH] Fix signal frame unwinding The current unwinding implementation on Haiku is messy and broken. 1. It searches weird paths for private headers, which is breaking builds in consuming projects, such as dotnet/runtime. 2. It does not even work, due to relying on incorrect private offsets. This commit strips all references to private headers and ports a working signal frame implementation. It has been tested against `tests/signal_unwind.pass.cpp` and can go pass the signal frame. --- libunwind/src/CMakeLists.txt | 16 --- libunwind/src/UnwindCursor.hpp | 227 - 2 files changed, 167 insertions(+), 76 deletions(-) diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt index d69013e5dace1..70bd3a017cda7 100644 --- a/libunwind/src/CMakeLists.txt +++ b/libunwind/src/CMakeLists.txt @@ -118,22 +118,6 @@ if (HAIKU) add_compile_flags("-D_DEFAULT_SOURCE") add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME") - - find_path(LIBUNWIND_HAIKU_PRIVATE_HEADERS -"commpage_defs.h" -PATHS ${CMAKE_SYSTEM_INCLUDE_PATH} -PATH_SUFFIXES "/private/system" -NO_DEFAULT_PATH -REQUIRED) - - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}") - if (LIBUNWIND_TARGET_TRIPLE) -if (${LIBUNWIND_TARGET_TRIPLE} MATCHES "^x86_64") - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/x86_64") -endif() - else() -include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/${CMAKE_SYSTEM_PROCESSOR}") - endif() endif () string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}") diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index ca9927edc9990..1c545978673b4 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -41,6 +41,14 @@ #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 #endif +#if defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) +#include +#include +#include +#include +#define _LIBUNWIND_CHECK_HAIKU_SIGRETURN 1 +#endif + #include "AddressSpace.hpp" #include "CompactUnwinder.hpp" #include "config.h" @@ -1015,7 +1023,7 @@ class UnwindCursor : public AbstractUnwindCursor{ template int stepThroughSigReturn(Registers &) { return UNW_STEP_END; } -#elif defined(_LIBUNWIND_TARGET_HAIKU) +#elif defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) bool setInfoForSigReturn(); int stepThroughSigReturn(); #endif @@ -2559,7 +2567,7 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, template void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) _isSigReturn = false; #endif @@ -2684,7 +2692,7 @@ void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) if (setInfoForSigReturn()) return; #endif @@ -2760,63 +2768,6 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { _isSignalFrame = true; return UNW_STEP_SUCCESS; } - -#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) -#include -#include - -extern "C" { -extern void *__gCommPageAddress; -} - -template -bool UnwindCursor::setInfoForSigReturn() { -#if defined(_LIBUNWIND_TARGET_X86_64) - addr_t signal_handler = - (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + - (addr_t)__gCommPageAddress); - addr_t signal_handler_ret = signal_handler + 45; -#endif - pint_t pc = static_cast(this->getReg(UNW_REG_IP)); - if (pc == signal_handler_ret) { -_info = {}; -_info.start_ip = signal_handler; -_info.end_ip = signal_handler_ret; -_isSigReturn = true; -return true; - } - return false; -} - -template -int UnwindCursor::stepThroughSigReturn() { - _isSignalFrame = true; - pint_t sp = _registers.getSP(); -#if defined(_LIBUNWIND_TARGET_X86_64) - vregs *regs = (vregs *)(sp + 0x70); - - _registers.setRegister(UNW_REG_IP, regs->rip); - _registers.setRegister(UNW_REG_SP, regs->rsp); - _registers.setRegister(UNW_X86_64_RAX, regs->rax); - _registers.setRegister(UNW_X86_64_RDX, regs->rdx); - _registers.setRegister(UNW_X86_64_RCX, regs->rcx); - _registers.setRegister(UNW_X86_64_RBX, regs->rbx); - _registers.setRegister(UNW_X86_64_RSI, regs->rsi); - _registers.setRegister(UNW_X86_64_RDI, regs->rdi); - _registers.setRegister(UNW_X86_64_RBP, regs->rbp); - _regist
[libunwind] Fix signal frame unwinding (PR #135367)
https://github.com/trungnt2910 updated https://github.com/llvm/llvm-project/pull/135367 >From 06e16ff58a908d6fd47a264f95f4b53eb6ad51a5 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Fri, 11 Apr 2025 23:50:16 +1000 Subject: [PATCH] Fix signal frame unwinding The current unwinding implementation on Haiku is messy and broken. 1. It searches weird paths for private headers, which is breaking builds in consuming projects, such as dotnet/runtime. 2. It does not even work, due to relying on incorrect private offsets. This commit strips all references to private headers and ports a working signal frame implementation. It has been tested against `tests/signal_unwind.pass.cpp` and can go pass the signal frame. --- libunwind/src/CMakeLists.txt | 16 --- libunwind/src/UnwindCursor.hpp | 227 - 2 files changed, 167 insertions(+), 76 deletions(-) diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt index d69013e5dace1..70bd3a017cda7 100644 --- a/libunwind/src/CMakeLists.txt +++ b/libunwind/src/CMakeLists.txt @@ -118,22 +118,6 @@ if (HAIKU) add_compile_flags("-D_DEFAULT_SOURCE") add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME") - - find_path(LIBUNWIND_HAIKU_PRIVATE_HEADERS -"commpage_defs.h" -PATHS ${CMAKE_SYSTEM_INCLUDE_PATH} -PATH_SUFFIXES "/private/system" -NO_DEFAULT_PATH -REQUIRED) - - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}") - if (LIBUNWIND_TARGET_TRIPLE) -if (${LIBUNWIND_TARGET_TRIPLE} MATCHES "^x86_64") - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/x86_64") -endif() - else() -include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/${CMAKE_SYSTEM_PROCESSOR}") - endif() endif () string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}") diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index ca9927edc9990..1c545978673b4 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -41,6 +41,14 @@ #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 #endif +#if defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) +#include +#include +#include +#include +#define _LIBUNWIND_CHECK_HAIKU_SIGRETURN 1 +#endif + #include "AddressSpace.hpp" #include "CompactUnwinder.hpp" #include "config.h" @@ -1015,7 +1023,7 @@ class UnwindCursor : public AbstractUnwindCursor{ template int stepThroughSigReturn(Registers &) { return UNW_STEP_END; } -#elif defined(_LIBUNWIND_TARGET_HAIKU) +#elif defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) bool setInfoForSigReturn(); int stepThroughSigReturn(); #endif @@ -2559,7 +2567,7 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, template void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) _isSigReturn = false; #endif @@ -2684,7 +2692,7 @@ void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) if (setInfoForSigReturn()) return; #endif @@ -2760,63 +2768,6 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { _isSignalFrame = true; return UNW_STEP_SUCCESS; } - -#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) -#include -#include - -extern "C" { -extern void *__gCommPageAddress; -} - -template -bool UnwindCursor::setInfoForSigReturn() { -#if defined(_LIBUNWIND_TARGET_X86_64) - addr_t signal_handler = - (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + - (addr_t)__gCommPageAddress); - addr_t signal_handler_ret = signal_handler + 45; -#endif - pint_t pc = static_cast(this->getReg(UNW_REG_IP)); - if (pc == signal_handler_ret) { -_info = {}; -_info.start_ip = signal_handler; -_info.end_ip = signal_handler_ret; -_isSigReturn = true; -return true; - } - return false; -} - -template -int UnwindCursor::stepThroughSigReturn() { - _isSignalFrame = true; - pint_t sp = _registers.getSP(); -#if defined(_LIBUNWIND_TARGET_X86_64) - vregs *regs = (vregs *)(sp + 0x70); - - _registers.setRegister(UNW_REG_IP, regs->rip); - _registers.setRegister(UNW_REG_SP, regs->rsp); - _registers.setRegister(UNW_X86_64_RAX, regs->rax); - _registers.setRegister(UNW_X86_64_RDX, regs->rdx); - _registers.setRegister(UNW_X86_64_RCX, regs->rcx); - _registers.setRegister(UNW_X86_64_RBX, regs->rbx); - _registers.setRegister(UNW_X86_64_RSI, regs->rsi); - _registers.setRegister(UNW_X86_64_RDI, regs->rdi); - _registers.setRegister(UNW_X86_64_RBP, regs->rbp); - _regist
[libunwind] Fix signal frame unwinding (PR #135367)
https://github.com/trungnt2910 updated https://github.com/llvm/llvm-project/pull/135367 >From 116b60a6740831b1376377e33762faf53305f6c2 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Fri, 11 Apr 2025 23:53:14 +1000 Subject: [PATCH] Fix signal frame unwinding The current unwinding implementation on Haiku is messy and broken. 1. It searches weird paths for private headers, which is breaking builds in consuming projects, such as dotnet/runtime. 2. It does not even work, due to relying on incorrect private offsets. This commit strips all references to private headers and ports a working signal frame implementation. It has been tested against `tests/signal_unwind.pass.cpp` and can go pass the signal frame. --- libunwind/src/CMakeLists.txt | 16 --- libunwind/src/UnwindCursor.hpp | 227 - 2 files changed, 167 insertions(+), 76 deletions(-) diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt index d69013e5dace1..70bd3a017cda7 100644 --- a/libunwind/src/CMakeLists.txt +++ b/libunwind/src/CMakeLists.txt @@ -118,22 +118,6 @@ if (HAIKU) add_compile_flags("-D_DEFAULT_SOURCE") add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME") - - find_path(LIBUNWIND_HAIKU_PRIVATE_HEADERS -"commpage_defs.h" -PATHS ${CMAKE_SYSTEM_INCLUDE_PATH} -PATH_SUFFIXES "/private/system" -NO_DEFAULT_PATH -REQUIRED) - - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}") - if (LIBUNWIND_TARGET_TRIPLE) -if (${LIBUNWIND_TARGET_TRIPLE} MATCHES "^x86_64") - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/x86_64") -endif() - else() -include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/${CMAKE_SYSTEM_PROCESSOR}") - endif() endif () string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}") diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index ca9927edc9990..1c545978673b4 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -41,6 +41,14 @@ #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 #endif +#if defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) +#include +#include +#include +#include +#define _LIBUNWIND_CHECK_HAIKU_SIGRETURN 1 +#endif + #include "AddressSpace.hpp" #include "CompactUnwinder.hpp" #include "config.h" @@ -1015,7 +1023,7 @@ class UnwindCursor : public AbstractUnwindCursor{ template int stepThroughSigReturn(Registers &) { return UNW_STEP_END; } -#elif defined(_LIBUNWIND_TARGET_HAIKU) +#elif defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) bool setInfoForSigReturn(); int stepThroughSigReturn(); #endif @@ -2559,7 +2567,7 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, template void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) _isSigReturn = false; #endif @@ -2684,7 +2692,7 @@ void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) if (setInfoForSigReturn()) return; #endif @@ -2760,63 +2768,6 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { _isSignalFrame = true; return UNW_STEP_SUCCESS; } - -#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) -#include -#include - -extern "C" { -extern void *__gCommPageAddress; -} - -template -bool UnwindCursor::setInfoForSigReturn() { -#if defined(_LIBUNWIND_TARGET_X86_64) - addr_t signal_handler = - (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + - (addr_t)__gCommPageAddress); - addr_t signal_handler_ret = signal_handler + 45; -#endif - pint_t pc = static_cast(this->getReg(UNW_REG_IP)); - if (pc == signal_handler_ret) { -_info = {}; -_info.start_ip = signal_handler; -_info.end_ip = signal_handler_ret; -_isSigReturn = true; -return true; - } - return false; -} - -template -int UnwindCursor::stepThroughSigReturn() { - _isSignalFrame = true; - pint_t sp = _registers.getSP(); -#if defined(_LIBUNWIND_TARGET_X86_64) - vregs *regs = (vregs *)(sp + 0x70); - - _registers.setRegister(UNW_REG_IP, regs->rip); - _registers.setRegister(UNW_REG_SP, regs->rsp); - _registers.setRegister(UNW_X86_64_RAX, regs->rax); - _registers.setRegister(UNW_X86_64_RDX, regs->rdx); - _registers.setRegister(UNW_X86_64_RCX, regs->rcx); - _registers.setRegister(UNW_X86_64_RBX, regs->rbx); - _registers.setRegister(UNW_X86_64_RSI, regs->rsi); - _registers.setRegister(UNW_X86_64_RDI, regs->rdi); - _registers.setRegister(UNW_X86_64_RBP, regs->rbp); - _regist
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. +extern "C" status_t __attribute__((weak)) +_kern_read_kernel_image_symbols(image_id id, elf_sym *symbolTable, +int32 *_symbolCount, char *stringTable, +size_t *_stringTableSize, addr_t *_imageDelta); + +static addr_t signalHandlerBegin = 0; +static addr_t signalHandlerEnd = 0; + +template +bool UnwindCursor::setInfoForSigReturn() { + if (signalHandlerBegin == 0) { +// If we do not have the addresses yet, find them now. + +// Determine if the private function is there and usable. +if (_kern_read_kernel_image_symbols == nullptr) { + signalHandlerBegin = (addr_t)-1; + return false; +} + +// Get the system commpage and enumerate its symbols. +image_id commpageImage = -1; +image_info info; +int32 cookie = 0; +while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) { trungnt2910 wrote: `dl_iterate_phdr` iterates through _program headers_, which the `commpage` does not seem to have. See also: https://github.com/haiku/haiku/blob/a1e94e45fc773750e0d106532299bf6da8d0e513/src/libs/bsd/dl_iterate_phdr.c#L43-L47 https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
trungnt2910 wrote: Yes, tested on `x86_64` and only `x86_64` (though support for other archs can be added by as easy as defining a few offsets and registers). Requires Haiku `hrev58811` to fully work with `tests/signal_unwind.pass.cpp`. This is also the same implementation used in my debugger ports for Haiku. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Improve support (PR #115462)
=?utf-8?q?Jérôme?= Duval , =?utf-8?q?Jérôme?= Duval Message-ID: In-Reply-To: trungnt2910 wrote: This code has **not** been tested against `tests/signal_unwind.pass.cpp`, and this exact test has failed when tested against `libunwind` in LLVM 20 on Haiku. See #135367 for an alternative implementation that works, and as a bonus, does not rely on private headers. https://github.com/llvm/llvm-project/pull/115462 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind] Fix Haiku signal frame unwinding (PR #135367)
https://github.com/trungnt2910 updated https://github.com/llvm/llvm-project/pull/135367 >From bc84623d87b606ff2af239170bd19c14cb4e2876 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Fri, 11 Apr 2025 23:53:14 +1000 Subject: [PATCH] [libunwind][Haiku] Fix signal frame unwinding The current unwinding implementation on Haiku is messy and broken. 1. It searches weird paths for private headers, which is breaking builds in consuming projects, such as dotnet/runtime. 2. It does not even work, due to relying on incorrect private offsets. This commit strips all references to private headers and ports a working signal frame implementation. It has been tested against `tests/signal_unwind.pass.cpp` and can go pass the signal frame. --- libunwind/src/CMakeLists.txt | 16 --- libunwind/src/UnwindCursor.hpp | 227 - 2 files changed, 167 insertions(+), 76 deletions(-) diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt index d69013e5dace1..70bd3a017cda7 100644 --- a/libunwind/src/CMakeLists.txt +++ b/libunwind/src/CMakeLists.txt @@ -118,22 +118,6 @@ if (HAIKU) add_compile_flags("-D_DEFAULT_SOURCE") add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME") - - find_path(LIBUNWIND_HAIKU_PRIVATE_HEADERS -"commpage_defs.h" -PATHS ${CMAKE_SYSTEM_INCLUDE_PATH} -PATH_SUFFIXES "/private/system" -NO_DEFAULT_PATH -REQUIRED) - - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}") - if (LIBUNWIND_TARGET_TRIPLE) -if (${LIBUNWIND_TARGET_TRIPLE} MATCHES "^x86_64") - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/x86_64") -endif() - else() -include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/${CMAKE_SYSTEM_PROCESSOR}") - endif() endif () string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}") diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index ca9927edc9990..1c545978673b4 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -41,6 +41,14 @@ #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 #endif +#if defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) +#include +#include +#include +#include +#define _LIBUNWIND_CHECK_HAIKU_SIGRETURN 1 +#endif + #include "AddressSpace.hpp" #include "CompactUnwinder.hpp" #include "config.h" @@ -1015,7 +1023,7 @@ class UnwindCursor : public AbstractUnwindCursor{ template int stepThroughSigReturn(Registers &) { return UNW_STEP_END; } -#elif defined(_LIBUNWIND_TARGET_HAIKU) +#elif defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) bool setInfoForSigReturn(); int stepThroughSigReturn(); #endif @@ -2559,7 +2567,7 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, template void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) _isSigReturn = false; #endif @@ -2684,7 +2692,7 @@ void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) if (setInfoForSigReturn()) return; #endif @@ -2760,63 +2768,6 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { _isSignalFrame = true; return UNW_STEP_SUCCESS; } - -#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) -#include -#include - -extern "C" { -extern void *__gCommPageAddress; -} - -template -bool UnwindCursor::setInfoForSigReturn() { -#if defined(_LIBUNWIND_TARGET_X86_64) - addr_t signal_handler = - (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + - (addr_t)__gCommPageAddress); - addr_t signal_handler_ret = signal_handler + 45; -#endif - pint_t pc = static_cast(this->getReg(UNW_REG_IP)); - if (pc == signal_handler_ret) { -_info = {}; -_info.start_ip = signal_handler; -_info.end_ip = signal_handler_ret; -_isSigReturn = true; -return true; - } - return false; -} - -template -int UnwindCursor::stepThroughSigReturn() { - _isSignalFrame = true; - pint_t sp = _registers.getSP(); -#if defined(_LIBUNWIND_TARGET_X86_64) - vregs *regs = (vregs *)(sp + 0x70); - - _registers.setRegister(UNW_REG_IP, regs->rip); - _registers.setRegister(UNW_REG_SP, regs->rsp); - _registers.setRegister(UNW_X86_64_RAX, regs->rax); - _registers.setRegister(UNW_X86_64_RDX, regs->rdx); - _registers.setRegister(UNW_X86_64_RCX, regs->rcx); - _registers.setRegister(UNW_X86_64_RBX, regs->rbx); - _registers.setRegister(UNW_X86_64_RSI, regs->rsi); - _registers.setRegister(UNW_X86_64_RDI, regs->rdi); - _registers.setRegister(UNW_X86_64_RBP, reg
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
trungnt2910 wrote: > Does it build on r1beta5? Theoretically yes, since I did not require any new Haiku nightly feature for tge implementation. The unwinding might not fully work due to missing CFE information in `libroot`, in this case for `_kern_send_signal`. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
https://github.com/trungnt2910 edited https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
trungnt2910 wrote: Apologize for the confusing naming, somehow the tag prefixes were missing when I applied the [patch](https://github.com/trungnt2910/libunwind-haiku/commit/94b98e00309e659f29daa8a192bdf00021eec4fc) from my test repo to the LLVM monorepo. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. +extern "C" status_t __attribute__((weak)) +_kern_read_kernel_image_symbols(image_id id, elf_sym *symbolTable, +int32 *_symbolCount, char *stringTable, +size_t *_stringTableSize, addr_t *_imageDelta); + +static addr_t signalHandlerBegin = 0; +static addr_t signalHandlerEnd = 0; + +template +bool UnwindCursor::setInfoForSigReturn() { + if (signalHandlerBegin == 0) { +// If we do not have the addresses yet, find them now. + +// Determine if the private function is there and usable. +if (_kern_read_kernel_image_symbols == nullptr) { + signalHandlerBegin = (addr_t)-1; + return false; +} + +// Get the system commpage and enumerate its symbols. +image_id commpageImage = -1; +image_info info; +int32 cookie = 0; +while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) { trungnt2910 wrote: Same goes to including private headers because any of them can be changed anytime. And I'd say the probability of Haiku devs moving headers around is way higher than them implementing multiuser concerns. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. +extern "C" status_t __attribute__((weak)) +_kern_read_kernel_image_symbols(image_id id, elf_sym *symbolTable, +int32 *_symbolCount, char *stringTable, +size_t *_stringTableSize, addr_t *_imageDelta); + +static addr_t signalHandlerBegin = 0; +static addr_t signalHandlerEnd = 0; + +template +bool UnwindCursor::setInfoForSigReturn() { + if (signalHandlerBegin == 0) { +// If we do not have the addresses yet, find them now. + +// Determine if the private function is there and usable. +if (_kern_read_kernel_image_symbols == nullptr) { + signalHandlerBegin = (addr_t)-1; + return false; +} + +// Get the system commpage and enumerate its symbols. +image_id commpageImage = -1; +image_info info; +int32 cookie = 0; +while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) { trungnt2910 wrote: I don't think `libunwind` supports this feature for other OSes. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. +extern "C" status_t __attribute__((weak)) +_kern_read_kernel_image_symbols(image_id id, elf_sym *symbolTable, +int32 *_symbolCount, char *stringTable, +size_t *_stringTableSize, addr_t *_imageDelta); + +static addr_t signalHandlerBegin = 0; +static addr_t signalHandlerEnd = 0; + +template +bool UnwindCursor::setInfoForSigReturn() { + if (signalHandlerBegin == 0) { +// If we do not have the addresses yet, find them now. + +// Determine if the private function is there and usable. +if (_kern_read_kernel_image_symbols == nullptr) { + signalHandlerBegin = (addr_t)-1; + return false; +} + +// Get the system commpage and enumerate its symbols. +image_id commpageImage = -1; +image_info info; +int32 cookie = 0; +while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) { trungnt2910 wrote: >From what I understand for Linux, they don't provide any APIs, but instead a >stable _ABI_ where magic numbers can last long. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. +extern "C" status_t __attribute__((weak)) +_kern_read_kernel_image_symbols(image_id id, elf_sym *symbolTable, +int32 *_symbolCount, char *stringTable, +size_t *_stringTableSize, addr_t *_imageDelta); + +static addr_t signalHandlerBegin = 0; +static addr_t signalHandlerEnd = 0; + +template +bool UnwindCursor::setInfoForSigReturn() { + if (signalHandlerBegin == 0) { +// If we do not have the addresses yet, find them now. + +// Determine if the private function is there and usable. +if (_kern_read_kernel_image_symbols == nullptr) { + signalHandlerBegin = (addr_t)-1; + return false; +} + +// Get the system commpage and enumerate its symbols. +image_id commpageImage = -1; +image_info info; +int32 cookie = 0; +while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) { trungnt2910 wrote: An example, right here in `libunwind`: https://github.com/llvm/llvm-project/blob/1c5961c0481b9c7421d38e3141d3c5a1e6084234/libunwind/src/UnwindCursor.hpp#L2850-L2862 https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. +extern "C" status_t __attribute__((weak)) +_kern_read_kernel_image_symbols(image_id id, elf_sym *symbolTable, +int32 *_symbolCount, char *stringTable, +size_t *_stringTableSize, addr_t *_imageDelta); + +static addr_t signalHandlerBegin = 0; +static addr_t signalHandlerEnd = 0; + +template +bool UnwindCursor::setInfoForSigReturn() { + if (signalHandlerBegin == 0) { +// If we do not have the addresses yet, find them now. + +// Determine if the private function is there and usable. +if (_kern_read_kernel_image_symbols == nullptr) { + signalHandlerBegin = (addr_t)-1; + return false; +} + +// Get the system commpage and enumerate its symbols. +image_id commpageImage = -1; +image_info info; +int32 cookie = 0; +while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) { trungnt2910 wrote: Perhaps a `get_commpage_symbols`, or even better, `is_signal_handler_frame` and `get_signal_handler_frame_context` under `` since debuggers and tools like this usually want them. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
https://github.com/trungnt2910 edited https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. trungnt2910 wrote: > provide signal handler address and size in commpage entries. But `commpage` entries are private ABIs, aren't they? https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. trungnt2910 wrote: > If this is getting upstreamed we should really export this symbol not as a > syscall so we can avoid ABI breaks. Just like in the [GDB port](https://www.haiku-os.org/blog/trungnt2910/2024-07-28_gsoc_2024_debugging_progress_2/#private-syscalls), if the syscall disappears the function will silently fail, and other normal unwinding can still happen as usual. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. +extern "C" status_t __attribute__((weak)) +_kern_read_kernel_image_symbols(image_id id, elf_sym *symbolTable, +int32 *_symbolCount, char *stringTable, +size_t *_stringTableSize, addr_t *_imageDelta); + +static addr_t signalHandlerBegin = 0; +static addr_t signalHandlerEnd = 0; + +template +bool UnwindCursor::setInfoForSigReturn() { + if (signalHandlerBegin == 0) { +// If we do not have the addresses yet, find them now. + +// Determine if the private function is there and usable. +if (_kern_read_kernel_image_symbols == nullptr) { + signalHandlerBegin = (addr_t)-1; + return false; +} + +// Get the system commpage and enumerate its symbols. +image_id commpageImage = -1; +image_info info; +int32 cookie = 0; +while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) { trungnt2910 wrote: That'd require some kernel side changes, wouldn't that? https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
https://github.com/trungnt2910 updated https://github.com/llvm/llvm-project/pull/135367 >From 0ce9ca670b3b3d851f171b4a841a28ffa683108c Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Fri, 11 Apr 2025 23:53:14 +1000 Subject: [PATCH] [libunwind][Haiku] Fix signal frame unwinding The current unwinding implementation on Haiku is messy and broken. 1. It searches weird paths for private headers, which is breaking builds in consuming projects, such as dotnet/runtime. 2. It does not even work, due to relying on incorrect private offsets. This commit strips all references to private headers and ports a working signal frame implementation. It has been tested against `tests/signal_unwind.pass.cpp` and can go pass the signal frame. --- libunwind/src/CMakeLists.txt | 16 libunwind/src/UnwindCursor.hpp | 154 - 2 files changed, 94 insertions(+), 76 deletions(-) diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt index d69013e5dace1..70bd3a017cda7 100644 --- a/libunwind/src/CMakeLists.txt +++ b/libunwind/src/CMakeLists.txt @@ -118,22 +118,6 @@ if (HAIKU) add_compile_flags("-D_DEFAULT_SOURCE") add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME") - - find_path(LIBUNWIND_HAIKU_PRIVATE_HEADERS -"commpage_defs.h" -PATHS ${CMAKE_SYSTEM_INCLUDE_PATH} -PATH_SUFFIXES "/private/system" -NO_DEFAULT_PATH -REQUIRED) - - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}") - if (LIBUNWIND_TARGET_TRIPLE) -if (${LIBUNWIND_TARGET_TRIPLE} MATCHES "^x86_64") - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/x86_64") -endif() - else() -include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/${CMAKE_SYSTEM_PROCESSOR}") - endif() endif () string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}") diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index ca9927edc9990..27737a0ad1b67 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -41,6 +41,11 @@ #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 #endif +#if defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) +#include +#define _LIBUNWIND_CHECK_HAIKU_SIGRETURN 1 +#endif + #include "AddressSpace.hpp" #include "CompactUnwinder.hpp" #include "config.h" @@ -1015,7 +1020,7 @@ class UnwindCursor : public AbstractUnwindCursor{ template int stepThroughSigReturn(Registers &) { return UNW_STEP_END; } -#elif defined(_LIBUNWIND_TARGET_HAIKU) +#elif defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) bool setInfoForSigReturn(); int stepThroughSigReturn(); #endif @@ -2559,7 +2564,7 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, template void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) _isSigReturn = false; #endif @@ -2684,7 +2689,7 @@ void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) if (setInfoForSigReturn()) return; #endif @@ -2760,63 +2765,6 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { _isSignalFrame = true; return UNW_STEP_SUCCESS; } - -#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) -#include -#include - -extern "C" { -extern void *__gCommPageAddress; -} - -template -bool UnwindCursor::setInfoForSigReturn() { -#if defined(_LIBUNWIND_TARGET_X86_64) - addr_t signal_handler = - (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + - (addr_t)__gCommPageAddress); - addr_t signal_handler_ret = signal_handler + 45; -#endif - pint_t pc = static_cast(this->getReg(UNW_REG_IP)); - if (pc == signal_handler_ret) { -_info = {}; -_info.start_ip = signal_handler; -_info.end_ip = signal_handler_ret; -_isSigReturn = true; -return true; - } - return false; -} - -template -int UnwindCursor::stepThroughSigReturn() { - _isSignalFrame = true; - pint_t sp = _registers.getSP(); -#if defined(_LIBUNWIND_TARGET_X86_64) - vregs *regs = (vregs *)(sp + 0x70); - - _registers.setRegister(UNW_REG_IP, regs->rip); - _registers.setRegister(UNW_REG_SP, regs->rsp); - _registers.setRegister(UNW_X86_64_RAX, regs->rax); - _registers.setRegister(UNW_X86_64_RDX, regs->rdx); - _registers.setRegister(UNW_X86_64_RCX, regs->rcx); - _registers.setRegister(UNW_X86_64_RBX, regs->rbx); - _registers.setRegister(UNW_X86_64_RSI, regs->rsi); - _registers.setRegister(UNW_X86_64_RDI, regs->rdi); - _registers.setRegister(UNW_X86_64_RBP, regs->rbp); - _registers.setRegiste
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. +extern "C" status_t __attribute__((weak)) +_kern_read_kernel_image_symbols(image_id id, elf_sym *symbolTable, +int32 *_symbolCount, char *stringTable, +size_t *_stringTableSize, addr_t *_imageDelta); + +static addr_t signalHandlerBegin = 0; +static addr_t signalHandlerEnd = 0; + +template +bool UnwindCursor::setInfoForSigReturn() { + if (signalHandlerBegin == 0) { +// If we do not have the addresses yet, find them now. + +// Determine if the private function is there and usable. +if (_kern_read_kernel_image_symbols == nullptr) { + signalHandlerBegin = (addr_t)-1; + return false; +} + +// Get the system commpage and enumerate its symbols. +image_id commpageImage = -1; +image_info info; +int32 cookie = 0; +while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) { trungnt2910 wrote: The responsibility of kernel image enumeration has been moved to Haiku's own `libroot.so`. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2983,162 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) + +#if defined(B_HAIKU_32_BIT) +typedef Elf32_Sym elf_sym; +#define ELF_ST_TYPE ELF32_ST_TYPE +#elif defined(B_HAIKU_64_BIT) +typedef Elf64_Sym elf_sym; +#define ELF_ST_TYPE ELF64_ST_TYPE +#endif + +// Private syscall declared as a weak symbol to prevent ABI breaks. trungnt2910 wrote: Updated to use the new capabilities of `dladdr` in favor of the private syscall. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
trungnt2910 wrote: Submitted a new implementation that uses Haiku's recent [special handling](https://github.com/haiku/haiku/commit/1e1ad7efc96f94447815373be60fc1cc74962c65) of the `commpage` in `dladdr` to detect the signal handler function. This removes the need for both private headers and re-declarations of private symbols. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
@@ -3032,6 +2980,93 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) +static size_t signalHandlerSize = 0; + +template +bool UnwindCursor::setInfoForSigReturn() { + Dl_info dlinfo; + auto isSignalHandler = [&](pint_t addr) { +if (!dladdr(reinterpret_cast(addr), &dlinfo)) + return false; +if (strcmp(dlinfo.dli_fname, "commpage")) + return false; +if (dlinfo.dli_sname == NULL || +strcmp(dlinfo.dli_sname, "commpage_signal_handler")) + return false; +return true; + }; + + pint_t pc = static_cast(this->getReg(UNW_REG_IP)); + if (!isSignalHandler(pc)) +return false; + + pint_t start = reinterpret_cast(dlinfo.dli_saddr); + + if (signalHandlerSize == 0) { +size_t boundLow = 0; +size_t boundHigh = static_cast(-1); trungnt2910 wrote: Done. https://github.com/llvm/llvm-project/pull/135367 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Fix signal frame unwinding (PR #135367)
https://github.com/trungnt2910 updated https://github.com/llvm/llvm-project/pull/135367 >From 464d992011ad3191f67c1308741e3a5c66c96237 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Fri, 11 Apr 2025 23:53:14 +1000 Subject: [PATCH] [libunwind][Haiku] Fix signal frame unwinding The current unwinding implementation on Haiku is messy and broken. 1. It searches weird paths for private headers, which is breaking builds in consuming projects, such as dotnet/runtime. 2. It does not even work, due to relying on incorrect private offsets. This commit strips all references to private headers and ports a working signal frame implementation. It has been tested against `tests/signal_unwind.pass.cpp` and can go pass the signal frame. --- libunwind/src/CMakeLists.txt | 16 libunwind/src/UnwindCursor.hpp | 159 - 2 files changed, 99 insertions(+), 76 deletions(-) diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt index d69013e5dace1..70bd3a017cda7 100644 --- a/libunwind/src/CMakeLists.txt +++ b/libunwind/src/CMakeLists.txt @@ -118,22 +118,6 @@ if (HAIKU) add_compile_flags("-D_DEFAULT_SOURCE") add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME") - - find_path(LIBUNWIND_HAIKU_PRIVATE_HEADERS -"commpage_defs.h" -PATHS ${CMAKE_SYSTEM_INCLUDE_PATH} -PATH_SUFFIXES "/private/system" -NO_DEFAULT_PATH -REQUIRED) - - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}") - if (LIBUNWIND_TARGET_TRIPLE) -if (${LIBUNWIND_TARGET_TRIPLE} MATCHES "^x86_64") - include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/x86_64") -endif() - else() -include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/${CMAKE_SYSTEM_PROCESSOR}") - endif() endif () string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}") diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index ca9927edc9990..e70cf3b0ab38c 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -41,6 +41,12 @@ #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 #endif +#if defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) +#include +#include +#define _LIBUNWIND_CHECK_HAIKU_SIGRETURN 1 +#endif + #include "AddressSpace.hpp" #include "CompactUnwinder.hpp" #include "config.h" @@ -1015,7 +1021,7 @@ class UnwindCursor : public AbstractUnwindCursor{ template int stepThroughSigReturn(Registers &) { return UNW_STEP_END; } -#elif defined(_LIBUNWIND_TARGET_HAIKU) +#elif defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) bool setInfoForSigReturn(); int stepThroughSigReturn(); #endif @@ -2559,7 +2565,7 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, template void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) _isSigReturn = false; #endif @@ -2684,7 +2690,7 @@ void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ -defined(_LIBUNWIND_TARGET_HAIKU) +defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) if (setInfoForSigReturn()) return; #endif @@ -2760,63 +2766,6 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { _isSignalFrame = true; return UNW_STEP_SUCCESS; } - -#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) -#include -#include - -extern "C" { -extern void *__gCommPageAddress; -} - -template -bool UnwindCursor::setInfoForSigReturn() { -#if defined(_LIBUNWIND_TARGET_X86_64) - addr_t signal_handler = - (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + - (addr_t)__gCommPageAddress); - addr_t signal_handler_ret = signal_handler + 45; -#endif - pint_t pc = static_cast(this->getReg(UNW_REG_IP)); - if (pc == signal_handler_ret) { -_info = {}; -_info.start_ip = signal_handler; -_info.end_ip = signal_handler_ret; -_isSigReturn = true; -return true; - } - return false; -} - -template -int UnwindCursor::stepThroughSigReturn() { - _isSignalFrame = true; - pint_t sp = _registers.getSP(); -#if defined(_LIBUNWIND_TARGET_X86_64) - vregs *regs = (vregs *)(sp + 0x70); - - _registers.setRegister(UNW_REG_IP, regs->rip); - _registers.setRegister(UNW_REG_SP, regs->rsp); - _registers.setRegister(UNW_X86_64_RAX, regs->rax); - _registers.setRegister(UNW_X86_64_RDX, regs->rdx); - _registers.setRegister(UNW_X86_64_RCX, regs->rcx); - _registers.setRegister(UNW_X86_64_RBX, regs->rbx); - _registers.setRegister(UNW_X86_64_RSI, regs->rsi); - _registers.setRegister(UNW_X86_64_RDI, regs->rdi); - _registers.setRegister(UNW_X86_64_RBP, regs->rbp); - _registers