[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
Mon Apr 17 18:04:47 PDT 2023


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

Fix clang-format issue


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,55 @@
 #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
+  // __default_sa_restorer. 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 &) {
+
+  const pint_t kOffsetSpToSigcontext = 176;
+
+  // 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.
+  pint_t sigctx = sp + sizeof(siginfo_t) + kOffsetSpToSigcontext;
+
+  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.setSP(_addressSpace.get64(sigctx + static_cast<pint_t>(2 * 8)));
+  _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.514488.patch
Type: text/x-patch
Size: 3150 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20230418/dd76c42d/attachment.bin>


More information about the libcxx-commits mailing list