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