1 //===-- SymbolFileDWARFDwo.cpp --------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "SymbolFileDWARFDwo.h" 10 11 #include "lldb/Core/Section.h" 12 #include "lldb/Expression/DWARFExpression.h" 13 #include "lldb/Symbol/ObjectFile.h" 14 #include "lldb/Utility/LLDBAssert.h" 15 #include "llvm/Support/Casting.h" 16 17 #include "DWARFCompileUnit.h" 18 #include "DWARFDebugInfo.h" 19 #include "DWARFUnit.h" 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 char SymbolFileDWARFDwo::ID; 25 26 SymbolFileDWARFDwo::SymbolFileDWARFDwo(SymbolFileDWARF &base_symbol_file, 27 ObjectFileSP objfile, uint32_t id) 28 : SymbolFileDWARF(objfile, objfile->GetSectionList( 29 /*update_module_section_list*/ false)), 30 m_base_symbol_file(base_symbol_file) { 31 SetID(user_id_t(id) << 32); 32 33 // Parsing of the dwarf unit index is not thread-safe, so we need to prime it 34 // to enable subsequent concurrent lookups. 35 m_context.GetAsLLVM().getCUIndex(); 36 } 37 38 DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) { 39 if (const llvm::DWARFUnitIndex &index = m_context.GetAsLLVM().getCUIndex()) { 40 if (const llvm::DWARFUnitIndex::Entry *entry = index.getFromHash(hash)) { 41 if (auto *unit_contrib = entry->getContribution()) 42 return llvm::dyn_cast_or_null<DWARFCompileUnit>( 43 DebugInfo().GetUnitAtOffset(DIERef::Section::DebugInfo, 44 unit_contrib->Offset)); 45 } 46 return nullptr; 47 } 48 49 DWARFCompileUnit *cu = FindSingleCompileUnit(); 50 if (!cu) 51 return nullptr; 52 if (hash != cu->GetDWOId()) 53 return nullptr; 54 return cu; 55 } 56 57 DWARFCompileUnit *SymbolFileDWARFDwo::FindSingleCompileUnit() { 58 DWARFDebugInfo &debug_info = DebugInfo(); 59 60 // Right now we only support dwo files with one compile unit. If we don't have 61 // type units, we can just check for the unit count. 62 if (!debug_info.ContainsTypeUnits() && debug_info.GetNumUnits() == 1) 63 return llvm::cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(0)); 64 65 // Otherwise, we have to run through all units, and find the compile unit that 66 // way. 67 DWARFCompileUnit *cu = nullptr; 68 for (size_t i = 0; i < debug_info.GetNumUnits(); ++i) { 69 if (auto *candidate = 70 llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(i))) { 71 if (cu) 72 return nullptr; // More that one CU found. 73 cu = candidate; 74 } 75 } 76 return cu; 77 } 78 79 SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() { 80 return GetBaseSymbolFile().GetDIEToType(); 81 } 82 83 SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() { 84 return GetBaseSymbolFile().GetDIEToVariable(); 85 } 86 87 SymbolFileDWARF::DIEToClangType & 88 SymbolFileDWARFDwo::GetForwardDeclDieToClangType() { 89 return GetBaseSymbolFile().GetForwardDeclDieToClangType(); 90 } 91 92 SymbolFileDWARF::ClangTypeToDIE & 93 SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() { 94 return GetBaseSymbolFile().GetForwardDeclClangTypeToDie(); 95 } 96 97 void SymbolFileDWARFDwo::GetObjCMethods( 98 lldb_private::ConstString class_name, 99 llvm::function_ref<bool(DWARFDIE die)> callback) { 100 GetBaseSymbolFile().GetObjCMethods(class_name, callback); 101 } 102 103 UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() { 104 return GetBaseSymbolFile().GetUniqueDWARFASTTypeMap(); 105 } 106 107 lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext( 108 const DWARFDeclContext &die_decl_ctx) { 109 return GetBaseSymbolFile().FindDefinitionTypeForDWARFDeclContext( 110 die_decl_ctx); 111 } 112 113 lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE( 114 const DWARFDIE &die, lldb_private::ConstString type_name, 115 bool must_be_implementation) { 116 return GetBaseSymbolFile().FindCompleteObjCDefinitionTypeForDIE( 117 die, type_name, must_be_implementation); 118 } 119 120 llvm::Expected<TypeSystem &> 121 SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { 122 return GetBaseSymbolFile().GetTypeSystemForLanguage(language); 123 } 124 125 DWARFDIE 126 SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { 127 if (die_ref.dwo_num() == GetDwoNum()) 128 return DebugInfo().GetDIE(die_ref); 129 return GetBaseSymbolFile().GetDIE(die_ref); 130 } 131