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"
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_namespaces_table_up ||
46  apple_types_table_up || 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 
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 
65  const RegularExpression &regex,
66  llvm::function_ref<bool(DWARFDIE die)> callback) {
67  if (!m_apple_names_up)
68  return;
69 
71  m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
72  // This is not really the DIE name.
74  DIERefCallback(callback, regex.GetText()));
75 }
76 
78  DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) {
79  if (!m_apple_names_up)
80  return;
81 
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);
88  DWARFMappedHash::ExtractDIEArray(hash_data, DIERefCallback(callback));
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 
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) {
176  if (!m_apple_namespaces_up)
177  return;
178  m_apple_namespaces_up->FindByName(
179  name.GetStringRef(), DIERefCallback(callback, name.GetStringRef()));
180 }
181 
184  const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
185  llvm::function_ref<bool(DWARFDIE die)> callback) {
186  m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) {
187  return ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf,
188  parent_decl_ctx, name_type_mask, 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 
205  if (m_apple_names_up)
206  s.PutCString(".apple_names index present\n");
207  if (m_apple_namespaces_up)
208  s.PutCString(".apple_namespaces index present\n");
209  if (m_apple_types_up)
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 }
DIERef
Identifies a DWARF debug info entry within a given Module.
Definition: DIERef.h:26
lldb_private::RegularExpression
Definition: RegularExpression.h:18
dw_tag_t
llvm::dwarf::Tag dw_tag_t
Definition: dwarf.h:25
DWARF_LOG_LOOKUPS
#define DWARF_LOG_LOOKUPS
Definition: LogChannelDWARF.h:16
lldb_private::AppleDWARFIndex::GetCompleteObjCClass
void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, llvm::function_ref< bool(DWARFDIE die)> callback) override
Definition: AppleDWARFIndex.cpp:100
lldb_private::AppleDWARFIndex::GetObjCMethods
void GetObjCMethods(ConstString class_name, llvm::function_ref< bool(DWARFDIE die)> callback) override
Definition: AppleDWARFIndex.cpp:91
Module.h
lldb_private::AppleDWARFIndex::Create
static std::unique_ptr< AppleDWARFIndex > Create(Module &module, DWARFDataExtractor apple_names, DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types, DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str)
Definition: AppleDWARFIndex.cpp:20
SymbolFileDWARF
Definition: SymbolFileDWARF.h:58
lldb_private::Module
Definition: Module.h:84
lldb_private::AppleDWARFIndex::Dump
void Dump(Stream &s) override
Definition: AppleDWARFIndex.cpp:204
lldb_private::Stream
Definition: Stream.h:28
lldb_private::DWARFDataExtractor
Definition: DWARFDataExtractor.h:18
lldb_private::AppleDWARFIndex::GetFunctions
void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, llvm::function_ref< bool(DWARFDIE die)> callback) override
Definition: AppleDWARFIndex.cpp:182
DWARFDeclContext.h
DWARFDIE
Definition: DWARFDIE.h:16
DWARFUnit
Definition: DWARFUnit.h:81
dwarf
Definition: ABISysV_arc.cpp:61
DWARFUnit::GetNextUnitOffset
dw_offset_t GetNextUnitOffset() const
Definition: DWARFUnit.h:147
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:202
DWARFDeclContext::GetQualifiedName
const char * GetQualifiedName() const
Definition: DWARFDeclContext.cpp:11
DWARFDeclContext::GetSize
uint32_t GetSize() const
Definition: DWARFDeclContext.h:53
lldb_private::ConstString
Definition: ConstString.h:40
DWARFMappedHash::ExtractDIEArray
static bool ExtractDIEArray(const DIEInfoArray &die_info_array, llvm::function_ref< bool(DIERef ref)> callback)
Definition: HashedNameToDIE.cpp:12
LogChannelDWARF.h
AppleDWARFIndex.h
DWARFUnit.h
lldb_private::CompilerDeclContext
Represents a generic declaration context in a program.
Definition: CompilerDeclContext.h:30
DWARFUnit::GetOffset
dw_offset_t GetOffset() const
Definition: DWARFUnit.h:131
lldbassert
#define lldbassert(x)
Definition: LLDBAssert.h:15
uint32_t
lldb_private::AppleDWARFIndex::GetTypes
void GetTypes(ConstString name, llvm::function_ref< bool(DWARFDIE die)> callback) override
Definition: AppleDWARFIndex.cpp:111
DWARFUnit::GetNonSkeletonUnit
DWARFUnit & GetNonSkeletonUnit()
Definition: DWARFUnit.cpp:627
DWARFMappedHash::DIEInfoArray
std::vector< DIEInfo > DIEInfoArray
Definition: HashedNameToDIE.h:77
Function.h
DWARFMappedHash::eAtomTypeTag
@ eAtomTypeTag
DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2.
Definition: HashedNameToDIE.h:34
DWARFDeclContext
Definition: DWARFDeclContext.h:23
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
SymbolFileDWARF::GetDwoNum
virtual llvm::Optional< uint32_t > GetDwoNum()
Definition: SymbolFileDWARF.h:279
lldb_private::LogChannelDWARF::GetLogIfAny
static Log * GetLogIfAny(uint32_t mask)
Definition: LogChannelDWARF.h:31
DWARF_LOG_TYPE_COMPLETION
#define DWARF_LOG_TYPE_COMPLETION
Definition: LogChannelDWARF.h:17
lldb_private::Log
Definition: Log.h:49
lldb_private::Stream::PutCString
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
DWARFUnit::GetSymbolFileDWARF
SymbolFileDWARF & GetSymbolFileDWARF() const
Definition: DWARFUnit.h:195
lldb_private::RegularExpression::GetText
llvm::StringRef GetText() const
Access the regular expression text.
Definition: RegularExpression.cpp:33
DWARFMappedHash::eAtomTypeQualNameHash
@ eAtomTypeQualNameHash
A 32 bit hash of the full qualified name (since all hash entries are basename only) For example a typ...
Definition: HashedNameToDIE.h:44
lldb
Definition: SBAddress.h:15
lldb_private::AppleDWARFIndex::GetNamespaces
void GetNamespaces(ConstString name, llvm::function_ref< bool(DWARFDIE die)> callback) override
Definition: AppleDWARFIndex.cpp:174
lldb_private::AppleDWARFIndex::GetGlobalVariables
void GetGlobalVariables(ConstString basename, llvm::function_ref< bool(DWARFDIE die)> callback) override
Finds global variables with the given base name.
Definition: AppleDWARFIndex.cpp:55