jankratochvil created this revision.
Herald added a subscriber: JDevlieghere.

It does not make sense to extract whole DW_TAG_partial_unit only to find out it 
is a partial unit and so it cannot be indexed on its own.

All DWZ patches are also applied in: git clone -b dwz 
git://git.jankratochvil.net/lldb


https://reviews.llvm.org/D40471

Files:
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
  source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2045,9 +2045,10 @@
     auto extract_fn = [debug_info, &clear_cu_dies](size_t cu_idx) {
       DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
       if (dwarf_cu) {
-        // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the
+        // dwarf_cu->ExtractDIEsIfNeeded will return zero if the
         // DIEs for a compile unit have already been parsed.
-        if (dwarf_cu->ExtractDIEsIfNeeded(false) > 1)
+        if (dwarf_cu->ExtractDIEsIfNeeded(DWARFCompileUnit::
+            ExtractDIEsIfNeededKind::AllDiesButCuDieOnlyForPartialUnits) > 1)
           clear_cu_dies[cu_idx] = true;
       }
     };
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
@@ -76,7 +76,10 @@
           DWARFFormValue::GetFixedFormSizesForAddressSize(
               cu->GetAddressByteSize(), cu->IsDWARF64());
 
-      bool clear_dies = cu->ExtractDIEsIfNeeded(false) > 1;
+      bool clear_dies = cu->ExtractDIEsIfNeeded(
+          DWARFCompileUnit::ExtractDIEsIfNeededKind::AllDies) > 1;
+      // In DW_TAG_partial_unit by DWZ cannot be DW_TAG_subprogram definition
+      // (see DWZ checksum_die).  But there can be DW_TAG_variable.
 
       DWARFDIECollection dies;
       const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_subprogram, dies) +
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -85,7 +85,13 @@
       lldb::offset_t *offset_ptr);
   ~DWARFCompileUnit();
 
-  size_t ExtractDIEsIfNeeded(bool cu_die_only);
+  enum class ExtractDIEsIfNeededKind {
+    CuDieOnly,
+    AllDies,
+    AllDiesButCuDieOnlyForPartialUnits,
+  };
+  size_t ExtractDIEsIfNeeded(ExtractDIEsIfNeededKind kind);
+
   DWARFDIE LookupAddress(const dw_addr_t address);
   size_t AppendDIEsWithTag(const dw_tag_t tag,
                            DWARFDIECollection &matching_dies,
@@ -247,14 +253,14 @@
   DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
 
   const DWARFDebugInfoEntry *GetCompileUnitDIEPtrOnly() {
-    ExtractDIEsIfNeeded(true);
+    ExtractDIEsIfNeeded(ExtractDIEsIfNeededKind::CuDieOnly);
     if (m_data->m_die_array.empty())
       return NULL;
     return &m_data->m_die_array[0];
   }
 
   const DWARFDebugInfoEntry *DIEPtr() {
-    ExtractDIEsIfNeeded(false);
+    ExtractDIEsIfNeeded(ExtractDIEsIfNeededKind::AllDies);
     if (m_data->m_die_array.empty())
       return NULL;
     return &m_data->m_die_array[0];
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -119,11 +119,27 @@
 // Parses a compile unit and indexes its DIEs if it hasn't already been
 // done.
 //----------------------------------------------------------------------
-size_t DWARFCompileUnit::ExtractDIEsIfNeeded(bool cu_die_only) {
+size_t DWARFCompileUnit::ExtractDIEsIfNeeded(ExtractDIEsIfNeededKind kind) {
   size_t initial_die_array_size;
-  auto already_parsed = [cu_die_only, &initial_die_array_size]() -> bool {
-    return (cu_die_only && initial_die_array_size > 0)
-        || initial_die_array_size > 1;
+  auto already_parsed =
+      [kind, &initial_die_array_size, this]() -> bool {
+    initial_die_array_size = m_data->m_die_array.size();    
+    if (initial_die_array_size > 1)
+      return true;
+    switch (kind) {
+    case ExtractDIEsIfNeededKind::CuDieOnly:
+      if (initial_die_array_size > 0)
+        return true;
+      break;
+    case ExtractDIEsIfNeededKind::AllDies:
+      break;
+    case ExtractDIEsIfNeededKind::AllDiesButCuDieOnlyForPartialUnits: {
+      if (initial_die_array_size > 0
+          && GetCompileUnitDIEOnly().TagOrig() == DW_TAG_partial_unit)
+        return true;
+      } break;
+    }
+    return false;
   };
   if (already_parsed() && m_data->m_die_array_finished)
     return 0;
@@ -139,17 +155,17 @@
   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
   Timer scoped_timer(
       func_cat,
-      "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )",
-      m_offset, cu_die_only);
+      "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( kind = %i )",
+      m_offset, int(kind));
 
   // Set the offset to that of the first DIE and calculate the start of the
   // next compilation unit header.
   lldb::offset_t file_offset = ThisCUUniqToFileOffset(GetFirstDIEOffset());
   lldb::offset_t next_cu_offset = GetNextCompileUnitOffset();
 
   DWARFDebugInfoEntry die;
   // Keep a flat array of the DIE for binary lookup by DIE offset
-  if (!cu_die_only) {
+  if (kind != ExtractDIEsIfNeededKind::CuDieOnly) {
     Log *log(
         LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS));
     if (log) {
@@ -193,7 +209,10 @@
         base_addr = die.GetAttributeValueAsAddress(m_data->m_dwarf2Data, this,
                                                    DW_AT_entry_pc, 0);
       SetBaseAddress(base_addr);
-      if (cu_die_only)
+      if (kind == ExtractDIEsIfNeededKind::CuDieOnly)
+        return 1;
+      if (kind == ExtractDIEsIfNeededKind::AllDiesButCuDieOnlyForPartialUnits
+          && die.TagOrig() == DW_TAG_partial_unit)
         return 1;
     } else {
       if (null_die) {
@@ -277,7 +296,7 @@
     return m_data->m_die_array.size();
 
   DWARFCompileUnit *dwo_cu = m_data->m_dwo_symbol_file->GetCompileUnit();
-  size_t dwo_die_count = dwo_cu->ExtractDIEsIfNeeded(cu_die_only);
+  size_t dwo_die_count = dwo_cu->ExtractDIEsIfNeeded(kind);
   return m_data->m_die_array.size() + dwo_die_count -
          1; // We have 2 CU die, but we want to count it only as one
 }
@@ -437,9 +456,10 @@
   // units
   // to stay loaded when they weren't needed. So we can end up parsing the DWARF
   // and then throwing them all away to keep memory usage down.
-  const bool clear_dies = ExtractDIEsIfNeeded(false) > 1;
+  const bool clear_dies = ExtractDIEsIfNeeded(
+      ExtractDIEsIfNeededKind::AllDiesButCuDieOnlyForPartialUnits) > 1;
 
-  die = DIEPtr();
+  die = GetCompileUnitDIEPtrOnly();
   if (die)
     die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges);
 
@@ -566,7 +586,7 @@
       return m_data->m_dwo_symbol_file->GetCompileUnit()->GetDIE(die_offset);
 
     if (ContainsDIEOffset(die_offset)) {
-      ExtractDIEsIfNeeded(false);
+      ExtractDIEsIfNeeded(ExtractDIEsIfNeededKind::AllDies);
       dw_offset_t die_file_offset = ThisCUUniqToFileOffset(die_offset);
       DWARFDebugInfoEntry::iterator end = m_data->m_die_array.end();
       DWARFDebugInfoEntry::iterator pos = lower_bound(
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH] D40... Jan Kratochvil via Phabricator via lldb-commits

Reply via email to