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 @@ -75,6 +75,8 @@ } uint32_t GetNextUnitOffset() const { return m_offset + m_length + 4; } + llvm::Error ApplyIndexEntry(const llvm::DWARFUnitIndex::Entry *index_entry); + static llvm::Expected extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section, lldb_private::DWARFContext &dwarf_context, 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 @@ -875,11 +875,37 @@ return *m_func_aranges_up; } -llvm::Expected -DWARFUnitHeader::extract(const DWARFDataExtractor &data, - DIERef::Section section, - lldb_private::DWARFContext &context, - lldb::offset_t *offset_ptr) { +llvm::Error DWARFUnitHeader::ApplyIndexEntry( + const llvm::DWARFUnitIndex::Entry *index_entry) { + // We should only be calling this function when the index entry is not set and + // we have a valid one to set it to. + assert(index_entry); + assert(!m_index_entry); + + if (m_abbr_offset) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Package unit with a non-zero abbreviation offset"); + + auto *unit_contrib = index_entry->getContribution(); + if (!unit_contrib || unit_contrib->getLength32() != m_length + 4) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Inconsistent DWARF package unit index"); + + auto *abbr_entry = index_entry->getContribution(llvm::DW_SECT_ABBREV); + if (!abbr_entry) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "DWARF package index missing abbreviation column"); + + m_abbr_offset = abbr_entry->getOffset(); + m_index_entry = index_entry; + return llvm::Error::success(); +} + +llvm::Expected DWARFUnitHeader::extract( + const DWARFDataExtractor &data, DIERef::Section section, + lldb_private::DWARFContext &context, lldb::offset_t *offset_ptr) { DWARFUnitHeader header; header.m_offset = *offset_ptr; header.m_length = data.GetDWARFInitialLength(offset_ptr); @@ -903,42 +929,6 @@ header.m_type_offset = data.GetDWARFOffset(offset_ptr); } - if (context.isDwo()) { - const llvm::DWARFUnitIndex *Index; - if (header.IsTypeUnit()) { - Index = &context.GetAsLLVM().getTUIndex(); - if (*Index) - header.m_index_entry = Index->getFromHash(header.m_type_hash); - } else { - Index = &context.GetAsLLVM().getCUIndex(); - if (*Index && header.m_version >= 5 && header.m_dwo_id) - header.m_index_entry = Index->getFromHash(*header.m_dwo_id); - } - if (!header.m_index_entry) - header.m_index_entry = Index->getFromOffset(header.m_offset); - } - - if (header.m_index_entry) { - if (header.m_abbr_offset) { - return llvm::createStringError( - llvm::inconvertibleErrorCode(), - "Package unit with a non-zero abbreviation offset"); - } - auto *unit_contrib = header.m_index_entry->getContribution(); - if (!unit_contrib || unit_contrib->getLength32() != header.m_length + 4) { - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Inconsistent DWARF package unit index"); - } - auto *abbr_entry = - header.m_index_entry->getContribution(llvm::DW_SECT_ABBREV); - if (!abbr_entry) { - return llvm::createStringError( - llvm::inconvertibleErrorCode(), - "DWARF package index missing abbreviation column"); - } - header.m_abbr_offset = abbr_entry->getOffset(); - } - bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1); bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version); bool addr_size_OK = (header.m_addr_size == 2) || (header.m_addr_size == 4) || @@ -968,11 +958,32 @@ DIERef::Section section, lldb::offset_t *offset_ptr) { assert(debug_info.ValidOffset(*offset_ptr)); - auto expected_header = DWARFUnitHeader::extract( - debug_info, section, dwarf.GetDWARFContext(), offset_ptr); + DWARFContext &context = dwarf.GetDWARFContext(); + auto expected_header = + DWARFUnitHeader::extract(debug_info, section, context, offset_ptr); if (!expected_header) return expected_header.takeError(); + if (context.isDwo()) { + const llvm::DWARFUnitIndex::Entry *entry = nullptr; + const llvm::DWARFUnitIndex &index = expected_header->IsTypeUnit() + ? context.GetAsLLVM().getTUIndex() + : context.GetAsLLVM().getCUIndex(); + if (index) { + if (expected_header->IsTypeUnit()) + entry = index.getFromHash(expected_header->GetTypeHash()); + else if (auto dwo_id = expected_header->GetDWOId()) + entry = index.getFromHash(*dwo_id); + } + if (!entry) + entry = index.getFromOffset(expected_header->GetOffset()); + if (entry) { + if (llvm::Error err = expected_header->ApplyIndexEntry(entry)) { + return err; + } + } + } + const DWARFDebugAbbrev *abbr = dwarf.DebugAbbrev(); if (!abbr) return llvm::make_error(