Author: jmolenda Date: Tue May 3 22:09:40 2016 New Revision: 268475 URL: http://llvm.org/viewvc/llvm-project?rev=268475&view=rev Log: Add a way for an ObjectFile to indicate that assembly emulation should not be used for this module -- for use when an ObjectFile knows that it does not have meaningful or accurate function start addresses.
More commonly, it is not clear that function start addresses are missing in a module. There are certain cases on Mac OS X where we can tell that a Mach-O binary has been stripped of this essential information, and the unwinder can end up emulating many megabytes of instructions for a single "function" in the binary. When a Mach-O binary is missing both an LC_FUNCTION_STARTS load command (very unusual) and an eh_frame section, then we will assume it has also been stripped of symbols and that instruction emulation will not be useful on this module. <rdar://problem/25988067> Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h lldb/trunk/include/lldb/Symbol/UnwindTable.h lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h lldb/trunk/source/Symbol/FuncUnwinders.cpp lldb/trunk/source/Symbol/UnwindTable.cpp Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=268475&r1=268474&r2=268475&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original) +++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Tue May 3 22:09:40 2016 @@ -551,6 +551,35 @@ public: GetUnwindTable () { return m_unwind_table; } //------------------------------------------------------------------ + /// Returns if the function bounds for symbols in this symbol file + /// are likely accurate. + /// + /// The unwinder can emulate the instructions of functions to understand + /// prologue/epilogue code sequences, where registers are spilled on + /// the stack, etc. This feature relies on having the correct start + /// addresses of all functions. If the ObjectFile has a way to tell + /// that symbols have been stripped and there's no way to reconstruct + /// start addresses (e.g. LC_FUNCTION_STARTS on Mach-O, or eh_frame + /// unwind info), the ObjectFile should indicate that assembly emulation + /// should not be used for this module. + /// + /// It is uncommon for this to return false. An ObjectFile needs to + /// be sure that symbol start addresses are unavailable before false + /// is returned. If it is unclear, this should return true. + /// + /// @return + /// Returns true if assembly emulation should be used for this + /// module. + /// Only returns false if the ObjectFile is sure that symbol + /// addresses are insufficient for accurate assembly emulation. + //------------------------------------------------------------------ + virtual bool + AllowAssemblyEmulationUnwindPlans () + { + return true; + } + + //------------------------------------------------------------------ /// Similar to Process::GetImageInfoAddress(). /// /// Some platforms embed auxiliary structures useful to debuggers in the Modified: lldb/trunk/include/lldb/Symbol/UnwindTable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/UnwindTable.h?rev=268475&r1=268474&r2=268475&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/UnwindTable.h (original) +++ lldb/trunk/include/lldb/Symbol/UnwindTable.h Tue May 3 22:09:40 2016 @@ -40,6 +40,9 @@ public: lldb::FuncUnwindersSP GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc); + bool + GetAllowAssemblyEmulationUnwindPlans (); + // Normally when we create a new FuncUnwinders object we track it in this UnwindTable so it can // be reused later. But for the target modules show-unwind we want to create brand new // UnwindPlans for the function of interest - so ignore any existing FuncUnwinders for that Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=268475&r1=268474&r2=268475&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Tue May 3 22:09:40 2016 @@ -1130,7 +1130,9 @@ ObjectFileMachO::ObjectFileMachO(const l m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(), - m_thread_context_offsets_valid(false) + m_thread_context_offsets_valid(false), + m_reexported_dylibs (), + m_allow_assembly_emulation_unwind_plans (true) { ::memset (&m_header, 0, sizeof(m_header)); ::memset (&m_dysymtab, 0, sizeof(m_dysymtab)); @@ -1145,7 +1147,9 @@ ObjectFileMachO::ObjectFileMachO (const m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(), - m_thread_context_offsets_valid(false) + m_thread_context_offsets_valid(false), + m_reexported_dylibs (), + m_allow_assembly_emulation_unwind_plans (true) { ::memset (&m_header, 0, sizeof(m_header)); ::memset (&m_dysymtab, 0, sizeof(m_dysymtab)); @@ -2603,6 +2607,18 @@ ObjectFileMachO::ParseSymtab () const size_t function_starts_count = function_starts.GetSize(); + if (function_starts_count == 0) + { + // No LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume the binary + // has been stripped. Don't allow assembly language instruction emulation because we don't + // know proper function start boundaries. + m_allow_assembly_emulation_unwind_plans = false; + Log *unwind_or_symbol_log (lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_UNWIND)); + + if (unwind_or_symbol_log) + module_sp->LogMessage(unwind_or_symbol_log, "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds"); + } + const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : static_cast<user_id_t>(NO_SECT); @@ -5624,6 +5640,12 @@ ObjectFileMachO::GetIsDynamicLinkEditor( return m_header.filetype == llvm::MachO::MH_DYLINKER; } +bool +ObjectFileMachO::AllowAssemblyEmulationUnwindPlans () +{ + return m_allow_assembly_emulation_unwind_plans; +} + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=268475&r1=268474&r2=268475&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original) +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Tue May 3 22:09:40 2016 @@ -176,6 +176,9 @@ public: lldb::offset_t *data_offset_ptr, llvm::MachO::mach_header &header); + bool + AllowAssemblyEmulationUnwindPlans () override; + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -247,6 +250,7 @@ protected: FileRangeArray m_thread_context_offsets; bool m_thread_context_offsets_valid; lldb_private::FileSpecList m_reexported_dylibs; + bool m_allow_assembly_emulation_unwind_plans; }; #endif // liblldb_ObjectFileMachO_h_ Modified: lldb/trunk/source/Symbol/FuncUnwinders.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/FuncUnwinders.cpp?rev=268475&r1=268474&r2=268475&view=diff ============================================================================== --- lldb/trunk/source/Symbol/FuncUnwinders.cpp (original) +++ lldb/trunk/source/Symbol/FuncUnwinders.cpp Tue May 3 22:09:40 2016 @@ -206,8 +206,12 @@ FuncUnwinders::GetEHFrameAugmentedUnwind UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan (Target &target, Thread &thread, int current_offset) { - if (m_unwind_plan_assembly_sp.get() || m_tried_unwind_plan_assembly) + if (m_unwind_plan_assembly_sp.get() + || m_tried_unwind_plan_assembly + || m_unwind_table.GetAllowAssemblyEmulationUnwindPlans () == false) + { return m_unwind_plan_assembly_sp; + } Mutex::Locker lock (m_mutex); m_tried_unwind_plan_assembly = true; Modified: lldb/trunk/source/Symbol/UnwindTable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/UnwindTable.cpp?rev=268475&r1=268474&r2=268475&view=diff ============================================================================== --- lldb/trunk/source/Symbol/UnwindTable.cpp (original) +++ lldb/trunk/source/Symbol/UnwindTable.cpp Tue May 3 22:09:40 2016 @@ -189,3 +189,9 @@ UnwindTable::GetArchitecture (lldb_priva { return m_object_file.GetArchitecture (arch); } + +bool +UnwindTable::GetAllowAssemblyEmulationUnwindPlans () +{ + return m_object_file.AllowAssemblyEmulationUnwindPlans (); +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits