1 //===-- AppleDWARFIndex.cpp ------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "Plugins/SymbolFile/DWARF/AppleDWARFIndex.h"
11 #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
12 #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
13 #include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
14 #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Symbol/Function.h"
19 using namespace lldb_private;
22 std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
23 Module &module, DWARFDataExtractor apple_names,
24 DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
25 DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str) {
26 auto apple_names_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
27 apple_names, debug_str, ".apple_names");
28 if (!apple_names_table_up->IsValid())
29 apple_names_table_up.reset();
31 auto apple_namespaces_table_up =
32 llvm::make_unique<DWARFMappedHash::MemoryTable>(
33 apple_namespaces, debug_str, ".apple_namespaces");
34 if (!apple_namespaces_table_up->IsValid())
35 apple_namespaces_table_up.reset();
37 auto apple_types_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
38 apple_types, debug_str, ".apple_types");
39 if (!apple_types_table_up->IsValid())
40 apple_types_table_up.reset();
42 auto apple_objc_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
43 apple_objc, debug_str, ".apple_objc");
44 if (!apple_objc_table_up->IsValid())
45 apple_objc_table_up.reset();
47 if (apple_names_table_up || apple_names_table_up || apple_types_table_up ||
49 return llvm::make_unique<AppleDWARFIndex>(
50 module, std::move(apple_names_table_up),
51 std::move(apple_namespaces_table_up), std::move(apple_types_table_up),
52 std::move(apple_objc_table_up));
57 void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
59 m_apple_names_up->FindByName(basename.GetStringRef(), offsets);
62 void AppleDWARFIndex::GetGlobalVariables(const RegularExpression ®ex,
64 if (!m_apple_names_up)
67 DWARFMappedHash::DIEInfoArray hash_data;
68 if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
69 DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
72 void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
74 if (!m_apple_names_up)
77 DWARFMappedHash::DIEInfoArray hash_data;
78 if (m_apple_names_up->AppendAllDIEsInRange(
79 cu.GetOffset(), cu.GetNextCompileUnitOffset(), hash_data))
80 DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
83 void AppleDWARFIndex::GetObjCMethods(ConstString class_name,
86 m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets);
89 void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name,
90 bool must_be_implementation,
92 if (m_apple_types_up) {
93 m_apple_types_up->FindCompleteObjCClassByName(
94 class_name.GetStringRef(), offsets, must_be_implementation);
98 void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
100 m_apple_types_up->FindByName(name.GetStringRef(), offsets);
103 void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
105 if (!m_apple_types_up)
108 Log *log = LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
110 const bool has_tag = m_apple_types_up->GetHeader().header_data.ContainsAtom(
111 DWARFMappedHash::eAtomTypeTag);
112 const bool has_qualified_name_hash =
113 m_apple_types_up->GetHeader().header_data.ContainsAtom(
114 DWARFMappedHash::eAtomTypeQualNameHash);
115 const ConstString type_name(context[0].name);
116 const dw_tag_t tag = context[0].tag;
117 if (has_tag && has_qualified_name_hash) {
118 const char *qualified_name = context.GetQualifiedName();
119 const uint32_t qualified_name_hash = llvm::djbHash(qualified_name);
121 m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
122 m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
123 type_name.GetStringRef(), tag, qualified_name_hash, offsets);
124 } else if (has_tag) {
126 m_module.LogMessage(log, "FindByNameAndTag()");
127 m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
129 m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
132 void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
133 if (m_apple_namespaces_up)
134 m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
137 void AppleDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info,
138 const CompilerDeclContext &parent_decl_ctx,
139 uint32_t name_type_mask,
140 std::vector<DWARFDIE> &dies) {
142 m_apple_names_up->FindByName(name.GetStringRef(), offsets);
143 for (const DIERef &die_ref : offsets) {
144 ProcessFunctionDIE(name.GetStringRef(), die_ref, info, parent_decl_ctx,
145 name_type_mask, dies);
149 void AppleDWARFIndex::GetFunctions(const RegularExpression ®ex,
151 if (!m_apple_names_up)
154 DWARFMappedHash::DIEInfoArray hash_data;
155 if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
156 DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
159 void AppleDWARFIndex::ReportInvalidDIEOffset(dw_offset_t offset,
160 llvm::StringRef name) {
161 m_module.ReportErrorIfModifyDetected(
162 "the DWARF debug information has been modified (accelerator table had "
163 "bad die 0x%8.8x for '%s')\n",
164 offset, name.str().c_str());
167 void AppleDWARFIndex::Dump(Stream &s) {
168 if (m_apple_names_up)
169 s.PutCString(".apple_names index present\n");
170 if (m_apple_namespaces_up)
171 s.PutCString(".apple_namespaces index present\n");
172 if (m_apple_types_up)
173 s.PutCString(".apple_types index present\n");
175 s.PutCString(".apple_objc index present\n");
176 // TODO: Dump index contents