1 //===-- SymbolVendor.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 "lldb/Symbol/SymbolVendor.h" 10 11 #include "lldb/Core/Module.h" 12 #include "lldb/Core/PluginManager.h" 13 #include "lldb/Symbol/CompileUnit.h" 14 #include "lldb/Symbol/ObjectFile.h" 15 #include "lldb/Symbol/SymbolFile.h" 16 #include "lldb/Utility/Stream.h" 17 18 using namespace lldb; 19 using namespace lldb_private; 20 21 // FindPlugin 22 // 23 // Platforms can register a callback to use when creating symbol vendors to 24 // allow for complex debug information file setups, and to also allow for 25 // finding separate debug information files. 26 SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp, 27 lldb_private::Stream *feedback_strm) { 28 std::unique_ptr<SymbolVendor> instance_up; 29 SymbolVendorCreateInstance create_callback; 30 31 for (size_t idx = 0; 32 (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex( 33 idx)) != nullptr; 34 ++idx) { 35 instance_up.reset(create_callback(module_sp, feedback_strm)); 36 37 if (instance_up) { 38 return instance_up.release(); 39 } 40 } 41 // The default implementation just tries to create debug information using 42 // the file representation for the module. 43 ObjectFileSP sym_objfile_sp; 44 FileSpec sym_spec = module_sp->GetSymbolFileFileSpec(); 45 if (sym_spec && sym_spec != module_sp->GetObjectFile()->GetFileSpec()) { 46 DataBufferSP data_sp; 47 offset_t data_offset = 0; 48 sym_objfile_sp = ObjectFile::FindPlugin( 49 module_sp, &sym_spec, 0, FileSystem::Instance().GetByteSize(sym_spec), 50 data_sp, data_offset); 51 } 52 if (!sym_objfile_sp) 53 sym_objfile_sp = module_sp->GetObjectFile()->shared_from_this(); 54 instance_up.reset(new SymbolVendor(module_sp)); 55 instance_up->AddSymbolFileRepresentation(sym_objfile_sp); 56 return instance_up.release(); 57 } 58 59 // SymbolVendor constructor 60 SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp) 61 : ModuleChild(module_sp), m_sym_file_up() {} 62 63 // Destructor 64 SymbolVendor::~SymbolVendor() {} 65 66 // Add a representation given an object file. 67 void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) { 68 ModuleSP module_sp(GetModule()); 69 if (module_sp) { 70 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 71 if (objfile_sp) { 72 m_objfile_sp = objfile_sp; 73 m_sym_file_up.reset(SymbolFile::FindPlugin(objfile_sp.get())); 74 } 75 } 76 } 77 78 size_t SymbolVendor::GetNumCompileUnits() { 79 ModuleSP module_sp(GetModule()); 80 if (module_sp) { 81 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 82 if (m_sym_file_up) 83 return m_sym_file_up->GetNumCompileUnits(); 84 } 85 return 0; 86 } 87 88 lldb::LanguageType SymbolVendor::ParseLanguage(CompileUnit &comp_unit) { 89 ModuleSP module_sp(GetModule()); 90 if (module_sp) { 91 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 92 if (m_sym_file_up) 93 return m_sym_file_up->ParseLanguage(comp_unit); 94 } 95 return eLanguageTypeUnknown; 96 } 97 98 size_t SymbolVendor::ParseFunctions(CompileUnit &comp_unit) { 99 ModuleSP module_sp(GetModule()); 100 if (module_sp) { 101 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 102 if (m_sym_file_up) 103 return m_sym_file_up->ParseFunctions(comp_unit); 104 } 105 return 0; 106 } 107 108 bool SymbolVendor::ParseLineTable(CompileUnit &comp_unit) { 109 ModuleSP module_sp(GetModule()); 110 if (module_sp) { 111 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 112 if (m_sym_file_up) 113 return m_sym_file_up->ParseLineTable(comp_unit); 114 } 115 return false; 116 } 117 118 bool SymbolVendor::ParseDebugMacros(CompileUnit &comp_unit) { 119 ModuleSP module_sp(GetModule()); 120 if (module_sp) { 121 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 122 if (m_sym_file_up) 123 return m_sym_file_up->ParseDebugMacros(comp_unit); 124 } 125 return false; 126 } 127 bool SymbolVendor::ParseSupportFiles(CompileUnit &comp_unit, 128 FileSpecList &support_files) { 129 ModuleSP module_sp(GetModule()); 130 if (module_sp) { 131 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 132 if (m_sym_file_up) 133 return m_sym_file_up->ParseSupportFiles(comp_unit, support_files); 134 } 135 return false; 136 } 137 138 bool SymbolVendor::ParseIsOptimized(CompileUnit &comp_unit) { 139 ModuleSP module_sp(GetModule()); 140 if (module_sp) { 141 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 142 if (m_sym_file_up) 143 return m_sym_file_up->ParseIsOptimized(comp_unit); 144 } 145 return false; 146 } 147 148 bool SymbolVendor::ParseImportedModules( 149 const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { 150 ModuleSP module_sp(GetModule()); 151 if (module_sp) { 152 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 153 if (m_sym_file_up) 154 return m_sym_file_up->ParseImportedModules(sc, imported_modules); 155 } 156 return false; 157 } 158 159 size_t SymbolVendor::ParseBlocksRecursive(Function &func) { 160 ModuleSP module_sp(GetModule()); 161 if (module_sp) { 162 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 163 if (m_sym_file_up) 164 return m_sym_file_up->ParseBlocksRecursive(func); 165 } 166 return 0; 167 } 168 169 size_t SymbolVendor::ParseTypes(CompileUnit &comp_unit) { 170 ModuleSP module_sp(GetModule()); 171 if (module_sp) { 172 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 173 if (m_sym_file_up) 174 return m_sym_file_up->ParseTypes(comp_unit); 175 } 176 return 0; 177 } 178 179 size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) { 180 ModuleSP module_sp(GetModule()); 181 if (module_sp) { 182 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 183 if (m_sym_file_up) 184 return m_sym_file_up->ParseVariablesForContext(sc); 185 } 186 return 0; 187 } 188 189 Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) { 190 ModuleSP module_sp(GetModule()); 191 if (module_sp) { 192 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 193 if (m_sym_file_up) 194 return m_sym_file_up->ResolveTypeUID(type_uid); 195 } 196 return nullptr; 197 } 198 199 uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr, 200 SymbolContextItem resolve_scope, 201 SymbolContext &sc) { 202 ModuleSP module_sp(GetModule()); 203 if (module_sp) { 204 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 205 if (m_sym_file_up) 206 return m_sym_file_up->ResolveSymbolContext(so_addr, resolve_scope, sc); 207 } 208 return 0; 209 } 210 211 uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec, 212 uint32_t line, bool check_inlines, 213 SymbolContextItem resolve_scope, 214 SymbolContextList &sc_list) { 215 ModuleSP module_sp(GetModule()); 216 if (module_sp) { 217 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 218 if (m_sym_file_up) 219 return m_sym_file_up->ResolveSymbolContext(file_spec, line, check_inlines, 220 resolve_scope, sc_list); 221 } 222 return 0; 223 } 224 225 size_t 226 SymbolVendor::FindGlobalVariables(ConstString name, 227 const CompilerDeclContext *parent_decl_ctx, 228 size_t max_matches, VariableList &variables) { 229 ModuleSP module_sp(GetModule()); 230 if (module_sp) { 231 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 232 if (m_sym_file_up) 233 return m_sym_file_up->FindGlobalVariables(name, parent_decl_ctx, 234 max_matches, variables); 235 } 236 return 0; 237 } 238 239 size_t SymbolVendor::FindGlobalVariables(const RegularExpression ®ex, 240 size_t max_matches, 241 VariableList &variables) { 242 ModuleSP module_sp(GetModule()); 243 if (module_sp) { 244 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 245 if (m_sym_file_up) 246 return m_sym_file_up->FindGlobalVariables(regex, max_matches, variables); 247 } 248 return 0; 249 } 250 251 size_t SymbolVendor::FindFunctions(ConstString name, 252 const CompilerDeclContext *parent_decl_ctx, 253 FunctionNameType name_type_mask, 254 bool include_inlines, bool append, 255 SymbolContextList &sc_list) { 256 ModuleSP module_sp(GetModule()); 257 if (module_sp) { 258 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 259 if (m_sym_file_up) 260 return m_sym_file_up->FindFunctions(name, parent_decl_ctx, name_type_mask, 261 include_inlines, append, sc_list); 262 } 263 return 0; 264 } 265 266 size_t SymbolVendor::FindFunctions(const RegularExpression ®ex, 267 bool include_inlines, bool append, 268 SymbolContextList &sc_list) { 269 ModuleSP module_sp(GetModule()); 270 if (module_sp) { 271 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 272 if (m_sym_file_up) 273 return m_sym_file_up->FindFunctions(regex, include_inlines, append, 274 sc_list); 275 } 276 return 0; 277 } 278 279 size_t SymbolVendor::FindTypes( 280 ConstString name, const CompilerDeclContext *parent_decl_ctx, 281 bool append, size_t max_matches, 282 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 283 TypeMap &types) { 284 ModuleSP module_sp(GetModule()); 285 if (module_sp) { 286 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 287 if (m_sym_file_up) 288 return m_sym_file_up->FindTypes(name, parent_decl_ctx, append, 289 max_matches, searched_symbol_files, 290 types); 291 } 292 if (!append) 293 types.Clear(); 294 return 0; 295 } 296 297 size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context, 298 bool append, TypeMap &types) { 299 ModuleSP module_sp(GetModule()); 300 if (module_sp) { 301 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 302 if (m_sym_file_up) 303 return m_sym_file_up->FindTypes(context, append, types); 304 } 305 if (!append) 306 types.Clear(); 307 return 0; 308 } 309 310 size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask, 311 lldb_private::TypeList &type_list) { 312 ModuleSP module_sp(GetModule()); 313 if (module_sp) { 314 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 315 if (m_sym_file_up) 316 return m_sym_file_up->GetTypes(sc_scope, type_mask, type_list); 317 } 318 return 0; 319 } 320 321 CompilerDeclContext 322 SymbolVendor::FindNamespace(ConstString name, 323 const CompilerDeclContext *parent_decl_ctx) { 324 CompilerDeclContext namespace_decl_ctx; 325 ModuleSP module_sp(GetModule()); 326 if (module_sp) { 327 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 328 if (m_sym_file_up) 329 namespace_decl_ctx = m_sym_file_up->FindNamespace(name, parent_decl_ctx); 330 } 331 return namespace_decl_ctx; 332 } 333 334 void SymbolVendor::Dump(Stream *s) { 335 ModuleSP module_sp(GetModule()); 336 if (module_sp) { 337 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 338 339 s->Printf("%p: ", static_cast<void *>(this)); 340 s->Indent(); 341 s->PutCString("SymbolVendor"); 342 if (m_sym_file_up) { 343 *s << " " << m_sym_file_up->GetPluginName(); 344 ObjectFile *objfile = m_sym_file_up->GetObjectFile(); 345 if (objfile) { 346 const FileSpec &objfile_file_spec = objfile->GetFileSpec(); 347 if (objfile_file_spec) { 348 s->PutCString(" ("); 349 objfile_file_spec.Dump(s); 350 s->PutChar(')'); 351 } 352 } 353 } 354 s->EOL(); 355 if (m_sym_file_up) 356 m_sym_file_up->Dump(*s); 357 s->IndentMore(); 358 359 if (Symtab *symtab = GetSymtab()) 360 symtab->Dump(s, nullptr, eSortOrderNone); 361 362 s->IndentLess(); 363 } 364 } 365 366 CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) { 367 ModuleSP module_sp(GetModule()); 368 if (module_sp) { 369 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 370 if (m_sym_file_up) 371 return m_sym_file_up->GetCompileUnitAtIndex(idx); 372 } 373 return nullptr; 374 } 375 376 FileSpec SymbolVendor::GetMainFileSpec() const { 377 if (m_sym_file_up) { 378 const ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile(); 379 if (symfile_objfile) 380 return symfile_objfile->GetFileSpec(); 381 } 382 383 return FileSpec(); 384 } 385 386 Symtab *SymbolVendor::GetSymtab() { 387 if (m_sym_file_up) 388 return m_sym_file_up->GetSymtab(); 389 return nullptr; 390 } 391 392 void SymbolVendor::SectionFileAddressesChanged() { 393 if (m_sym_file_up) 394 m_sym_file_up->SectionFileAddressesChanged(); 395 } 396 397 // PluginInterface protocol 398 lldb_private::ConstString SymbolVendor::GetPluginName() { 399 static ConstString g_name("vendor-default"); 400 return g_name; 401 } 402 403 uint32_t SymbolVendor::GetPluginVersion() { return 1; } 404