LLDB mainline
AppleDWARFIndex.cpp
Go to the documentation of this file.
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
13
14#include "lldb/Core/Module.h"
16
17using namespace lldb_private;
18using namespace lldb;
19using namespace lldb_private::dwarf;
20
21std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
22 Module &module, DWARFDataExtractor apple_names,
23 DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
24 DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str) {
25 auto apple_names_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
26 apple_names, debug_str, ".apple_names");
27 if (!apple_names_table_up->IsValid())
28 apple_names_table_up.reset();
29
30 auto apple_namespaces_table_up =
31 std::make_unique<DWARFMappedHash::MemoryTable>(
32 apple_namespaces, debug_str, ".apple_namespaces");
33 if (!apple_namespaces_table_up->IsValid())
34 apple_namespaces_table_up.reset();
35
36 auto apple_types_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
37 apple_types, debug_str, ".apple_types");
38 if (!apple_types_table_up->IsValid())
39 apple_types_table_up.reset();
40
41 auto apple_objc_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
42 apple_objc, debug_str, ".apple_objc");
43 if (!apple_objc_table_up->IsValid())
44 apple_objc_table_up.reset();
45
46 if (apple_names_table_up || apple_namespaces_table_up ||
47 apple_types_table_up || apple_objc_table_up)
48 return std::make_unique<AppleDWARFIndex>(
49 module, std::move(apple_names_table_up),
50 std::move(apple_namespaces_table_up), std::move(apple_types_table_up),
51 std::move(apple_objc_table_up));
52
53 return nullptr;
54}
55
57 ConstString basename, llvm::function_ref<bool(DWARFDIE die)> callback) {
59 return;
60 m_apple_names_up->FindByName(
61 basename.GetStringRef(),
62 DIERefCallback(callback, basename.GetStringRef()));
63}
64
66 const RegularExpression &regex,
67 llvm::function_ref<bool(DWARFDIE die)> callback) {
69 return;
70
72 m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
73 // This is not really the DIE name.
75 DIERefCallback(callback, regex.GetText()));
76}
77
79 DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) {
81 return;
82
83 const DWARFUnit &non_skeleton_cu = cu.GetNonSkeletonUnit();
85 m_apple_names_up->AppendAllDIEsInRange(non_skeleton_cu.GetOffset(),
86 non_skeleton_cu.GetNextUnitOffset(),
87 hash_data);
89}
90
92 ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) {
93 if (!m_apple_objc_up)
94 return;
95 m_apple_objc_up->FindByName(
96 class_name.GetStringRef(),
97 DIERefCallback(callback, class_name.GetStringRef()));
98}
99
101 ConstString class_name, bool must_be_implementation,
102 llvm::function_ref<bool(DWARFDIE die)> callback) {
103 if (!m_apple_types_up)
104 return;
105 m_apple_types_up->FindCompleteObjCClassByName(
106 class_name.GetStringRef(),
107 DIERefCallback(callback, class_name.GetStringRef()),
108 must_be_implementation);
109}
110
112 ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
113 if (!m_apple_types_up)
114 return;
115 m_apple_types_up->FindByName(name.GetStringRef(),
116 DIERefCallback(callback, name.GetStringRef()));
117}
118
120 const DWARFDeclContext &context,
121 llvm::function_ref<bool(DWARFDIE die)> callback) {
122 if (!m_apple_types_up)
123 return;
124
126 const bool has_tag = m_apple_types_up->GetHeader().header_data.ContainsAtom(
128 const bool has_qualified_name_hash =
129 m_apple_types_up->GetHeader().header_data.ContainsAtom(
131
132 const ConstString type_name(context[0].name);
133 const dw_tag_t tag = context[0].tag;
134 if (has_tag && has_qualified_name_hash) {
135 const char *qualified_name = context.GetQualifiedName();
136 const uint32_t qualified_name_hash = llvm::djbHash(qualified_name);
137 if (log)
138 m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
139 m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
140 type_name.GetStringRef(), tag, qualified_name_hash,
141 DIERefCallback(callback, type_name.GetStringRef()));
142 return;
143 }
144
145 if (has_tag) {
146 // When searching for a scoped type (for example,
147 // "std::vector<int>::const_iterator") searching for the innermost
148 // name alone ("const_iterator") could yield many false
149 // positives. By searching for the parent type ("vector<int>")
150 // first we can avoid extracting type DIEs from object files that
151 // would fail the filter anyway.
152 if (!has_qualified_name_hash && (context.GetSize() > 1) &&
153 (context[1].tag == DW_TAG_class_type ||
154 context[1].tag == DW_TAG_structure_type)) {
155 if (m_apple_types_up->FindByName(context[1].name,
156 [&](DIERef ref) { return false; }))
157 return;
158 }
159
160 if (log)
161 m_module.LogMessage(log, "FindByNameAndTag()");
162 m_apple_types_up->FindByNameAndTag(
163 type_name.GetStringRef(), tag,
164 DIERefCallback(callback, type_name.GetStringRef()));
165 return;
166 }
167
168 m_apple_types_up->FindByName(
169 type_name.GetStringRef(),
170 DIERefCallback(callback, type_name.GetStringRef()));
171}
172
174 ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
176 return;
177 m_apple_namespaces_up->FindByName(
178 name.GetStringRef(), DIERefCallback(callback, name.GetStringRef()));
179}
180
182 const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf,
183 const CompilerDeclContext &parent_decl_ctx,
184 llvm::function_ref<bool(DWARFDIE die)> callback) {
185 ConstString name = lookup_info.GetLookupName();
186 m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) {
187 return ProcessFunctionDIE(lookup_info, die_ref, dwarf, parent_decl_ctx,
188 callback);
189 });
190}
191
193 const RegularExpression &regex,
194 llvm::function_ref<bool(DWARFDIE die)> callback) {
195 if (!m_apple_names_up)
196 return;
197
199 m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
201 DIERefCallback(callback, regex.GetText()));
202}
203
206 s.PutCString(".apple_names index present\n");
208 s.PutCString(".apple_namespaces index present\n");
210 s.PutCString(".apple_types index present\n");
211 if (m_apple_objc_up)
212 s.PutCString(".apple_objc index present\n");
213 // TODO: Dump index contents
214}
Identifies a DWARF debug info entry within a given Module.
Definition: DIERef.h:28
const char * GetQualifiedName() const
uint32_t GetSize() const
@ eAtomTypeQualNameHash
A 32 bit hash of the full qualified name (since all hash entries are basename only) For example a typ...
@ eAtomTypeTag
DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2.
std::vector< DIEInfo > DIEInfoArray
static bool ExtractDIEArray(const DIEInfoArray &die_info_array, llvm::function_ref< bool(DIERef ref)> callback)
dw_offset_t GetNextUnitOffset() const
Definition: DWARFUnit.h:150
DWARFUnit & GetNonSkeletonUnit()
Definition: DWARFUnit.cpp:663
dw_offset_t GetOffset() const
Definition: DWARFUnit.h:134
void GetGlobalVariables(ConstString basename, llvm::function_ref< bool(DWARFDIE die)> callback) override
Finds global variables with the given base name.
void GetNamespaces(ConstString name, llvm::function_ref< bool(DWARFDIE die)> callback) override
void GetObjCMethods(ConstString class_name, llvm::function_ref< bool(DWARFDIE die)> callback) override
static std::unique_ptr< AppleDWARFIndex > Create(Module &module, DWARFDataExtractor apple_names, DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types, DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str)
std::unique_ptr< DWARFMappedHash::MemoryTable > m_apple_types_up
void GetTypes(ConstString name, llvm::function_ref< bool(DWARFDIE die)> callback) override
std::unique_ptr< DWARFMappedHash::MemoryTable > m_apple_objc_up
std::unique_ptr< DWARFMappedHash::MemoryTable > m_apple_names_up
void Dump(Stream &s) override
void GetFunctions(const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, llvm::function_ref< bool(DWARFDIE die)> callback) override
void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, llvm::function_ref< bool(DWARFDIE die)> callback) override
std::unique_ptr< DWARFMappedHash::MemoryTable > m_apple_namespaces_up
Represents a generic declaration context in a program.
A uniqued constant string class.
Definition: ConstString.h:39
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:204
DIERefCallbackImpl DIERefCallback(llvm::function_ref< bool(DWARFDIE die)> callback, llvm::StringRef name={}) const
Definition: DWARFIndex.h:96
A class that encapsulates name lookup information.
Definition: Module.h:950
ConstString GetLookupName() const
Definition: Module.h:961
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:88
void LogMessage(Log *log, const char *format, Args &&...args)
Definition: Module.h:829
llvm::StringRef GetText() const
Access the regular expression text.
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
llvm::dwarf::Tag dw_tag_t
Definition: dwarf.h:26
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:309
Definition: SBAddress.h:15