]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / SymbolFile / DWARF / AppleDWARFIndex.cpp
1 //===-- AppleDWARFIndex.cpp ------------------------------------*- C++ -*-===//
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
9 #include "Plugins/SymbolFile/DWARF/AppleDWARFIndex.h"
10 #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
11 #include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
12 #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
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 = llvm::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       llvm::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 = llvm::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 = llvm::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_names_table_up || apple_types_table_up ||
46       apple_objc_table_up)
47     return llvm::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
55 void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
56   if (m_apple_names_up)
57     m_apple_names_up->FindByName(basename.GetStringRef(), offsets);
58 }
59
60 void AppleDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
61                                          DIEArray &offsets) {
62   if (!m_apple_names_up)
63     return;
64
65   DWARFMappedHash::DIEInfoArray hash_data;
66   if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
67     DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
68 }
69
70 void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
71                                          DIEArray &offsets) {
72   if (!m_apple_names_up)
73     return;
74
75   DWARFMappedHash::DIEInfoArray hash_data;
76   if (m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(),
77                                              cu.GetNextUnitOffset(), hash_data))
78     DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
79 }
80
81 void AppleDWARFIndex::GetObjCMethods(ConstString class_name,
82                                      DIEArray &offsets) {
83   if (m_apple_objc_up)
84     m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets);
85 }
86
87 void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name,
88                                            bool must_be_implementation,
89                                            DIEArray &offsets) {
90   if (m_apple_types_up) {
91     m_apple_types_up->FindCompleteObjCClassByName(
92         class_name.GetStringRef(), offsets, must_be_implementation);
93   }
94 }
95
96 void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
97   if (m_apple_types_up)
98     m_apple_types_up->FindByName(name.GetStringRef(), offsets);
99 }
100
101 void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
102                                DIEArray &offsets) {
103   if (!m_apple_types_up)
104     return;
105
106   Log *log = LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
107                                           DWARF_LOG_LOOKUPS);
108   const bool has_tag = m_apple_types_up->GetHeader().header_data.ContainsAtom(
109       DWARFMappedHash::eAtomTypeTag);
110   const bool has_qualified_name_hash =
111       m_apple_types_up->GetHeader().header_data.ContainsAtom(
112           DWARFMappedHash::eAtomTypeQualNameHash);
113   const ConstString type_name(context[0].name);
114   const dw_tag_t tag = context[0].tag;
115   if (has_tag && has_qualified_name_hash) {
116     const char *qualified_name = context.GetQualifiedName();
117     const uint32_t qualified_name_hash = llvm::djbHash(qualified_name);
118     if (log)
119       m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
120     m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
121         type_name.GetStringRef(), tag, qualified_name_hash, offsets);
122   } else if (has_tag) {
123     if (log)
124       m_module.LogMessage(log, "FindByNameAndTag()");
125     m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
126   } else
127     m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
128 }
129
130 void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
131   if (m_apple_namespaces_up)
132     m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
133 }
134
135 void AppleDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
136                                    const CompilerDeclContext &parent_decl_ctx,
137                                    uint32_t name_type_mask,
138                                    std::vector<DWARFDIE> &dies) {
139   DIEArray offsets;
140   m_apple_names_up->FindByName(name.GetStringRef(), offsets);
141   for (const DIERef &die_ref : offsets) {
142     ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, parent_decl_ctx,
143                        name_type_mask, dies);
144   }
145 }
146
147 void AppleDWARFIndex::GetFunctions(const RegularExpression &regex,
148                                    DIEArray &offsets) {
149   if (!m_apple_names_up)
150     return;
151
152   DWARFMappedHash::DIEInfoArray hash_data;
153   if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
154     DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
155 }
156
157 void AppleDWARFIndex::ReportInvalidDIERef(const DIERef &ref,
158                                           llvm::StringRef name) {
159   m_module.ReportErrorIfModifyDetected(
160       "the DWARF debug information has been modified (accelerator table had "
161       "bad die 0x%8.8x for '%s')\n",
162       ref.die_offset(), name.str().c_str());
163 }
164
165 void AppleDWARFIndex::Dump(Stream &s) {
166   if (m_apple_names_up)
167     s.PutCString(".apple_names index present\n");
168   if (m_apple_namespaces_up)
169     s.PutCString(".apple_namespaces index present\n");
170   if (m_apple_types_up)
171     s.PutCString(".apple_types index present\n");
172   if (m_apple_objc_up)
173     s.PutCString(".apple_objc index present\n");
174   // TODO: Dump index contents
175 }