Module.cpp revision 444fe998bf707bd076a70c3a779db8575533695e
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/DataBuffer.h" 12#include "lldb/Core/DataBufferHeap.h" 13#include "lldb/Core/Log.h" 14#include "lldb/Core/ModuleList.h" 15#include "lldb/Core/RegularExpression.h" 16#include "lldb/Core/StreamString.h" 17#include "lldb/Core/Timer.h" 18#include "lldb/Host/Host.h" 19#include "lldb/lldb-private-log.h" 20#include "lldb/Symbol/ObjectFile.h" 21#include "lldb/Symbol/SymbolContext.h" 22#include "lldb/Symbol/SymbolVendor.h" 23#include "lldb/Target/Process.h" 24#include "lldb/Target/Target.h" 25 26using namespace lldb; 27using namespace lldb_private; 28 29// Shared pointers to modules track module lifetimes in 30// targets and in the global module, but this collection 31// will track all module objects that are still alive 32typedef std::vector<Module *> ModuleCollection; 33 34static ModuleCollection & 35GetModuleCollection() 36{ 37 // This module collection needs to live past any module, so we could either make it a 38 // shared pointer in each module or just leak is. Since it is only an empty vector by 39 // the time all the modules have gone away, we just leak it for now. If we decide this 40 // is a big problem we can introduce a Finalize method that will tear everything down in 41 // a predictable order. 42 43 static ModuleCollection *g_module_collection = NULL; 44 if (g_module_collection == NULL) 45 g_module_collection = new ModuleCollection(); 46 47 return *g_module_collection; 48} 49 50Mutex * 51Module::GetAllocationModuleCollectionMutex() 52{ 53 // NOTE: The mutex below must be leaked since the global module list in 54 // the ModuleList class will get torn at some point, and we can't know 55 // if it will tear itself down before the "g_module_collection_mutex" below 56 // will. So we leak a Mutex object below to safeguard against that 57 58 static Mutex *g_module_collection_mutex = NULL; 59 if (g_module_collection_mutex == NULL) 60 g_module_collection_mutex = new Mutex (Mutex::eMutexTypeRecursive); // NOTE: known leak 61 return g_module_collection_mutex; 62} 63 64size_t 65Module::GetNumberAllocatedModules () 66{ 67 Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 68 return GetModuleCollection().size(); 69} 70 71Module * 72Module::GetAllocatedModuleAtIndex (size_t idx) 73{ 74 Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 75 ModuleCollection &modules = GetModuleCollection(); 76 if (idx < modules.size()) 77 return modules[idx]; 78 return NULL; 79} 80#if 0 81 82// These functions help us to determine if modules are still loaded, yet don't require that 83// you have a command interpreter and can easily be called from an external debugger. 84namespace lldb { 85 86 void 87 ClearModuleInfo (void) 88 { 89 ModuleList::RemoveOrphanSharedModules(); 90 } 91 92 void 93 DumpModuleInfo (void) 94 { 95 Mutex::Locker locker (Module::GetAllocationModuleCollectionMutex()); 96 ModuleCollection &modules = GetModuleCollection(); 97 const size_t count = modules.size(); 98 printf ("%s: %zu modules:\n", __PRETTY_FUNCTION__, count); 99 for (size_t i=0; i<count; ++i) 100 { 101 102 StreamString strm; 103 Module *module = modules[i]; 104 const bool in_shared_module_list = ModuleList::ModuleIsInCache (module); 105 module->GetDescription(&strm, eDescriptionLevelFull); 106 printf ("%p: shared = %i, ref_count = %3u, module = %s\n", 107 module, 108 in_shared_module_list, 109 (uint32_t)module->use_count(), 110 strm.GetString().c_str()); 111 } 112 } 113} 114 115#endif 116 117Module::Module (const ModuleSpec &module_spec) : 118 m_mutex (Mutex::eMutexTypeRecursive), 119 m_mod_time (module_spec.GetFileSpec().GetModificationTime()), 120 m_arch (module_spec.GetArchitecture()), 121 m_uuid (), 122 m_file (module_spec.GetFileSpec()), 123 m_platform_file(module_spec.GetPlatformFileSpec()), 124 m_symfile_spec (module_spec.GetSymbolFileSpec()), 125 m_object_name (module_spec.GetObjectName()), 126 m_object_offset (module_spec.GetObjectOffset()), 127 m_objfile_sp (), 128 m_symfile_ap (), 129 m_ast (), 130 m_did_load_objfile (false), 131 m_did_load_symbol_vendor (false), 132 m_did_parse_uuid (false), 133 m_did_init_ast (false), 134 m_is_dynamic_loader_module (false), 135 m_was_modified (false) 136{ 137 // Scope for locker below... 138 { 139 Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 140 GetModuleCollection().push_back(this); 141 } 142 143 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 144 if (log) 145 log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')", 146 this, 147 m_arch.GetArchitectureName(), 148 m_file.GetDirectory().AsCString(""), 149 m_file.GetFilename().AsCString(""), 150 m_object_name.IsEmpty() ? "" : "(", 151 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 152 m_object_name.IsEmpty() ? "" : ")"); 153} 154 155Module::Module(const FileSpec& file_spec, 156 const ArchSpec& arch, 157 const ConstString *object_name, 158 off_t object_offset) : 159 m_mutex (Mutex::eMutexTypeRecursive), 160 m_mod_time (file_spec.GetModificationTime()), 161 m_arch (arch), 162 m_uuid (), 163 m_file (file_spec), 164 m_platform_file(), 165 m_symfile_spec (), 166 m_object_name (), 167 m_object_offset (object_offset), 168 m_objfile_sp (), 169 m_symfile_ap (), 170 m_ast (), 171 m_did_load_objfile (false), 172 m_did_load_symbol_vendor (false), 173 m_did_parse_uuid (false), 174 m_did_init_ast (false), 175 m_is_dynamic_loader_module (false), 176 m_was_modified (false) 177{ 178 // Scope for locker below... 179 { 180 Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 181 GetModuleCollection().push_back(this); 182 } 183 184 if (object_name) 185 m_object_name = *object_name; 186 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 187 if (log) 188 log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')", 189 this, 190 m_arch.GetArchitectureName(), 191 m_file.GetDirectory().AsCString(""), 192 m_file.GetFilename().AsCString(""), 193 m_object_name.IsEmpty() ? "" : "(", 194 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 195 m_object_name.IsEmpty() ? "" : ")"); 196} 197 198Module::~Module() 199{ 200 // Scope for locker below... 201 { 202 Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 203 ModuleCollection &modules = GetModuleCollection(); 204 ModuleCollection::iterator end = modules.end(); 205 ModuleCollection::iterator pos = std::find(modules.begin(), end, this); 206 if (pos != end) 207 modules.erase(pos); 208 } 209 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 210 if (log) 211 log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')", 212 this, 213 m_arch.GetArchitectureName(), 214 m_file.GetDirectory().AsCString(""), 215 m_file.GetFilename().AsCString(""), 216 m_object_name.IsEmpty() ? "" : "(", 217 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 218 m_object_name.IsEmpty() ? "" : ")"); 219 // Release any auto pointers before we start tearing down our member 220 // variables since the object file and symbol files might need to make 221 // function calls back into this module object. The ordering is important 222 // here because symbol files can require the module object file. So we tear 223 // down the symbol file first, then the object file. 224 m_symfile_ap.reset(); 225 m_objfile_sp.reset(); 226} 227 228ObjectFile * 229Module::GetMemoryObjectFile (const lldb::ProcessSP &process_sp, lldb::addr_t header_addr, Error &error) 230{ 231 if (m_objfile_sp) 232 { 233 error.SetErrorString ("object file already exists"); 234 } 235 else 236 { 237 Mutex::Locker locker (m_mutex); 238 if (process_sp) 239 { 240 StreamString s; 241 if (m_file.GetFilename()) 242 s << m_file.GetFilename(); 243 s.Printf("[0x%16.16llx]", header_addr); 244 m_file.GetFilename().SetCString (s.GetData()); 245 m_did_load_objfile = true; 246 std::auto_ptr<DataBufferHeap> data_ap (new DataBufferHeap (512, 0)); 247 Error readmem_error; 248 const size_t bytes_read = process_sp->ReadMemory (header_addr, 249 data_ap->GetBytes(), 250 data_ap->GetByteSize(), 251 readmem_error); 252 if (bytes_read == 512) 253 { 254 DataBufferSP data_sp(data_ap.release()); 255 m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp, header_addr, data_sp); 256 if (m_objfile_sp) 257 { 258 // Once we get the object file, update our module with the object file's 259 // architecture since it might differ in vendor/os if some parts were 260 // unknown. 261 m_objfile_sp->GetArchitecture (m_arch); 262 } 263 else 264 { 265 error.SetErrorString ("unable to find suitable object file plug-in"); 266 } 267 } 268 else 269 { 270 error.SetErrorStringWithFormat ("unable to read header from memory: %s", readmem_error.AsCString()); 271 } 272 } 273 else 274 { 275 error.SetErrorString ("invalid process"); 276 } 277 } 278 return m_objfile_sp.get(); 279} 280 281 282const lldb_private::UUID& 283Module::GetUUID() 284{ 285 Mutex::Locker locker (m_mutex); 286 if (m_did_parse_uuid == false) 287 { 288 ObjectFile * obj_file = GetObjectFile (); 289 290 if (obj_file != NULL) 291 { 292 obj_file->GetUUID(&m_uuid); 293 m_did_parse_uuid = true; 294 } 295 } 296 return m_uuid; 297} 298 299ClangASTContext & 300Module::GetClangASTContext () 301{ 302 Mutex::Locker locker (m_mutex); 303 if (m_did_init_ast == false) 304 { 305 ObjectFile * objfile = GetObjectFile(); 306 ArchSpec object_arch; 307 if (objfile && objfile->GetArchitecture(object_arch)) 308 { 309 m_did_init_ast = true; 310 m_ast.SetArchitecture (object_arch); 311 } 312 } 313 return m_ast; 314} 315 316void 317Module::ParseAllDebugSymbols() 318{ 319 Mutex::Locker locker (m_mutex); 320 uint32_t num_comp_units = GetNumCompileUnits(); 321 if (num_comp_units == 0) 322 return; 323 324 SymbolContext sc; 325 sc.module_sp = shared_from_this(); 326 uint32_t cu_idx; 327 SymbolVendor *symbols = GetSymbolVendor (); 328 329 for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++) 330 { 331 sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get(); 332 if (sc.comp_unit) 333 { 334 sc.function = NULL; 335 symbols->ParseVariablesForContext(sc); 336 337 symbols->ParseCompileUnitFunctions(sc); 338 339 uint32_t func_idx; 340 for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx) 341 { 342 symbols->ParseFunctionBlocks(sc); 343 344 // Parse the variables for this function and all its blocks 345 symbols->ParseVariablesForContext(sc); 346 } 347 348 349 // Parse all types for this compile unit 350 sc.function = NULL; 351 symbols->ParseTypes(sc); 352 } 353 } 354} 355 356void 357Module::CalculateSymbolContext(SymbolContext* sc) 358{ 359 sc->module_sp = shared_from_this(); 360} 361 362ModuleSP 363Module::CalculateSymbolContextModule () 364{ 365 return shared_from_this(); 366} 367 368void 369Module::DumpSymbolContext(Stream *s) 370{ 371 s->Printf(", Module{%p}", this); 372} 373 374uint32_t 375Module::GetNumCompileUnits() 376{ 377 Mutex::Locker locker (m_mutex); 378 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this); 379 SymbolVendor *symbols = GetSymbolVendor (); 380 if (symbols) 381 return symbols->GetNumCompileUnits(); 382 return 0; 383} 384 385CompUnitSP 386Module::GetCompileUnitAtIndex (uint32_t index) 387{ 388 Mutex::Locker locker (m_mutex); 389 uint32_t num_comp_units = GetNumCompileUnits (); 390 CompUnitSP cu_sp; 391 392 if (index < num_comp_units) 393 { 394 SymbolVendor *symbols = GetSymbolVendor (); 395 if (symbols) 396 cu_sp = symbols->GetCompileUnitAtIndex(index); 397 } 398 return cu_sp; 399} 400 401bool 402Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) 403{ 404 Mutex::Locker locker (m_mutex); 405 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr); 406 ObjectFile* ofile = GetObjectFile(); 407 if (ofile) 408 return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList()); 409 return false; 410} 411 412uint32_t 413Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 414{ 415 Mutex::Locker locker (m_mutex); 416 uint32_t resolved_flags = 0; 417 418 // Clear the result symbol context in case we don't find anything 419 sc.Clear(); 420 421 // Get the section from the section/offset address. 422 SectionSP section_sp (so_addr.GetSection()); 423 424 // Make sure the section matches this module before we try and match anything 425 if (section_sp && section_sp->GetModule().get() == this) 426 { 427 // If the section offset based address resolved itself, then this 428 // is the right module. 429 sc.module_sp = shared_from_this(); 430 resolved_flags |= eSymbolContextModule; 431 432 // Resolve the compile unit, function, block, line table or line 433 // entry if requested. 434 if (resolve_scope & eSymbolContextCompUnit || 435 resolve_scope & eSymbolContextFunction || 436 resolve_scope & eSymbolContextBlock || 437 resolve_scope & eSymbolContextLineEntry ) 438 { 439 SymbolVendor *symbols = GetSymbolVendor (); 440 if (symbols) 441 resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc); 442 } 443 444 // Resolve the symbol if requested, but don't re-look it up if we've already found it. 445 if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol)) 446 { 447 ObjectFile* ofile = GetObjectFile(); 448 if (ofile) 449 { 450 Symtab *symtab = ofile->GetSymtab(); 451 if (symtab) 452 { 453 if (so_addr.IsSectionOffset()) 454 { 455 sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); 456 if (sc.symbol) 457 resolved_flags |= eSymbolContextSymbol; 458 } 459 } 460 } 461 } 462 } 463 return resolved_flags; 464} 465 466uint32_t 467Module::ResolveSymbolContextForFilePath 468( 469 const char *file_path, 470 uint32_t line, 471 bool check_inlines, 472 uint32_t resolve_scope, 473 SymbolContextList& sc_list 474) 475{ 476 FileSpec file_spec(file_path, false); 477 return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list); 478} 479 480uint32_t 481Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 482{ 483 Mutex::Locker locker (m_mutex); 484 Timer scoped_timer(__PRETTY_FUNCTION__, 485 "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)", 486 file_spec.GetDirectory().AsCString(""), 487 file_spec.GetDirectory() ? "/" : "", 488 file_spec.GetFilename().AsCString(""), 489 line, 490 check_inlines ? "yes" : "no", 491 resolve_scope); 492 493 const uint32_t initial_count = sc_list.GetSize(); 494 495 SymbolVendor *symbols = GetSymbolVendor (); 496 if (symbols) 497 symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list); 498 499 return sc_list.GetSize() - initial_count; 500} 501 502 503uint32_t 504Module::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables) 505{ 506 SymbolVendor *symbols = GetSymbolVendor (); 507 if (symbols) 508 return symbols->FindGlobalVariables(name, namespace_decl, append, max_matches, variables); 509 return 0; 510} 511uint32_t 512Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 513{ 514 SymbolVendor *symbols = GetSymbolVendor (); 515 if (symbols) 516 return symbols->FindGlobalVariables(regex, append, max_matches, variables); 517 return 0; 518} 519 520uint32_t 521Module::FindCompileUnits (const FileSpec &path, 522 bool append, 523 SymbolContextList &sc_list) 524{ 525 if (!append) 526 sc_list.Clear(); 527 528 const uint32_t start_size = sc_list.GetSize(); 529 const uint32_t num_compile_units = GetNumCompileUnits(); 530 SymbolContext sc; 531 sc.module_sp = shared_from_this(); 532 const bool compare_directory = path.GetDirectory(); 533 for (uint32_t i=0; i<num_compile_units; ++i) 534 { 535 sc.comp_unit = GetCompileUnitAtIndex(i).get(); 536 if (FileSpec::Equal (*sc.comp_unit, path, compare_directory)) 537 sc_list.Append(sc); 538 } 539 return sc_list.GetSize() - start_size; 540} 541 542uint32_t 543Module::FindFunctions (const ConstString &name, 544 const ClangNamespaceDecl *namespace_decl, 545 uint32_t name_type_mask, 546 bool include_symbols, 547 bool include_inlines, 548 bool append, 549 SymbolContextList& sc_list) 550{ 551 if (!append) 552 sc_list.Clear(); 553 554 const uint32_t start_size = sc_list.GetSize(); 555 556 // Find all the functions (not symbols, but debug information functions... 557 SymbolVendor *symbols = GetSymbolVendor (); 558 if (symbols) 559 symbols->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, append, sc_list); 560 561 // Now check our symbol table for symbols that are code symbols if requested 562 if (include_symbols) 563 { 564 ObjectFile *objfile = GetObjectFile(); 565 if (objfile) 566 { 567 Symtab *symtab = objfile->GetSymtab(); 568 if (symtab) 569 { 570 std::vector<uint32_t> symbol_indexes; 571 symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 572 const uint32_t num_matches = symbol_indexes.size(); 573 if (num_matches) 574 { 575 const bool merge_symbol_into_function = true; 576 SymbolContext sc(this); 577 for (uint32_t i=0; i<num_matches; i++) 578 { 579 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); 580 sc_list.AppendIfUnique (sc, merge_symbol_into_function); 581 } 582 } 583 } 584 } 585 } 586 return sc_list.GetSize() - start_size; 587} 588 589uint32_t 590Module::FindFunctions (const RegularExpression& regex, 591 bool include_symbols, 592 bool include_inlines, 593 bool append, 594 SymbolContextList& sc_list) 595{ 596 if (!append) 597 sc_list.Clear(); 598 599 const uint32_t start_size = sc_list.GetSize(); 600 601 SymbolVendor *symbols = GetSymbolVendor (); 602 if (symbols) 603 symbols->FindFunctions(regex, include_inlines, append, sc_list); 604 // Now check our symbol table for symbols that are code symbols if requested 605 if (include_symbols) 606 { 607 ObjectFile *objfile = GetObjectFile(); 608 if (objfile) 609 { 610 Symtab *symtab = objfile->GetSymtab(); 611 if (symtab) 612 { 613 std::vector<uint32_t> symbol_indexes; 614 symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 615 const uint32_t num_matches = symbol_indexes.size(); 616 if (num_matches) 617 { 618 const bool merge_symbol_into_function = true; 619 SymbolContext sc(this); 620 for (uint32_t i=0; i<num_matches; i++) 621 { 622 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); 623 sc_list.AppendIfUnique (sc, merge_symbol_into_function); 624 } 625 } 626 } 627 } 628 } 629 return sc_list.GetSize() - start_size; 630} 631 632uint32_t 633Module::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types) 634{ 635 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 636 if (sc.module_sp.get() == NULL || sc.module_sp.get() == this) 637 { 638 SymbolVendor *symbols = GetSymbolVendor (); 639 if (symbols) 640 return symbols->FindTypes(sc, name, namespace_decl, append, max_matches, types); 641 } 642 return 0; 643} 644 645// depending on implementation details, type lookup might fail because of 646// embedded spurious namespace:: prefixes. this call strips them, paying 647// attention to the fact that a type might have namespace'd type names as 648// arguments to templates, and those must not be stripped off 649static const char* 650StripTypeName(const char* name_cstr) 651{ 652 // Protect against null c string. 653 if (!name_cstr) 654 return name_cstr; 655 const char* skip_namespace = strstr(name_cstr, "::"); 656 const char* template_arg_char = strchr(name_cstr, '<'); 657 while (skip_namespace != NULL) 658 { 659 if (template_arg_char != NULL && 660 skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go 661 break; 662 name_cstr = skip_namespace+2; 663 skip_namespace = strstr(name_cstr, "::"); 664 } 665 return name_cstr; 666} 667 668uint32_t 669Module::FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types) 670{ 671 uint32_t retval = FindTypes_Impl(sc, name, namespace_decl, append, max_matches, types); 672 673 if (retval == 0) 674 { 675 const char *orig_name = name.GetCString(); 676 const char *stripped = StripTypeName(orig_name); 677 // Only do this lookup if StripTypeName has stripped the name: 678 if (stripped != orig_name) 679 return FindTypes_Impl(sc, ConstString(stripped), namespace_decl, append, max_matches, types); 680 else 681 return 0; 682 } 683 else 684 return retval; 685 686} 687 688//uint32_t 689//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types) 690//{ 691// Timer scoped_timer(__PRETTY_FUNCTION__); 692// SymbolVendor *symbols = GetSymbolVendor (); 693// if (symbols) 694// return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types); 695// return 0; 696// 697//} 698 699SymbolVendor* 700Module::GetSymbolVendor (bool can_create) 701{ 702 Mutex::Locker locker (m_mutex); 703 if (m_did_load_symbol_vendor == false && can_create) 704 { 705 ObjectFile *obj_file = GetObjectFile (); 706 if (obj_file != NULL) 707 { 708 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 709 m_symfile_ap.reset(SymbolVendor::FindPlugin(shared_from_this())); 710 m_did_load_symbol_vendor = true; 711 } 712 } 713 return m_symfile_ap.get(); 714} 715 716void 717Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name) 718{ 719 // Container objects whose paths do not specify a file directly can call 720 // this function to correct the file and object names. 721 m_file = file; 722 m_mod_time = file.GetModificationTime(); 723 m_object_name = object_name; 724} 725 726const ArchSpec& 727Module::GetArchitecture () const 728{ 729 return m_arch; 730} 731 732void 733Module::GetDescription (Stream *s, lldb::DescriptionLevel level) 734{ 735 Mutex::Locker locker (m_mutex); 736 737 if (level >= eDescriptionLevelFull) 738 { 739 if (m_arch.IsValid()) 740 s->Printf("(%s) ", m_arch.GetArchitectureName()); 741 } 742 743 if (level == eDescriptionLevelBrief) 744 { 745 const char *filename = m_file.GetFilename().GetCString(); 746 if (filename) 747 s->PutCString (filename); 748 } 749 else 750 { 751 char path[PATH_MAX]; 752 if (m_file.GetPath(path, sizeof(path))) 753 s->PutCString(path); 754 } 755 756 const char *object_name = m_object_name.GetCString(); 757 if (object_name) 758 s->Printf("(%s)", object_name); 759} 760 761void 762Module::ReportError (const char *format, ...) 763{ 764 if (format && format[0]) 765 { 766 StreamString strm; 767 strm.PutCString("error: "); 768 GetDescription(&strm, lldb::eDescriptionLevelBrief); 769 strm.PutChar (' '); 770 va_list args; 771 va_start (args, format); 772 strm.PrintfVarArg(format, args); 773 va_end (args); 774 775 const int format_len = strlen(format); 776 if (format_len > 0) 777 { 778 const char last_char = format[format_len-1]; 779 if (last_char != '\n' || last_char != '\r') 780 strm.EOL(); 781 } 782 Host::SystemLog (Host::eSystemLogError, "%s", strm.GetString().c_str()); 783 784 } 785} 786 787void 788Module::ReportErrorIfModifyDetected (const char *format, ...) 789{ 790 if (!GetModified(true) && GetModified(false)) 791 { 792 if (format) 793 { 794 StreamString strm; 795 strm.PutCString("error: the object file "); 796 GetDescription(&strm, lldb::eDescriptionLevelFull); 797 strm.PutCString (" has been modified\n"); 798 799 va_list args; 800 va_start (args, format); 801 strm.PrintfVarArg(format, args); 802 va_end (args); 803 804 const int format_len = strlen(format); 805 if (format_len > 0) 806 { 807 const char last_char = format[format_len-1]; 808 if (last_char != '\n' || last_char != '\r') 809 strm.EOL(); 810 } 811 strm.PutCString("The debug session should be aborted as the original debug information has been overwritten.\n"); 812 Host::SystemLog (Host::eSystemLogError, "%s", strm.GetString().c_str()); 813 } 814 } 815} 816 817void 818Module::ReportWarning (const char *format, ...) 819{ 820 if (format && format[0]) 821 { 822 StreamString strm; 823 strm.PutCString("warning: "); 824 GetDescription(&strm, lldb::eDescriptionLevelFull); 825 strm.PutChar (' '); 826 827 va_list args; 828 va_start (args, format); 829 strm.PrintfVarArg(format, args); 830 va_end (args); 831 832 const int format_len = strlen(format); 833 if (format_len > 0) 834 { 835 const char last_char = format[format_len-1]; 836 if (last_char != '\n' || last_char != '\r') 837 strm.EOL(); 838 } 839 Host::SystemLog (Host::eSystemLogWarning, "%s", strm.GetString().c_str()); 840 } 841} 842 843void 844Module::LogMessage (Log *log, const char *format, ...) 845{ 846 if (log) 847 { 848 StreamString log_message; 849 GetDescription(&log_message, lldb::eDescriptionLevelFull); 850 log_message.PutCString (": "); 851 va_list args; 852 va_start (args, format); 853 log_message.PrintfVarArg (format, args); 854 va_end (args); 855 log->PutCString(log_message.GetString().c_str()); 856 } 857} 858 859bool 860Module::GetModified (bool use_cached_only) 861{ 862 if (m_was_modified == false && use_cached_only == false) 863 { 864 TimeValue curr_mod_time (m_file.GetModificationTime()); 865 m_was_modified = curr_mod_time != m_mod_time; 866 } 867 return m_was_modified; 868} 869 870bool 871Module::SetModified (bool b) 872{ 873 const bool prev_value = m_was_modified; 874 m_was_modified = b; 875 return prev_value; 876} 877 878 879void 880Module::Dump(Stream *s) 881{ 882 Mutex::Locker locker (m_mutex); 883 //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 884 s->Indent(); 885 s->Printf("Module %s/%s%s%s%s\n", 886 m_file.GetDirectory().AsCString(), 887 m_file.GetFilename().AsCString(), 888 m_object_name ? "(" : "", 889 m_object_name ? m_object_name.GetCString() : "", 890 m_object_name ? ")" : ""); 891 892 s->IndentMore(); 893 ObjectFile *objfile = GetObjectFile (); 894 895 if (objfile) 896 objfile->Dump(s); 897 898 SymbolVendor *symbols = GetSymbolVendor (); 899 900 if (symbols) 901 symbols->Dump(s); 902 903 s->IndentLess(); 904} 905 906 907TypeList* 908Module::GetTypeList () 909{ 910 SymbolVendor *symbols = GetSymbolVendor (); 911 if (symbols) 912 return &symbols->GetTypeList(); 913 return NULL; 914} 915 916const ConstString & 917Module::GetObjectName() const 918{ 919 return m_object_name; 920} 921 922ObjectFile * 923Module::GetObjectFile() 924{ 925 Mutex::Locker locker (m_mutex); 926 if (m_did_load_objfile == false) 927 { 928 m_did_load_objfile = true; 929 Timer scoped_timer(__PRETTY_FUNCTION__, 930 "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString("")); 931 DataBufferSP file_data_sp; 932 m_objfile_sp = ObjectFile::FindPlugin (shared_from_this(), 933 &m_file, 934 m_object_offset, 935 m_file.GetByteSize(), 936 file_data_sp); 937 if (m_objfile_sp) 938 { 939 // Once we get the object file, update our module with the object file's 940 // architecture since it might differ in vendor/os if some parts were 941 // unknown. 942 m_objfile_sp->GetArchitecture (m_arch); 943 } 944 } 945 return m_objfile_sp.get(); 946} 947 948 949const Symbol * 950Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type) 951{ 952 Timer scoped_timer(__PRETTY_FUNCTION__, 953 "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)", 954 name.AsCString(), 955 symbol_type); 956 ObjectFile *objfile = GetObjectFile(); 957 if (objfile) 958 { 959 Symtab *symtab = objfile->GetSymtab(); 960 if (symtab) 961 return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny); 962 } 963 return NULL; 964} 965void 966Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list) 967{ 968 // No need to protect this call using m_mutex all other method calls are 969 // already thread safe. 970 971 size_t num_indices = symbol_indexes.size(); 972 if (num_indices > 0) 973 { 974 SymbolContext sc; 975 CalculateSymbolContext (&sc); 976 for (size_t i = 0; i < num_indices; i++) 977 { 978 sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]); 979 if (sc.symbol) 980 sc_list.Append (sc); 981 } 982 } 983} 984 985size_t 986Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list) 987{ 988 // No need to protect this call using m_mutex all other method calls are 989 // already thread safe. 990 991 992 Timer scoped_timer(__PRETTY_FUNCTION__, 993 "Module::FindSymbolsWithNameAndType (name = %s, type = %i)", 994 name.AsCString(), 995 symbol_type); 996 const size_t initial_size = sc_list.GetSize(); 997 ObjectFile *objfile = GetObjectFile (); 998 if (objfile) 999 { 1000 Symtab *symtab = objfile->GetSymtab(); 1001 if (symtab) 1002 { 1003 std::vector<uint32_t> symbol_indexes; 1004 symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes); 1005 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); 1006 } 1007 } 1008 return sc_list.GetSize() - initial_size; 1009} 1010 1011size_t 1012Module::FindSymbolsMatchingRegExAndType (const RegularExpression ®ex, SymbolType symbol_type, SymbolContextList &sc_list) 1013{ 1014 // No need to protect this call using m_mutex all other method calls are 1015 // already thread safe. 1016 1017 Timer scoped_timer(__PRETTY_FUNCTION__, 1018 "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)", 1019 regex.GetText(), 1020 symbol_type); 1021 const size_t initial_size = sc_list.GetSize(); 1022 ObjectFile *objfile = GetObjectFile (); 1023 if (objfile) 1024 { 1025 Symtab *symtab = objfile->GetSymtab(); 1026 if (symtab) 1027 { 1028 std::vector<uint32_t> symbol_indexes; 1029 symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 1030 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); 1031 } 1032 } 1033 return sc_list.GetSize() - initial_size; 1034} 1035 1036const TimeValue & 1037Module::GetModificationTime () const 1038{ 1039 return m_mod_time; 1040} 1041 1042bool 1043Module::IsExecutable () 1044{ 1045 if (GetObjectFile() == NULL) 1046 return false; 1047 else 1048 return GetObjectFile()->IsExecutable(); 1049} 1050 1051bool 1052Module::IsLoadedInTarget (Target *target) 1053{ 1054 ObjectFile *obj_file = GetObjectFile(); 1055 if (obj_file) 1056 { 1057 SectionList *sections = obj_file->GetSectionList(); 1058 if (sections != NULL) 1059 { 1060 size_t num_sections = sections->GetSize(); 1061 for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) 1062 { 1063 SectionSP section_sp = sections->GetSectionAtIndex(sect_idx); 1064 if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) 1065 { 1066 return true; 1067 } 1068 } 1069 } 1070 } 1071 return false; 1072} 1073bool 1074Module::SetArchitecture (const ArchSpec &new_arch) 1075{ 1076 if (!m_arch.IsValid()) 1077 { 1078 m_arch = new_arch; 1079 return true; 1080 } 1081 return m_arch == new_arch; 1082} 1083 1084bool 1085Module::SetLoadAddress (Target &target, lldb::addr_t offset, bool &changed) 1086{ 1087 changed = false; 1088 ObjectFile *image_object_file = GetObjectFile(); 1089 if (image_object_file) 1090 { 1091 SectionList *section_list = image_object_file->GetSectionList (); 1092 if (section_list) 1093 { 1094 const size_t num_sections = section_list->GetSize(); 1095 size_t sect_idx = 0; 1096 for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) 1097 { 1098 // Iterate through the object file sections to find the 1099 // first section that starts of file offset zero and that 1100 // has bytes in the file... 1101 Section *section = section_list->GetSectionAtIndex (sect_idx).get(); 1102 if (section) 1103 { 1104 if (target.GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + offset)) 1105 changed = true; 1106 } 1107 } 1108 return sect_idx > 0; 1109 } 1110 } 1111 return false; 1112} 1113 1114 1115bool 1116Module::MatchesModuleSpec (const ModuleSpec &module_ref) 1117{ 1118 const UUID &uuid = module_ref.GetUUID(); 1119 1120 if (uuid.IsValid()) 1121 { 1122 // If the UUID matches, then nothing more needs to match... 1123 if (uuid == GetUUID()) 1124 return true; 1125 else 1126 return false; 1127 } 1128 1129 const FileSpec &file_spec = module_ref.GetFileSpec(); 1130 if (file_spec) 1131 { 1132 if (!FileSpec::Equal (file_spec, m_file, file_spec.GetDirectory())) 1133 return false; 1134 } 1135 1136 const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec(); 1137 if (platform_file_spec) 1138 { 1139 if (!FileSpec::Equal (platform_file_spec, m_platform_file, platform_file_spec.GetDirectory())) 1140 return false; 1141 } 1142 1143 const ArchSpec &arch = module_ref.GetArchitecture(); 1144 if (arch.IsValid()) 1145 { 1146 if (m_arch != arch) 1147 return false; 1148 } 1149 1150 const ConstString &object_name = module_ref.GetObjectName(); 1151 if (object_name) 1152 { 1153 if (object_name != GetObjectName()) 1154 return false; 1155 } 1156 return true; 1157} 1158 1159