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 @@ -51,7 +51,7 @@ uint64_t m_type_hash = 0; uint32_t m_type_offset = 0; - uint64_t m_dwo_id = 0; + llvm::Optional m_dwo_id; DWARFUnitHeader() = default; @@ -67,7 +67,7 @@ } uint64_t GetTypeHash() const { return m_type_hash; } dw_offset_t GetTypeOffset() const { return m_type_offset; } - uint64_t GetDWOId() const { return m_dwo_id; } + llvm::Optional GetDWOId() const { return m_dwo_id; } bool IsTypeUnit() const { return m_unit_type == llvm::dwarf::DW_UT_type || m_unit_type == llvm::dwarf::DW_UT_split_type; @@ -92,7 +92,7 @@ virtual ~DWARFUnit(); bool IsDWOUnit() { return m_is_dwo; } - uint64_t GetDWOId(); + llvm::Optional GetDWOId(); void ExtractUnitDIEIfNeeded(); void ExtractUnitDIENoDwoIfNeeded(); @@ -336,7 +336,7 @@ bool m_is_dwo; bool m_has_parsed_non_skeleton_unit; /// Value of DW_AT_GNU_dwo_id (v4) or dwo_id from CU header (v5). - uint64_t m_dwo_id; + llvm::Optional m_dwo_id; private: void ParseProducerInfo(); 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 @@ -77,12 +77,15 @@ m_has_parsed_non_skeleton_unit = true; + if (!m_dwo_id) + return; // No DWO file. + std::shared_ptr dwo_symbol_file = m_dwarf.GetDwoSymbolFileForCompileUnit(*this, m_first_die); if (!dwo_symbol_file) return; - DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(m_dwo_id); + DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(*m_dwo_id); if (!dwo_cu) return; // Can't fetch the compile unit from the dwo file. @@ -345,7 +348,7 @@ SetStrOffsetsBase(baseOffset); } -uint64_t DWARFUnit::GetDWOId() { +llvm::Optional DWARFUnit::GetDWOId() { ExtractUnitDIENoDwoIfNeeded(); return m_dwo_id; } @@ -467,7 +470,7 @@ GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( "Failed to find location list contribution for CU with DWO Id " "0x%" PRIx64, - this->GetDWOId()); + *GetDWOId()); return; } offset += contribution->Offset; @@ -889,8 +892,8 @@ header.m_index_entry = Index->getFromHash(header.m_type_hash); } else { Index = &context.GetAsLLVM().getCUIndex(); - if (*Index && header.m_version >= 5) - header.m_index_entry = Index->getFromHash(header.m_dwo_id); + 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); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -148,19 +148,36 @@ const LanguageType cu_language = SymbolFileDWARF::GetLanguage(unit); - IndexUnitImpl(unit, cu_language, set); - - if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) { - // Type units in a dwp file are indexed separately, so we just need to - // process the split unit here. However, if the split unit is in a dwo file, - // then we need to process type units here. - if (dwo_symbol_file == dwp) { - IndexUnitImpl(unit.GetNonSkeletonUnit(), cu_language, set); - } else { - DWARFDebugInfo &dwo_info = dwo_symbol_file->DebugInfo(); - for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) - IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set); + // First check if the unit has a DWO ID. If it does then we only want to index + // the .dwo file or nothing at all. If we have a compile unit where we can't + // locate the .dwo/.dwp file we don't want to index anything from the skeleton + // compile unit because it is usally has no children unless + // -fsplit-dwarf-inlining was used at compile time. This option will add a + // copy of all DW_TAG_subprogram and any contained DW_TAG_inline_subroutine + // DIEs so that symbolication will still work in the absence of the .dwo/.dwp + // file, but the functions have no return types and all arguments and locals + // have been removed. So we don't want to index any of these hacked up + // function types. Types can still exist in the skeleton compile unit DWARF + // though as some functions have template parameter types and other things + // that cause extra copies of types to be included, but we should find these + // types in the .dwo file only as methods could have return types removed and + // we don't have to index incomplete types from the skeletone compile unit. + if (unit.GetDWOId()) { + if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) { + // Type units in a dwp file are indexed separately, so we just need to + // process the split unit here. However, if the split unit is in a dwo file, + // then we need to process type units here. + if (dwo_symbol_file == dwp) { + IndexUnitImpl(unit.GetNonSkeletonUnit(), cu_language, set); + } else { + DWARFDebugInfo &dwo_info = dwo_symbol_file->DebugInfo(); + for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) + IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set); + } } + } else { + // We either have a normal compile unit which we want to index. + IndexUnitImpl(unit, cu_language, set); } }