1 //===-- Module.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/Core/Module.h" 11 #include "lldb/Core/Log.h" 12 #include "lldb/Core/ModuleList.h" 13 #include "lldb/Core/RegularExpression.h" 14 #include "lldb/Core/StreamString.h" 15 #include "lldb/Core/Timer.h" 16 #include "lldb/lldb-private-log.h" 17 #include "lldb/Symbol/ObjectFile.h" 18 #include "lldb/Symbol/SymbolContext.h" 19 #include "lldb/Symbol/SymbolVendor.h" 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 // Shared pointers to modules track module lifetimes in 25 // targets and in the global module, but this collection 26 // will track all module objects that are still alive 27 typedef std::vector<Module *> ModuleCollection; 28 29 static ModuleCollection & 30 GetModuleCollection() 31 { 32 // This module collection needs to live past any module, so we could either make it a 33 // shared pointer in each module or just leak is. Since it is only an empty vector by 34 // the time all the modules have gone away, we just leak it for now. If we decide this 35 // is a big problem we can introduce a Finalize method that will tear everything down in 36 // a predictable order. 37 38 static ModuleCollection *g_module_collection = NULL; 39 if (g_module_collection == NULL) 40 g_module_collection = new ModuleCollection(); 41 42 return *g_module_collection; 43 } 44 45 Mutex & 46 Module::GetAllocationModuleCollectionMutex() 47 { 48 static Mutex g_module_collection_mutex(Mutex::eMutexTypeRecursive); 49 return g_module_collection_mutex; 50 } 51 52 size_t 53 Module::GetNumberAllocatedModules () 54 { 55 Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 56 return GetModuleCollection().size(); 57 } 58 59 Module * 60 Module::GetAllocatedModuleAtIndex (size_t idx) 61 { 62 Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 63 ModuleCollection &modules = GetModuleCollection(); 64 if (idx < modules.size()) 65 return modules[idx]; 66 return NULL; 67 } 68 69 70 71 72 Module::Module(const FileSpec& file_spec, const ArchSpec& arch, const ConstString *object_name, off_t object_offset) : 73 m_mutex (Mutex::eMutexTypeRecursive), 74 m_mod_time (file_spec.GetModificationTime()), 75 m_arch (arch), 76 m_uuid (), 77 m_file (file_spec), 78 m_platform_file(), 79 m_object_name (), 80 m_object_offset (object_offset), 81 m_objfile_sp (), 82 m_symfile_ap (), 83 m_ast (), 84 m_did_load_objfile (false), 85 m_did_load_symbol_vendor (false), 86 m_did_parse_uuid (false), 87 m_did_init_ast (false), 88 m_is_dynamic_loader_module (false) 89 { 90 // Scope for locker below... 91 { 92 Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 93 GetModuleCollection().push_back(this); 94 } 95 96 if (object_name) 97 m_object_name = *object_name; 98 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 99 if (log) 100 log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')", 101 this, 102 m_arch.GetArchitectureName(), 103 m_file.GetDirectory().AsCString(""), 104 m_file.GetFilename().AsCString(""), 105 m_object_name.IsEmpty() ? "" : "(", 106 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 107 m_object_name.IsEmpty() ? "" : ")"); 108 } 109 110 Module::~Module() 111 { 112 // Scope for locker below... 113 { 114 Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 115 ModuleCollection &modules = GetModuleCollection(); 116 ModuleCollection::iterator end = modules.end(); 117 ModuleCollection::iterator pos = std::find(modules.begin(), end, this); 118 if (pos != end) 119 modules.erase(pos); 120 } 121 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 122 if (log) 123 log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')", 124 this, 125 m_arch.GetArchitectureName(), 126 m_file.GetDirectory().AsCString(""), 127 m_file.GetFilename().AsCString(""), 128 m_object_name.IsEmpty() ? "" : "(", 129 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 130 m_object_name.IsEmpty() ? "" : ")"); 131 // Release any auto pointers before we start tearing down our member 132 // variables since the object file and symbol files might need to make 133 // function calls back into this module object. The ordering is important 134 // here because symbol files can require the module object file. So we tear 135 // down the symbol file first, then the object file. 136 m_symfile_ap.reset(); 137 m_objfile_sp.reset(); 138 } 139 140 141 const lldb_private::UUID& 142 Module::GetUUID() 143 { 144 Mutex::Locker locker (m_mutex); 145 if (m_did_parse_uuid == false) 146 { 147 ObjectFile * obj_file = GetObjectFile (); 148 149 if (obj_file != NULL) 150 { 151 obj_file->GetUUID(&m_uuid); 152 m_did_parse_uuid = true; 153 } 154 } 155 return m_uuid; 156 } 157 158 ClangASTContext & 159 Module::GetClangASTContext () 160 { 161 Mutex::Locker locker (m_mutex); 162 if (m_did_init_ast == false) 163 { 164 ObjectFile * objfile = GetObjectFile(); 165 ArchSpec object_arch; 166 if (objfile && objfile->GetArchitecture(object_arch)) 167 { 168 m_did_init_ast = true; 169 m_ast.SetArchitecture (object_arch); 170 } 171 } 172 return m_ast; 173 } 174 175 void 176 Module::ParseAllDebugSymbols() 177 { 178 Mutex::Locker locker (m_mutex); 179 uint32_t num_comp_units = GetNumCompileUnits(); 180 if (num_comp_units == 0) 181 return; 182 183 SymbolContext sc; 184 sc.module_sp = this; 185 uint32_t cu_idx; 186 SymbolVendor *symbols = GetSymbolVendor (); 187 188 for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++) 189 { 190 sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get(); 191 if (sc.comp_unit) 192 { 193 sc.function = NULL; 194 symbols->ParseVariablesForContext(sc); 195 196 symbols->ParseCompileUnitFunctions(sc); 197 198 uint32_t func_idx; 199 for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx) 200 { 201 symbols->ParseFunctionBlocks(sc); 202 203 // Parse the variables for this function and all its blocks 204 symbols->ParseVariablesForContext(sc); 205 } 206 207 208 // Parse all types for this compile unit 209 sc.function = NULL; 210 symbols->ParseTypes(sc); 211 } 212 } 213 } 214 215 void 216 Module::CalculateSymbolContext(SymbolContext* sc) 217 { 218 sc->module_sp = this; 219 } 220 221 Module * 222 Module::CalculateSymbolContextModule () 223 { 224 return this; 225 } 226 227 void 228 Module::DumpSymbolContext(Stream *s) 229 { 230 s->Printf(", Module{%p}", this); 231 } 232 233 uint32_t 234 Module::GetNumCompileUnits() 235 { 236 Mutex::Locker locker (m_mutex); 237 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this); 238 SymbolVendor *symbols = GetSymbolVendor (); 239 if (symbols) 240 return symbols->GetNumCompileUnits(); 241 return 0; 242 } 243 244 CompUnitSP 245 Module::GetCompileUnitAtIndex (uint32_t index) 246 { 247 Mutex::Locker locker (m_mutex); 248 uint32_t num_comp_units = GetNumCompileUnits (); 249 CompUnitSP cu_sp; 250 251 if (index < num_comp_units) 252 { 253 SymbolVendor *symbols = GetSymbolVendor (); 254 if (symbols) 255 cu_sp = symbols->GetCompileUnitAtIndex(index); 256 } 257 return cu_sp; 258 } 259 260 bool 261 Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) 262 { 263 Mutex::Locker locker (m_mutex); 264 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr); 265 ObjectFile* ofile = GetObjectFile(); 266 if (ofile) 267 return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList()); 268 return false; 269 } 270 271 uint32_t 272 Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 273 { 274 Mutex::Locker locker (m_mutex); 275 uint32_t resolved_flags = 0; 276 277 // Clear the result symbol context in case we don't find anything 278 sc.Clear(); 279 280 // Get the section from the section/offset address. 281 const Section *section = so_addr.GetSection(); 282 283 // Make sure the section matches this module before we try and match anything 284 if (section && section->GetModule() == this) 285 { 286 // If the section offset based address resolved itself, then this 287 // is the right module. 288 sc.module_sp = this; 289 resolved_flags |= eSymbolContextModule; 290 291 // Resolve the compile unit, function, block, line table or line 292 // entry if requested. 293 if (resolve_scope & eSymbolContextCompUnit || 294 resolve_scope & eSymbolContextFunction || 295 resolve_scope & eSymbolContextBlock || 296 resolve_scope & eSymbolContextLineEntry ) 297 { 298 SymbolVendor *symbols = GetSymbolVendor (); 299 if (symbols) 300 resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc); 301 } 302 303 // Resolve the symbol if requested, but don't re-look it up if we've already found it. 304 if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol)) 305 { 306 ObjectFile* ofile = GetObjectFile(); 307 if (ofile) 308 { 309 Symtab *symtab = ofile->GetSymtab(); 310 if (symtab) 311 { 312 if (so_addr.IsSectionOffset()) 313 { 314 sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); 315 if (sc.symbol) 316 resolved_flags |= eSymbolContextSymbol; 317 } 318 } 319 } 320 } 321 } 322 return resolved_flags; 323 } 324 325 uint32_t 326 Module::ResolveSymbolContextForFilePath 327 ( 328 const char *file_path, 329 uint32_t line, 330 bool check_inlines, 331 uint32_t resolve_scope, 332 SymbolContextList& sc_list 333 ) 334 { 335 FileSpec file_spec(file_path, false); 336 return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list); 337 } 338 339 uint32_t 340 Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 341 { 342 Mutex::Locker locker (m_mutex); 343 Timer scoped_timer(__PRETTY_FUNCTION__, 344 "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)", 345 file_spec.GetDirectory().AsCString(""), 346 file_spec.GetDirectory() ? "/" : "", 347 file_spec.GetFilename().AsCString(""), 348 line, 349 check_inlines ? "yes" : "no", 350 resolve_scope); 351 352 const uint32_t initial_count = sc_list.GetSize(); 353 354 SymbolVendor *symbols = GetSymbolVendor (); 355 if (symbols) 356 symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list); 357 358 return sc_list.GetSize() - initial_count; 359 } 360 361 362 uint32_t 363 Module::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables) 364 { 365 SymbolVendor *symbols = GetSymbolVendor (); 366 if (symbols) 367 return symbols->FindGlobalVariables(name, namespace_decl, append, max_matches, variables); 368 return 0; 369 } 370 uint32_t 371 Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 372 { 373 SymbolVendor *symbols = GetSymbolVendor (); 374 if (symbols) 375 return symbols->FindGlobalVariables(regex, append, max_matches, variables); 376 return 0; 377 } 378 379 uint32_t 380 Module::FindCompileUnits (const FileSpec &path, 381 bool append, 382 SymbolContextList &sc_list) 383 { 384 if (!append) 385 sc_list.Clear(); 386 387 const uint32_t start_size = sc_list.GetSize(); 388 const uint32_t num_compile_units = GetNumCompileUnits(); 389 SymbolContext sc; 390 sc.module_sp = this; 391 const bool compare_directory = path.GetDirectory(); 392 for (uint32_t i=0; i<num_compile_units; ++i) 393 { 394 sc.comp_unit = GetCompileUnitAtIndex(i).get(); 395 if (FileSpec::Equal (*sc.comp_unit, path, compare_directory)) 396 sc_list.Append(sc); 397 } 398 return sc_list.GetSize() - start_size; 399 } 400 401 uint32_t 402 Module::FindFunctions (const ConstString &name, 403 const ClangNamespaceDecl *namespace_decl, 404 uint32_t name_type_mask, 405 bool include_symbols, 406 bool append, 407 SymbolContextList& sc_list) 408 { 409 if (!append) 410 sc_list.Clear(); 411 412 const uint32_t start_size = sc_list.GetSize(); 413 414 // Find all the functions (not symbols, but debug information functions... 415 SymbolVendor *symbols = GetSymbolVendor (); 416 if (symbols) 417 symbols->FindFunctions(name, namespace_decl, name_type_mask, append, sc_list); 418 419 // Now check our symbol table for symbols that are code symbols if requested 420 if (include_symbols) 421 { 422 ObjectFile *objfile = GetObjectFile(); 423 if (objfile) 424 { 425 Symtab *symtab = objfile->GetSymtab(); 426 if (symtab) 427 { 428 std::vector<uint32_t> symbol_indexes; 429 symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 430 const uint32_t num_matches = symbol_indexes.size(); 431 if (num_matches) 432 { 433 const bool merge_symbol_into_function = true; 434 SymbolContext sc(this); 435 for (uint32_t i=0; i<num_matches; i++) 436 { 437 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); 438 sc_list.AppendIfUnique (sc, merge_symbol_into_function); 439 } 440 } 441 } 442 } 443 } 444 return sc_list.GetSize() - start_size; 445 } 446 447 uint32_t 448 Module::FindFunctions (const RegularExpression& regex, 449 bool include_symbols, 450 bool append, 451 SymbolContextList& sc_list) 452 { 453 if (!append) 454 sc_list.Clear(); 455 456 const uint32_t start_size = sc_list.GetSize(); 457 458 SymbolVendor *symbols = GetSymbolVendor (); 459 if (symbols) 460 symbols->FindFunctions(regex, append, sc_list); 461 // Now check our symbol table for symbols that are code symbols if requested 462 if (include_symbols) 463 { 464 ObjectFile *objfile = GetObjectFile(); 465 if (objfile) 466 { 467 Symtab *symtab = objfile->GetSymtab(); 468 if (symtab) 469 { 470 std::vector<uint32_t> symbol_indexes; 471 symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 472 const uint32_t num_matches = symbol_indexes.size(); 473 if (num_matches) 474 { 475 const bool merge_symbol_into_function = true; 476 SymbolContext sc(this); 477 for (uint32_t i=0; i<num_matches; i++) 478 { 479 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); 480 sc_list.AppendIfUnique (sc, merge_symbol_into_function); 481 } 482 } 483 } 484 } 485 } 486 return sc_list.GetSize() - start_size; 487 } 488 489 uint32_t 490 Module::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types) 491 { 492 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 493 if (sc.module_sp.get() == NULL || sc.module_sp.get() == this) 494 { 495 SymbolVendor *symbols = GetSymbolVendor (); 496 if (symbols) 497 return symbols->FindTypes(sc, name, namespace_decl, append, max_matches, types); 498 } 499 return 0; 500 } 501 502 // depending on implementation details, type lookup might fail because of 503 // embedded spurious namespace:: prefixes. this call strips them, paying 504 // attention to the fact that a type might have namespace'd type names as 505 // arguments to templates, and those must not be stripped off 506 static const char* 507 StripTypeName(const char* name_cstr) 508 { 509 const char* skip_namespace = strstr(name_cstr, "::"); 510 const char* template_arg_char = strchr(name_cstr, '<'); 511 while (skip_namespace != NULL) 512 { 513 if (template_arg_char != NULL && 514 skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go 515 break; 516 name_cstr = skip_namespace+2; 517 skip_namespace = strstr(name_cstr, "::"); 518 } 519 return name_cstr; 520 } 521 522 uint32_t 523 Module::FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types) 524 { 525 uint32_t retval = FindTypes_Impl(sc, name, namespace_decl, append, max_matches, types); 526 527 if (retval == 0) 528 { 529 const char *stripped = StripTypeName(name.GetCString()); 530 return FindTypes_Impl(sc, ConstString(stripped), namespace_decl, append, max_matches, types); 531 } 532 else 533 return retval; 534 535 } 536 537 //uint32_t 538 //Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types) 539 //{ 540 // Timer scoped_timer(__PRETTY_FUNCTION__); 541 // SymbolVendor *symbols = GetSymbolVendor (); 542 // if (symbols) 543 // return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types); 544 // return 0; 545 // 546 //} 547 548 SymbolVendor* 549 Module::GetSymbolVendor (bool can_create) 550 { 551 Mutex::Locker locker (m_mutex); 552 if (m_did_load_symbol_vendor == false && can_create) 553 { 554 ObjectFile *obj_file = GetObjectFile (); 555 if (obj_file != NULL) 556 { 557 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 558 m_symfile_ap.reset(SymbolVendor::FindPlugin(this)); 559 m_did_load_symbol_vendor = true; 560 } 561 } 562 return m_symfile_ap.get(); 563 } 564 565 void 566 Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name) 567 { 568 // Container objects whose paths do not specify a file directly can call 569 // this function to correct the file and object names. 570 m_file = file; 571 m_mod_time = file.GetModificationTime(); 572 m_object_name = object_name; 573 } 574 575 const ArchSpec& 576 Module::GetArchitecture () const 577 { 578 return m_arch; 579 } 580 581 void 582 Module::GetDescription (Stream *s, lldb::DescriptionLevel level) 583 { 584 Mutex::Locker locker (m_mutex); 585 586 if (level >= eDescriptionLevelFull) 587 { 588 if (m_arch.IsValid()) 589 s->Printf("(%s) ", m_arch.GetArchitectureName()); 590 } 591 592 if (level == eDescriptionLevelBrief) 593 { 594 const char *filename = m_file.GetFilename().GetCString(); 595 if (filename) 596 s->PutCString (filename); 597 } 598 else 599 { 600 char path[PATH_MAX]; 601 if (m_file.GetPath(path, sizeof(path))) 602 s->PutCString(path); 603 } 604 605 const char *object_name = m_object_name.GetCString(); 606 if (object_name) 607 s->Printf("(%s)", object_name); 608 } 609 610 void 611 Module::ReportError (const char *format, ...) 612 { 613 StreamString module_description; 614 GetDescription(&module_description, lldb::eDescriptionLevelBrief); 615 ::fprintf (stderr, "error: %s ", module_description.GetString().c_str()); 616 617 va_list args; 618 va_start (args, format); 619 vfprintf (stderr, format, args); 620 va_end (args); 621 } 622 623 void 624 Module::ReportWarning (const char *format, ...) 625 { 626 StreamString module_description; 627 GetDescription(&module_description, lldb::eDescriptionLevelBrief); 628 ::fprintf (stderr, "warning: %s ", module_description.GetString().c_str()); 629 630 va_list args; 631 va_start (args, format); 632 vfprintf (stderr, format, args); 633 va_end (args); 634 } 635 636 void 637 Module::LogMessage (Log *log, const char *format, ...) 638 { 639 if (log) 640 { 641 StreamString log_message; 642 GetDescription(&log_message, lldb::eDescriptionLevelBrief); 643 log_message.PutCString (": "); 644 va_list args; 645 va_start (args, format); 646 log_message.PrintfVarArg (format, args); 647 va_end (args); 648 log->PutCString(log_message.GetString().c_str()); 649 } 650 } 651 652 void 653 Module::Dump(Stream *s) 654 { 655 Mutex::Locker locker (m_mutex); 656 //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 657 s->Indent(); 658 s->Printf("Module %s/%s%s%s%s\n", 659 m_file.GetDirectory().AsCString(), 660 m_file.GetFilename().AsCString(), 661 m_object_name ? "(" : "", 662 m_object_name ? m_object_name.GetCString() : "", 663 m_object_name ? ")" : ""); 664 665 s->IndentMore(); 666 ObjectFile *objfile = GetObjectFile (); 667 668 if (objfile) 669 objfile->Dump(s); 670 671 SymbolVendor *symbols = GetSymbolVendor (); 672 673 if (symbols) 674 symbols->Dump(s); 675 676 s->IndentLess(); 677 } 678 679 680 TypeList* 681 Module::GetTypeList () 682 { 683 SymbolVendor *symbols = GetSymbolVendor (); 684 if (symbols) 685 return &symbols->GetTypeList(); 686 return NULL; 687 } 688 689 const ConstString & 690 Module::GetObjectName() const 691 { 692 return m_object_name; 693 } 694 695 ObjectFile * 696 Module::GetObjectFile() 697 { 698 Mutex::Locker locker (m_mutex); 699 if (m_did_load_objfile == false) 700 { 701 m_did_load_objfile = true; 702 Timer scoped_timer(__PRETTY_FUNCTION__, 703 "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString("")); 704 m_objfile_sp = ObjectFile::FindPlugin(this, &m_file, m_object_offset, m_file.GetByteSize()); 705 if (m_objfile_sp) 706 { 707 // Once we get the object file, update our module with the object file's 708 // architecture since it might differ in vendor/os if some parts were 709 // unknown. 710 m_objfile_sp->GetArchitecture (m_arch); 711 } 712 } 713 return m_objfile_sp.get(); 714 } 715 716 717 const Symbol * 718 Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type) 719 { 720 Timer scoped_timer(__PRETTY_FUNCTION__, 721 "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)", 722 name.AsCString(), 723 symbol_type); 724 ObjectFile *objfile = GetObjectFile(); 725 if (objfile) 726 { 727 Symtab *symtab = objfile->GetSymtab(); 728 if (symtab) 729 return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny); 730 } 731 return NULL; 732 } 733 void 734 Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list) 735 { 736 // No need to protect this call using m_mutex all other method calls are 737 // already thread safe. 738 739 size_t num_indices = symbol_indexes.size(); 740 if (num_indices > 0) 741 { 742 SymbolContext sc; 743 CalculateSymbolContext (&sc); 744 for (size_t i = 0; i < num_indices; i++) 745 { 746 sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]); 747 if (sc.symbol) 748 sc_list.Append (sc); 749 } 750 } 751 } 752 753 size_t 754 Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list) 755 { 756 // No need to protect this call using m_mutex all other method calls are 757 // already thread safe. 758 759 760 Timer scoped_timer(__PRETTY_FUNCTION__, 761 "Module::FindSymbolsWithNameAndType (name = %s, type = %i)", 762 name.AsCString(), 763 symbol_type); 764 const size_t initial_size = sc_list.GetSize(); 765 ObjectFile *objfile = GetObjectFile (); 766 if (objfile) 767 { 768 Symtab *symtab = objfile->GetSymtab(); 769 if (symtab) 770 { 771 std::vector<uint32_t> symbol_indexes; 772 symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes); 773 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); 774 } 775 } 776 return sc_list.GetSize() - initial_size; 777 } 778 779 size_t 780 Module::FindSymbolsMatchingRegExAndType (const RegularExpression ®ex, SymbolType symbol_type, SymbolContextList &sc_list) 781 { 782 // No need to protect this call using m_mutex all other method calls are 783 // already thread safe. 784 785 Timer scoped_timer(__PRETTY_FUNCTION__, 786 "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)", 787 regex.GetText(), 788 symbol_type); 789 const size_t initial_size = sc_list.GetSize(); 790 ObjectFile *objfile = GetObjectFile (); 791 if (objfile) 792 { 793 Symtab *symtab = objfile->GetSymtab(); 794 if (symtab) 795 { 796 std::vector<uint32_t> symbol_indexes; 797 symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 798 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); 799 } 800 } 801 return sc_list.GetSize() - initial_size; 802 } 803 804 const TimeValue & 805 Module::GetModificationTime () const 806 { 807 return m_mod_time; 808 } 809 810 bool 811 Module::IsExecutable () 812 { 813 if (GetObjectFile() == NULL) 814 return false; 815 else 816 return GetObjectFile()->IsExecutable(); 817 } 818 819 bool 820 Module::IsLoadedInTarget (Target *target) 821 { 822 ObjectFile *obj_file = GetObjectFile(); 823 if (obj_file) 824 { 825 SectionList *sections = obj_file->GetSectionList(); 826 if (sections != NULL) 827 { 828 size_t num_sections = sections->GetSize(); 829 for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) 830 { 831 SectionSP section_sp = sections->GetSectionAtIndex(sect_idx); 832 if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) 833 { 834 return true; 835 } 836 } 837 } 838 } 839 return false; 840 } 841 bool 842 Module::SetArchitecture (const ArchSpec &new_arch) 843 { 844 if (!m_arch.IsValid()) 845 { 846 m_arch = new_arch; 847 return true; 848 } 849 return m_arch == new_arch; 850 } 851 852