llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-libunwind Author: Ed Maste (emaste) <details> <summary>Changes</summary> As discussed in #<!-- -->86320; opening this PR for CI. It looks like (prior to this change) there are no C++26 jobs right now. --- Full diff: https://github.com/llvm/llvm-project/pull/86658.diff 3 Files Affected: - (modified) libcxx/utils/ci/buildkite-pipeline.yml (+1-1) - (modified) libunwind/include/__libunwind_config.h (+5) - (modified) libunwind/src/UnwindCursor.hpp (+79-6) ``````````diff diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml index 31e794e67d330d..c43e414418729a 100644 --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -207,7 +207,7 @@ steps: - group: ':freebsd: FreeBSD' steps: - label: FreeBSD 13 amd64 - command: libcxx/utils/ci/run-buildbot generic-cxx23 + command: libcxx/utils/ci/run-buildbot generic-cxx26 env: CC: clang17 CXX: clang++17 diff --git a/libunwind/include/__libunwind_config.h b/libunwind/include/__libunwind_config.h index 8db336b2d727ce..783a488d7de0fd 100644 --- a/libunwind/include/__libunwind_config.h +++ b/libunwind/include/__libunwind_config.h @@ -39,6 +39,9 @@ # if defined(__HAIKU__) # define _LIBUNWIND_TARGET_HAIKU 1 # endif +#if defined(__FreeBSD__) +#define _LIBUNWIND_TARGET_FREEBSD 1 +#endif # if defined(__i386__) # define _LIBUNWIND_TARGET_I386 # define _LIBUNWIND_CONTEXT_SIZE 8 @@ -73,6 +76,8 @@ # define _LIBUNWIND_CONTEXT_SIZE 66 # if defined(__SEH__) # define _LIBUNWIND_CURSOR_SIZE 164 +#elif defined(_LIBUNWIND_TARGET_FREEBSD) +#define _LIBUNWIND_CURSOR_SIZE 80 # else # define _LIBUNWIND_CURSOR_SIZE 78 # endif diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index 7753936a5894a3..96d82d6aac7c93 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -39,6 +39,17 @@ #include <sys/uio.h> #include <unistd.h> #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 +#define _LIBUNWIND_CHECK_SIGRETURN 1 +#endif + +#if defined(_LIBUNWIND_TARGET_FREEBSD) && defined(_LIBUNWIND_TARGET_AARCH64) +#include <machine/frame.h> +#include <sys/sysctl.h> +#include <sys/ucontext.h> +#include <sys/user.h> +#include <unistd.h> +#define _LIBUNWIND_CHECK_FREEBSD_SIGRETURN 1 +#define _LIBUNWIND_CHECK_SIGRETURN 1 #endif #include "AddressSpace.hpp" @@ -983,7 +994,7 @@ class UnwindCursor : public AbstractUnwindCursor{ } #endif -#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +#if defined(_LIBUNWIND_CHECK_SIGRETURN) bool setInfoForSigReturn() { R dummy; return setInfoForSigReturn(dummy); @@ -1011,7 +1022,7 @@ class UnwindCursor : public AbstractUnwindCursor{ template <typename Registers> int stepThroughSigReturn(Registers &) { return UNW_STEP_END; } -#endif +#endif // defined(_LIBUNWIND_CHECK_SIGRETURN) #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) bool getInfoFromFdeCie(const typename CFI_Parser<A>::FDE_Info &fdeInfo, @@ -1314,9 +1325,14 @@ class UnwindCursor : public AbstractUnwindCursor{ unw_proc_info_t _info; bool _unwindInfoMissing; bool _isSignalFrame; -#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +#if defined(_LIBUNWIND_CHECK_SIGRETURN) bool _isSigReturn = false; +#if defined(_LIBUNWIND_CHECK_FREEBSD_SIGRETURN) + bool _isSigTrampDetermined = false; + pint_t _sigTrampStart; + pint_t _sigTrampEnd; #endif +#endif // defined(_LIBUNWIND_CHECK_SIGRETURN) }; @@ -2558,7 +2574,7 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable, template <typename A, typename R> void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { -#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +#if defined(_LIBUNWIND_CHECK_SIGRETURN) _isSigReturn = false; #endif @@ -2673,7 +2689,7 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { } #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +#if defined(_LIBUNWIND_CHECK_SIGRETURN) if (setInfoForSigReturn()) return; #endif @@ -2909,6 +2925,63 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) +#if defined(_LIBUNWIND_CHECK_FREEBSD_SIGRETURN) && \ + defined(_LIBUNWIND_TARGET_AARCH64) +template <typename A, typename R> +bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) { + // Look for the sigreturn trampoline. + // + // https://cgit.freebsd.org/src/tree/sys/arm64/arm64/sigtramp.S + const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP)); + + if (_isSigTrampDetermined == false) { + struct kinfo_sigtramp kst = {0}; + size_t len = sizeof(kst); + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_SIGTRAMP, getpid()}; + if (sysctl(mib, 4, &kst, &len, NULL, 0) == 0) { + _isSigTrampDetermined = true; + _sigTrampStart = reinterpret_cast<pint_t>(kst.ksigtramp_start); + _sigTrampEnd = reinterpret_cast<pint_t>(kst.ksigtramp_end); + } + } + + if (_isSigTrampDetermined == false || + (pc < _sigTrampStart || pc >= _sigTrampEnd)) + return false; + + _info = {}; + _info.start_ip = _sigTrampStart; + _info.end_ip = _sigTrampEnd; + _isSigReturn = true; + return true; +} + +template <typename A, typename R> +int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) { + // In the signal trampoline frame, sp points to a sigframe + const pint_t kOffsetSpToSigcontext = + offsetof(struct sigframe, sf_uc) + offsetof(ucontext_t, uc_mcontext); + + // Offsets from mcontext_t to each register. + const pint_t kOffsetGprs = offsetof(struct gpregs, gp_x[0]); + const pint_t kOffsetSp = offsetof(struct gpregs, gp_sp); + const pint_t kOffsetPc = offsetof(struct gpregs, gp_lr); + + pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext; + + for (int i = 0; i <= 29; ++i) { + uint64_t value = + _addressSpace.get64(sigctx + kOffsetGprs + static_cast<pint_t>(i * 8)); + _registers.setRegister(UNW_AARCH64_X0 + i, value); + } + _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp)); + _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc)); + _isSignalFrame = true; + return UNW_STEP_SUCCESS; +} +#endif // defined(_LIBUNWIND_CHECK_FREEBSD_SIGRETURN) && + // defined(_LIBUNWIND_TARGET_AARCH64) + template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) { (void)stage2; // Bottom of stack is defined is when unwind info cannot be found. @@ -2917,7 +2990,7 @@ template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) { // Use unwinding info to modify register set as if function returned. int result; -#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +#if defined(_LIBUNWIND_CHECK_SIGRETURN) if (_isSigReturn) { result = this->stepThroughSigReturn(); } else `````````` </details> https://github.com/llvm/llvm-project/pull/86658 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits