[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