1 //===-- SymbolFileDWARFDwo.cpp ----------------------------------*- C++ -*-===// 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 16 #include "DWARFUnit.h" 17 #include "DWARFDebugInfo.h" 18 19 using namespace lldb; 20 using namespace lldb_private; 21 22 SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile, 23 DWARFUnit *dwarf_cu) 24 : SymbolFileDWARF(objfile.get()), m_obj_file_sp(objfile), 25 m_base_dwarf_cu(dwarf_cu) { 26 SetID(((lldb::user_id_t)dwarf_cu->GetID()) << 32); 27 } 28 29 void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type, 30 DWARFDataExtractor &data) { 31 const SectionList *section_list = 32 m_obj_file->GetSectionList(false /* update_module_section_list */); 33 if (section_list) { 34 SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); 35 if (section_sp) { 36 37 if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) 38 return; 39 40 data.Clear(); 41 } 42 } 43 44 SymbolFileDWARF::LoadSectionData(sect_type, data); 45 } 46 47 lldb::CompUnitSP 48 SymbolFileDWARFDwo::ParseCompileUnit(DWARFUnit *dwarf_cu, 49 uint32_t cu_idx) { 50 assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit " 51 "called with incompatible compile " 52 "unit"); 53 return GetBaseSymbolFile()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX); 54 } 55 56 DWARFUnit *SymbolFileDWARFDwo::GetCompileUnit() { 57 // Only dwo files with 1 compile unit is supported 58 if (GetNumCompileUnits() == 1) 59 return DebugInfo()->GetUnitAtIndex(0); 60 else 61 return nullptr; 62 } 63 64 DWARFUnit * 65 SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { 66 return GetCompileUnit(); 67 } 68 69 SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() { 70 return GetBaseSymbolFile()->GetDIEToType(); 71 } 72 73 SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() { 74 return GetBaseSymbolFile()->GetDIEToVariable(); 75 } 76 77 SymbolFileDWARF::DIEToClangType & 78 SymbolFileDWARFDwo::GetForwardDeclDieToClangType() { 79 return GetBaseSymbolFile()->GetForwardDeclDieToClangType(); 80 } 81 82 SymbolFileDWARF::ClangTypeToDIE & 83 SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() { 84 return GetBaseSymbolFile()->GetForwardDeclClangTypeToDie(); 85 } 86 87 size_t SymbolFileDWARFDwo::GetObjCMethodDIEOffsets( 88 lldb_private::ConstString class_name, DIEArray &method_die_offsets) { 89 return GetBaseSymbolFile()->GetObjCMethodDIEOffsets( 90 class_name, method_die_offsets); 91 } 92 93 UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() { 94 return GetBaseSymbolFile()->GetUniqueDWARFASTTypeMap(); 95 } 96 97 lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext( 98 const DWARFDeclContext &die_decl_ctx) { 99 return GetBaseSymbolFile()->FindDefinitionTypeForDWARFDeclContext( 100 die_decl_ctx); 101 } 102 103 lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE( 104 const DWARFDIE &die, lldb_private::ConstString type_name, 105 bool must_be_implementation) { 106 return GetBaseSymbolFile()->FindCompleteObjCDefinitionTypeForDIE( 107 die, type_name, must_be_implementation); 108 } 109 110 DWARFUnit *SymbolFileDWARFDwo::GetBaseCompileUnit() { 111 return m_base_dwarf_cu; 112 } 113 114 const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_abbrev_data() { 115 return GetCachedSectionData(eSectionTypeDWARFDebugAbbrevDwo, 116 m_data_debug_abbrev); 117 } 118 119 const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_addr_data() { 120 // For single file split dwarf case (when we have .dwo sections in a .o), 121 // we do not want to use the .debug_addr section from .o file, 122 // but want to get one from the final executable. 123 // For regular split debug case, .dwo file does not contain the 124 // .debug_addr, so we would always fall back to such lookup anyways. 125 llvm::call_once(m_data_debug_addr.m_flag, [this] { 126 SymbolFileDWARF::LoadSectionData(eSectionTypeDWARFDebugAddr, 127 std::ref(m_data_debug_addr.m_data)); 128 }); 129 return m_data_debug_addr.m_data; 130 } 131 132 const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_info_data() { 133 return GetCachedSectionData(eSectionTypeDWARFDebugInfoDwo, m_data_debug_info); 134 } 135 136 const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_data() { 137 return GetCachedSectionData(eSectionTypeDWARFDebugStrDwo, m_data_debug_str); 138 } 139 140 const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_offsets_data() { 141 return GetCachedSectionData(eSectionTypeDWARFDebugStrOffsetsDwo, 142 m_data_debug_str_offsets); 143 } 144 145 SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() { 146 return m_base_dwarf_cu->GetSymbolFileDWARF(); 147 } 148 149 DWARFExpression::LocationListFormat 150 SymbolFileDWARFDwo::GetLocationListFormat() const { 151 return DWARFExpression::SplitDwarfLocationList; 152 } 153 154 TypeSystem * 155 SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { 156 return GetBaseSymbolFile()->GetTypeSystemForLanguage(language); 157 } 158 159 DWARFDIE 160 SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { 161 lldbassert(die_ref.cu_offset == m_base_dwarf_cu->GetOffset() || 162 die_ref.cu_offset == DW_INVALID_OFFSET); 163 return DebugInfo()->GetDIEForDIEOffset(die_ref.section, die_ref.die_offset); 164 } 165