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