[Lldb-commits] [lldb] r268475 - Add a way for an ObjectFile to indicate that assembly emulation

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Tue May 3 20:09:40 PDT 2016


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 ();
+}




More information about the lldb-commits mailing list