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