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> 

llvm-svn: 268475
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 9bd930f..09fc922 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1130,7 +1130,9 @@
     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 @@
     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 @@
 
         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 @@
     return m_header.filetype == llvm::MachO::MH_DYLINKER;
 }
 
+bool
+ObjectFileMachO::AllowAssemblyEmulationUnwindPlans ()
+{
+    return m_allow_assembly_emulation_unwind_plans;
+}
+
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------