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 #include <optional> 21 22 using namespace lldb; 23 using namespace lldb_private; 24 using namespace lldb_private::plugin::dwarf; 25 26 char SymbolFileDWARFDwo::ID; 27 28 SymbolFileDWARFDwo::SymbolFileDWARFDwo(SymbolFileDWARF &base_symbol_file, 29 ObjectFileSP objfile, uint32_t id) 30 : SymbolFileDWARF(objfile, objfile->GetSectionList( 31 /*update_module_section_list*/ false)), 32 m_base_symbol_file(base_symbol_file) { 33 SetFileIndex(id); 34 35 // Parsing of the dwarf unit index is not thread-safe, so we need to prime it 36 // to enable subsequent concurrent lookups. 37 m_context.GetAsLLVM().getCUIndex(); 38 } 39 40 DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) { 41 if (const llvm::DWARFUnitIndex &index = m_context.GetAsLLVM().getCUIndex()) { 42 if (const llvm::DWARFUnitIndex::Entry *entry = index.getFromHash(hash)) { 43 if (auto *unit_contrib = entry->getContribution()) 44 return llvm::dyn_cast_or_null<DWARFCompileUnit>( 45 DebugInfo().GetUnitAtOffset(DIERef::Section::DebugInfo, 46 unit_contrib->getOffset())); 47 } 48 return nullptr; 49 } 50 51 DWARFCompileUnit *cu = FindSingleCompileUnit(); 52 if (!cu) 53 return nullptr; 54 std::optional<uint64_t> dwo_id = cu->GetDWOId(); 55 if (!dwo_id || hash != *dwo_id) 56 return nullptr; 57 return cu; 58 } 59 60 DWARFCompileUnit *SymbolFileDWARFDwo::FindSingleCompileUnit() { 61 DWARFDebugInfo &debug_info = DebugInfo(); 62 63 // Right now we only support dwo files with one compile unit. If we don't have 64 // type units, we can just check for the unit count. 65 if (!debug_info.ContainsTypeUnits() && debug_info.GetNumUnits() == 1) 66 return llvm::cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(0)); 67 68 // Otherwise, we have to run through all units, and find the compile unit that 69 // way. 70 DWARFCompileUnit *cu = nullptr; 71 for (size_t i = 0; i < debug_info.GetNumUnits(); ++i) { 72 if (auto *candidate = 73 llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(i))) { 74 if (cu) 75 return nullptr; // More that one CU found. 76 cu = candidate; 77 } 78 } 79 return cu; 80 } 81 82 lldb::offset_t SymbolFileDWARFDwo::GetVendorDWARFOpcodeSize( 83 const lldb_private::DataExtractor &data, const lldb::offset_t data_offset, 84 const uint8_t op) const { 85 return GetBaseSymbolFile().GetVendorDWARFOpcodeSize(data, data_offset, op); 86 } 87 88 bool SymbolFileDWARFDwo::ParseVendorDWARFOpcode( 89 uint8_t op, const lldb_private::DataExtractor &opcodes, 90 lldb::offset_t &offset, std::vector<lldb_private::Value> &stack) const { 91 return GetBaseSymbolFile().ParseVendorDWARFOpcode(op, opcodes, offset, stack); 92 } 93 94 SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() { 95 return GetBaseSymbolFile().GetDIEToType(); 96 } 97 98 SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() { 99 return GetBaseSymbolFile().GetDIEToVariable(); 100 } 101 102 SymbolFileDWARF::DIEToCompilerType & 103 SymbolFileDWARFDwo::GetForwardDeclDIEToCompilerType() { 104 return GetBaseSymbolFile().GetForwardDeclDIEToCompilerType(); 105 } 106 107 SymbolFileDWARF::CompilerTypeToDIE & 108 SymbolFileDWARFDwo::GetForwardDeclCompilerTypeToDIE() { 109 return GetBaseSymbolFile().GetForwardDeclCompilerTypeToDIE(); 110 } 111 112 void SymbolFileDWARFDwo::GetObjCMethods( 113 lldb_private::ConstString class_name, 114 llvm::function_ref<bool(DWARFDIE die)> callback) { 115 GetBaseSymbolFile().GetObjCMethods(class_name, callback); 116 } 117 118 UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() { 119 return GetBaseSymbolFile().GetUniqueDWARFASTTypeMap(); 120 } 121 122 lldb::TypeSP 123 SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) { 124 return GetBaseSymbolFile().FindDefinitionTypeForDWARFDeclContext(die); 125 } 126 127 lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE( 128 const DWARFDIE &die, lldb_private::ConstString type_name, 129 bool must_be_implementation) { 130 return GetBaseSymbolFile().FindCompleteObjCDefinitionTypeForDIE( 131 die, type_name, must_be_implementation); 132 } 133 134 llvm::Expected<lldb::TypeSystemSP> 135 SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { 136 return GetBaseSymbolFile().GetTypeSystemForLanguage(language); 137 } 138 139 DWARFDIE 140 SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { 141 if (die_ref.file_index() == GetFileIndex()) 142 return DebugInfo().GetDIE(die_ref); 143 return GetBaseSymbolFile().GetDIE(die_ref); 144 } 145 146 void SymbolFileDWARFDwo::FindGlobalVariables( 147 ConstString name, const CompilerDeclContext &parent_decl_ctx, 148 uint32_t max_matches, VariableList &variables) { 149 GetBaseSymbolFile().FindGlobalVariables(name, parent_decl_ctx, max_matches, 150 variables); 151 } 152