Module.cpp revision 0fcec13c6639ab49216fa9447b25888b7bc9ff59
14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//===-- Module.cpp ----------------------------------------------*- C++ -*-===// 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// The LLVM Compiler Infrastructure 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// This file is distributed under the University of Illinois Open Source 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// License. See LICENSE.TXT for details. 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//===----------------------------------------------------------------------===// 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "lldb/Core/Module.h" 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "lldb/Core/Log.h" 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "lldb/Core/ModuleList.h" 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "lldb/Core/RegularExpression.h" 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "lldb/Core/Timer.h" 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "lldb/lldb-private-log.h" 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "lldb/Symbol/ObjectFile.h" 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "lldb/Symbol/SymbolContext.h" 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "lldb/Symbol/SymbolVendor.h" 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectusing namespace lldb; 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectusing namespace lldb_private; 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Shared pointers to modules track module lifetimes in 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// targets and in the global module, but this collection 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// will track all module objects that are still alive 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef std::vector<Module *> ModuleCollection; 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ModuleCollection & 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectGetModuleCollection() 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static ModuleCollection g_module_collection; 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return g_module_collection; 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectMutex & 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectModule::GetAllocationModuleCollectionMutex() 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static Mutex g_module_collection_mutex(Mutex::eMutexTypeRecursive); 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return g_module_collection_mutex; 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectsize_t 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectModule::GetNumberAllocatedModules () 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return GetModuleCollection().size(); 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectModule * 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectModule::GetAllocatedModuleAtIndex (size_t idx) 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ModuleCollection &modules = GetModuleCollection(); 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (idx < modules.size()) 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return modules[idx]; 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return NULL; 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectModule::Module(const FileSpec& file_spec, const ArchSpec& arch, const ConstString *object_name, off_t object_offset) : 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_mutex (Mutex::eMutexTypeRecursive), 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_mod_time (file_spec.GetModificationTime()), 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_arch (arch), 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_uuid (), 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_file (file_spec), 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_platform_file(), 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_object_name (), 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_object_offset (object_offset), 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_objfile_sp (), 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_symfile_ap (), 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_ast (), 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_did_load_objfile (false), 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_did_load_symbol_vendor (false), 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_did_parse_uuid (false), 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_did_init_ast (false), 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_is_dynamic_loader_module (false) 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Scope for locker below... 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project GetModuleCollection().push_back(this); 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (object_name) 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_object_name = *object_name; 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (log) 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')", 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project this, 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_arch.GetArchitectureName(), 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_file.GetDirectory().AsCString(""), 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_file.GetFilename().AsCString(""), 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_object_name.IsEmpty() ? "" : "(", 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_object_name.IsEmpty() ? "" : ")"); 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectModule::~Module() 1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Scope for locker below... 1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Mutex::Locker locker (GetAllocationModuleCollectionMutex()); 1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ModuleCollection &modules = GetModuleCollection(); 1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ModuleCollection::iterator end = modules.end(); 1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ModuleCollection::iterator pos = std::find(modules.begin(), end, this); 1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (pos != end) 1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project modules.erase(pos); 1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (log) 1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')", 1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project this, 1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_arch.GetArchitectureName(), 1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_file.GetDirectory().AsCString(""), 1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_file.GetFilename().AsCString(""), 1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_object_name.IsEmpty() ? "" : "(", 1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_object_name.IsEmpty() ? "" : ")"); 1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Release any auto pointers before we start tearing down our member 1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // variables since the object file and symbol files might need to make 1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // function calls back into this module object. The ordering is important 1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // here because symbol files can require the module object file. So we tear 1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // down the symbol file first, then the object file. 1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_symfile_ap.reset(); 1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_objfile_sp.reset(); 1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectconst lldb_private::UUID& 1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectModule::GetUUID() 1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Mutex::Locker locker (m_mutex); 1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (m_did_parse_uuid == false) 1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ObjectFile * obj_file = GetObjectFile (); 1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (obj_file != NULL) 1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project obj_file->GetUUID(&m_uuid); 1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_did_parse_uuid = true; 1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return m_uuid; 1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectClangASTContext & 1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectModule::GetClangASTContext () 1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Mutex::Locker locker (m_mutex); 1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (m_did_init_ast == false) 1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ObjectFile * objfile = GetObjectFile(); 1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ArchSpec object_arch; 1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (objfile && objfile->GetArchitecture(object_arch)) 1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_did_init_ast = true; 1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project m_ast.SetArchitecture (object_arch); 1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return m_ast; 1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 165void 166Module::ParseAllDebugSymbols() 167{ 168 Mutex::Locker locker (m_mutex); 169 uint32_t num_comp_units = GetNumCompileUnits(); 170 if (num_comp_units == 0) 171 return; 172 173 SymbolContext sc; 174 sc.module_sp = this; 175 uint32_t cu_idx; 176 SymbolVendor *symbols = GetSymbolVendor (); 177 178 for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++) 179 { 180 sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get(); 181 if (sc.comp_unit) 182 { 183 sc.function = NULL; 184 symbols->ParseVariablesForContext(sc); 185 186 symbols->ParseCompileUnitFunctions(sc); 187 188 uint32_t func_idx; 189 for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx) 190 { 191 symbols->ParseFunctionBlocks(sc); 192 193 // Parse the variables for this function and all its blocks 194 symbols->ParseVariablesForContext(sc); 195 } 196 197 198 // Parse all types for this compile unit 199 sc.function = NULL; 200 symbols->ParseTypes(sc); 201 } 202 } 203} 204 205void 206Module::CalculateSymbolContext(SymbolContext* sc) 207{ 208 sc->module_sp = this; 209} 210 211Module * 212Module::CalculateSymbolContextModule () 213{ 214 return this; 215} 216 217void 218Module::DumpSymbolContext(Stream *s) 219{ 220 s->Printf(", Module{%p}", this); 221} 222 223uint32_t 224Module::GetNumCompileUnits() 225{ 226 Mutex::Locker locker (m_mutex); 227 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this); 228 SymbolVendor *symbols = GetSymbolVendor (); 229 if (symbols) 230 return symbols->GetNumCompileUnits(); 231 return 0; 232} 233 234CompUnitSP 235Module::GetCompileUnitAtIndex (uint32_t index) 236{ 237 Mutex::Locker locker (m_mutex); 238 uint32_t num_comp_units = GetNumCompileUnits (); 239 CompUnitSP cu_sp; 240 241 if (index < num_comp_units) 242 { 243 SymbolVendor *symbols = GetSymbolVendor (); 244 if (symbols) 245 cu_sp = symbols->GetCompileUnitAtIndex(index); 246 } 247 return cu_sp; 248} 249 250bool 251Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) 252{ 253 Mutex::Locker locker (m_mutex); 254 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr); 255 ObjectFile* ofile = GetObjectFile(); 256 if (ofile) 257 return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList()); 258 return false; 259} 260 261uint32_t 262Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 263{ 264 Mutex::Locker locker (m_mutex); 265 uint32_t resolved_flags = 0; 266 267 // Clear the result symbol context in case we don't find anything 268 sc.Clear(); 269 270 // Get the section from the section/offset address. 271 const Section *section = so_addr.GetSection(); 272 273 // Make sure the section matches this module before we try and match anything 274 if (section && section->GetModule() == this) 275 { 276 // If the section offset based address resolved itself, then this 277 // is the right module. 278 sc.module_sp = this; 279 resolved_flags |= eSymbolContextModule; 280 281 // Resolve the compile unit, function, block, line table or line 282 // entry if requested. 283 if (resolve_scope & eSymbolContextCompUnit || 284 resolve_scope & eSymbolContextFunction || 285 resolve_scope & eSymbolContextBlock || 286 resolve_scope & eSymbolContextLineEntry ) 287 { 288 SymbolVendor *symbols = GetSymbolVendor (); 289 if (symbols) 290 resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc); 291 } 292 293 // Resolve the symbol if requested, but don't re-look it up if we've already found it. 294 if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol)) 295 { 296 ObjectFile* ofile = GetObjectFile(); 297 if (ofile) 298 { 299 Symtab *symtab = ofile->GetSymtab(); 300 if (symtab) 301 { 302 if (so_addr.IsSectionOffset()) 303 { 304 sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); 305 if (sc.symbol) 306 resolved_flags |= eSymbolContextSymbol; 307 } 308 } 309 } 310 } 311 } 312 return resolved_flags; 313} 314 315uint32_t 316Module::ResolveSymbolContextForFilePath 317( 318 const char *file_path, 319 uint32_t line, 320 bool check_inlines, 321 uint32_t resolve_scope, 322 SymbolContextList& sc_list 323) 324{ 325 FileSpec file_spec(file_path, false); 326 return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list); 327} 328 329uint32_t 330Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 331{ 332 Mutex::Locker locker (m_mutex); 333 Timer scoped_timer(__PRETTY_FUNCTION__, 334 "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)", 335 file_spec.GetDirectory().AsCString(""), 336 file_spec.GetDirectory() ? "/" : "", 337 file_spec.GetFilename().AsCString(""), 338 line, 339 check_inlines ? "yes" : "no", 340 resolve_scope); 341 342 const uint32_t initial_count = sc_list.GetSize(); 343 344 SymbolVendor *symbols = GetSymbolVendor (); 345 if (symbols) 346 symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list); 347 348 return sc_list.GetSize() - initial_count; 349} 350 351 352uint32_t 353Module::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables) 354{ 355 SymbolVendor *symbols = GetSymbolVendor (); 356 if (symbols) 357 return symbols->FindGlobalVariables(name, namespace_decl, append, max_matches, variables); 358 return 0; 359} 360uint32_t 361Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 362{ 363 SymbolVendor *symbols = GetSymbolVendor (); 364 if (symbols) 365 return symbols->FindGlobalVariables(regex, append, max_matches, variables); 366 return 0; 367} 368 369uint32_t 370Module::FindCompileUnits (const FileSpec &path, 371 bool append, 372 SymbolContextList &sc_list) 373{ 374 if (!append) 375 sc_list.Clear(); 376 377 const uint32_t start_size = sc_list.GetSize(); 378 const uint32_t num_compile_units = GetNumCompileUnits(); 379 SymbolContext sc; 380 sc.module_sp = this; 381 const bool compare_directory = path.GetDirectory(); 382 for (uint32_t i=0; i<num_compile_units; ++i) 383 { 384 sc.comp_unit = GetCompileUnitAtIndex(i).get(); 385 if (FileSpec::Equal (*sc.comp_unit, path, compare_directory)) 386 sc_list.Append(sc); 387 } 388 return sc_list.GetSize() - start_size; 389} 390 391uint32_t 392Module::FindFunctions (const ConstString &name, 393 const ClangNamespaceDecl *namespace_decl, 394 uint32_t name_type_mask, 395 bool include_symbols, 396 bool append, 397 SymbolContextList& sc_list) 398{ 399 if (!append) 400 sc_list.Clear(); 401 402 const uint32_t start_size = sc_list.GetSize(); 403 404 // Find all the functions (not symbols, but debug information functions... 405 SymbolVendor *symbols = GetSymbolVendor (); 406 if (symbols) 407 symbols->FindFunctions(name, namespace_decl, name_type_mask, append, sc_list); 408 409 // Now check our symbol table for symbols that are code symbols if requested 410 if (include_symbols) 411 { 412 ObjectFile *objfile = GetObjectFile(); 413 if (objfile) 414 { 415 Symtab *symtab = objfile->GetSymtab(); 416 if (symtab) 417 { 418 std::vector<uint32_t> symbol_indexes; 419 symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 420 const uint32_t num_matches = symbol_indexes.size(); 421 if (num_matches) 422 { 423 const bool merge_symbol_into_function = true; 424 SymbolContext sc(this); 425 for (uint32_t i=0; i<num_matches; i++) 426 { 427 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); 428 sc_list.AppendIfUnique (sc, merge_symbol_into_function); 429 } 430 } 431 } 432 } 433 } 434 return sc_list.GetSize() - start_size; 435} 436 437uint32_t 438Module::FindFunctions (const RegularExpression& regex, 439 bool include_symbols, 440 bool append, 441 SymbolContextList& sc_list) 442{ 443 if (!append) 444 sc_list.Clear(); 445 446 const uint32_t start_size = sc_list.GetSize(); 447 448 SymbolVendor *symbols = GetSymbolVendor (); 449 if (symbols) 450 symbols->FindFunctions(regex, append, sc_list); 451 // Now check our symbol table for symbols that are code symbols if requested 452 if (include_symbols) 453 { 454 ObjectFile *objfile = GetObjectFile(); 455 if (objfile) 456 { 457 Symtab *symtab = objfile->GetSymtab(); 458 if (symtab) 459 { 460 std::vector<uint32_t> symbol_indexes; 461 symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 462 const uint32_t num_matches = symbol_indexes.size(); 463 if (num_matches) 464 { 465 const bool merge_symbol_into_function = true; 466 SymbolContext sc(this); 467 for (uint32_t i=0; i<num_matches; i++) 468 { 469 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); 470 sc_list.AppendIfUnique (sc, merge_symbol_into_function); 471 } 472 } 473 } 474 } 475 } 476 return sc_list.GetSize() - start_size; 477} 478 479uint32_t 480Module::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types) 481{ 482 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 483 if (sc.module_sp.get() == NULL || sc.module_sp.get() == this) 484 { 485 SymbolVendor *symbols = GetSymbolVendor (); 486 if (symbols) 487 return symbols->FindTypes(sc, name, namespace_decl, append, max_matches, types); 488 } 489 return 0; 490} 491 492// depending on implementation details, type lookup might fail because of 493// embedded spurious namespace:: prefixes. this call strips them, paying 494// attention to the fact that a type might have namespace'd type names as 495// arguments to templates, and those must not be stripped off 496static const char* 497StripTypeName(const char* name_cstr) 498{ 499 const char* skip_namespace = strstr(name_cstr, "::"); 500 const char* template_arg_char = strchr(name_cstr, '<'); 501 while (skip_namespace != NULL) 502 { 503 if (template_arg_char != NULL && 504 skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go 505 break; 506 name_cstr = skip_namespace+2; 507 skip_namespace = strstr(name_cstr, "::"); 508 } 509 return name_cstr; 510} 511 512uint32_t 513Module::FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types) 514{ 515 uint32_t retval = FindTypes_Impl(sc, name, namespace_decl, append, max_matches, types); 516 517 if (retval == 0) 518 { 519 const char *stripped = StripTypeName(name.GetCString()); 520 return FindTypes_Impl(sc, ConstString(stripped), namespace_decl, append, max_matches, types); 521 } 522 else 523 return retval; 524 525} 526 527//uint32_t 528//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types) 529//{ 530// Timer scoped_timer(__PRETTY_FUNCTION__); 531// SymbolVendor *symbols = GetSymbolVendor (); 532// if (symbols) 533// return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types); 534// return 0; 535// 536//} 537 538SymbolVendor* 539Module::GetSymbolVendor (bool can_create) 540{ 541 Mutex::Locker locker (m_mutex); 542 if (m_did_load_symbol_vendor == false && can_create) 543 { 544 ObjectFile *obj_file = GetObjectFile (); 545 if (obj_file != NULL) 546 { 547 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 548 m_symfile_ap.reset(SymbolVendor::FindPlugin(this)); 549 m_did_load_symbol_vendor = true; 550 } 551 } 552 return m_symfile_ap.get(); 553} 554 555void 556Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name) 557{ 558 // Container objects whose paths do not specify a file directly can call 559 // this function to correct the file and object names. 560 m_file = file; 561 m_mod_time = file.GetModificationTime(); 562 m_object_name = object_name; 563} 564 565const ArchSpec& 566Module::GetArchitecture () const 567{ 568 return m_arch; 569} 570 571void 572Module::GetDescription (Stream *s) 573{ 574 Mutex::Locker locker (m_mutex); 575 576 if (m_arch.IsValid()) 577 s->Printf("(%s) ", m_arch.GetArchitectureName()); 578 579 char path[PATH_MAX]; 580 if (m_file.GetPath(path, sizeof(path))) 581 s->PutCString(path); 582 583 const char *object_name = m_object_name.GetCString(); 584 if (object_name) 585 s->Printf("(%s)", object_name); 586} 587 588void 589Module::Dump(Stream *s) 590{ 591 Mutex::Locker locker (m_mutex); 592 //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 593 s->Indent(); 594 s->Printf("Module %s/%s%s%s%s\n", 595 m_file.GetDirectory().AsCString(), 596 m_file.GetFilename().AsCString(), 597 m_object_name ? "(" : "", 598 m_object_name ? m_object_name.GetCString() : "", 599 m_object_name ? ")" : ""); 600 601 s->IndentMore(); 602 ObjectFile *objfile = GetObjectFile (); 603 604 if (objfile) 605 objfile->Dump(s); 606 607 SymbolVendor *symbols = GetSymbolVendor (); 608 609 if (symbols) 610 symbols->Dump(s); 611 612 s->IndentLess(); 613} 614 615 616TypeList* 617Module::GetTypeList () 618{ 619 SymbolVendor *symbols = GetSymbolVendor (); 620 if (symbols) 621 return &symbols->GetTypeList(); 622 return NULL; 623} 624 625const ConstString & 626Module::GetObjectName() const 627{ 628 return m_object_name; 629} 630 631ObjectFile * 632Module::GetObjectFile() 633{ 634 Mutex::Locker locker (m_mutex); 635 if (m_did_load_objfile == false) 636 { 637 m_did_load_objfile = true; 638 Timer scoped_timer(__PRETTY_FUNCTION__, 639 "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString("")); 640 m_objfile_sp = ObjectFile::FindPlugin(this, &m_file, m_object_offset, m_file.GetByteSize()); 641 if (m_objfile_sp) 642 { 643 // Once we get the object file, update our module with the object file's 644 // architecture since it might differ in vendor/os if some parts were 645 // unknown. 646 m_objfile_sp->GetArchitecture (m_arch); 647 } 648 } 649 return m_objfile_sp.get(); 650} 651 652 653const Symbol * 654Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type) 655{ 656 Timer scoped_timer(__PRETTY_FUNCTION__, 657 "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)", 658 name.AsCString(), 659 symbol_type); 660 ObjectFile *objfile = GetObjectFile(); 661 if (objfile) 662 { 663 Symtab *symtab = objfile->GetSymtab(); 664 if (symtab) 665 return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny); 666 } 667 return NULL; 668} 669void 670Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list) 671{ 672 // No need to protect this call using m_mutex all other method calls are 673 // already thread safe. 674 675 size_t num_indices = symbol_indexes.size(); 676 if (num_indices > 0) 677 { 678 SymbolContext sc; 679 CalculateSymbolContext (&sc); 680 for (size_t i = 0; i < num_indices; i++) 681 { 682 sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]); 683 if (sc.symbol) 684 sc_list.Append (sc); 685 } 686 } 687} 688 689size_t 690Module::FindSymbolsWithNameAndType (const ConstString &name, const ClangNamespaceDecl *namespace_decl, SymbolType symbol_type, SymbolContextList &sc_list) 691{ 692 // No need to protect this call using m_mutex all other method calls are 693 // already thread safe. 694 695 696 Timer scoped_timer(__PRETTY_FUNCTION__, 697 "Module::FindSymbolsWithNameAndType (name = %s, type = %i)", 698 name.AsCString(), 699 symbol_type); 700 const size_t initial_size = sc_list.GetSize(); 701 ObjectFile *objfile = GetObjectFile (); 702 if (objfile) 703 { 704 Symtab *symtab = objfile->GetSymtab(); 705 if (symtab) 706 { 707 std::vector<uint32_t> symbol_indexes; 708 symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes); 709 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); 710 } 711 } 712 return sc_list.GetSize() - initial_size; 713} 714 715size_t 716Module::FindSymbolsMatchingRegExAndType (const RegularExpression ®ex, SymbolType symbol_type, SymbolContextList &sc_list) 717{ 718 // No need to protect this call using m_mutex all other method calls are 719 // already thread safe. 720 721 Timer scoped_timer(__PRETTY_FUNCTION__, 722 "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)", 723 regex.GetText(), 724 symbol_type); 725 const size_t initial_size = sc_list.GetSize(); 726 ObjectFile *objfile = GetObjectFile (); 727 if (objfile) 728 { 729 Symtab *symtab = objfile->GetSymtab(); 730 if (symtab) 731 { 732 std::vector<uint32_t> symbol_indexes; 733 symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 734 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); 735 } 736 } 737 return sc_list.GetSize() - initial_size; 738} 739 740const TimeValue & 741Module::GetModificationTime () const 742{ 743 return m_mod_time; 744} 745 746bool 747Module::IsExecutable () 748{ 749 if (GetObjectFile() == NULL) 750 return false; 751 else 752 return GetObjectFile()->IsExecutable(); 753} 754 755bool 756Module::IsLoadedInTarget (Target *target) 757{ 758 ObjectFile *obj_file = GetObjectFile(); 759 if (obj_file) 760 { 761 SectionList *sections = obj_file->GetSectionList(); 762 if (sections != NULL) 763 { 764 size_t num_sections = sections->GetSize(); 765 for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) 766 { 767 SectionSP section_sp = sections->GetSectionAtIndex(sect_idx); 768 if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) 769 { 770 return true; 771 } 772 } 773 } 774 } 775 return false; 776} 777bool 778Module::SetArchitecture (const ArchSpec &new_arch) 779{ 780 if (!m_arch.IsValid()) 781 { 782 m_arch = new_arch; 783 return true; 784 } 785 return m_arch == new_arch; 786} 787 788