diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -277,7 +277,7 @@ } SymbolFileDWARF &m_dwarf; - std::unique_ptr m_dwo_symbol_file; + std::shared_ptr m_dwo; DWARFUnitHeader m_header; const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr; void *m_user_data = nullptr; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -188,7 +188,7 @@ // simultaneously. We also don't need to do that as the dwo file will // contain a superset of information. So, we don't even attempt to parse // any remaining DIEs. - if (m_dwo_symbol_file) { + if (m_dwo) { m_die_array.front().SetHasChildren(false); break; } @@ -249,10 +249,8 @@ m_die_array.shrink_to_fit(); - if (m_dwo_symbol_file) { - DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); - dwo_cu->ExtractDIEsIfNeeded(); - } + if (m_dwo) + m_dwo->ExtractDIEsIfNeeded(); } // This is used when a split dwarf is enabled. @@ -339,12 +337,14 @@ if (m_is_dwo) return; - std::unique_ptr dwo_symbol_file = + std::shared_ptr dwo_symbol_file = m_dwarf.GetDwoSymbolFileForCompileUnit(*this, cu_die); if (!dwo_symbol_file) return; - DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); + uint64_t main_dwo_id = + cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0); + DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(main_dwo_id); if (!dwo_cu) return; // Can't fetch the compile unit from the dwo file. dwo_cu->SetUserData(this); @@ -353,16 +353,6 @@ if (!dwo_cu_die.IsValid()) return; // Can't fetch the compile unit DIE from the dwo file. - uint64_t main_dwo_id = - cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0); - uint64_t sub_dwo_id = - dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0); - if (main_dwo_id != sub_dwo_id) - return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to - // a differectn compilation. - - m_dwo_symbol_file = std::move(dwo_symbol_file); - // Here for DWO CU we want to use the address base set in the skeleton unit // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_* @@ -376,21 +366,22 @@ if (GetVersion() <= 4 && gnu_ranges_base) dwo_cu->SetRangesBase(*gnu_ranges_base); - else if (m_dwo_symbol_file->GetDWARFContext() + else if (dwo_symbol_file->GetDWARFContext() .getOrLoadRngListsData() .GetByteSize() > 0) dwo_cu->SetRangesBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); - if (GetVersion() >= 5 && m_dwo_symbol_file->GetDWARFContext() - .getOrLoadLocListsData() - .GetByteSize() > 0) + if (GetVersion() >= 5 && + dwo_symbol_file->GetDWARFContext().getOrLoadLocListsData().GetByteSize() > + 0) dwo_cu->SetLoclistsBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); dwo_cu->SetBaseAddress(GetBaseAddress()); - for (size_t i = 0; i < m_dwo_symbol_file->DebugInfo()->GetNumUnits(); ++i) { - DWARFUnit *unit = m_dwo_symbol_file->DebugInfo()->GetUnitAtIndex(i); + for (size_t i = 0; i < dwo_symbol_file->DebugInfo()->GetNumUnits(); ++i) { + DWARFUnit *unit = dwo_symbol_file->DebugInfo()->GetUnitAtIndex(i); SetDwoStrOffsetsBase(unit); } + m_dwo = std::shared_ptr(std::move(dwo_symbol_file), dwo_cu); } DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) { @@ -507,8 +498,8 @@ m_die_array.clear(); m_die_array.shrink_to_fit(); - if (m_dwo_symbol_file) - m_dwo_symbol_file->GetCompileUnit()->ClearDIEsRWLocked(); + if (m_dwo) + m_dwo->ClearDIEsRWLocked(); } lldb::ByteOrder DWARFUnit::GetByteOrder() const { @@ -549,8 +540,9 @@ } DWARFUnit &DWARFUnit::GetNonSkeletonUnit() { - if (SymbolFileDWARFDwo *dwo = GetDwoSymbolFile()) - return *dwo->GetCompileUnit(); + ExtractUnitDIEIfNeeded(); + if (m_dwo) + return *m_dwo; return *this; } @@ -755,7 +747,9 @@ SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() { ExtractUnitDIEIfNeeded(); - return m_dwo_symbol_file.get(); + if (m_dwo) + return &llvm::cast(m_dwo->GetSymbolFileDWARF()); + return nullptr; } const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() { @@ -765,11 +759,10 @@ if (die) die->BuildFunctionAddressRangeTable(this, m_func_aranges_up.get()); - if (m_dwo_symbol_file) { - DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); - const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr(); + if (m_dwo) { + const DWARFDebugInfoEntry *dwo_die = m_dwo->DIEPtr(); if (dwo_die) - dwo_die->BuildFunctionAddressRangeTable(dwo_cu, + dwo_die->BuildFunctionAddressRangeTable(m_dwo.get(), m_func_aranges_up.get()); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -270,7 +270,7 @@ lldb::user_id_t GetUID(DIERef ref); - std::unique_ptr + std::shared_ptr GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1552,7 +1552,7 @@ return {}; } -std::unique_ptr +std::shared_ptr SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) { // If this is a Darwin-style debug map (non-.dSYM) symbol file, @@ -1607,7 +1607,7 @@ if (dwo_obj_file == nullptr) return nullptr; - return std::make_unique(*this, dwo_obj_file, + return std::make_shared(*this, dwo_obj_file, dwarf_cu->GetID()); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -29,10 +29,7 @@ ~SymbolFileDWARFDwo() override = default; - DWARFCompileUnit *GetCompileUnit(); - - DWARFUnit * - GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override; + DWARFCompileUnit *GetDWOCompileUnitForHash(uint64_t hash); size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name, DIEArray &method_die_offsets) override; @@ -68,10 +65,11 @@ SymbolFileDWARF &GetBaseSymbolFile() { return m_base_symbol_file; } - DWARFCompileUnit *ComputeCompileUnit(); + /// If this file contains exactly one compile unit, this function will return + /// it. Otherwise it returns nullptr. + DWARFCompileUnit *FindSingleCompileUnit(); SymbolFileDWARF &m_base_symbol_file; - DWARFCompileUnit *m_cu = nullptr; }; #endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -49,13 +49,17 @@ SymbolFileDWARF::LoadSectionData(sect_type, data); } -DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() { - if (!m_cu) - m_cu = ComputeCompileUnit(); - return m_cu; +DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) { + DWARFCompileUnit *cu = FindSingleCompileUnit(); + if (!cu) + return nullptr; + if (hash != + cu->GetUnitDIEOnly().GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0)) + return nullptr; + return cu; } -DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() { +DWARFCompileUnit *SymbolFileDWARFDwo::FindSingleCompileUnit() { DWARFDebugInfo *debug_info = DebugInfo(); if (!debug_info) return nullptr; @@ -79,11 +83,6 @@ return cu; } -DWARFUnit * -SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { - return GetCompileUnit(); -} - SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() { return GetBaseSymbolFile().GetDIEToType(); }