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,8 +155,8 @@ 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. @@ -149,7 +165,7 @@ 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( 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/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; } };