diff --git a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp index a5547a4699ca9..d209980d65589 100644 --- a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp +++ b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp @@ -735,6 +735,8 @@ UnwindPlanSP ABISysV_riscv::CreateFunctionEntryUnwindPlan() { plan_sp->AppendRow(std::move(row)); plan_sp->SetSourceName("riscv function-entry unwind plan"); plan_sp->SetSourcedFromCompiler(eLazyBoolNo); + plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo); + return plan_sp; } @@ -761,6 +763,8 @@ UnwindPlanSP ABISysV_riscv::CreateDefaultUnwindPlan() { plan_sp->SetSourceName("riscv default unwind plan"); plan_sp->SetSourcedFromCompiler(eLazyBoolNo); plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo); + return plan_sp; } diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index da14da44f5939..1bcf97a9ff3d5 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -15,6 +15,7 @@ #endif #include "Plugins/Process/Utility/LinuxSignals.h" +#include "Plugins/Process/Utility/lldb-riscv-register-enums.h" #include "Utility/ARM64_DWARF_Registers.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" @@ -220,6 +221,7 @@ void PlatformLinux::CalculateTrapHandlerSymbolNames() { m_trap_handlers.push_back(ConstString("_sigtramp")); m_trap_handlers.push_back(ConstString("__kernel_rt_sigreturn")); m_trap_handlers.push_back(ConstString("__restore_rt")); + m_trap_handlers.push_back(ConstString("__vdso_rt_sigreturn")); } static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) { @@ -302,12 +304,56 @@ static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) { return unwind_plan_sp; } +static lldb::UnwindPlanSP GetRISCVTrapHandlerUnwindPlan(ConstString name) { + if (name != "__vdso_rt_sigreturn") + return UnwindPlanSP{}; + + UnwindPlan::Row row; + + // In the signal trampoline frame, sp points to an rt_sigframe[1], which is: + // - 128-byte siginfo struct + // - ucontext struct: + // - 8-byte long (uc_flags) + // - 8-byte pointer (*uc_link) + // - 24-byte struct (uc_stack) + // - 8-byte struct (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 + // - struct sigcontext uc_mcontext + // [1] + // https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c + + constexpr size_t siginfo_size = 128; + constexpr size_t uc_flags_size = 8; + constexpr size_t uc_link_ptr_size = 8; + constexpr size_t uc_stack_size = 24; + constexpr size_t uc_sigmask_size = 8; + constexpr size_t padding_size = 128; + + constexpr size_t offset = siginfo_size + uc_flags_size + uc_link_ptr_size + + uc_stack_size + uc_sigmask_size + padding_size; + + row.GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_riscv, offset); + for (uint32_t reg_num = 0; reg_num <= 31; ++reg_num) + row.SetRegisterLocationToAtCFAPlusOffset(reg_num, reg_num * 8, false); + + UnwindPlanSP unwind_plan_sp = std::make_shared(eRegisterKindLLDB); + unwind_plan_sp->AppendRow(std::move(row)); + unwind_plan_sp->SetSourceName("RISC-V Linux sigcontext"); + unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes); + unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes); + + return unwind_plan_sp; +} + lldb::UnwindPlanSP PlatformLinux::GetTrapHandlerUnwindPlan(const llvm::Triple &triple, ConstString name) { if (triple.isAArch64()) return GetAArch64TrapHandlerUnwindPlan(name); - + if (triple.isRISCV()) + return GetRISCVTrapHandlerUnwindPlan(name); return {}; }