Module.cpp revision 801417e453f8531ac176cd952200587bf15d9ccf
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/Timer.h" 15#include "lldb/lldb-private-log.h" 16#include "lldb/Symbol/ObjectFile.h" 17#include "lldb/Symbol/SymbolContext.h" 18#include "lldb/Symbol/SymbolVendor.h" 19 20using namespace lldb; 21using namespace lldb_private; 22 23Module::Module(const FileSpec& file_spec, const ArchSpec& arch, const ConstString *object_name, off_t object_offset) : 24 m_mutex (Mutex::eMutexTypeRecursive), 25 m_mod_time (file_spec.GetModificationTime()), 26 m_arch (arch), 27 m_uuid (), 28 m_file (file_spec), 29 m_platform_file(), 30 m_object_name (), 31 m_object_offset (object_offset), 32 m_objfile_ap (), 33 m_symfile_ap (), 34 m_ast (), 35 m_did_load_objfile (false), 36 m_did_load_symbol_vendor (false), 37 m_did_parse_uuid (false), 38 m_did_init_ast (false), 39 m_is_dynamic_loader_module (false) 40{ 41 if (object_name) 42 m_object_name = *object_name; 43 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 44 if (log) 45 log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')", 46 this, 47 m_arch.GetArchitectureName(), 48 m_file.GetDirectory().AsCString(""), 49 m_file.GetFilename().AsCString(""), 50 m_object_name.IsEmpty() ? "" : "(", 51 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 52 m_object_name.IsEmpty() ? "" : ")"); 53} 54 55Module::~Module() 56{ 57 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 58 if (log) 59 log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')", 60 this, 61 m_arch.GetArchitectureName(), 62 m_file.GetDirectory().AsCString(""), 63 m_file.GetFilename().AsCString(""), 64 m_object_name.IsEmpty() ? "" : "(", 65 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 66 m_object_name.IsEmpty() ? "" : ")"); 67 // Release any auto pointers before we start tearing down our member 68 // variables since the object file and symbol files might need to make 69 // function calls back into this module object. The ordering is important 70 // here because symbol files can require the module object file. So we tear 71 // down the symbol file first, then the object file. 72 m_symfile_ap.reset(); 73 m_objfile_ap.reset(); 74} 75 76 77ModuleSP 78Module::GetSP () const 79{ 80 return ModuleList::GetModuleSP (this); 81} 82 83const lldb_private::UUID& 84Module::GetUUID() 85{ 86 Mutex::Locker locker (m_mutex); 87 if (m_did_parse_uuid == false) 88 { 89 ObjectFile * obj_file = GetObjectFile (); 90 91 if (obj_file != NULL) 92 { 93 obj_file->GetUUID(&m_uuid); 94 m_did_parse_uuid = true; 95 } 96 } 97 return m_uuid; 98} 99 100ClangASTContext & 101Module::GetClangASTContext () 102{ 103 Mutex::Locker locker (m_mutex); 104 if (m_did_init_ast == false) 105 { 106 ObjectFile * objfile = GetObjectFile(); 107 ArchSpec object_arch; 108 if (objfile && objfile->GetArchitecture(object_arch)) 109 { 110 m_did_init_ast = true; 111 m_ast.SetArchitecture (object_arch); 112 } 113 } 114 return m_ast; 115} 116 117void 118Module::ParseAllDebugSymbols() 119{ 120 Mutex::Locker locker (m_mutex); 121 uint32_t num_comp_units = GetNumCompileUnits(); 122 if (num_comp_units == 0) 123 return; 124 125 TargetSP null_target; 126 SymbolContext sc(null_target, GetSP()); 127 uint32_t cu_idx; 128 SymbolVendor *symbols = GetSymbolVendor (); 129 130 for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++) 131 { 132 sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get(); 133 if (sc.comp_unit) 134 { 135 sc.function = NULL; 136 symbols->ParseVariablesForContext(sc); 137 138 symbols->ParseCompileUnitFunctions(sc); 139 140 uint32_t func_idx; 141 for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx) 142 { 143 symbols->ParseFunctionBlocks(sc); 144 145 // Parse the variables for this function and all its blocks 146 symbols->ParseVariablesForContext(sc); 147 } 148 149 150 // Parse all types for this compile unit 151 sc.function = NULL; 152 symbols->ParseTypes(sc); 153 } 154 } 155} 156 157void 158Module::CalculateSymbolContext(SymbolContext* sc) 159{ 160 sc->module_sp = GetSP(); 161} 162 163void 164Module::DumpSymbolContext(Stream *s) 165{ 166 s->Printf(", Module{0x%8.8x}", this); 167} 168 169uint32_t 170Module::GetNumCompileUnits() 171{ 172 Mutex::Locker locker (m_mutex); 173 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this); 174 SymbolVendor *symbols = GetSymbolVendor (); 175 if (symbols) 176 return symbols->GetNumCompileUnits(); 177 return 0; 178} 179 180CompUnitSP 181Module::GetCompileUnitAtIndex (uint32_t index) 182{ 183 Mutex::Locker locker (m_mutex); 184 uint32_t num_comp_units = GetNumCompileUnits (); 185 CompUnitSP cu_sp; 186 187 if (index < num_comp_units) 188 { 189 SymbolVendor *symbols = GetSymbolVendor (); 190 if (symbols) 191 cu_sp = symbols->GetCompileUnitAtIndex(index); 192 } 193 return cu_sp; 194} 195 196bool 197Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) 198{ 199 Mutex::Locker locker (m_mutex); 200 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr); 201 ObjectFile* ofile = GetObjectFile(); 202 if (ofile) 203 return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList()); 204 return false; 205} 206 207uint32_t 208Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 209{ 210 Mutex::Locker locker (m_mutex); 211 uint32_t resolved_flags = 0; 212 213 // Clear the result symbol context in case we don't find anything 214 sc.Clear(); 215 216 // Get the section from the section/offset address. 217 const Section *section = so_addr.GetSection(); 218 219 // Make sure the section matches this module before we try and match anything 220 if (section && section->GetModule() == this) 221 { 222 // If the section offset based address resolved itself, then this 223 // is the right module. 224 sc.module_sp = GetSP(); 225 resolved_flags |= eSymbolContextModule; 226 227 // Resolve the compile unit, function, block, line table or line 228 // entry if requested. 229 if (resolve_scope & eSymbolContextCompUnit || 230 resolve_scope & eSymbolContextFunction || 231 resolve_scope & eSymbolContextBlock || 232 resolve_scope & eSymbolContextLineEntry ) 233 { 234 SymbolVendor *symbols = GetSymbolVendor (); 235 if (symbols) 236 resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc); 237 } 238 239 // Resolve the symbol if requested, but don't re-look it up if we've already found it. 240 if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol)) 241 { 242 ObjectFile* ofile = GetObjectFile(); 243 if (ofile) 244 { 245 Symtab *symtab = ofile->GetSymtab(); 246 if (symtab) 247 { 248 if (so_addr.IsSectionOffset()) 249 { 250 sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); 251 if (sc.symbol) 252 resolved_flags |= eSymbolContextSymbol; 253 } 254 } 255 } 256 } 257 } 258 return resolved_flags; 259} 260 261uint32_t 262Module::ResolveSymbolContextForFilePath 263( 264 const char *file_path, 265 uint32_t line, 266 bool check_inlines, 267 uint32_t resolve_scope, 268 SymbolContextList& sc_list 269) 270{ 271 FileSpec file_spec(file_path, false); 272 return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list); 273} 274 275uint32_t 276Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 277{ 278 Mutex::Locker locker (m_mutex); 279 Timer scoped_timer(__PRETTY_FUNCTION__, 280 "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)", 281 file_spec.GetDirectory().AsCString(""), 282 file_spec.GetDirectory() ? "/" : "", 283 file_spec.GetFilename().AsCString(""), 284 line, 285 check_inlines ? "yes" : "no", 286 resolve_scope); 287 288 const uint32_t initial_count = sc_list.GetSize(); 289 290 SymbolVendor *symbols = GetSymbolVendor (); 291 if (symbols) 292 symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list); 293 294 return sc_list.GetSize() - initial_count; 295} 296 297 298uint32_t 299Module::FindGlobalVariables(const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) 300{ 301 SymbolVendor *symbols = GetSymbolVendor (); 302 if (symbols) 303 return symbols->FindGlobalVariables(name, append, max_matches, variables); 304 return 0; 305} 306uint32_t 307Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 308{ 309 SymbolVendor *symbols = GetSymbolVendor (); 310 if (symbols) 311 return symbols->FindGlobalVariables(regex, append, max_matches, variables); 312 return 0; 313} 314 315uint32_t 316Module::FindCompileUnits (const FileSpec &path, 317 bool append, 318 SymbolContextList &sc_list) 319{ 320 if (!append) 321 sc_list.Clear(); 322 323 const uint32_t start_size = sc_list.GetSize(); 324 const uint32_t num_compile_units = GetNumCompileUnits(); 325 SymbolContext sc; 326 sc.module_sp = GetSP(); 327 const bool compare_directory = path.GetDirectory(); 328 for (uint32_t i=0; i<num_compile_units; ++i) 329 { 330 sc.comp_unit = GetCompileUnitAtIndex(i).get(); 331 if (FileSpec::Equal (*sc.comp_unit, path, compare_directory)) 332 sc_list.Append(sc); 333 } 334 return sc_list.GetSize() - start_size; 335} 336 337uint32_t 338Module::FindFunctions (const ConstString &name, 339 uint32_t name_type_mask, 340 bool include_symbols, 341 bool append, 342 SymbolContextList& sc_list) 343{ 344 if (!append) 345 sc_list.Clear(); 346 347 const uint32_t start_size = sc_list.GetSize(); 348 349 // Find all the functions (not symbols, but debug information functions... 350 SymbolVendor *symbols = GetSymbolVendor (); 351 if (symbols) 352 symbols->FindFunctions(name, name_type_mask, append, sc_list); 353 354 // Now check our symbol table for symbols that are code symbols if requested 355 if (include_symbols) 356 { 357 ObjectFile *objfile = GetObjectFile(); 358 if (objfile) 359 { 360 Symtab *symtab = objfile->GetSymtab(); 361 if (symtab) 362 { 363 std::vector<uint32_t> symbol_indexes; 364 symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 365 const uint32_t num_matches = symbol_indexes.size(); 366 if (num_matches) 367 { 368 const bool merge_symbol_into_function = true; 369 SymbolContext sc(this); 370 for (uint32_t i=0; i<num_matches; i++) 371 { 372 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); 373 sc_list.AppendIfUnique (sc, merge_symbol_into_function); 374 } 375 } 376 } 377 } 378 } 379 return sc_list.GetSize() - start_size; 380} 381 382uint32_t 383Module::FindFunctions (const RegularExpression& regex, 384 bool include_symbols, 385 bool append, 386 SymbolContextList& sc_list) 387{ 388 if (!append) 389 sc_list.Clear(); 390 391 const uint32_t start_size = sc_list.GetSize(); 392 393 SymbolVendor *symbols = GetSymbolVendor (); 394 if (symbols) 395 symbols->FindFunctions(regex, append, sc_list); 396 // Now check our symbol table for symbols that are code symbols if requested 397 if (include_symbols) 398 { 399 ObjectFile *objfile = GetObjectFile(); 400 if (objfile) 401 { 402 Symtab *symtab = objfile->GetSymtab(); 403 if (symtab) 404 { 405 std::vector<uint32_t> symbol_indexes; 406 symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 407 const uint32_t num_matches = symbol_indexes.size(); 408 if (num_matches) 409 { 410 const bool merge_symbol_into_function = true; 411 SymbolContext sc(this); 412 for (uint32_t i=0; i<num_matches; i++) 413 { 414 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); 415 sc_list.AppendIfUnique (sc, merge_symbol_into_function); 416 } 417 } 418 } 419 } 420 } 421 return sc_list.GetSize() - start_size; 422} 423 424uint32_t 425Module::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) 426{ 427 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 428 if (sc.module_sp.get() == NULL || sc.module_sp.get() == this) 429 { 430 SymbolVendor *symbols = GetSymbolVendor (); 431 if (symbols) 432 return symbols->FindTypes(sc, name, append, max_matches, types); 433 } 434 return 0; 435} 436 437//uint32_t 438//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types) 439//{ 440// Timer scoped_timer(__PRETTY_FUNCTION__); 441// SymbolVendor *symbols = GetSymbolVendor (); 442// if (symbols) 443// return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types); 444// return 0; 445// 446//} 447 448SymbolVendor* 449Module::GetSymbolVendor (bool can_create) 450{ 451 Mutex::Locker locker (m_mutex); 452 if (m_did_load_symbol_vendor == false && can_create) 453 { 454 ObjectFile *obj_file = GetObjectFile (); 455 if (obj_file != NULL) 456 { 457 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 458 m_symfile_ap.reset(SymbolVendor::FindPlugin(this)); 459 m_did_load_symbol_vendor = true; 460 } 461 } 462 return m_symfile_ap.get(); 463} 464 465void 466Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name) 467{ 468 // Container objects whose paths do not specify a file directly can call 469 // this function to correct the file and object names. 470 m_file = file; 471 m_mod_time = file.GetModificationTime(); 472 m_object_name = object_name; 473} 474 475const ArchSpec& 476Module::GetArchitecture () const 477{ 478 return m_arch; 479} 480 481void 482Module::GetDescription (Stream *s) 483{ 484 Mutex::Locker locker (m_mutex); 485 486 if (m_arch.IsValid()) 487 s->Printf("(%s) ", m_arch.GetArchitectureName()); 488 489 char path[PATH_MAX]; 490 if (m_file.GetPath(path, sizeof(path))) 491 s->PutCString(path); 492 493 const char *object_name = m_object_name.GetCString(); 494 if (object_name) 495 s->Printf("(%s)", object_name); 496} 497 498void 499Module::Dump(Stream *s) 500{ 501 Mutex::Locker locker (m_mutex); 502 //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 503 s->Indent(); 504 s->Printf("Module %s/%s%s%s%s\n", 505 m_file.GetDirectory().AsCString(), 506 m_file.GetFilename().AsCString(), 507 m_object_name ? "(" : "", 508 m_object_name ? m_object_name.GetCString() : "", 509 m_object_name ? ")" : ""); 510 511 s->IndentMore(); 512 ObjectFile *objfile = GetObjectFile (); 513 514 if (objfile) 515 objfile->Dump(s); 516 517 SymbolVendor *symbols = GetSymbolVendor (); 518 519 if (symbols) 520 symbols->Dump(s); 521 522 s->IndentLess(); 523} 524 525 526TypeList* 527Module::GetTypeList () 528{ 529 SymbolVendor *symbols = GetSymbolVendor (); 530 if (symbols) 531 return &symbols->GetTypeList(); 532 return NULL; 533} 534 535const ConstString & 536Module::GetObjectName() const 537{ 538 return m_object_name; 539} 540 541ObjectFile * 542Module::GetObjectFile() 543{ 544 Mutex::Locker locker (m_mutex); 545 if (m_did_load_objfile == false) 546 { 547 m_did_load_objfile = true; 548 Timer scoped_timer(__PRETTY_FUNCTION__, 549 "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString("")); 550 m_objfile_ap.reset(ObjectFile::FindPlugin(this, &m_file, m_object_offset, m_file.GetByteSize())); 551 } 552 return m_objfile_ap.get(); 553} 554 555 556const Symbol * 557Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type) 558{ 559 Timer scoped_timer(__PRETTY_FUNCTION__, 560 "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)", 561 name.AsCString(), 562 symbol_type); 563 ObjectFile *objfile = GetObjectFile(); 564 if (objfile) 565 { 566 Symtab *symtab = objfile->GetSymtab(); 567 if (symtab) 568 return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny); 569 } 570 return NULL; 571} 572void 573Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list) 574{ 575 // No need to protect this call using m_mutex all other method calls are 576 // already thread safe. 577 578 size_t num_indices = symbol_indexes.size(); 579 if (num_indices > 0) 580 { 581 SymbolContext sc; 582 CalculateSymbolContext (&sc); 583 for (size_t i = 0; i < num_indices; i++) 584 { 585 sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]); 586 if (sc.symbol) 587 sc_list.Append (sc); 588 } 589 } 590} 591 592size_t 593Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list) 594{ 595 // No need to protect this call using m_mutex all other method calls are 596 // already thread safe. 597 598 599 Timer scoped_timer(__PRETTY_FUNCTION__, 600 "Module::FindSymbolsWithNameAndType (name = %s, type = %i)", 601 name.AsCString(), 602 symbol_type); 603 const size_t initial_size = sc_list.GetSize(); 604 ObjectFile *objfile = GetObjectFile (); 605 if (objfile) 606 { 607 Symtab *symtab = objfile->GetSymtab(); 608 if (symtab) 609 { 610 std::vector<uint32_t> symbol_indexes; 611 symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes); 612 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); 613 } 614 } 615 return sc_list.GetSize() - initial_size; 616} 617 618size_t 619Module::FindSymbolsMatchingRegExAndType (const RegularExpression ®ex, SymbolType symbol_type, SymbolContextList &sc_list) 620{ 621 // No need to protect this call using m_mutex all other method calls are 622 // already thread safe. 623 624 Timer scoped_timer(__PRETTY_FUNCTION__, 625 "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)", 626 regex.GetText(), 627 symbol_type); 628 const size_t initial_size = sc_list.GetSize(); 629 ObjectFile *objfile = GetObjectFile (); 630 if (objfile) 631 { 632 Symtab *symtab = objfile->GetSymtab(); 633 if (symtab) 634 { 635 std::vector<uint32_t> symbol_indexes; 636 symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 637 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); 638 } 639 } 640 return sc_list.GetSize() - initial_size; 641} 642 643const TimeValue & 644Module::GetModificationTime () const 645{ 646 return m_mod_time; 647} 648 649bool 650Module::IsExecutable () 651{ 652 if (GetObjectFile() == NULL) 653 return false; 654 else 655 return GetObjectFile()->IsExecutable(); 656} 657 658bool 659Module::SetArchitecture (const ArchSpec &new_arch) 660{ 661 if (!m_arch.IsValid()) 662 { 663 m_arch = new_arch; 664 return true; 665 } 666 return m_arch == new_arch; 667} 668 669