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