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 uint64_t SymbolFileDWARFDwo::GetDebugInfoSize(bool load_all_debug_info) { 89 // Directly get debug info from current dwo object file's section list 90 // instead of asking SymbolFileCommon::GetDebugInfo() which parses from 91 // owning module which is wrong. 92 SectionList *section_list = 93 m_objfile_sp->GetSectionList(/*update_module_section_list=*/false); 94 if (section_list) 95 return section_list->GetDebugInfoSize(); 96 return 0; 97 } 98 99 bool SymbolFileDWARFDwo::ParseVendorDWARFOpcode( 100 uint8_t op, const lldb_private::DataExtractor &opcodes, 101 lldb::offset_t &offset, std::vector<lldb_private::Value> &stack) const { 102 return GetBaseSymbolFile().ParseVendorDWARFOpcode(op, opcodes, offset, stack); 103 } 104 105 llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> & 106 SymbolFileDWARFDwo::GetDIEToType() { 107 return GetBaseSymbolFile().GetDIEToType(); 108 } 109 110 SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() { 111 return GetBaseSymbolFile().GetDIEToVariable(); 112 } 113 114 llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> & 115 SymbolFileDWARFDwo::GetForwardDeclCompilerTypeToDIE() { 116 return GetBaseSymbolFile().GetForwardDeclCompilerTypeToDIE(); 117 } 118 119 void SymbolFileDWARFDwo::GetObjCMethods( 120 lldb_private::ConstString class_name, 121 llvm::function_ref<bool(DWARFDIE die)> callback) { 122 GetBaseSymbolFile().GetObjCMethods(class_name, callback); 123 } 124 125 UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() { 126 return GetBaseSymbolFile().GetUniqueDWARFASTTypeMap(); 127 } 128 129 DWARFDIE SymbolFileDWARFDwo::FindDefinitionDIE(const DWARFDIE &die) { 130 return GetBaseSymbolFile().FindDefinitionDIE(die); 131 } 132 133 lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE( 134 const DWARFDIE &die, lldb_private::ConstString type_name, 135 bool must_be_implementation) { 136 return GetBaseSymbolFile().FindCompleteObjCDefinitionTypeForDIE( 137 die, type_name, must_be_implementation); 138 } 139 140 llvm::Expected<lldb::TypeSystemSP> 141 SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { 142 return GetBaseSymbolFile().GetTypeSystemForLanguage(language); 143 } 144 145 DWARFDIE 146 SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { 147 if (die_ref.file_index() == GetFileIndex()) 148 return DebugInfo().GetDIE(die_ref.section(), die_ref.die_offset()); 149 return GetBaseSymbolFile().GetDIE(die_ref); 150 } 151 152 void SymbolFileDWARFDwo::FindGlobalVariables( 153 ConstString name, const CompilerDeclContext &parent_decl_ctx, 154 uint32_t max_matches, VariableList &variables) { 155 GetBaseSymbolFile().FindGlobalVariables(name, parent_decl_ctx, max_matches, 156 variables); 157 } 158 159 bool SymbolFileDWARFDwo::GetDebugInfoIndexWasLoadedFromCache() const { 160 return GetBaseSymbolFile().GetDebugInfoIndexWasLoadedFromCache(); 161 } 162 void SymbolFileDWARFDwo::SetDebugInfoIndexWasLoadedFromCache() { 163 GetBaseSymbolFile().SetDebugInfoIndexWasLoadedFromCache(); 164 } 165 bool SymbolFileDWARFDwo::GetDebugInfoIndexWasSavedToCache() const { 166 return GetBaseSymbolFile().GetDebugInfoIndexWasSavedToCache(); 167 } 168 void SymbolFileDWARFDwo::SetDebugInfoIndexWasSavedToCache() { 169 GetBaseSymbolFile().SetDebugInfoIndexWasSavedToCache(); 170 } 171 bool SymbolFileDWARFDwo::GetDebugInfoHadFrameVariableErrors() const { 172 return GetBaseSymbolFile().GetDebugInfoHadFrameVariableErrors(); 173 } 174 void SymbolFileDWARFDwo::SetDebugInfoHadFrameVariableErrors() { 175 return GetBaseSymbolFile().SetDebugInfoHadFrameVariableErrors(); 176 } 177 178 SymbolFileDWARF * 179 SymbolFileDWARFDwo::GetDIERefSymbolFile(const DIERef &die_ref) { 180 return GetBaseSymbolFile().GetDIERefSymbolFile(die_ref); 181 } 182