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() {} 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 122 SymbolVendor::ParseCompileUnitLanguage(const SymbolContext &sc) { 123 ModuleSP module_sp(GetModule()); 124 if (module_sp) { 125 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 126 if (m_sym_file_ap.get()) 127 return m_sym_file_ap->ParseCompileUnitLanguage(sc); 128 } 129 return eLanguageTypeUnknown; 130 } 131 132 size_t SymbolVendor::ParseCompileUnitFunctions(const SymbolContext &sc) { 133 ModuleSP module_sp(GetModule()); 134 if (module_sp) { 135 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 136 if (m_sym_file_ap.get()) 137 return m_sym_file_ap->ParseCompileUnitFunctions(sc); 138 } 139 return 0; 140 } 141 142 bool SymbolVendor::ParseCompileUnitLineTable(const SymbolContext &sc) { 143 ModuleSP module_sp(GetModule()); 144 if (module_sp) { 145 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 146 if (m_sym_file_ap.get()) 147 return m_sym_file_ap->ParseCompileUnitLineTable(sc); 148 } 149 return false; 150 } 151 152 bool SymbolVendor::ParseCompileUnitDebugMacros(const SymbolContext &sc) { 153 ModuleSP module_sp(GetModule()); 154 if (module_sp) { 155 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 156 if (m_sym_file_ap.get()) 157 return m_sym_file_ap->ParseCompileUnitDebugMacros(sc); 158 } 159 return false; 160 } 161 bool SymbolVendor::ParseCompileUnitSupportFiles(const SymbolContext &sc, 162 FileSpecList &support_files) { 163 ModuleSP module_sp(GetModule()); 164 if (module_sp) { 165 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 166 if (m_sym_file_ap.get()) 167 return m_sym_file_ap->ParseCompileUnitSupportFiles(sc, support_files); 168 } 169 return false; 170 } 171 172 bool SymbolVendor::ParseCompileUnitIsOptimized(const SymbolContext &sc) { 173 ModuleSP module_sp(GetModule()); 174 if (module_sp) { 175 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 176 if (m_sym_file_ap.get()) 177 return m_sym_file_ap->ParseCompileUnitIsOptimized(sc); 178 } 179 return false; 180 } 181 182 bool SymbolVendor::ParseImportedModules( 183 const SymbolContext &sc, std::vector<ConstString> &imported_modules) { 184 ModuleSP module_sp(GetModule()); 185 if (module_sp) { 186 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 187 if (m_sym_file_ap.get()) 188 return m_sym_file_ap->ParseImportedModules(sc, imported_modules); 189 } 190 return false; 191 } 192 193 size_t SymbolVendor::ParseFunctionBlocks(const SymbolContext &sc) { 194 ModuleSP module_sp(GetModule()); 195 if (module_sp) { 196 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 197 if (m_sym_file_ap.get()) 198 return m_sym_file_ap->ParseFunctionBlocks(sc); 199 } 200 return 0; 201 } 202 203 size_t SymbolVendor::ParseTypes(const SymbolContext &sc) { 204 ModuleSP module_sp(GetModule()); 205 if (module_sp) { 206 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 207 if (m_sym_file_ap.get()) 208 return m_sym_file_ap->ParseTypes(sc); 209 } 210 return 0; 211 } 212 213 size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) { 214 ModuleSP module_sp(GetModule()); 215 if (module_sp) { 216 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 217 if (m_sym_file_ap.get()) 218 return m_sym_file_ap->ParseVariablesForContext(sc); 219 } 220 return 0; 221 } 222 223 Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) { 224 ModuleSP module_sp(GetModule()); 225 if (module_sp) { 226 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 227 if (m_sym_file_ap.get()) 228 return m_sym_file_ap->ResolveTypeUID(type_uid); 229 } 230 return nullptr; 231 } 232 233 uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr, 234 SymbolContextItem resolve_scope, 235 SymbolContext &sc) { 236 ModuleSP module_sp(GetModule()); 237 if (module_sp) { 238 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 239 if (m_sym_file_ap.get()) 240 return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc); 241 } 242 return 0; 243 } 244 245 uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec, 246 uint32_t line, bool check_inlines, 247 SymbolContextItem resolve_scope, 248 SymbolContextList &sc_list) { 249 ModuleSP module_sp(GetModule()); 250 if (module_sp) { 251 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 252 if (m_sym_file_ap.get()) 253 return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines, 254 resolve_scope, sc_list); 255 } 256 return 0; 257 } 258 259 size_t 260 SymbolVendor::FindGlobalVariables(const ConstString &name, 261 const CompilerDeclContext *parent_decl_ctx, 262 size_t max_matches, VariableList &variables) { 263 ModuleSP module_sp(GetModule()); 264 if (module_sp) { 265 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 266 if (m_sym_file_ap.get()) 267 return m_sym_file_ap->FindGlobalVariables(name, parent_decl_ctx, 268 max_matches, variables); 269 } 270 return 0; 271 } 272 273 size_t SymbolVendor::FindGlobalVariables(const RegularExpression ®ex, 274 size_t max_matches, 275 VariableList &variables) { 276 ModuleSP module_sp(GetModule()); 277 if (module_sp) { 278 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 279 if (m_sym_file_ap.get()) 280 return m_sym_file_ap->FindGlobalVariables(regex, max_matches, variables); 281 } 282 return 0; 283 } 284 285 size_t SymbolVendor::FindFunctions(const ConstString &name, 286 const CompilerDeclContext *parent_decl_ctx, 287 FunctionNameType name_type_mask, 288 bool include_inlines, bool append, 289 SymbolContextList &sc_list) { 290 ModuleSP module_sp(GetModule()); 291 if (module_sp) { 292 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 293 if (m_sym_file_ap.get()) 294 return m_sym_file_ap->FindFunctions(name, parent_decl_ctx, name_type_mask, 295 include_inlines, append, sc_list); 296 } 297 return 0; 298 } 299 300 size_t SymbolVendor::FindFunctions(const RegularExpression ®ex, 301 bool include_inlines, bool append, 302 SymbolContextList &sc_list) { 303 ModuleSP module_sp(GetModule()); 304 if (module_sp) { 305 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 306 if (m_sym_file_ap.get()) 307 return m_sym_file_ap->FindFunctions(regex, include_inlines, append, 308 sc_list); 309 } 310 return 0; 311 } 312 313 size_t SymbolVendor::FindTypes( 314 const SymbolContext &sc, const ConstString &name, 315 const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, 316 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 317 TypeMap &types) { 318 ModuleSP module_sp(GetModule()); 319 if (module_sp) { 320 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 321 if (m_sym_file_ap.get()) 322 return m_sym_file_ap->FindTypes(sc, name, parent_decl_ctx, append, 323 max_matches, searched_symbol_files, 324 types); 325 } 326 if (!append) 327 types.Clear(); 328 return 0; 329 } 330 331 size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context, 332 bool append, TypeMap &types) { 333 ModuleSP module_sp(GetModule()); 334 if (module_sp) { 335 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 336 if (m_sym_file_ap.get()) 337 return m_sym_file_ap->FindTypes(context, append, types); 338 } 339 if (!append) 340 types.Clear(); 341 return 0; 342 } 343 344 size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask, 345 lldb_private::TypeList &type_list) { 346 ModuleSP module_sp(GetModule()); 347 if (module_sp) { 348 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 349 if (m_sym_file_ap.get()) 350 return m_sym_file_ap->GetTypes(sc_scope, type_mask, type_list); 351 } 352 return 0; 353 } 354 355 CompilerDeclContext 356 SymbolVendor::FindNamespace(const SymbolContext &sc, const ConstString &name, 357 const CompilerDeclContext *parent_decl_ctx) { 358 CompilerDeclContext namespace_decl_ctx; 359 ModuleSP module_sp(GetModule()); 360 if (module_sp) { 361 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 362 if (m_sym_file_ap.get()) 363 namespace_decl_ctx = 364 m_sym_file_ap->FindNamespace(sc, name, parent_decl_ctx); 365 } 366 return namespace_decl_ctx; 367 } 368 369 void SymbolVendor::Dump(Stream *s) { 370 ModuleSP module_sp(GetModule()); 371 if (module_sp) { 372 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 373 374 bool show_context = false; 375 376 s->Printf("%p: ", static_cast<void *>(this)); 377 s->Indent(); 378 s->PutCString("SymbolVendor"); 379 if (m_sym_file_ap.get()) { 380 ObjectFile *objfile = m_sym_file_ap->GetObjectFile(); 381 if (objfile) { 382 const FileSpec &objfile_file_spec = objfile->GetFileSpec(); 383 if (objfile_file_spec) { 384 s->PutCString(" ("); 385 objfile_file_spec.Dump(s); 386 s->PutChar(')'); 387 } 388 } 389 } 390 s->EOL(); 391 if (m_sym_file_ap) 392 m_sym_file_ap->Dump(*s); 393 s->IndentMore(); 394 m_type_list.Dump(s, show_context); 395 396 CompileUnitConstIter cu_pos, cu_end; 397 cu_end = m_compile_units.end(); 398 for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos) { 399 // We currently only dump the compile units that have been parsed 400 if (cu_pos->get()) 401 (*cu_pos)->Dump(s, show_context); 402 } 403 404 s->IndentLess(); 405 } 406 } 407 408 CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) { 409 CompUnitSP cu_sp; 410 ModuleSP module_sp(GetModule()); 411 if (module_sp) { 412 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 413 const size_t num_compile_units = GetNumCompileUnits(); 414 if (idx < num_compile_units) { 415 cu_sp = m_compile_units[idx]; 416 if (cu_sp.get() == nullptr) { 417 m_compile_units[idx] = m_sym_file_ap->ParseCompileUnitAtIndex(idx); 418 cu_sp = m_compile_units[idx]; 419 } 420 } 421 } 422 return cu_sp; 423 } 424 425 FileSpec SymbolVendor::GetMainFileSpec() const { 426 if (m_sym_file_ap.get()) { 427 const ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile(); 428 if (symfile_objfile) 429 return symfile_objfile->GetFileSpec(); 430 } 431 432 return FileSpec(); 433 } 434 435 Symtab *SymbolVendor::GetSymtab() { 436 ModuleSP module_sp(GetModule()); 437 if (module_sp) { 438 ObjectFile *objfile = module_sp->GetObjectFile(); 439 if (objfile) { 440 // Get symbol table from unified section list. 441 return objfile->GetSymtab(); 442 } 443 } 444 return nullptr; 445 } 446 447 void SymbolVendor::ClearSymtab() { 448 ModuleSP module_sp(GetModule()); 449 if (module_sp) { 450 ObjectFile *objfile = module_sp->GetObjectFile(); 451 if (objfile) { 452 // Clear symbol table from unified section list. 453 objfile->ClearSymtab(); 454 } 455 } 456 } 457 458 void SymbolVendor::SectionFileAddressesChanged() { 459 ModuleSP module_sp(GetModule()); 460 if (module_sp) { 461 ObjectFile *module_objfile = module_sp->GetObjectFile(); 462 if (m_sym_file_ap.get()) { 463 ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile(); 464 if (symfile_objfile != module_objfile) 465 symfile_objfile->SectionFileAddressesChanged(); 466 } 467 Symtab *symtab = GetSymtab(); 468 if (symtab) { 469 symtab->SectionFileAddressesChanged(); 470 } 471 } 472 } 473 474 //------------------------------------------------------------------ 475 // PluginInterface protocol 476 //------------------------------------------------------------------ 477 lldb_private::ConstString SymbolVendor::GetPluginName() { 478 static ConstString g_name("vendor-default"); 479 return g_name; 480 } 481 482 uint32_t SymbolVendor::GetPluginVersion() { return 1; } 483