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
84 const DWARFUnit &non_skeleton_cu = cu.GetNonSkeletonUnit();
86 m_apple_names_up->AppendAllDIEsInRange(non_skeleton_cu.GetOffset(),
87 non_skeleton_cu.GetNextUnitOffset(),
88 hash_data);
90}
91
93 ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) {
94 if (!m_apple_objc_up)
95 return;
96 m_apple_objc_up->FindByName(
97 class_name.GetStringRef(),
98 DIERefCallback(callback, class_name.GetStringRef()));
99}
100
102 ConstString class_name, bool must_be_implementation,
103 llvm::function_ref<bool(DWARFDIE die)> callback) {
104 if (!m_apple_types_up)
105 return;
106 m_apple_types_up->FindCompleteObjCClassByName(
107 class_name.GetStringRef(),
108 DIERefCallback(callback, class_name.GetStringRef()),
109 must_be_implementation);
110}
111
113 ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
114 if (!m_apple_types_up)
115 return;
116 m_apple_types_up->FindByName(name.GetStringRef(),
117 DIERefCallback(callback, name.GetStringRef()));
118}
119
121 const DWARFDeclContext &context,
122 llvm::function_ref<bool(DWARFDIE die)> callback) {
123 if (!m_apple_types_up)
124 return;
125
127 const bool has_tag = m_apple_types_up->GetHeader().header_data.ContainsAtom(
129 const bool has_qualified_name_hash =
130 m_apple_types_up->GetHeader().header_data.ContainsAtom(
132
133 const ConstString type_name(context[0].name);
134 const dw_tag_t tag = context[0].tag;
135 if (has_tag && has_qualified_name_hash) {
136 const char *qualified_name = context.GetQualifiedName();
137 const uint32_t qualified_name_hash = llvm::djbHash(qualified_name);
138 if (log)
139 m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
140 m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
141 type_name.GetStringRef(), tag, qualified_name_hash,
142 DIERefCallback(callback, type_name.GetStringRef()));
143 return;
144 }
145
146 if (has_tag) {
147 // When searching for a scoped type (for example,
148 // "std::vector<int>::const_iterator") searching for the innermost
149 // name alone ("const_iterator") could yield many false
150 // positives. By searching for the parent type ("vector<int>")
151 // first we can avoid extracting type DIEs from object files that
152 // would fail the filter anyway.
153 if (!has_qualified_name_hash && (context.GetSize() > 1) &&
154 (context[1].tag == DW_TAG_class_type ||
155 context[1].tag == DW_TAG_structure_type)) {
156 if (m_apple_types_up->FindByName(context[1].name,
157 [&](DIERef ref) { return false; }))
158 return;
159 }
160
161 if (log)
162 m_module.LogMessage(log, "FindByNameAndTag()");
163 m_apple_types_up->FindByNameAndTag(
164 type_name.GetStringRef(), tag,
165 DIERefCallback(callback, type_name.GetStringRef()));
166 return;
167 }
168
169 m_apple_types_up->FindByName(
170 type_name.GetStringRef(),
171 DIERefCallback(callback, type_name.GetStringRef()));
172}
173
175 ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
177 return;
178 m_apple_namespaces_up->FindByName(
179 name.GetStringRef(), DIERefCallback(callback, name.GetStringRef()));
180}
181
183 const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf,
184 const CompilerDeclContext &parent_decl_ctx,
185 llvm::function_ref<bool(DWARFDIE die)> callback) {
186 ConstString name = lookup_info.GetLookupName();
187 m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) {
188 return ProcessFunctionDIE(lookup_info, die_ref, dwarf, parent_decl_ctx,
189 callback);
190 });
191}
192
194 const RegularExpression &regex,
195 llvm::function_ref<bool(DWARFDIE die)> callback) {
196 if (!m_apple_names_up)
197 return;
198
200 m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
202 DIERefCallback(callback, regex.GetText()));
203}
204
207 s.PutCString(".apple_names index present\n");
209 s.PutCString(".apple_namespaces index present\n");
211 s.PutCString(".apple_types index present\n");
212 if (m_apple_objc_up)
213 s.PutCString(".apple_objc index present\n");
214 // TODO: Dump index contents
215}
#define lldbassert(x)
Definition: LLDBAssert.h:15
Identifies a DWARF debug info entry within a given Module.
Definition: DIERef.h:26
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)
SymbolFileDWARF & GetSymbolFileDWARF() const
Definition: DWARFUnit.h:200
dw_offset_t GetNextUnitOffset() const
Definition: DWARFUnit.h:150
DWARFUnit & GetNonSkeletonUnit()
Definition: DWARFUnit.cpp:662
dw_offset_t GetOffset() const
Definition: DWARFUnit.h:134
virtual std::optional< uint32_t > GetDwoNum()
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:201
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:28
A class that represents a running process on the host machine.
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