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