Skip to content

Commit f234312

Browse files
committed
[lldb][RISCV] Implement trap handler unwind plan
1 parent 5821b09 commit f234312

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#endif
1616

1717
#include "Plugins/Process/Utility/LinuxSignals.h"
18+
#include "Plugins/Process/Utility/lldb-riscv-register-enums.h"
1819
#include "Utility/ARM64_DWARF_Registers.h"
1920
#include "lldb/Core/Debugger.h"
2021
#include "lldb/Core/PluginManager.h"
@@ -220,6 +221,7 @@ void PlatformLinux::CalculateTrapHandlerSymbolNames() {
220221
m_trap_handlers.push_back(ConstString("_sigtramp"));
221222
m_trap_handlers.push_back(ConstString("__kernel_rt_sigreturn"));
222223
m_trap_handlers.push_back(ConstString("__restore_rt"));
224+
m_trap_handlers.push_back(ConstString("__vdso_rt_sigreturn"));
223225
}
224226

225227
static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) {
@@ -302,12 +304,57 @@ static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) {
302304
return unwind_plan_sp;
303305
}
304306

307+
static lldb::UnwindPlanSP GetRISCVTrapHandlerUnwindPlan(ConstString name) {
308+
if (name != "__vdso_rt_sigreturn")
309+
return UnwindPlanSP{};
310+
311+
UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>();
312+
row->SetOffset(0);
313+
314+
// In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
315+
// - 128-byte siginfo struct
316+
// - ucontext struct:
317+
// - 8-byte long (uc_flags)
318+
// - 8-byte pointer (*uc_link)
319+
// - 24-byte struct (uc_stack)
320+
// - 8-byte struct (uc_sigmask)
321+
// - 120-byte of padding to allow sigset_t to be expanded in the future
322+
// - 8 bytes of padding because sigcontext has 16-byte alignment
323+
// - struct sigcontext uc_mcontext
324+
// [1]
325+
// https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c
326+
327+
constexpr size_t siginfo_size = 128;
328+
constexpr size_t uc_flags_size = 8;
329+
constexpr size_t uc_link_ptr_size = 8;
330+
constexpr size_t uc_stack_size = 24;
331+
constexpr size_t uc_sigmask_size = 8;
332+
constexpr size_t padding_size = 128;
333+
334+
constexpr size_t offset = siginfo_size + uc_flags_size + uc_link_ptr_size +
335+
uc_stack_size + uc_sigmask_size + padding_size;
336+
337+
row->GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_riscv, offset);
338+
for (uint32_t reg_num = 0; reg_num <= 31; ++reg_num)
339+
row->SetRegisterLocationToAtCFAPlusOffset(reg_num, reg_num * 8, false);
340+
341+
UnwindPlanSP unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindLLDB);
342+
unwind_plan_sp->AppendRow(row);
343+
unwind_plan_sp->SetSourceName("RISC-V Linux sigcontext");
344+
unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
345+
unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
346+
unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes);
347+
348+
return unwind_plan_sp;
349+
}
350+
305351
lldb::UnwindPlanSP
306352
PlatformLinux::GetTrapHandlerUnwindPlan(const llvm::Triple &triple,
307353
ConstString name) {
308354
if (triple.isAArch64())
309355
return GetAArch64TrapHandlerUnwindPlan(name);
310-
356+
if (triple.isRISCV())
357+
return GetRISCVTrapHandlerUnwindPlan(name);
311358
return {};
312359
}
313360

0 commit comments

Comments
 (0)