summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Symbol/FuncUnwinders.h8
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp2
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp2
-rw-r--r--lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp14
-rw-r--r--lldb/source/Symbol/FuncUnwinders.cpp38
6 files changed, 61 insertions, 5 deletions
diff --git a/lldb/include/lldb/Symbol/FuncUnwinders.h b/lldb/include/lldb/Symbol/FuncUnwinders.h
index ca775496e52..10e4d56995b 100644
--- a/lldb/include/lldb/Symbol/FuncUnwinders.h
+++ b/lldb/include/lldb/Symbol/FuncUnwinders.h
@@ -55,6 +55,9 @@ public:
lldb::UnwindPlanSP
GetUnwindPlanArchitectureDefault (lldb_private::Thread& thread);
+ lldb::UnwindPlanSP
+ GetUnwindPlanArchitectureDefaultAtFunctionEntry (lldb_private::Thread& thread);
+
Address&
GetFirstNonPrologueInsn (Target& target);
@@ -78,11 +81,14 @@ private:
lldb::UnwindPlanSP m_unwind_plan_non_call_site_sp;
lldb::UnwindPlanSP m_unwind_plan_fast_sp;
lldb::UnwindPlanSP m_unwind_plan_arch_default_sp;
+ lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp;
bool m_tried_unwind_at_call_site:1,
m_tried_unwind_at_non_call_site:1,
m_tried_unwind_fast:1,
- m_tried_unwind_arch_default:1;
+ m_tried_unwind_arch_default:1,
+ m_tried_unwind_arch_default_at_func_entry:1;
+
Address m_first_non_prologue_insn;
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index 03fa88ed93a..6035b051559 100644
--- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -538,7 +538,7 @@ ABIMacOSX_arm::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
// All other registers are the same.
- unwind_plan.SetSourceName (pluginName);
+ unwind_plan.SetSourceName ("arm at-func-entry default");
return true;
}
diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index 57593c9f4af..b356d774d4d 100644
--- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -803,7 +803,7 @@ ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
row.SetCFAOffset (4);
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName (pluginName);
+ unwind_plan.SetSourceName ("i386 at-func-entry default");
return true;
}
diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
index 53437185bcf..f7f5c011828 100644
--- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -661,7 +661,7 @@ ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
row.SetCFAOffset (8);
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName (pluginName);
+ unwind_plan.SetSourceName ("x86_64 at-func-entry default");
return true;
}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 9759a66ec64..5a4e8b44d4a 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -552,7 +552,19 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
m_all_registers_available = true;
}
- // No Module for the current pc, try using the architecture default unwind.
+ // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer) so the pc is 0x0
+ // in the zeroth frame, we need to use the "unwind at first instruction" arch default UnwindPlan
+ if (behaves_like_zeroth_frame
+ && m_current_pc.IsValid()
+ && m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()) == 0)
+ {
+ unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
+ abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp);
+ m_frame_type = eNormalFrame;
+ return unwind_plan_sp;
+ }
+
+ // No Module fm_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()or the current pc, try using the architecture default unwind.
if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL || m_current_pc.GetModule()->GetObjectFile() == NULL)
{
m_frame_type = eNormalFrame;
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