sgraenitz updated this revision to Diff 166699.
sgraenitz added a comment.

Address Jonas' feedback #2


https://reviews.llvm.org/D52375

Files:
  include/lldb/Symbol/Symtab.h
  source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
  source/Symbol/Symtab.cpp

Index: source/Symbol/Symtab.cpp
===================================================================
--- source/Symbol/Symtab.cpp
+++ source/Symbol/Symtab.cpp
@@ -509,6 +509,16 @@
   return indexes.size() - prev_size;
 }
 
+bool Symtab::HasSymbolWithTypeAndFlags(lldb::SymbolType symbol_type,
+                                       uint32_t flags_value) const {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  for (const Symbol &symbol : m_symbols)
+    if (symbol.GetType() == symbol_type && symbol.GetFlags() == flags_value)
+      return true;
+
+  return false;
+}
+
 uint32_t Symtab::AppendSymbolIndexesWithType(SymbolType symbol_type,
                                              Debug symbol_debug_type,
                                              Visibility symbol_visibility,
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -131,7 +131,11 @@
   uint32_t GetPluginVersion() override;
 
 protected:
-  enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
+  enum {
+    kHaveInitializedOSOs = (1 << 0),
+    kHaveCheckedCUInfos = (1 << 1),
+    kNumFlags
+  };
 
   friend class DebugMapModule;
   friend struct DIERef;
@@ -172,13 +176,17 @@
           first_symbol_id(UINT32_MAX), last_symbol_id(UINT32_MAX),
           file_range_map(), file_range_map_valid(false) {}
 
+    bool Init(lldb_private::Symbol *so, lldb_private::Symbol *oso);
     const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
   };
 
   //------------------------------------------------------------------
   // Protected Member Functions
   //------------------------------------------------------------------
   void InitOSO();
+  bool HasCompileUnits();
+  void ReportErrorInitOSO(lldb_private::Symbol *so_symbol,
+                          lldb_private::Symbol *oso_symbol, uint32_t oso_idx);
 
   static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
     return (uint32_t)((uid >> 32ull) - 1ull);
@@ -247,6 +255,11 @@
 
   lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf);
 
+  lldb::CompUnitSP GetCompileUnitByIndex(SymbolFileDWARF *oso_dwarf,
+                                         uint32_t cu_idx);
+  lldb::CompUnitSP GetCompileUnitByOffset(SymbolFileDWARF *oso_dwarf,
+                                          dw_offset_t cu_offset);
+
   CompileUnitInfo *GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf);
 
   lldb::TypeSP
@@ -297,6 +310,8 @@
   // Member Variables
   //------------------------------------------------------------------
   std::bitset<kNumFlags> m_flags;
+  bool m_has_compile_unit_infos;
+  std::vector<lldb::offset_t> m_oso_compile_unit_offset;
   std::vector<CompileUnitInfo> m_compile_unit_infos;
   std::vector<uint32_t> m_func_indexes; // Sorted by address
   std::vector<uint32_t> m_glob_indexes;
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -37,6 +37,7 @@
 #include "lldb/Symbol/VariableList.h"
 #include "llvm/Support/ScopedPrinter.h"
 
+#include "DWARFCompileUnit.h"
 #include "LogChannelDWARF.h"
 #include "SymbolFileDWARF.h"
 
@@ -169,6 +170,23 @@
   return file_range_map;
 }
 
+bool SymbolFileDWARFDebugMap::CompileUnitInfo::Init(Symbol *so, Symbol *oso) {
+  if (!so || so->GetType() != eSymbolTypeSourceFile)
+    return false;
+
+  if (!oso || oso->GetType() != eSymbolTypeObjectFile)
+    return false;
+
+  if (so->GetSiblingIndex() == UINT32_MAX)
+    return false;
+
+  llvm::StringRef so_file_name = so->GetName().GetStringRef();
+  so_file.SetFile(so_file_name, false, FileSpec::Style::native);
+  oso_mod_time = llvm::sys::toTimePoint(oso->GetIntegerValue(0));
+  oso_path = oso->GetName();
+  return true;
+}
+
 class DebugMapModule : public Module {
 public:
   DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx,
@@ -251,61 +269,63 @@
 }
 
 SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile)
-    : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(),
-      m_glob_indexes(),
+    : SymbolFile(ofile), m_flags(), m_has_compile_unit_infos(false),
+      m_compile_unit_infos(), m_func_indexes(), m_glob_indexes(),
       m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
 
 SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
 
 void SymbolFileDWARFDebugMap::InitializeObject() {}
 
-void SymbolFileDWARFDebugMap::InitOSO() {
-  if (m_flags.test(kHaveInitializedOSOs))
-    return;
-
-  m_flags.set(kHaveInitializedOSOs);
-
-  // If the object file has been stripped, there is no sense in looking further
-  // as all of the debug symbols for the debug map will not be available
-  if (m_obj_file->IsStripped())
-    return;
-
-  // Also make sure the file type is some sort of executable. Core files, debug
-  // info files (dSYM), object files (.o files), and stub libraries all can
-  switch (m_obj_file->GetType()) {
+static bool IsExecutableType(ObjectFile::Type type) {
+  switch (type) {
   case ObjectFile::eTypeInvalid:
   case ObjectFile::eTypeCoreFile:
   case ObjectFile::eTypeDebugInfo:
   case ObjectFile::eTypeObjectFile:
   case ObjectFile::eTypeStubLibrary:
   case ObjectFile::eTypeUnknown:
   case ObjectFile::eTypeJIT:
-    return;
+    return false;
 
   case ObjectFile::eTypeExecutable:
   case ObjectFile::eTypeDynamicLinker:
   case ObjectFile::eTypeSharedLibrary:
-    break;
+    return true;
   }
+}
 
-  // In order to get the abilities of this plug-in, we look at the list of
-  // N_OSO entries (object files) from the symbol table and make sure that
-  // these files exist and also contain valid DWARF. If we get any of that then
-  // we return the abilities of the first N_OSO's DWARF.
+static uint32_t GetOSOSymbolFlags() {
+  // When a mach-o symbol is encoded, the n_type field is encoded in bits
+  // 23:16, and the n_desc field is encoded in bits 15:0.
+  //
+  // N_OSO object file symbols have a flags value as follows:
+  // bits 23:16 == 0x66 (N_OSO)
+  // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
+  return 0x660001u;
+}
+
+void SymbolFileDWARFDebugMap::InitOSO() {
+  if (m_flags.test(kHaveInitializedOSOs))
+    return;
+
+  m_flags.set(kHaveInitializedOSOs);
+
+  // If the object file has been stripped, there is no sense in looking further
+  // as all of the debug symbols for the debug map will not be available
+  if (m_obj_file->IsStripped())
+    return;
+
+  // Also make sure the file type is some sort of executable.
+  if (!IsExecutableType(m_obj_file->GetType()))
+    return;
 
   Symtab *symtab = m_obj_file->GetSymtab();
   if (symtab) {
     Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
 
     std::vector<uint32_t> oso_indexes;
-    // When a mach-o symbol is encoded, the n_type field is encoded in bits
-    // 23:16, and the n_desc field is encoded in bits 15:0.
-    //
-    // To find all N_OSO entries that are part of the DWARF + debug map we find
-    // only object file symbols with the flags value as follows: bits 23:16 ==
-    // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object
-    // file)
-    const uint32_t k_oso_symbol_flags_value = 0x660001u;
+    const uint32_t k_oso_symbol_flags_value = GetOSOSymbolFlags();
 
     const uint32_t oso_index_count =
         symtab->AppendSymbolIndexesWithTypeAndFlagsValue(
@@ -340,67 +360,97 @@
       }
       m_debug_map.Sort();
 
-      m_compile_unit_infos.resize(oso_index_count);
+      assert(m_compile_unit_infos.empty());
+      assert(m_oso_compile_unit_offset.empty());
 
       for (uint32_t i = 0; i < oso_index_count; ++i) {
         const uint32_t so_idx = oso_indexes[i] - 1;
         const uint32_t oso_idx = oso_indexes[i];
-        const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
-        const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
-        if (so_symbol && oso_symbol &&
-            so_symbol->GetType() == eSymbolTypeSourceFile &&
-            oso_symbol->GetType() == eSymbolTypeObjectFile) {
-          m_compile_unit_infos[i].so_file.SetFile(
-              so_symbol->GetName().AsCString(), false, FileSpec::Style::native);
-          m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
-          m_compile_unit_infos[i].oso_mod_time =
-              llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0));
+        Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
+        Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
+
+        // oso_info is the basis for the individual cu_infos below.
+        CompileUnitInfo oso_info;
+        if (!oso_info.Init(so_symbol, oso_symbol)) {
+          ReportErrorInitOSO(so_symbol, oso_symbol, oso_idx);
+          continue;
+        }
+
+        SymbolFileDWARF *sym_file = GetSymbolFileByCompUnitInfo(&oso_info);
+        if (!sym_file)
+          continue;
+
+        const auto &debug_info_data = sym_file->get_debug_info_data();
+        auto ExtractNext = [sym_file, &debug_info_data](lldb::offset_t offs) {
+          return DWARFCompileUnit::Extract(sym_file, debug_info_data, &offs);
+        };
+
+        for (DWARFUnitSP cu_sp = ExtractNext(0); cu_sp != nullptr;
+             cu_sp = ExtractNext(cu_sp->GetNextCompileUnitOffset())) {
+          // FIXME: Multiple OSO entries with multiple CUs may be a rare, but
+          // while I am here, I should store CU OFFSETS BY OSO ENTRY! It may
+          // move to m_oso_entry_info.
+          m_oso_compile_unit_offset.push_back(cu_sp->GetOffset());
+
+          // Make a copy of the oso_info and add compile unit specific data.
+          //
+          // FIXME: There is no CU-specific data currently, because symbol
+          // ranges are the same for all CUs and the offset is stored
+          // separately. It may be turned into a m_oso_entry_info.
+          m_compile_unit_infos.push_back(oso_info);
+          CompileUnitInfo &cu_info = m_compile_unit_infos.back();
+
           uint32_t sibling_idx = so_symbol->GetSiblingIndex();
-          // The sibling index can't be less that or equal to the current index
-          // "i"
-          if (sibling_idx == UINT32_MAX) {
-            m_obj_file->GetModule()->ReportError(
-                "N_SO in symbol with UID %u has invalid sibling in debug map, "
-                "please file a bug and attach the binary listed in this error",
-                so_symbol->GetID());
-          } else {
-            const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
-            m_compile_unit_infos[i].first_symbol_index = so_idx;
-            m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
-            m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
-            m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
-
-            if (log)
-              log->Printf("Initialized OSO 0x%8.8x: file=%s", i,
-                          oso_symbol->GetName().GetCString());
-          }
-        } else {
-          if (oso_symbol == NULL)
-            m_obj_file->GetModule()->ReportError(
-                "N_OSO symbol[%u] can't be found, please file a bug and attach "
-                "the binary listed in this error",
-                oso_idx);
-          else if (so_symbol == NULL)
-            m_obj_file->GetModule()->ReportError(
-                "N_SO not found for N_OSO symbol[%u], please file a bug and "
-                "attach the binary listed in this error",
-                oso_idx);
-          else if (so_symbol->GetType() != eSymbolTypeSourceFile)
-            m_obj_file->GetModule()->ReportError(
-                "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
-                "please file a bug and attach the binary listed in this error",
-                so_symbol->GetType(), oso_idx);
-          else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
-            m_obj_file->GetModule()->ReportError(
-                "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
-                "please file a bug and attach the binary listed in this error",
-                oso_symbol->GetType(), oso_idx);
+          const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
+
+          // For (regular) objects with only one compile unit, there is a
+          // bidirectional mapping between a symtab slice and a compile unit.
+          // LTO objects do not allow such a mapping and so we assign the full
+          // symtab range to all compile units of the same oso_entry.
+          cu_info.first_symbol_index = so_idx;
+          cu_info.last_symbol_index = sibling_idx - 1;
+          cu_info.first_symbol_id = so_symbol->GetID();
+          cu_info.last_symbol_id = last_symbol->GetID();
         }
+
+        if (log)
+          log->Printf("Initialized OSO 0x%8.8x: file=%s", i,
+                      oso_symbol->GetName().GetCString());
       }
     }
   }
 }
 
+void SymbolFileDWARFDebugMap::ReportErrorInitOSO(Symbol *so_symbol,
+                                                 Symbol *oso_symbol,
+                                                 uint32_t oso_idx) {
+  if (oso_symbol == NULL)
+    m_obj_file->GetModule()->ReportError(
+        "N_OSO symbol[%u] can't be found, please file a bug and attach "
+        "the binary listed in this error",
+        oso_idx);
+  else if (so_symbol == NULL)
+    m_obj_file->GetModule()->ReportError(
+        "N_SO not found for N_OSO symbol[%u], please file a bug and "
+        "attach the binary listed in this error",
+        oso_idx);
+  else if (so_symbol->GetType() != eSymbolTypeSourceFile)
+    m_obj_file->GetModule()->ReportError(
+        "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
+        "please file a bug and attach the binary listed in this error",
+        so_symbol->GetType(), oso_idx);
+  else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
+    m_obj_file->GetModule()->ReportError(
+        "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
+        "please file a bug and attach the binary listed in this error",
+        oso_symbol->GetType(), oso_idx);
+  else if (so_symbol->GetSiblingIndex() == UINT32_MAX)
+    m_obj_file->GetModule()->ReportError(
+        "N_SO in symbol with UID %u has invalid sibling in debug map, "
+        "please file a bug and attach the binary listed in this error",
+        so_symbol->GetID());
+}
+
 Module *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) {
   const uint32_t cu_count = GetNumCompileUnits();
   if (oso_idx < cu_count)
@@ -547,20 +597,40 @@
   // N_OSO entries (object files) from the symbol table and make sure that
   // these files exist and also contain valid DWARF. If we get any of that then
   // we return the abilities of the first N_OSO's DWARF.
+  if (HasCompileUnits())
+    return SymbolFile::CompileUnits | SymbolFile::Functions |
+           SymbolFile::Blocks | SymbolFile::GlobalVariables |
+           SymbolFile::LocalVariables | SymbolFile::VariableTypes |
+           SymbolFile::LineTables;
 
-  const uint32_t oso_index_count = GetNumCompileUnits();
-  if (oso_index_count > 0) {
-    InitOSO();
-    if (!m_compile_unit_infos.empty()) {
-      return SymbolFile::CompileUnits | SymbolFile::Functions |
-             SymbolFile::Blocks | SymbolFile::GlobalVariables |
-             SymbolFile::LocalVariables | SymbolFile::VariableTypes |
-             SymbolFile::LineTables;
-    }
-  }
   return 0;
 }
 
+bool SymbolFileDWARFDebugMap::HasCompileUnits() {
+  if (m_flags.test(kHaveCheckedCUInfos))
+    return m_has_compile_unit_infos;
+
+  m_flags.set(kHaveCheckedCUInfos);
+
+  // If the object file has been stripped, there is no sense in looking further
+  // as all of the debug symbols for the debug map will not be available.
+  //
+  // FIXME: This should be renamed to IsStrippedOrMissing()
+  if (m_obj_file->IsStripped())
+    return false;
+
+  if (!IsExecutableType(m_obj_file->GetType()))
+    return false;
+
+  assert(m_has_compile_unit_infos == false && "Arrive here only once");
+
+  if (Symtab *symtab = m_obj_file->GetSymtab())
+    m_has_compile_unit_infos = symtab->HasSymbolWithTypeAndFlags(
+        eSymbolTypeObjectFile, GetOSOSymbolFlags());
+
+  return m_has_compile_unit_infos;
+}
+
 uint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() {
   InitOSO();
   return m_compile_unit_infos.size();
@@ -575,12 +645,10 @@
     if (oso_module) {
       FileSpec so_file_spec;
       if (GetFileSpecForSO(cu_idx, so_file_spec)) {
-        // User zero as the ID to match the compile unit at offset zero in each
-        // .o file since each .o file can only have one compile unit for now.
-        lldb::user_id_t cu_id = 0;
-        m_compile_unit_infos[cu_idx].compile_unit_sp.reset(
-            new CompileUnit(m_obj_file->GetModule(), NULL, so_file_spec, cu_id,
-                            eLanguageTypeUnknown, eLazyBoolCalculate));
+        lldb::user_id_t cu_offset = m_oso_compile_unit_offset[cu_idx];
+        m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit(
+            m_obj_file->GetModule(), NULL, so_file_spec, cu_offset,
+            eLanguageTypeUnknown, eLazyBoolCalculate));
 
         if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
           // Let our symbol vendor know about this compile unit
@@ -734,6 +802,15 @@
       if (sc.symbol != NULL) {
         resolved_flags |= eSymbolContextSymbol;
 
+        // FIXME: Search by symbol Index/ID will NOT return the correct info for
+        // objects with multiple compile units. We cannot safely match slices of
+        // the symtab with individual units (it's very likely that optimization
+        // mixed it up), and so all compile units from such objects share the
+        // full symbol range.
+        //
+        // For the moment this is not a problem here, because we only use the
+        // compile unit info to find the module, which is invariant across all
+        // compile units of one object file.
         uint32_t oso_idx = 0;
         CompileUnitInfo *comp_unit_info =
             GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx);
@@ -1244,6 +1321,32 @@
   llvm_unreachable("this shouldn't happen");
 }
 
+lldb::CompUnitSP
+SymbolFileDWARFDebugMap::GetCompileUnitByIndex(SymbolFileDWARF *oso_dwarf,
+                                               uint32_t cu_idx) {
+  assert(cu_idx < GetNumCompileUnits() && "CU index out of range");
+  auto &cu_info = m_compile_unit_infos[cu_idx];
+  if (!cu_info.compile_unit_sp)
+    cu_info.compile_unit_sp = ParseCompileUnitAtIndex(cu_idx);
+
+  return cu_info.compile_unit_sp;
+}
+
+lldb::CompUnitSP
+SymbolFileDWARFDebugMap::GetCompileUnitByOffset(SymbolFileDWARF *oso_dwarf,
+                                                dw_offset_t cu_offset) {
+  auto begin = m_oso_compile_unit_offset.begin();
+  auto end = m_oso_compile_unit_offset.end();
+  auto it = std::lower_bound(begin, end, cu_offset);
+
+  if (it != end) {
+    uint32_t cu_idx = std::distance(begin, it);
+    return GetCompileUnitByIndex(oso_dwarf, cu_idx);
+  }
+
+  return nullptr;
+}
+
 SymbolFileDWARFDebugMap::CompileUnitInfo *
 SymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) {
   if (oso_dwarf) {
@@ -1380,6 +1483,16 @@
       addr_module->GetSymbolVendor()->GetSymbolFile()));
   if (cu_info) {
     const lldb::addr_t oso_file_addr = addr.GetFileAddress();
+
+    // FIXME: Search by symbol Index/ID will NOT return the correct info for
+    // objects with multiple compile units. We cannot safely match slices of
+    // the symtab with individual units (it's very likely that optimization
+    // mixed it up), and so all compile units from such objects share the
+    // full symbol range.
+    //
+    // For the moment this is not a problem here, because we only use the
+    // compile unit info to find the module, which is invariant across all
+    // compile units of one object file.
     const FileRangeMap::Entry *oso_range_entry =
         cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
     if (oso_range_entry) {
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -275,7 +275,7 @@
 
   lldb_private::CompileUnit *
   GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu,
-                              uint32_t cu_idx = UINT32_MAX);
+                              uint32_t cu_idx = DW_INVALID_INDEX);
 
   virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
                                          DIEArray &method_die_offsets);
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -781,9 +781,25 @@
       if (dwarf_cu->GetSymbolFileDWARF() != this) {
         return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu,
                                                                 cu_idx);
-      } else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile()) {
+      } else if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) {
+        assert(debug_map == m_debug_map_symfile &&
+               "debug_map is a nested instance derived from SymbolFile, "
+               "NOT SymbolFileDWARF");
+
         // Let the debug map create the compile unit
-        cu_sp = m_debug_map_symfile->GetCompileUnit(this);
+        if (debug_map->GetNumCompileUnits() == 1) {
+          cu_sp = debug_map->GetCompileUnit(this);
+        } else if (cu_idx != UINT32_MAX) {
+          cu_sp = debug_map->GetCompileUnitByIndex(this, cu_idx);
+        } else {
+          lldb::offset_t cu_offset = dwarf_cu->GetOffset();
+          if (cu_offset != DW_INVALID_OFFSET) {
+            cu_sp = debug_map->GetCompileUnitByOffset(this, cu_offset);
+          } else {
+            llvm_unreachable("Need more info to find the correct CU");
+          }
+        }
+
         dwarf_cu->SetUserData(cu_sp.get());
       } else {
         ModuleSP module_sp(m_obj_file->GetModule());
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -426,8 +426,9 @@
   const dw_offset_t cu_offset = GetOffset();
   if (die) {
     DWARFRangeList ranges;
+    static constexpr bool check_hi_lo_pc = true;
     const size_t num_ranges =
-        die->GetAttributeAddressRanges(dwarf, this, ranges, false);
+        die->GetAttributeAddressRanges(dwarf, this, ranges, check_hi_lo_pc);
     if (num_ranges > 0) {
       // This compile unit has DW_AT_ranges, assume this is correct if it is
       // present since clang no longer makes .debug_aranges by default and it
Index: include/lldb/Symbol/Symtab.h
===================================================================
--- include/lldb/Symbol/Symtab.h
+++ include/lldb/Symbol/Symtab.h
@@ -56,6 +56,10 @@
   Symbol *FindSymbolWithType(lldb::SymbolType symbol_type,
                              Debug symbol_debug_type,
                              Visibility symbol_visibility, uint32_t &start_idx);
+
+  bool HasSymbolWithTypeAndFlags(lldb::SymbolType symbol_type,
+                                 uint32_t flags_value) const;
+
   //----------------------------------------------------------------------
   /// Get the parent symbol for the given symbol.
   ///
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to