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 21using namespace lldb; 22using namespace lldb_private; 23 24char SymbolFileDWARFDwo::ID; 25 26SymbolFileDWARFDwo::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 38DWARFCompileUnit *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 58DWARFCompileUnit *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 80SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() { 81 return GetBaseSymbolFile().GetDIEToType(); 82} 83 84SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() { 85 return GetBaseSymbolFile().GetDIEToVariable(); 86} 87 88SymbolFileDWARF::DIEToClangType & 89SymbolFileDWARFDwo::GetForwardDeclDieToClangType() { 90 return GetBaseSymbolFile().GetForwardDeclDieToClangType(); 91} 92 93SymbolFileDWARF::ClangTypeToDIE & 94SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() { 95 return GetBaseSymbolFile().GetForwardDeclClangTypeToDie(); 96} 97 98void SymbolFileDWARFDwo::GetObjCMethods( 99 lldb_private::ConstString class_name, 100 llvm::function_ref<bool(DWARFDIE die)> callback) { 101 GetBaseSymbolFile().GetObjCMethods(class_name, callback); 102} 103 104UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() { 105 return GetBaseSymbolFile().GetUniqueDWARFASTTypeMap(); 106} 107 108lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext( 109 const DWARFDeclContext &die_decl_ctx) { 110 return GetBaseSymbolFile().FindDefinitionTypeForDWARFDeclContext( 111 die_decl_ctx); 112} 113 114lldb::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 121llvm::Expected<TypeSystem &> 122SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { 123 return GetBaseSymbolFile().GetTypeSystemForLanguage(language); 124} 125 126DWARFDIE 127SymbolFileDWARFDwo::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