Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down
48 changes: 47 additions & 1 deletion lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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<UnwindPlan>(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 {};
}

Expand Down
Loading