]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
Import tzdata 2020c
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / SymbolFile / DWARF / AppleDWARFIndex.cpp
1 //===-- AppleDWARFIndex.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 "Plugins/SymbolFile/DWARF/AppleDWARFIndex.h"
10 #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
11 #include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
12 #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
13
14 #include "lldb/Core/Module.h"
15 #include "lldb/Symbol/Function.h"
16
17 using namespace lldb_private;
18 using namespace lldb;
19
20 std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
21     Module &module, DWARFDataExtractor apple_names,
22     DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
23     DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str) {
24   auto apple_names_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
25       apple_names, debug_str, ".apple_names");
26   if (!apple_names_table_up->IsValid())
27     apple_names_table_up.reset();
28
29   auto apple_namespaces_table_up =
30       std::make_unique<DWARFMappedHash::MemoryTable>(
31           apple_namespaces, debug_str, ".apple_namespaces");
32   if (!apple_namespaces_table_up->IsValid())
33     apple_namespaces_table_up.reset();
34
35   auto apple_types_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
36       apple_types, debug_str, ".apple_types");
37   if (!apple_types_table_up->IsValid())
38     apple_types_table_up.reset();
39
40   auto apple_objc_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
41       apple_objc, debug_str, ".apple_objc");
42   if (!apple_objc_table_up->IsValid())
43     apple_objc_table_up.reset();
44
45   if (apple_names_table_up || apple_names_table_up || apple_types_table_up ||
46       apple_objc_table_up)
47     return std::make_unique<AppleDWARFIndex>(
48         module, std::move(apple_names_table_up),
49         std::move(apple_namespaces_table_up), std::move(apple_types_table_up),
50         std::move(apple_objc_table_up));
51
52   return nullptr;
53 }
54
55 void AppleDWARFIndex::GetGlobalVariables(
56     ConstString basename, llvm::function_ref<bool(DWARFDIE die)> callback) {
57   if (!m_apple_names_up)
58     return;
59   m_apple_names_up->FindByName(
60       basename.GetStringRef(),
61       DIERefCallback(callback, basename.GetStringRef()));
62 }
63
64 void AppleDWARFIndex::GetGlobalVariables(
65     const RegularExpression &regex,
66     llvm::function_ref<bool(DWARFDIE die)> callback) {
67   if (!m_apple_names_up)
68     return;
69
70   DWARFMappedHash::DIEInfoArray hash_data;
71   m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
72   // This is not really the DIE name.
73   DWARFMappedHash::ExtractDIEArray(hash_data,
74                                    DIERefCallback(callback, regex.GetText()));
75 }
76
77 void AppleDWARFIndex::GetGlobalVariables(
78     const DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) {
79   if (!m_apple_names_up)
80     return;
81
82   DWARFMappedHash::DIEInfoArray hash_data;
83   m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), cu.GetNextUnitOffset(),
84                                          hash_data);
85   DWARFMappedHash::ExtractDIEArray(hash_data, DIERefCallback(callback));
86 }
87
88 void AppleDWARFIndex::GetObjCMethods(
89     ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) {
90   if (!m_apple_objc_up)
91     return;
92   m_apple_objc_up->FindByName(
93       class_name.GetStringRef(),
94       DIERefCallback(callback, class_name.GetStringRef()));
95 }
96
97 void AppleDWARFIndex::GetCompleteObjCClass(
98     ConstString class_name, bool must_be_implementation,
99     llvm::function_ref<bool(DWARFDIE die)> callback) {
100   if (!m_apple_types_up)
101     return;
102   m_apple_types_up->FindCompleteObjCClassByName(
103       class_name.GetStringRef(),
104       DIERefCallback(callback, class_name.GetStringRef()),
105       must_be_implementation);
106 }
107
108 void AppleDWARFIndex::GetTypes(
109     ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
110   if (!m_apple_types_up)
111     return;
112   m_apple_types_up->FindByName(name.GetStringRef(),
113                                DIERefCallback(callback, name.GetStringRef()));
114 }
115
116 void AppleDWARFIndex::GetTypes(
117     const DWARFDeclContext &context,
118     llvm::function_ref<bool(DWARFDIE die)> callback) {
119   if (!m_apple_types_up)
120     return;
121
122   Log *log = LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
123                                           DWARF_LOG_LOOKUPS);
124   const bool has_tag = m_apple_types_up->GetHeader().header_data.ContainsAtom(
125       DWARFMappedHash::eAtomTypeTag);
126   const bool has_qualified_name_hash =
127       m_apple_types_up->GetHeader().header_data.ContainsAtom(
128           DWARFMappedHash::eAtomTypeQualNameHash);
129
130   const ConstString type_name(context[0].name);
131   const dw_tag_t tag = context[0].tag;
132   if (has_tag && has_qualified_name_hash) {
133     const char *qualified_name = context.GetQualifiedName();
134     const uint32_t qualified_name_hash = llvm::djbHash(qualified_name);
135     if (log)
136       m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
137     m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
138         type_name.GetStringRef(), tag, qualified_name_hash,
139         DIERefCallback(callback, type_name.GetStringRef()));
140     return;
141   }
142
143   if (has_tag) {
144     // When searching for a scoped type (for example,
145     // "std::vector<int>::const_iterator") searching for the innermost
146     // name alone ("const_iterator") could yield many false
147     // positives. By searching for the parent type ("vector<int>")
148     // first we can avoid extracting type DIEs from object files that
149     // would fail the filter anyway.
150     if (!has_qualified_name_hash && (context.GetSize() > 1) &&
151         (context[1].tag == DW_TAG_class_type ||
152          context[1].tag == DW_TAG_structure_type)) {
153       if (m_apple_types_up->FindByName(context[1].name,
154                                        [&](DIERef ref) { return false; }))
155         return;
156     }
157
158     if (log)
159       m_module.LogMessage(log, "FindByNameAndTag()");
160     m_apple_types_up->FindByNameAndTag(
161         type_name.GetStringRef(), tag,
162         DIERefCallback(callback, type_name.GetStringRef()));
163     return;
164   }
165
166   m_apple_types_up->FindByName(
167       type_name.GetStringRef(),
168       DIERefCallback(callback, type_name.GetStringRef()));
169 }
170
171 void AppleDWARFIndex::GetNamespaces(
172     ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
173   if (!m_apple_namespaces_up)
174     return;
175   m_apple_namespaces_up->FindByName(
176       name.GetStringRef(), DIERefCallback(callback, name.GetStringRef()));
177 }
178
179 void AppleDWARFIndex::GetFunctions(
180     ConstString name, SymbolFileDWARF &dwarf,
181     const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
182     llvm::function_ref<bool(DWARFDIE die)> callback) {
183   m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) {
184     return ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf,
185                               parent_decl_ctx, name_type_mask, callback);
186   });
187 }
188
189 void AppleDWARFIndex::GetFunctions(
190     const RegularExpression &regex,
191     llvm::function_ref<bool(DWARFDIE die)> callback) {
192   if (!m_apple_names_up)
193     return;
194
195   DWARFMappedHash::DIEInfoArray hash_data;
196   m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
197   DWARFMappedHash::ExtractDIEArray(hash_data,
198                                    DIERefCallback(callback, regex.GetText()));
199 }
200
201 void AppleDWARFIndex::Dump(Stream &s) {
202   if (m_apple_names_up)
203     s.PutCString(".apple_names index present\n");
204   if (m_apple_namespaces_up)
205     s.PutCString(".apple_namespaces index present\n");
206   if (m_apple_types_up)
207     s.PutCString(".apple_types index present\n");
208   if (m_apple_objc_up)
209     s.PutCString(".apple_objc index present\n");
210   // TODO: Dump index contents
211 }