]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / SymbolFile / DWARF / AppleDWARFIndex.cpp
1 //===-- AppleDWARFIndex.cpp ------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
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"
15
16 #include "lldb/Core/Module.h"
17 #include "lldb/Symbol/Function.h"
18
19 using namespace lldb_private;
20 using namespace lldb;
21
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();
30
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();
36
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();
41
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();
46
47   if (apple_names_table_up || apple_names_table_up || apple_types_table_up ||
48       apple_objc_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));
53
54   return nullptr;
55 }
56
57 void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
58   if (m_apple_names_up)
59     m_apple_names_up->FindByName(basename.GetStringRef(), offsets);
60 }
61
62 void AppleDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
63                                          DIEArray &offsets) {
64   if (!m_apple_names_up)
65     return;
66
67   DWARFMappedHash::DIEInfoArray hash_data;
68   if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
69     DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
70 }
71
72 void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
73                                          DIEArray &offsets) {
74   if (!m_apple_names_up)
75     return;
76
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);
81 }
82
83 void AppleDWARFIndex::GetObjCMethods(ConstString class_name,
84                                      DIEArray &offsets) {
85   if (m_apple_objc_up)
86     m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets);
87 }
88
89 void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name,
90                                            bool must_be_implementation,
91                                            DIEArray &offsets) {
92   if (m_apple_types_up) {
93     m_apple_types_up->FindCompleteObjCClassByName(
94         class_name.GetStringRef(), offsets, must_be_implementation);
95   }
96 }
97
98 void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
99   if (m_apple_types_up)
100     m_apple_types_up->FindByName(name.GetStringRef(), offsets);
101 }
102
103 void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
104                                DIEArray &offsets) {
105   if (!m_apple_types_up)
106     return;
107
108   Log *log = LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
109                                           DWARF_LOG_LOOKUPS);
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);
120     if (log)
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) {
125     if (log)
126       m_module.LogMessage(log, "FindByNameAndTag()");
127     m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
128   } else
129     m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
130 }
131
132 void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
133   if (m_apple_namespaces_up)
134     m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
135 }
136
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) {
141   DIEArray offsets;
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);
146   }
147 }
148
149 void AppleDWARFIndex::GetFunctions(const RegularExpression &regex,
150                                    DIEArray &offsets) {
151   if (!m_apple_names_up)
152     return;
153
154   DWARFMappedHash::DIEInfoArray hash_data;
155   if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
156     DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
157 }
158
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());
165 }
166
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");
174   if (m_apple_objc_up)
175     s.PutCString(".apple_objc index present\n");
176   // TODO: Dump index contents
177 }