|
31 | 31 | #endif
|
32 | 32 |
|
33 | 33 | #if defined(_LIBUNWIND_TARGET_LINUX) && \
|
34 |
| - (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_RISCV) || \ |
35 |
| - defined(_LIBUNWIND_TARGET_S390X)) |
| 34 | + (defined(_LIBUNWIND_TARGET_AARCH64) || \ |
| 35 | + defined(_LIBUNWIND_TARGET_LOONGARCH) || \ |
| 36 | + defined(_LIBUNWIND_TARGET_RISCV) || defined(_LIBUNWIND_TARGET_S390X)) |
36 | 37 | #include <errno.h>
|
37 | 38 | #include <signal.h>
|
38 | 39 | #include <sys/syscall.h>
|
@@ -996,6 +997,10 @@ class UnwindCursor : public AbstractUnwindCursor{
|
996 | 997 | bool setInfoForSigReturn(Registers_arm64 &);
|
997 | 998 | int stepThroughSigReturn(Registers_arm64 &);
|
998 | 999 | #endif
|
| 1000 | +#if defined(_LIBUNWIND_TARGET_LOONGARCH) |
| 1001 | + bool setInfoForSigReturn(Registers_loongarch &); |
| 1002 | + int stepThroughSigReturn(Registers_loongarch &); |
| 1003 | +#endif |
999 | 1004 | #if defined(_LIBUNWIND_TARGET_RISCV)
|
1000 | 1005 | bool setInfoForSigReturn(Registers_riscv &);
|
1001 | 1006 | int stepThroughSigReturn(Registers_riscv &);
|
@@ -2815,6 +2820,61 @@ int UnwindCursor<A, R>::stepThroughSigReturn() {
|
2815 | 2820 | #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
|
2816 | 2821 | // defined(_LIBUNWIND_TARGET_AARCH64)
|
2817 | 2822 |
|
| 2823 | +#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \ |
| 2824 | + defined(_LIBUNWIND_TARGET_LOONGARCH) |
| 2825 | +template <typename A, typename R> |
| 2826 | +bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_loongarch &) { |
| 2827 | + const pint_t pc = static_cast<pint_t>(getReg(UNW_REG_IP)); |
| 2828 | + // The PC might contain an invalid address if the unwind info is bad, so |
| 2829 | + // directly accessing it could cause a SIGSEGV. |
| 2830 | + if (!isReadableAddr(pc)) |
| 2831 | + return false; |
| 2832 | + const auto *instructions = reinterpret_cast<const uint32_t *>(pc); |
| 2833 | + // Look for the two instructions used in the sigreturn trampoline |
| 2834 | + // __vdso_rt_sigreturn: |
| 2835 | + // |
| 2836 | + // 0x03822c0b li a7,0x8b |
| 2837 | + // 0x002b0000 syscall 0 |
| 2838 | + if (instructions[0] != 0x03822c0b || instructions[1] != 0x002b0000) |
| 2839 | + return false; |
| 2840 | + |
| 2841 | + _info = {}; |
| 2842 | + _info.start_ip = pc; |
| 2843 | + _info.end_ip = pc + 4; |
| 2844 | + _isSigReturn = true; |
| 2845 | + return true; |
| 2846 | +} |
| 2847 | + |
| 2848 | +template <typename A, typename R> |
| 2849 | +int UnwindCursor<A, R>::stepThroughSigReturn(Registers_loongarch &) { |
| 2850 | + // In the signal trampoline frame, sp points to an rt_sigframe[1], which is: |
| 2851 | + // - 128-byte siginfo struct |
| 2852 | + // - ucontext_t struct: |
| 2853 | + // - 8-byte long (__uc_flags) |
| 2854 | + // - 8-byte pointer (*uc_link) |
| 2855 | + // - 24-byte uc_stack |
| 2856 | + // - 8-byte uc_sigmask |
| 2857 | + // - 120-byte of padding to allow sigset_t to be expanded in the future |
| 2858 | + // - 8 bytes of padding because sigcontext has 16-byte alignment |
| 2859 | + // - struct sigcontext uc_mcontext |
| 2860 | + // [1] |
| 2861 | + // https://github.com/torvalds/linux/blob/master/arch/loongarch/kernel/signal.c |
| 2862 | + const pint_t kOffsetSpToSigcontext = 128 + 8 + 8 + 24 + 8 + 128; |
| 2863 | + |
| 2864 | + const pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext; |
| 2865 | + _registers.setIP(_addressSpace.get64(sigctx)); |
| 2866 | + for (int i = UNW_LOONGARCH_R1; i <= UNW_LOONGARCH_R31; ++i) { |
| 2867 | + // skip R0 |
| 2868 | + uint64_t value = |
| 2869 | + _addressSpace.get64(sigctx + static_cast<pint_t>((i + 1) * 8)); |
| 2870 | + _registers.setRegister(i, value); |
| 2871 | + } |
| 2872 | + _isSignalFrame = true; |
| 2873 | + return UNW_STEP_SUCCESS; |
| 2874 | +} |
| 2875 | +#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && |
| 2876 | + // defined(_LIBUNWIND_TARGET_LOONGARCH) |
| 2877 | + |
2818 | 2878 | #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
|
2819 | 2879 | defined(_LIBUNWIND_TARGET_RISCV)
|
2820 | 2880 | template <typename A, typename R>
|
|
0 commit comments