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