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 != 53 cu->GetUnitDIEOnly().GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0)) 54 return nullptr; 55 return cu; 56 } 57 58 DWARFCompileUnit *SymbolFileDWARFDwo::FindSingleCompileUnit() { 59 DWARFDebugInfo &debug_info = DebugInfo(); 60 61 // Right now we only support dwo files with one compile unit. If we don't have 62 // type units, we can just check for the unit count. 63 if (!debug_info.ContainsTypeUnits() && debug_info.GetNumUnits() == 1) 64 return llvm::cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(0)); 65 66 // Otherwise, we have to run through all units, and find the compile unit that 67 // way. 68 DWARFCompileUnit *cu = nullptr; 69 for (size_t i = 0; i < debug_info.GetNumUnits(); ++i) { 70 if (auto *candidate = 71 llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(i))) { 72 if (cu) 73 return nullptr; // More that one CU found. 74 cu = candidate; 75 } 76 } 77 return cu; 78 } 79 80 SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() { 81 return GetBaseSymbolFile().GetDIEToType(); 82 } 83 84 SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() { 85 return GetBaseSymbolFile().GetDIEToVariable(); 86 } 87 88 SymbolFileDWARF::DIEToClangType & 89 SymbolFileDWARFDwo::GetForwardDeclDieToClangType() { 90 return GetBaseSymbolFile().GetForwardDeclDieToClangType(); 91 } 92 93 SymbolFileDWARF::ClangTypeToDIE & 94 SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() { 95 return GetBaseSymbolFile().GetForwardDeclClangTypeToDie(); 96 } 97 98 void SymbolFileDWARFDwo::GetObjCMethods( 99 lldb_private::ConstString class_name, 100 llvm::function_ref<bool(DWARFDIE die)> callback) { 101 GetBaseSymbolFile().GetObjCMethods(class_name, callback); 102 } 103 104 UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() { 105 return GetBaseSymbolFile().GetUniqueDWARFASTTypeMap(); 106 } 107 108 lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext( 109 const DWARFDeclContext &die_decl_ctx) { 110 return GetBaseSymbolFile().FindDefinitionTypeForDWARFDeclContext( 111 die_decl_ctx); 112 } 113 114 lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE( 115 const DWARFDIE &die, lldb_private::ConstString type_name, 116 bool must_be_implementation) { 117 return GetBaseSymbolFile().FindCompleteObjCDefinitionTypeForDIE( 118 die, type_name, must_be_implementation); 119 } 120 121 llvm::Expected<TypeSystem &> 122 SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { 123 return GetBaseSymbolFile().GetTypeSystemForLanguage(language); 124 } 125 126 DWARFDIE 127 SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { 128 if (die_ref.dwo_num() == GetDwoNum()) 129 return DebugInfo().GetDIE(die_ref); 130 return GetBaseSymbolFile().GetDIE(die_ref); 131 } 132