diff options
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) { |

