[libcxx-commits] [PATCH] D148499: [RISC-V libunwind]:Fix RISC-V backtrace issue

Feng Wang via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri May 5 19:53:45 PDT 2023


wf520gg updated this revision to Diff 520023.
wf520gg added a comment.

Modify some comment and


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148499/new/

https://reviews.llvm.org/D148499

Files:
  libunwind/src/UnwindCursor.hpp


Index: libunwind/src/UnwindCursor.hpp
===================================================================
--- libunwind/src/UnwindCursor.hpp
+++ libunwind/src/UnwindCursor.hpp
@@ -31,7 +31,8 @@
 #endif
 
 #if defined(_LIBUNWIND_TARGET_LINUX) &&                                        \
-    (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_S390X))
+    (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_S390X) || \
+     defined(_LIBUNWIND_TARGET_RISCV))
 #include <sys/syscall.h>
 #include <sys/uio.h>
 #include <unistd.h>
@@ -994,6 +995,10 @@
 #if defined(_LIBUNWIND_TARGET_S390X)
   bool setInfoForSigReturn(Registers_s390x &);
   int stepThroughSigReturn(Registers_s390x &);
+#endif
+#if defined(_LIBUNWIND_TARGET_RISCV)
+  bool setInfoForSigReturn(Registers_riscv &);
+  int stepThroughSigReturn(Registers_riscv &);
 #endif
   template <typename Registers> bool setInfoForSigReturn(Registers &) {
     return false;
@@ -2824,6 +2829,64 @@
 #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
        // defined(_LIBUNWIND_TARGET_S390X)
 
+#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&                               \
+    defined(_LIBUNWIND_TARGET_RISCV)
+template <typename A, typename R>
+bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) {
+  const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
+  uint32_t instructions[2];
+  struct iovec local_iov = {&instructions, sizeof instructions};
+  struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof instructions};
+  long bytesRead =
+      syscall(SYS_process_vm_readv, getpid(), &local_iov, 1, &remote_iov, 1, 0);
+  // A signal frame will have a return address pointing to
+  // __vdso_rt_sigteturn. This code is hardwired as:
+  //
+  // 0x08b00893		li	a7,0x8b
+  // 0x00000073		ecall
+  if (bytesRead != sizeof instructions || instructions[0] != 0x08b00893 ||
+      instructions[1] != 0x00000073)
+    return false;
+
+  _info = {};
+  _info.start_ip = pc;
+  _info.end_ip = pc + 4;
+  _isSigReturn = true;
+  return true;
+}
+
+template <typename A, typename R>
+int UnwindCursor<A, R>::stepThroughSigReturn(Registers_riscv &) {
+  // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
+  //  - ucontext_t struct:
+  //     - 8-byte long (__uc_flags)
+  //     - 8-byte pointer (*uc_link)
+  //     - 24-byte uc_stack
+  //     - 8-byte uc_sigmask
+  //     - 120-byte of padding to allow sigset_t to be expanded in the future
+  //     - 8 bytes of padding because sigcontext has 16-byte alignment
+  //     - uc_mcontext
+  // [1] riscv-glibc/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h 
+  const pint_t kOffsetSpTomcontext = 8 + 8 + 24 + 8 + 128;
+
+  // Determine current SP.
+  const pint_t sp = static_cast<pint_t>(this->getReg(UNW_REG_SP));
+  // rt_sigframe contains the siginfo structure, the ucontext, and then
+  // the trampoline. We store the mcontext inside ucontext as sigctx.
+  // - 128-byte siginfo struct
+  pint_t sigctx = sp + 128 + kOffsetSpTomcontext;
+
+  for (int i = 0; i <= UNW_RISCV_X31; ++i) {
+    uint64_t value = _addressSpace.get64(sigctx + static_cast<pint_t>(i * 8));
+    _registers.setRegister(i, value);
+  }
+  _registers.setIP(_addressSpace.get64(sigctx));
+  _isSignalFrame = true;
+  return UNW_STEP_SUCCESS;
+}
+#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
+       // defined(_LIBUNWIND_TARGET_RISCV)
+
 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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D148499.520023.patch
Type: text/x-patch
Size: 3583 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20230506/7e88c4e8/attachment-0001.bin>


More information about the libcxx-commits mailing list