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