1 //===-- SymbolVendor.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 "lldb/Symbol/SymbolVendor.h" 11 12 #include "lldb/Core/Module.h" 13 #include "lldb/Core/PluginManager.h" 14 #include "lldb/Symbol/CompileUnit.h" 15 #include "lldb/Symbol/ObjectFile.h" 16 #include "lldb/Symbol/SymbolFile.h" 17 #include "lldb/Utility/Stream.h" 18 19 using namespace lldb; 20 using namespace lldb_private; 21 22 //---------------------------------------------------------------------- 23 // FindPlugin 24 // 25 // Platforms can register a callback to use when creating symbol vendors to 26 // allow for complex debug information file setups, and to also allow for 27 // finding separate debug information files. 28 //---------------------------------------------------------------------- 29 SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp, 30 lldb_private::Stream *feedback_strm) { 31 std::unique_ptr<SymbolVendor> instance_ap; 32 SymbolVendorCreateInstance create_callback; 33 34 for (size_t idx = 0; 35 (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex( 36 idx)) != nullptr; 37 ++idx) { 38 instance_ap.reset(create_callback(module_sp, feedback_strm)); 39 40 if (instance_ap.get()) { 41 return instance_ap.release(); 42 } 43 } 44 // The default implementation just tries to create debug information using 45 // the file representation for the module. 46 instance_ap.reset(new SymbolVendor(module_sp)); 47 if (instance_ap.get()) { 48 ObjectFile *objfile = module_sp->GetObjectFile(); 49 if (objfile) 50 instance_ap->AddSymbolFileRepresentation(objfile->shared_from_this()); 51 } 52 return instance_ap.release(); 53 } 54 55 //---------------------------------------------------------------------- 56 // SymbolVendor constructor 57 //---------------------------------------------------------------------- 58 SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp) 59 : ModuleChild(module_sp), m_type_list(), m_compile_units(), 60 m_sym_file_ap(), m_symtab() {} 61 62 //---------------------------------------------------------------------- 63 // Destructor 64 //---------------------------------------------------------------------- 65 SymbolVendor::~SymbolVendor() {} 66 67 //---------------------------------------------------------------------- 68 // Add a representation given an object file. 69 //---------------------------------------------------------------------- 70 void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) { 71 ModuleSP module_sp(GetModule()); 72 if (module_sp) { 73 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 74 if (objfile_sp) { 75 m_objfile_sp = objfile_sp; 76 m_sym_file_ap.reset(SymbolFile::FindPlugin(objfile_sp.get())); 77 } 78 } 79 } 80 81 bool SymbolVendor::SetCompileUnitAtIndex(size_t idx, const CompUnitSP &cu_sp) { 82 ModuleSP module_sp(GetModule()); 83 if (module_sp) { 84 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 85 const size_t num_compile_units = GetNumCompileUnits(); 86 if (idx < num_compile_units) { 87 // Fire off an assertion if this compile unit already exists for now. The 88 // partial parsing should take care of only setting the compile unit 89 // once, so if this assertion fails, we need to make sure that we don't 90 // have a race condition, or have a second parse of the same compile 91 // unit. 92 assert(m_compile_units[idx].get() == nullptr); 93 m_compile_units[idx] = cu_sp; 94 return true; 95 } else { 96 // This should NOT happen, and if it does, we want to crash and know 97 // about it 98 assert(idx < num_compile_units); 99 } 100 } 101 return false; 102 } 103 104 size_t SymbolVendor::GetNumCompileUnits() { 105 ModuleSP module_sp(GetModule()); 106 if (module_sp) { 107 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 108 if (m_compile_units.empty()) { 109 if (m_sym_file_ap.get()) { 110 // Resize our array of compile unit shared pointers -- which will each 111 // remain NULL until someone asks for the actual compile unit 112 // information. When this happens, the symbol file will be asked to 113 // parse this compile unit information. 114 m_compile_units.resize(m_sym_file_ap->GetNumCompileUnits()); 115 } 116 } 117 } 118 return m_compile_units.size(); 119 } 120 121 lldb::LanguageType SymbolVendor::ParseLanguage(CompileUnit &comp_unit) { 122 ModuleSP module_sp(GetModule()); 123 if (module_sp) { 124 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 125 if (m_sym_file_ap.get()) 126 return m_sym_file_ap->ParseLanguage(comp_unit); 127 } 128 return eLanguageTypeUnknown; 129 } 130 131 size_t SymbolVendor::ParseFunctions(CompileUnit &comp_unit) { 132 ModuleSP module_sp(GetModule()); 133 if (module_sp) { 134 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 135 if (m_sym_file_ap.get()) 136 return m_sym_file_ap->ParseFunctions(comp_unit); 137 } 138 return 0; 139 } 140 141 bool SymbolVendor::ParseLineTable(CompileUnit &comp_unit) { 142 ModuleSP module_sp(GetModule()); 143 if (module_sp) { 144 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 145 if (m_sym_file_ap.get()) 146 return m_sym_file_ap->ParseLineTable(comp_unit); 147 } 148 return false; 149 } 150 151 bool SymbolVendor::ParseDebugMacros(CompileUnit &comp_unit) { 152 ModuleSP module_sp(GetModule()); 153 if (module_sp) { 154 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 155 if (m_sym_file_ap.get()) 156 return m_sym_file_ap->ParseDebugMacros(comp_unit); 157 } 158 return false; 159 } 160 bool SymbolVendor::ParseSupportFiles(CompileUnit &comp_unit, 161 FileSpecList &support_files) { 162 ModuleSP module_sp(GetModule()); 163 if (module_sp) { 164 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 165 if (m_sym_file_ap.get()) 166 return m_sym_file_ap->ParseSupportFiles(comp_unit, support_files); 167 } 168 return false; 169 } 170 171 bool SymbolVendor::ParseIsOptimized(CompileUnit &comp_unit) { 172 ModuleSP module_sp(GetModule()); 173 if (module_sp) { 174 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 175 if (m_sym_file_ap.get()) 176 return m_sym_file_ap->ParseIsOptimized(comp_unit); 177 } 178 return false; 179 } 180 181 bool SymbolVendor::ParseImportedModules( 182 const SymbolContext &sc, std::vector<ConstString> &imported_modules) { 183 ModuleSP module_sp(GetModule()); 184 if (module_sp) { 185 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 186 if (m_sym_file_ap.get()) 187 return m_sym_file_ap->ParseImportedModules(sc, imported_modules); 188 } 189 return false; 190 } 191 192 size_t SymbolVendor::ParseBlocksRecursive(Function &func) { 193 ModuleSP module_sp(GetModule()); 194 if (module_sp) { 195 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 196 if (m_sym_file_ap.get()) 197 return m_sym_file_ap->ParseBlocksRecursive(func); 198 } 199 return 0; 200 } 201 202 size_t SymbolVendor::ParseTypes(CompileUnit &comp_unit) { 203 ModuleSP module_sp(GetModule()); 204 if (module_sp) { 205 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 206 if (m_sym_file_ap.get()) 207 return m_sym_file_ap->ParseTypes(comp_unit); 208 } 209 return 0; 210 } 211 212 size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) { 213 ModuleSP module_sp(GetModule()); 214 if (module_sp) { 215 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 216 if (m_sym_file_ap.get()) 217 return m_sym_file_ap->ParseVariablesForContext(sc); 218 } 219 return 0; 220 } 221 222 Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) { 223 ModuleSP module_sp(GetModule()); 224 if (module_sp) { 225 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 226 if (m_sym_file_ap.get()) 227 return m_sym_file_ap->ResolveTypeUID(type_uid); 228 } 229 return nullptr; 230 } 231 232 uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr, 233 SymbolContextItem resolve_scope, 234 SymbolContext &sc) { 235 ModuleSP module_sp(GetModule()); 236 if (module_sp) { 237 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 238 if (m_sym_file_ap.get()) 239 return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc); 240 } 241 return 0; 242 } 243 244 uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec, 245 uint32_t line, bool check_inlines, 246 SymbolContextItem resolve_scope, 247 SymbolContextList &sc_list) { 248 ModuleSP module_sp(GetModule()); 249 if (module_sp) { 250 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 251 if (m_sym_file_ap.get()) 252 return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines, 253 resolve_scope, sc_list); 254 } 255 return 0; 256 } 257 258 size_t 259 SymbolVendor::FindGlobalVariables(const ConstString &name, 260 const CompilerDeclContext *parent_decl_ctx, 261 size_t max_matches, VariableList &variables) { 262 ModuleSP module_sp(GetModule()); 263 if (module_sp) { 264 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 265 if (m_sym_file_ap.get()) 266 return m_sym_file_ap->FindGlobalVariables(name, parent_decl_ctx, 267 max_matches, variables); 268 } 269 return 0; 270 } 271 272 size_t SymbolVendor::FindGlobalVariables(const RegularExpression ®ex, 273 size_t max_matches, 274 VariableList &variables) { 275 ModuleSP module_sp(GetModule()); 276 if (module_sp) { 277 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 278 if (m_sym_file_ap.get()) 279 return m_sym_file_ap->FindGlobalVariables(regex, max_matches, variables); 280 } 281 return 0; 282 } 283 284 size_t SymbolVendor::FindFunctions(const ConstString &name, 285 const CompilerDeclContext *parent_decl_ctx, 286 FunctionNameType name_type_mask, 287 bool include_inlines, bool append, 288 SymbolContextList &sc_list) { 289 ModuleSP module_sp(GetModule()); 290 if (module_sp) { 291 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 292 if (m_sym_file_ap.get()) 293 return m_sym_file_ap->FindFunctions(name, parent_decl_ctx, name_type_mask, 294 include_inlines, append, sc_list); 295 } 296 return 0; 297 } 298 299 size_t SymbolVendor::FindFunctions(const RegularExpression ®ex, 300 bool include_inlines, bool append, 301 SymbolContextList &sc_list) { 302 ModuleSP module_sp(GetModule()); 303 if (module_sp) { 304 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 305 if (m_sym_file_ap.get()) 306 return m_sym_file_ap->FindFunctions(regex, include_inlines, append, 307 sc_list); 308 } 309 return 0; 310 } 311 312 size_t SymbolVendor::FindTypes( 313 const ConstString &name, const CompilerDeclContext *parent_decl_ctx, 314 bool append, size_t max_matches, 315 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 316 TypeMap &types) { 317 ModuleSP module_sp(GetModule()); 318 if (module_sp) { 319 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 320 if (m_sym_file_ap.get()) 321 return m_sym_file_ap->FindTypes(name, parent_decl_ctx, append, 322 max_matches, searched_symbol_files, 323 types); 324 } 325 if (!append) 326 types.Clear(); 327 return 0; 328 } 329 330 size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context, 331 bool append, TypeMap &types) { 332 ModuleSP module_sp(GetModule()); 333 if (module_sp) { 334 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 335 if (m_sym_file_ap.get()) 336 return m_sym_file_ap->FindTypes(context, append, types); 337 } 338 if (!append) 339 types.Clear(); 340 return 0; 341 } 342 343 size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask, 344 lldb_private::TypeList &type_list) { 345 ModuleSP module_sp(GetModule()); 346 if (module_sp) { 347 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 348 if (m_sym_file_ap.get()) 349 return m_sym_file_ap->GetTypes(sc_scope, type_mask, type_list); 350 } 351 return 0; 352 } 353 354 CompilerDeclContext 355 SymbolVendor::FindNamespace(const ConstString &name, 356 const CompilerDeclContext *parent_decl_ctx) { 357 CompilerDeclContext namespace_decl_ctx; 358 ModuleSP module_sp(GetModule()); 359 if (module_sp) { 360 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 361 if (m_sym_file_ap.get()) 362 namespace_decl_ctx = m_sym_file_ap->FindNamespace(name, parent_decl_ctx); 363 } 364 return namespace_decl_ctx; 365 } 366 367 void SymbolVendor::Dump(Stream *s) { 368 ModuleSP module_sp(GetModule()); 369 if (module_sp) { 370 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 371 372 bool show_context = false; 373 374 s->Printf("%p: ", static_cast<void *>(this)); 375 s->Indent(); 376 s->PutCString("SymbolVendor"); 377 if (m_sym_file_ap.get()) { 378 *s << " " << m_sym_file_ap->GetPluginName(); 379 ObjectFile *objfile = m_sym_file_ap->GetObjectFile(); 380 if (objfile) { 381 const FileSpec &objfile_file_spec = objfile->GetFileSpec(); 382 if (objfile_file_spec) { 383 s->PutCString(" ("); 384 objfile_file_spec.Dump(s); 385 s->PutChar(')'); 386 } 387 } 388 } 389 s->EOL(); 390 if (m_sym_file_ap) 391 m_sym_file_ap->Dump(*s); 392 s->IndentMore(); 393 m_type_list.Dump(s, show_context); 394 395 CompileUnitConstIter cu_pos, cu_end; 396 cu_end = m_compile_units.end(); 397 for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos) { 398 // We currently only dump the compile units that have been parsed 399 if (cu_pos->get()) 400 (*cu_pos)->Dump(s, show_context); 401 } 402 403 if (Symtab *symtab = GetSymtab()) 404 symtab->Dump(s, nullptr, eSortOrderNone); 405 406 s->IndentLess(); 407 } 408 } 409 410 CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) { 411 CompUnitSP cu_sp; 412 ModuleSP module_sp(GetModule()); 413 if (module_sp) { 414 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 415 const size_t num_compile_units = GetNumCompileUnits(); 416 if (idx < num_compile_units) { 417 cu_sp = m_compile_units[idx]; 418 if (cu_sp.get() == nullptr) { 419 m_compile_units[idx] = m_sym_file_ap->ParseCompileUnitAtIndex(idx); 420 cu_sp = m_compile_units[idx]; 421 } 422 } 423 } 424 return cu_sp; 425 } 426 427 FileSpec SymbolVendor::GetMainFileSpec() const { 428 if (m_sym_file_ap.get()) { 429 const ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile(); 430 if (symfile_objfile) 431 return symfile_objfile->GetFileSpec(); 432 } 433 434 return FileSpec(); 435 } 436 437 Symtab *SymbolVendor::GetSymtab() { 438 ModuleSP module_sp(GetModule()); 439 if (!module_sp) 440 return nullptr; 441 442 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 443 444 if (m_symtab) 445 return m_symtab; 446 447 ObjectFile *objfile = module_sp->GetObjectFile(); 448 if (!objfile) 449 return nullptr; 450 451 m_symtab = objfile->GetSymtab(); 452 if (m_symtab && m_sym_file_ap) 453 m_sym_file_ap->AddSymbols(*m_symtab); 454 455 return m_symtab; 456 } 457 458 void SymbolVendor::ClearSymtab() { 459 ModuleSP module_sp(GetModule()); 460 if (module_sp) { 461 ObjectFile *objfile = module_sp->GetObjectFile(); 462 if (objfile) { 463 // Clear symbol table from unified section list. 464 objfile->ClearSymtab(); 465 } 466 } 467 } 468 469 void SymbolVendor::SectionFileAddressesChanged() { 470 ModuleSP module_sp(GetModule()); 471 if (module_sp) { 472 ObjectFile *module_objfile = module_sp->GetObjectFile(); 473 if (m_sym_file_ap.get()) { 474 ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile(); 475 if (symfile_objfile != module_objfile) 476 symfile_objfile->SectionFileAddressesChanged(); 477 } 478 Symtab *symtab = GetSymtab(); 479 if (symtab) { 480 symtab->SectionFileAddressesChanged(); 481 } 482 } 483 } 484 485 //------------------------------------------------------------------ 486 // PluginInterface protocol 487 //------------------------------------------------------------------ 488 lldb_private::ConstString SymbolVendor::GetPluginName() { 489 static ConstString g_name("vendor-default"); 490 return g_name; 491 } 492 493 uint32_t SymbolVendor::GetPluginVersion() { return 1; } 494