Skip to content

Commit 5c6e69f

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

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

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

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

0 commit comments

Comments
 (0)