diff options
Diffstat (limited to 'source/Symbol/FuncUnwinders.cpp')
-rw-r--r-- | source/Symbol/FuncUnwinders.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/source/Symbol/FuncUnwinders.cpp b/source/Symbol/FuncUnwinders.cpp index 09cb9b00aaf3..f609bf7821e1 100644 --- a/source/Symbol/FuncUnwinders.cpp +++ b/source/Symbol/FuncUnwinders.cpp @@ -10,6 +10,7 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" #include "lldb/Symbol/ArmUnwindInfo.h" +#include "lldb/Symbol/CallFrameInfo.h" #include "lldb/Symbol/CompactUnwindInfo.h" #include "lldb/Symbol/DWARFCallFrameInfo.h" #include "lldb/Symbol/ObjectFile.h" @@ -58,6 +59,8 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target, Thread &thread) { std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (UnwindPlanSP plan_sp = GetObjectFileUnwindPlan(target)) + return plan_sp; if (UnwindPlanSP plan_sp = GetSymbolFileUnwindPlan(thread)) return plan_sp; if (UnwindPlanSP plan_sp = GetDebugFrameUnwindPlan(target)) @@ -97,6 +100,26 @@ UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) { return UnwindPlanSP(); } +lldb::UnwindPlanSP FuncUnwinders::GetObjectFileUnwindPlan(Target &target) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (m_unwind_plan_object_file_sp.get() || + m_tried_unwind_plan_object_file) + return m_unwind_plan_object_file_sp; + + m_tried_unwind_plan_object_file = true; + if (m_range.GetBaseAddress().IsValid()) { + CallFrameInfo *object_file_frame = m_unwind_table.GetObjectFileUnwindInfo(); + if (object_file_frame) { + m_unwind_plan_object_file_sp = + std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); + if (!object_file_frame->GetUnwindPlan(m_range, + *m_unwind_plan_object_file_sp)) + m_unwind_plan_object_file_sp.reset(); + } + } + return m_unwind_plan_object_file_sp; +} + UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame) @@ -185,6 +208,38 @@ UnwindPlanSP FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) { return m_unwind_plan_symbol_file_sp; } +UnwindPlanSP +FuncUnwinders::GetObjectFileAugmentedUnwindPlan(Target &target, + Thread &thread) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (m_unwind_plan_object_file_augmented_sp.get() || + m_tried_unwind_plan_object_file_augmented) + return m_unwind_plan_object_file_augmented_sp; + + m_tried_unwind_plan_object_file_augmented = true; + + UnwindPlanSP object_file_unwind_plan = GetObjectFileUnwindPlan(target); + if (!object_file_unwind_plan) + return m_unwind_plan_object_file_augmented_sp; + + m_unwind_plan_object_file_augmented_sp = + std::make_shared<UnwindPlan>(*object_file_unwind_plan); + + // Augment the instructions with epilogue descriptions if necessary + // so the UnwindPlan can be used at any instruction in the function. + + UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target)); + if (assembly_profiler_sp) { + if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite( + m_range, thread, *m_unwind_plan_object_file_augmented_sp)) { + m_unwind_plan_object_file_augmented_sp.reset(); + } + } else { + m_unwind_plan_object_file_augmented_sp.reset(); + } + return m_unwind_plan_object_file_augmented_sp; +} + UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target, Thread &thread) { std::lock_guard<std::recursive_mutex> guard(m_mutex); @@ -328,6 +383,8 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target, UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan(target); if (!eh_frame_sp) eh_frame_sp = GetDebugFrameUnwindPlan(target); + if (!eh_frame_sp) + eh_frame_sp = GetObjectFileUnwindPlan(target); UnwindPlanSP arch_default_at_entry_sp = GetUnwindPlanArchitectureDefaultAtFunctionEntry(thread); UnwindPlanSP arch_default_sp = GetUnwindPlanArchitectureDefault(thread); @@ -366,6 +423,8 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target, return plan_sp; if (UnwindPlanSP plan_sp = GetEHFrameAugmentedUnwindPlan(target, thread)) return plan_sp; + if (UnwindPlanSP plan_sp = GetObjectFileAugmentedUnwindPlan(target, thread)) + return plan_sp; return assembly_sp; } @@ -473,6 +532,9 @@ Address FuncUnwinders::GetLSDAAddress(Target &target) { if (unwind_plan_sp.get() == nullptr) { unwind_plan_sp = GetCompactUnwindUnwindPlan(target); } + if (unwind_plan_sp.get() == nullptr) { + unwind_plan_sp = GetObjectFileUnwindPlan(target); + } if (unwind_plan_sp.get() && unwind_plan_sp->GetLSDAAddress().IsValid()) { lsda_addr = unwind_plan_sp->GetLSDAAddress(); } @@ -486,6 +548,9 @@ Address FuncUnwinders::GetPersonalityRoutinePtrAddress(Target &target) { if (unwind_plan_sp.get() == nullptr) { unwind_plan_sp = GetCompactUnwindUnwindPlan(target); } + if (unwind_plan_sp.get() == nullptr) { + unwind_plan_sp = GetObjectFileUnwindPlan(target); + } if (unwind_plan_sp.get() && unwind_plan_sp->GetPersonalityFunctionPtr().IsValid()) { personality_addr = unwind_plan_sp->GetPersonalityFunctionPtr(); |