augusto2112 created this revision.
augusto2112 added reviewers: aprantl, jasonmolenda, jingham.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: lldb-commits, sstefan1.
Herald added a project: LLDB.

Currently, SymbolFileDWARFDebugMap works on the assumption that there is
only one compile unit per object file. This patch documents this
limitation (when using the general SymbolFile API), and allows users of
the concrete SymbolFileDWARFDebugMap class to find out about these extra
compile units.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D136114

Files:
  lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h

Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -19,6 +19,7 @@
 #include "UniqueDWARFASTType.h"
 
 class SymbolFileDWARF;
+class DWARFCompileUnit;
 class DWARFDebugAranges;
 class DWARFDeclContext;
 
@@ -174,7 +175,10 @@
     llvm::sys::TimePoint<> oso_mod_time;
     lldb_private::Status oso_load_error;
     OSOInfoSP oso_sp;
+    // The first compile unit, which appears in the nlist symbol table.
     lldb::CompUnitSP compile_unit_sp;
+    // The rest of the compile units that an object file contains.
+    llvm::SmallVector<lldb::CompUnitSP, 1> extra_compile_units_sps;
     uint32_t first_symbol_index = UINT32_MAX;
     uint32_t last_symbol_index = UINT32_MAX;
     uint32_t first_symbol_id = UINT32_MAX;
@@ -193,7 +197,17 @@
   // Protected Member Functions
   void InitOSO();
 
+  /// This function actually returns the number of object files, which may be
+  /// less than the actual number of compile units, since an object file may
+  /// contain more than one compile unit. SymbolFileDWARFDebugMap looks up the
+  /// number of compile units by reading the nlist symbol table, which
+  /// currently, on macOS, only reports one compile unit per object file, and
+  /// there's no efficient way to calculate the actual number of compile units
+  /// upfront.
   uint32_t CalculateNumCompileUnits() override;
+
+  /// This function actually returns the first compile unit the object file at
+  /// the given index contains.
   lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
 
   static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
@@ -263,7 +277,11 @@
   void SetCompileUnit(SymbolFileDWARF *oso_dwarf,
                       const lldb::CompUnitSP &cu_sp);
 
-  lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf);
+  /// Returns the compile unit associated with the dwarf compile unit. This may
+  /// be one of the extra compile units an object file contains which isn't
+  /// reachable by ParseCompileUnitAtIndex(uint32_t).
+  lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf,
+                                  DWARFCompileUnit &dwarf_cu);
 
   CompileUnitInfo *GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf);
 
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -7,7 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "SymbolFileDWARFDebugMap.h"
+#include "DWARFCompileUnit.h"
 #include "DWARFDebugAranges.h"
+#include "DWARFDebugInfo.h"
 
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleList.h"
@@ -17,6 +19,7 @@
 #include "lldb/Utility/RangeMap.h"
 #include "lldb/Utility/RegularExpression.h"
 #include "lldb/Utility/Timer.h"
+#include "lldb/Utility/StreamString.h"
 
 //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
 #if defined(DEBUG_OSO_DMAP)
@@ -586,25 +589,40 @@
   const uint32_t cu_count = GetNumCompileUnits();
 
   if (cu_idx < cu_count) {
-    Module *oso_module = GetModuleByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
+    auto &cu_info = m_compile_unit_infos[cu_idx];
+    Module *oso_module = GetModuleByCompUnitInfo(&cu_info);
     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.
+        // .o file since each .o file.
         lldb::user_id_t cu_id = 0;
         m_compile_unit_infos[cu_idx].compile_unit_sp =
             std::make_shared<CompileUnit>(
                 m_objfile_sp->GetModule(), nullptr, so_file_spec, cu_id,
                 eLanguageTypeUnknown, eLazyBoolCalculate);
-
-        if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
-          SetCompileUnitAtIndex(cu_idx,
-                                m_compile_unit_infos[cu_idx].compile_unit_sp);
+        if (cu_info.compile_unit_sp) 
+          SetCompileUnitAtIndex(cu_idx, cu_info.compile_unit_sp);
+      }
+      // If there's a symbol file also register all the extra compile units.
+      if (SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo(&cu_info)) {
+        auto num_dwarf_units = oso_symfile->DebugInfo().GetNumUnits();
+        for (size_t i = 0; i < num_dwarf_units; ++i) {
+          auto *dwarf_unit = oso_symfile->DebugInfo().GetUnitAtIndex(i);
+          if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(dwarf_unit)) {
+            // The "main" one was already registered.
+            if (dwarf_cu->GetID() == 0)
+              continue;
+            cu_info.extra_compile_units_sps.push_back(
+                std::make_shared<CompileUnit>(
+                    m_objfile_sp->GetModule(), nullptr, so_file_spec,
+                    dwarf_cu->GetID(), eLanguageTypeUnknown,
+                    eLazyBoolCalculate));
+          }
         }
       }
     }
-    comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
+    comp_unit_sp = cu_info.compile_unit_sp;
   }
 
   return comp_unit_sp;
@@ -621,6 +639,9 @@
   for (uint32_t i = 0; i < cu_count; ++i) {
     if (&comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
       return &m_compile_unit_infos[i];
+     for (auto &extra: m_compile_unit_infos[i].extra_compile_units_sps) 
+       if (&comp_unit == extra.get())
+         return &m_compile_unit_infos[i];
   }
   return nullptr;
 }
@@ -1239,7 +1260,7 @@
 }
 
 lldb::CompUnitSP
-SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) {
+SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf, DWARFCompileUnit &dwarf_cu) {
   if (oso_dwarf) {
     const uint32_t cu_count = GetNumCompileUnits();
     for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
@@ -1247,10 +1268,14 @@
           GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
       if (oso_symfile == oso_dwarf) {
         if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
-          m_compile_unit_infos[cu_idx].compile_unit_sp =
-              ParseCompileUnitAtIndex(cu_idx);
+          ParseCompileUnitAtIndex(cu_idx);
+
+        if (dwarf_cu.GetID() == 0)
+          return m_compile_unit_infos[cu_idx].compile_unit_sp;
 
-        return m_compile_unit_infos[cu_idx].compile_unit_sp;
+        for (auto &cu : m_compile_unit_infos[cu_idx].extra_compile_units_sps)
+          if (cu->GetID() == dwarf_cu.GetID())
+            return cu;
       }
     }
   }
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -702,9 +702,9 @@
     // We already parsed this compile unit, had out a shared pointer to it
     cu_sp = comp_unit->shared_from_this();
   } else {
-    if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) {
+    if (GetDebugMapSymfile()) {
       // Let the debug map create the compile unit
-      cu_sp = m_debug_map_symfile->GetCompileUnit(this);
+      cu_sp = m_debug_map_symfile->GetCompileUnit(this, dwarf_cu);
       dwarf_cu.SetUserData(cu_sp.get());
     } else {
       ModuleSP module_sp(m_objfile_sp->GetModule());
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -54,7 +54,7 @@
 
   // Set the offset to that of the first DIE and calculate the start of the
   // next compilation unit header.
-  lldb::offset_t offset = GetFirstDIEOffset();
+  lldb::offset_t offset = GetFirstDIEOffset();;
 
   // We are in our compile unit, parse starting at the offset we were told to
   // parse
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -52,7 +52,7 @@
     }
   }
 
-  if (debug_aranges->GetNumRanges() == num_debug_aranges) {
+  if (debug_aranges->GetNumRanges() == num_debug_aranges && cu_offset == 0) {
     // We got nothing from the debug info, maybe we have a line tables only
     // situation. Check the line tables and build the arange table from this.
     SymbolContext sc;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to