aboutsummaryrefslogtreecommitdiffstats
path: root/source/Symbol/FuncUnwinders.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Symbol/FuncUnwinders.cpp')
-rw-r--r--source/Symbol/FuncUnwinders.cpp65
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();