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