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