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