Skip to content

[libc++] Switch FreeBSD to C++26 #86658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 28, 2024
Merged

[libc++] Switch FreeBSD to C++26 #86658

merged 1 commit into from
Mar 28, 2024

Conversation

emaste
Copy link
Member

@emaste emaste commented Mar 26, 2024

As discussed in #86320; opening this PR for CI.

It looks like (prior to this change) there are no C++26 jobs right now.

@emaste emaste requested review from a team as code owners March 26, 2024 12:37
@llvmbot llvmbot added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. libunwind labels Mar 26, 2024
@llvmbot
Copy link
Member

llvmbot commented Mar 26, 2024

@llvm/pr-subscribers-libcxx

@llvm/pr-subscribers-libunwind

Author: Ed Maste (emaste)

Changes

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 --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

@philnik777
Copy link
Contributor

The C++26 job is part of the first jobs that get run. Did you just miss it, or do you mean something else?

@@ -39,6 +39,9 @@
# if defined(__HAIKU__)
# define _LIBUNWIND_TARGET_HAIKU 1
# endif
#if defined(__FreeBSD__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these changes related?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, libunwind change was included by accident - I just let the CI jobs finish rather than restarting; I will update the pull req to fix.

@emaste
Copy link
Member Author

emaste commented Mar 26, 2024

The C++26 job is part of the first jobs that get run'

Oops, I did miss that. I think this would be the only buildkite job using generic-cxx26

@philnik777
Copy link
Contributor

Yes, it would be the only buildkite one (AFAIK). I don't think that would make much of a difference though.

Copy link
Contributor

@philnik777 philnik777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with the libunwind changes removed.

@emaste emaste changed the title [DRAFT][libc++] Switch FreeBSD to C++26 [libc++] Switch FreeBSD to C++26 Mar 26, 2024
Copy link
Member

@mordante mordante left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! LGTM! Please update the commit message before landing.

@emaste emaste removed the libunwind label Mar 28, 2024
@emaste emaste merged commit ffed554 into llvm:main Mar 28, 2024
@emaste emaste deleted the freebsd-cxx26 branch March 28, 2024 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants