/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- SymbolFileSymtab.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 | | |
9 | | #include "SymbolFileSymtab.h" |
10 | | |
11 | | #include "lldb/Core/Module.h" |
12 | | #include "lldb/Core/PluginManager.h" |
13 | | #include "lldb/Symbol/CompileUnit.h" |
14 | | #include "lldb/Symbol/Function.h" |
15 | | #include "lldb/Symbol/ObjectFile.h" |
16 | | #include "lldb/Symbol/Symbol.h" |
17 | | #include "lldb/Symbol/SymbolContext.h" |
18 | | #include "lldb/Symbol/Symtab.h" |
19 | | #include "lldb/Symbol/TypeList.h" |
20 | | #include "lldb/Utility/RegularExpression.h" |
21 | | #include "lldb/Utility/Timer.h" |
22 | | |
23 | | #include <memory> |
24 | | #include <optional> |
25 | | |
26 | | using namespace lldb; |
27 | | using namespace lldb_private; |
28 | | |
29 | | LLDB_PLUGIN_DEFINE(SymbolFileSymtab) |
30 | | |
31 | | char SymbolFileSymtab::ID; |
32 | | |
33 | 3.99k | void SymbolFileSymtab::Initialize() { |
34 | 3.99k | PluginManager::RegisterPlugin(GetPluginNameStatic(), |
35 | 3.99k | GetPluginDescriptionStatic(), CreateInstance); |
36 | 3.99k | } |
37 | | |
38 | 3.98k | void SymbolFileSymtab::Terminate() { |
39 | 3.98k | PluginManager::UnregisterPlugin(CreateInstance); |
40 | 3.98k | } |
41 | | |
42 | 3.99k | llvm::StringRef SymbolFileSymtab::GetPluginDescriptionStatic() { |
43 | 3.99k | return "Reads debug symbols from an object file's symbol table."; |
44 | 3.99k | } |
45 | | |
46 | 109k | SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFileSP objfile_sp) { |
47 | 109k | return new SymbolFileSymtab(std::move(objfile_sp)); |
48 | 109k | } |
49 | | |
50 | | void SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope, |
51 | | TypeClass type_mask, |
52 | 0 | lldb_private::TypeList &type_list) {} |
53 | | |
54 | | SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp) |
55 | 109k | : SymbolFileCommon(std::move(objfile_sp)), m_source_indexes(), |
56 | 109k | m_func_indexes(), m_code_indexes(), m_objc_class_name_to_index() {} |
57 | | |
58 | 109k | uint32_t SymbolFileSymtab::CalculateAbilities() { |
59 | 109k | uint32_t abilities = 0; |
60 | 109k | if (m_objfile_sp) { |
61 | 109k | const Symtab *symtab = m_objfile_sp->GetSymtab(); |
62 | 109k | if (symtab) { |
63 | | // The snippet of code below will get the indexes the module symbol table |
64 | | // entries that are code, data, or function related (debug info), sort |
65 | | // them by value (address) and dump the sorted symbols. |
66 | 109k | if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, |
67 | 109k | m_source_indexes)) { |
68 | 16 | abilities |= CompileUnits; |
69 | 16 | } |
70 | | |
71 | 109k | if (symtab->AppendSymbolIndexesWithType( |
72 | 109k | eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, |
73 | 109k | m_func_indexes)) { |
74 | 0 | symtab->SortSymbolIndexesByValue(m_func_indexes, true); |
75 | 0 | abilities |= Functions; |
76 | 0 | } |
77 | | |
78 | 109k | if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, |
79 | 109k | Symtab::eVisibilityAny, |
80 | 109k | m_code_indexes)) { |
81 | 106k | symtab->SortSymbolIndexesByValue(m_code_indexes, true); |
82 | 106k | abilities |= Functions; |
83 | 106k | } |
84 | | |
85 | 109k | if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, |
86 | 109k | m_data_indexes)) { |
87 | 104k | symtab->SortSymbolIndexesByValue(m_data_indexes, true); |
88 | 104k | abilities |= GlobalVariables; |
89 | 104k | } |
90 | | |
91 | 109k | lldb_private::Symtab::IndexCollection objc_class_indexes; |
92 | 109k | if (symtab->AppendSymbolIndexesWithType(eSymbolTypeObjCClass, |
93 | 109k | objc_class_indexes)) { |
94 | 12.9k | symtab->AppendSymbolNamesToMap(objc_class_indexes, true, true, |
95 | 12.9k | m_objc_class_name_to_index); |
96 | 12.9k | m_objc_class_name_to_index.Sort(); |
97 | 12.9k | } |
98 | 109k | } |
99 | 109k | } |
100 | 109k | return abilities; |
101 | 109k | } |
102 | | |
103 | 84.7k | uint32_t SymbolFileSymtab::CalculateNumCompileUnits() { |
104 | | // If we don't have any source file symbols we will just have one compile |
105 | | // unit for the entire object file |
106 | 84.7k | if (m_source_indexes.empty()) |
107 | 84.7k | return 0; |
108 | | |
109 | | // If we have any source file symbols we will logically organize the object |
110 | | // symbols using these. |
111 | 0 | return m_source_indexes.size(); |
112 | 84.7k | } |
113 | | |
114 | 0 | CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) { |
115 | 0 | CompUnitSP cu_sp; |
116 | | |
117 | | // If we don't have any source file symbols we will just have one compile |
118 | | // unit for the entire object file |
119 | 0 | if (idx < m_source_indexes.size()) { |
120 | 0 | const Symbol *cu_symbol = |
121 | 0 | m_objfile_sp->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); |
122 | 0 | if (cu_symbol) |
123 | 0 | cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, |
124 | 0 | cu_symbol->GetName().AsCString(), 0, |
125 | 0 | eLanguageTypeUnknown, eLazyBoolNo); |
126 | 0 | } |
127 | 0 | return cu_sp; |
128 | 0 | } |
129 | | |
130 | 0 | lldb::LanguageType SymbolFileSymtab::ParseLanguage(CompileUnit &comp_unit) { |
131 | 0 | return eLanguageTypeUnknown; |
132 | 0 | } |
133 | | |
134 | 0 | size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) { |
135 | 0 | std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); |
136 | 0 | size_t num_added = 0; |
137 | | // We must at least have a valid compile unit |
138 | 0 | const Symtab *symtab = m_objfile_sp->GetSymtab(); |
139 | 0 | const Symbol *curr_symbol = nullptr; |
140 | 0 | const Symbol *next_symbol = nullptr; |
141 | | // const char *prefix = m_objfile_sp->SymbolPrefix(); |
142 | | // if (prefix == NULL) |
143 | | // prefix == ""; |
144 | | // |
145 | | // const uint32_t prefix_len = strlen(prefix); |
146 | | |
147 | | // If we don't have any source file symbols we will just have one compile |
148 | | // unit for the entire object file |
149 | 0 | if (m_source_indexes.empty()) { |
150 | | // The only time we will have a user ID of zero is when we don't have and |
151 | | // source file symbols and we declare one compile unit for the entire |
152 | | // object file |
153 | 0 | if (!m_func_indexes.empty()) { |
154 | 0 | } |
155 | |
|
156 | 0 | if (!m_code_indexes.empty()) { |
157 | | // StreamFile s(stdout); |
158 | | // symtab->Dump(&s, m_code_indexes); |
159 | |
|
160 | 0 | uint32_t idx = 0; // Index into the indexes |
161 | 0 | const uint32_t num_indexes = m_code_indexes.size(); |
162 | 0 | for (idx = 0; idx < num_indexes; ++idx) { |
163 | 0 | uint32_t symbol_idx = m_code_indexes[idx]; |
164 | 0 | curr_symbol = symtab->SymbolAtIndex(symbol_idx); |
165 | 0 | if (curr_symbol) { |
166 | | // Union of all ranges in the function DIE (if the function is |
167 | | // discontiguous) |
168 | 0 | AddressRange func_range(curr_symbol->GetAddress(), 0); |
169 | 0 | if (func_range.GetBaseAddress().IsSectionOffset()) { |
170 | 0 | uint32_t symbol_size = curr_symbol->GetByteSize(); |
171 | 0 | if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling()) |
172 | 0 | func_range.SetByteSize(symbol_size); |
173 | 0 | else if (idx + 1 < num_indexes) { |
174 | 0 | next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]); |
175 | 0 | if (next_symbol) { |
176 | 0 | func_range.SetByteSize( |
177 | 0 | next_symbol->GetAddressRef().GetOffset() - |
178 | 0 | curr_symbol->GetAddressRef().GetOffset()); |
179 | 0 | } |
180 | 0 | } |
181 | |
|
182 | 0 | FunctionSP func_sp( |
183 | 0 | new Function(&comp_unit, |
184 | 0 | symbol_idx, // UserID is the DIE offset |
185 | 0 | LLDB_INVALID_UID, // We don't have any type info |
186 | | // for this function |
187 | 0 | curr_symbol->GetMangled(), // Linker/mangled name |
188 | 0 | nullptr, // no return type for a code symbol... |
189 | 0 | func_range)); // first address range |
190 | |
|
191 | 0 | if (func_sp.get() != nullptr) { |
192 | 0 | comp_unit.AddFunction(func_sp); |
193 | 0 | ++num_added; |
194 | 0 | } |
195 | 0 | } |
196 | 0 | } |
197 | 0 | } |
198 | 0 | } |
199 | 0 | } else { |
200 | | // We assume we |
201 | 0 | } |
202 | 0 | return num_added; |
203 | 0 | } |
204 | | |
205 | 0 | size_t SymbolFileSymtab::ParseTypes(CompileUnit &comp_unit) { return 0; } |
206 | | |
207 | 0 | bool SymbolFileSymtab::ParseLineTable(CompileUnit &comp_unit) { return false; } |
208 | | |
209 | 0 | bool SymbolFileSymtab::ParseDebugMacros(CompileUnit &comp_unit) { |
210 | 0 | return false; |
211 | 0 | } |
212 | | |
213 | | bool SymbolFileSymtab::ParseSupportFiles(CompileUnit &comp_unit, |
214 | 0 | FileSpecList &support_files) { |
215 | 0 | return false; |
216 | 0 | } |
217 | | |
218 | | bool SymbolFileSymtab::ParseImportedModules( |
219 | 0 | const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { |
220 | 0 | return false; |
221 | 0 | } |
222 | | |
223 | 0 | size_t SymbolFileSymtab::ParseBlocksRecursive(Function &func) { return 0; } |
224 | | |
225 | 0 | size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) { |
226 | 0 | return 0; |
227 | 0 | } |
228 | | |
229 | 0 | Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) { |
230 | 0 | return nullptr; |
231 | 0 | } |
232 | | |
233 | | std::optional<SymbolFile::ArrayInfo> |
234 | | SymbolFileSymtab::GetDynamicArrayInfoForUID( |
235 | 0 | lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { |
236 | 0 | return std::nullopt; |
237 | 0 | } |
238 | | |
239 | 0 | bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) { |
240 | 0 | return false; |
241 | 0 | } |
242 | | |
243 | | uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr, |
244 | | SymbolContextItem resolve_scope, |
245 | 2.51M | SymbolContext &sc) { |
246 | 2.51M | std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); |
247 | 2.51M | if (m_objfile_sp->GetSymtab() == nullptr) |
248 | 0 | return 0; |
249 | | |
250 | 2.51M | uint32_t resolved_flags = 0; |
251 | 2.51M | if (resolve_scope & eSymbolContextSymbol) { |
252 | 2.49M | sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress( |
253 | 2.49M | so_addr.GetFileAddress()); |
254 | 2.49M | if (sc.symbol) |
255 | 2.49M | resolved_flags |= eSymbolContextSymbol; |
256 | 2.49M | } |
257 | 2.51M | return resolved_flags; |
258 | 2.51M | } |