summaryrefslogtreecommitdiffstats
path: root/lldb/source/Symbol/FuncUnwinders.cpp
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2011-09-15 00:44:34 +0000
committerJason Molenda <jmolenda@apple.com>2011-09-15 00:44:34 +0000
commit995cd3a51407c47c386d80ba6c62760ea878e533 (patch)
treeb70e968238170612c8969d26b9ce2ef55a5d579b /lldb/source/Symbol/FuncUnwinders.cpp
parente1dadb831a2ba3d68a576611670704c9bd1c2bc8 (diff)
downloadbcm5719-llvm-995cd3a51407c47c386d80ba6c62760ea878e533.tar.gz
bcm5719-llvm-995cd3a51407c47c386d80ba6c62760ea878e533.zip
Have the FuncUnwinder object request & provide an architecture-defined
UnwindPlan for unwinding from the first instruction of an otherwise unknown function call (GetUnwindPlanArchitectureDefaultAtFunctionEntry()). Update RegisterContextLLDB::GetFullUnwindPlanForFrame() to detect the case of a frame 0 at address 0x0 which indicates that we jumped through a NULL function pointer. Use the ABI's FunctionEntryUnwindPlan to find the caller frame. These changes make it so lldb can identify the calling frame correctly in code like int main () { void (*f)(void) = 0; f(); } llvm-svn: 139760
Diffstat (limited to 'lldb/source/Symbol/FuncUnwinders.cpp')
-rw-r--r--lldb/source/Symbol/FuncUnwinders.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/lldb/source/Symbol/FuncUnwinders.cpp b/lldb/source/Symbol/FuncUnwinders.cpp
index 12f77942d70..e01f0b7b6c3 100644
--- a/lldb/source/Symbol/FuncUnwinders.cpp
+++ b/lldb/source/Symbol/FuncUnwinders.cpp
@@ -42,6 +42,7 @@ FuncUnwinders::FuncUnwinders
m_tried_unwind_at_non_call_site (false),
m_tried_unwind_fast (false),
m_tried_unwind_arch_default (false),
+ m_tried_unwind_arch_default_at_func_entry (false),
m_first_non_prologue_insn()
{
}
@@ -181,6 +182,43 @@ FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread)
return m_unwind_plan_arch_default_sp;
}
+UnwindPlanSP
+FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry (Thread& thread)
+{
+ // Lock the mutex to ensure we can always give out the most appropriate
+ // information. We want to make sure if someone requests an unwind
+ // plan, that they get one and don't run into a race condition where one
+ // thread has started to create the unwind plan and has put it into
+ // the auto_ptr member variable, and have another thread enter this function
+ // and return the partially filled pointer contained in the auto_ptr.
+ // We also want to make sure that we lock out other unwind plans from
+ // being accessed until this one is done creating itself in case someone
+ // had some code like:
+ // UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
+ // if (best_unwind_plan == NULL)
+ // best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
+ Mutex::Locker locker (m_mutex);
+ if (m_tried_unwind_arch_default_at_func_entry == false && m_unwind_plan_arch_default_at_func_entry_sp.get() == NULL)
+ {
+ m_tried_unwind_arch_default_at_func_entry = true;
+ Address current_pc;
+ Target *target = thread.CalculateTarget();
+ if (target)
+ {
+ ABI *abi = thread.GetProcess().GetABI().get();
+ if (abi)
+ {
+ m_unwind_plan_arch_default_at_func_entry_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
+ if (m_unwind_plan_arch_default_at_func_entry_sp)
+ abi->CreateFunctionEntryUnwindPlan(*m_unwind_plan_arch_default_at_func_entry_sp);
+ }
+ }
+ }
+
+ return m_unwind_plan_arch_default_sp;
+}
+
+
Address&
FuncUnwinders::GetFirstNonPrologueInsn (Target& target)
{
OpenPOWER on IntegriCloud