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