Module.cpp revision 24bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Module.cpp ----------------------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Module.h" 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h" 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/ModuleList.h" 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/RegularExpression.h" 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Timer.h" 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h" 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Symbol/ObjectFile.h" 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Symbol/SymbolContext.h" 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Symbol/SymbolVendor.h" 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::Module(const FileSpec& file_spec, const ArchSpec& arch, const ConstString *object_name, off_t object_offset) : 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_mutex (Mutex::eMutexTypeRecursive), 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_mod_time (file_spec.GetModificationTime()), 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_arch (arch), 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_uuid (), 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_file (file_spec), 2924bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton m_platform_file(), 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name (), 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_objfile_ap (), 32236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton m_symfile_ap (), 33b01000fd063629facd45044f137446fb748ee179Greg Clayton m_ast (), 34236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton m_did_load_objfile (false), 35236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton m_did_load_symbol_vendor (false), 36236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton m_did_parse_uuid (false), 37b01000fd063629facd45044f137446fb748ee179Greg Clayton m_did_init_ast (false), 38236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton m_is_dynamic_loader_module (false) 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (object_name) 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name = *object_name; 42e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')", 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, 46940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton m_arch.GetArchitectureName(), 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_file.GetDirectory().AsCString(""), 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_file.GetFilename().AsCString(""), 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name.IsEmpty() ? "" : "(", 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name.IsEmpty() ? "" : ")"); 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::~Module() 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 56e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')", 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, 60940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton m_arch.GetArchitectureName(), 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_file.GetDirectory().AsCString(""), 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_file.GetFilename().AsCString(""), 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name.IsEmpty() ? "" : "(", 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name.IsEmpty() ? "" : ")"); 66b01000fd063629facd45044f137446fb748ee179Greg Clayton // Release any auto pointers before we start tearing down our member 67b01000fd063629facd45044f137446fb748ee179Greg Clayton // variables since the object file and symbol files might need to make 68b01000fd063629facd45044f137446fb748ee179Greg Clayton // function calls back into this module object. The ordering is important 69b01000fd063629facd45044f137446fb748ee179Greg Clayton // here because symbol files can require the module object file. So we tear 70b01000fd063629facd45044f137446fb748ee179Greg Clayton // down the symbol file first, then the object file. 71b01000fd063629facd45044f137446fb748ee179Greg Clayton m_symfile_ap.reset(); 72b01000fd063629facd45044f137446fb748ee179Greg Clayton m_objfile_ap.reset(); 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModuleSP 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::GetSP () 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return ModuleList::GetModuleSP (this); 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 820467c78e9a75eff9ec33d3c1f39fa83e1c5d9241Greg Claytonconst lldb_private::UUID& 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::GetUUID() 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker (m_mutex); 86236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton if (m_did_parse_uuid == false) 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ObjectFile * obj_file = GetObjectFile (); 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (obj_file != NULL) 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner obj_file->GetUUID(&m_uuid); 93236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton m_did_parse_uuid = true; 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_uuid; 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 99b01000fd063629facd45044f137446fb748ee179Greg ClaytonClangASTContext & 100b01000fd063629facd45044f137446fb748ee179Greg ClaytonModule::GetClangASTContext () 101b01000fd063629facd45044f137446fb748ee179Greg Clayton{ 102b01000fd063629facd45044f137446fb748ee179Greg Clayton Mutex::Locker locker (m_mutex); 103b01000fd063629facd45044f137446fb748ee179Greg Clayton if (m_did_init_ast == false) 104b01000fd063629facd45044f137446fb748ee179Greg Clayton { 105b01000fd063629facd45044f137446fb748ee179Greg Clayton ObjectFile * objfile = GetObjectFile(); 106395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton ArchSpec object_arch; 107395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton if (objfile && objfile->GetArchitecture(object_arch)) 108b01000fd063629facd45044f137446fb748ee179Greg Clayton { 109b01000fd063629facd45044f137446fb748ee179Greg Clayton m_did_init_ast = true; 110395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton m_ast.SetArchitecture (object_arch); 111b01000fd063629facd45044f137446fb748ee179Greg Clayton } 112b01000fd063629facd45044f137446fb748ee179Greg Clayton } 113b01000fd063629facd45044f137446fb748ee179Greg Clayton return m_ast; 114b01000fd063629facd45044f137446fb748ee179Greg Clayton} 115b01000fd063629facd45044f137446fb748ee179Greg Clayton 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::ParseAllDebugSymbols() 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker (m_mutex); 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t num_comp_units = GetNumCompileUnits(); 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_comp_units == 0) 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner TargetSP null_target; 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolContext sc(null_target, GetSP()); 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t cu_idx; 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++) 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get(); 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (sc.comp_unit) 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sc.function = NULL; 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symbols->ParseVariablesForContext(sc); 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symbols->ParseCompileUnitFunctions(sc); 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t func_idx; 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx) 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symbols->ParseFunctionBlocks(sc); 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Parse the variables for this function and all its blocks 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symbols->ParseVariablesForContext(sc); 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Parse all types for this compile unit 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sc.function = NULL; 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symbols->ParseTypes(sc); 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::CalculateSymbolContext(SymbolContext* sc) 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sc->module_sp = GetSP(); 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::DumpSymbolContext(Stream *s) 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s->Printf(", Module{0x%8.8x}", this); 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t 16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::GetNumCompileUnits() 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker (m_mutex); 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this); 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symbols) 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return symbols->GetNumCompileUnits(); 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCompUnitSP 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::GetCompileUnitAtIndex (uint32_t index) 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker (m_mutex); 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t num_comp_units = GetNumCompileUnits (); 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CompUnitSP cu_sp; 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (index < num_comp_units) 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symbols) 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cu_sp = symbols->GetCompileUnitAtIndex(index); 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return cu_sp; 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//CompUnitSP 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//Module::FindCompUnit(lldb::user_id_t uid) 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//{ 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// CompUnitSP cu_sp; 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// SymbolVendor *symbols = GetSymbolVendor (); 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (symbols) 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// cu_sp = symbols->FindCompUnit(uid); 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// return cu_sp; 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//} 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker (m_mutex); 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr); 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ObjectFile* ofile = GetObjectFile(); 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (ofile) 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList()); 21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t 21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker (m_mutex); 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t resolved_flags = 0; 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Clear the result symbol context in case we don't find anything 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sc.Clear(); 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Get the section from the section/offset address. 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const Section *section = so_addr.GetSection(); 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Make sure the section matches this module before we try and match anything 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (section && section->GetModule() == this) 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If the section offset based address resolved itself, then this 23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // is the right module. 23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sc.module_sp = GetSP(); 23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner resolved_flags |= eSymbolContextModule; 23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Resolve the compile unit, function, block, line table or line 23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // entry if requested. 23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (resolve_scope & eSymbolContextCompUnit || 23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner resolve_scope & eSymbolContextFunction || 24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner resolve_scope & eSymbolContextBlock || 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner resolve_scope & eSymbolContextLineEntry ) 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symbols) 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc); 24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 248bddb78944a140c3ca1324d356aa83495331ff50dJim Ingham // Resolve the symbol if requested, but don't re-look it up if we've already found it. 249bddb78944a140c3ca1324d356aa83495331ff50dJim Ingham if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol)) 25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ObjectFile* ofile = GetObjectFile(); 25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (ofile) 25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Symtab *symtab = ofile->GetSymtab(); 25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symtab) 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (so_addr.IsSectionOffset()) 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (sc.symbol) 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner resolved_flags |= eSymbolContextSymbol; 26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return resolved_flags; 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t 271537a7a86687683fd403ce652d178fbc89e06ef9fGreg ClaytonModule::ResolveSymbolContextForFilePath 272537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton( 273537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton const char *file_path, 274537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton uint32_t line, 275537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton bool check_inlines, 276537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton uint32_t resolve_scope, 277537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton SymbolContextList& sc_list 278537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton) 27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 280537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton FileSpec file_spec(file_path, false); 28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list); 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker (m_mutex); 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer(__PRETTY_FUNCTION__, 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)", 29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner file_spec.GetDirectory().AsCString(""), 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner file_spec.GetDirectory() ? "/" : "", 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner file_spec.GetFilename().AsCString(""), 29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner line, 29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner check_inlines ? "yes" : "no", 29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner resolve_scope); 29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t initial_count = sc_list.GetSize(); 29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symbols) 30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list); 30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return sc_list.GetSize() - initial_count; 30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t 30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::FindGlobalVariables(const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) 30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symbols) 31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return symbols->FindGlobalVariables(name, append, max_matches, variables); 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symbols) 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return symbols->FindGlobalVariables(regex, append, max_matches, variables); 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t 32528d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg ClaytonModule::FindFunctions (const ConstString &name, 32628d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton uint32_t name_type_mask, 32728d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton bool include_symbols, 32828d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton bool append, 32928d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton SymbolContextList& sc_list) 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 33128d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton if (!append) 33228d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton sc_list.Clear(); 33328d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton 33428d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton const uint32_t start_size = sc_list.GetSize(); 33528d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton 33628d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton // Find all the functions (not symbols, but debug information functions... 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symbols) 33928d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton symbols->FindFunctions(name, name_type_mask, append, sc_list); 34028d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton 34128d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton // Now check our symbol table for symbols that are code symbols if requested 34228d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton if (include_symbols) 34328d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton { 34428d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton ObjectFile *objfile = GetObjectFile(); 34528d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton if (objfile) 34628d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton { 34728d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton Symtab *symtab = objfile->GetSymtab(); 34828d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton if (symtab) 34928d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton { 35028d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton std::vector<uint32_t> symbol_indexes; 35128d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 35228d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton const uint32_t num_matches = symbol_indexes.size(); 35328d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton if (num_matches) 35428d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton { 355889fbd0581c24523642e0a04d659cc8f3dcdb4edGreg Clayton const bool merge_symbol_into_function = true; 35628d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton SymbolContext sc(this); 35728d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton for (uint32_t i=0; i<num_matches; i++) 35828d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton { 35928d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); 360889fbd0581c24523642e0a04d659cc8f3dcdb4edGreg Clayton sc_list.AppendIfUnique (sc, merge_symbol_into_function); 36128d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton } 36228d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton } 36328d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton } 36428d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton } 36528d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton } 36628d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton return sc_list.GetSize() - start_size; 36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t 37028d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg ClaytonModule::FindFunctions (const RegularExpression& regex, 37128d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton bool include_symbols, 37228d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton bool append, 37328d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton SymbolContextList& sc_list) 37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 37528d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton if (!append) 37628d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton sc_list.Clear(); 37728d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton 37828d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton const uint32_t start_size = sc_list.GetSize(); 37928d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton 38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symbols) 38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return symbols->FindFunctions(regex, append, sc_list); 38328d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton // Now check our symbol table for symbols that are code symbols if requested 38428d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton if (include_symbols) 38528d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton { 38628d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton ObjectFile *objfile = GetObjectFile(); 38728d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton if (objfile) 38828d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton { 38928d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton Symtab *symtab = objfile->GetSymtab(); 39028d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton if (symtab) 39128d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton { 39228d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton std::vector<uint32_t> symbol_indexes; 39328d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 39428d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton const uint32_t num_matches = symbol_indexes.size(); 39528d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton if (num_matches) 39628d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton { 397889fbd0581c24523642e0a04d659cc8f3dcdb4edGreg Clayton const bool merge_symbol_into_function = true; 39828d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton SymbolContext sc(this); 39928d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton for (uint32_t i=0; i<num_matches; i++) 40028d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton { 40128d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); 402889fbd0581c24523642e0a04d659cc8f3dcdb4edGreg Clayton sc_list.AppendIfUnique (sc, merge_symbol_into_function); 40328d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton } 40428d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton } 40528d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton } 40628d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton } 40728d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton } 40828d5fcc3158aebf543e0f3d0a3608c1746f5ef15Greg Clayton return sc_list.GetSize() - start_size; 40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4117aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Claytonuint32_t 4127aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg ClaytonModule::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) 4137aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton{ 4147aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 4157aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton if (sc.module_sp.get() == NULL || sc.module_sp.get() == this) 4167aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton { 4177aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton SymbolVendor *symbols = GetSymbolVendor (); 4187aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton if (symbols) 4197aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton return symbols->FindTypes(sc, name, append, max_matches, types); 4207aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton } 4217aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton return 0; 4227aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton} 4237aff9ffaec7ffc44dec3c64557dfadcc8a0833a6Greg Clayton 42424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//uint32_t 42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types) 42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//{ 42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Timer scoped_timer(__PRETTY_FUNCTION__); 42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// SymbolVendor *symbols = GetSymbolVendor (); 42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if (symbols) 43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types); 43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// return 0; 43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//} 43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSymbolVendor* 43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::GetSymbolVendor (bool can_create) 43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 43824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker (m_mutex); 439236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton if (m_did_load_symbol_vendor == false && can_create) 44024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ObjectFile *obj_file = GetObjectFile (); 44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (obj_file != NULL) 44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_symfile_ap.reset(SymbolVendor::FindPlugin(this)); 446236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton m_did_load_symbol_vendor = true; 44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_symfile_ap.get(); 45024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name) 45424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 45524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Container objects whose paths do not specify a file directly can call 45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // this function to correct the file and object names. 45724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_file = file; 45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_mod_time = file.GetModificationTime(); 45924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name = object_name; 46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst ArchSpec& 46324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::GetArchitecture () const 46424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 46524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_arch; 46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 4697826c8894803dc729f29789ebc038956a94d3e7aCaroline TiceModule::GetDescription (Stream *s) 4707826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice{ 4717826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice Mutex::Locker locker (m_mutex); 4727826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice 47349ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton if (m_arch.IsValid()) 474940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton s->Printf("(%s) ", m_arch.GetArchitectureName()); 4757826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice 47649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton char path[PATH_MAX]; 47749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton if (m_file.GetPath(path, sizeof(path))) 47849ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton s->PutCString(path); 47949ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton 48049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton const char *object_name = m_object_name.GetCString(); 48149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton if (object_name) 48249ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton s->Printf("(%s)", object_name); 4837826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice} 4847826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice 4857826c8894803dc729f29789ebc038956a94d3e7aCaroline Ticevoid 48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::Dump(Stream *s) 48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker (m_mutex); 4893fed8b9b2696fc2ea78005c8f9b1c621d5748042Greg Clayton //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s->Indent(); 49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s->Printf("Module %s/%s%s%s%s\n", 49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_file.GetDirectory().AsCString(), 49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_file.GetFilename().AsCString(), 49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name ? "(" : "", 49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name ? m_object_name.GetCString() : "", 49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_object_name ? ")" : ""); 49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s->IndentMore(); 49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ObjectFile *objfile = GetObjectFile (); 50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (objfile) 50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner objfile->Dump(s); 50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symbols) 50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symbols->Dump(s); 50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner s->IndentLess(); 51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerTypeList* 51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::GetTypeList () 51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 51624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolVendor *symbols = GetSymbolVendor (); 51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symbols) 51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return &symbols->GetTypeList(); 51924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return NULL; 52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst ConstString & 52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::GetObjectName() const 52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_object_name; 52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerObjectFile * 52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::GetObjectFile() 53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 53124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker (m_mutex); 532236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton if (m_did_load_objfile == false) 53324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 534236c1c71fab5d56a4dbebaabb969a238f11d142eGreg Clayton m_did_load_objfile = true; 53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer(__PRETTY_FUNCTION__, 53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString("")); 53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_objfile_ap.reset(ObjectFile::FindPlugin(this, &m_file, 0, m_file.GetByteSize())); 53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_objfile_ap.get(); 54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 54324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst Symbol * 54424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type) 54524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 54624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer(__PRETTY_FUNCTION__, 54724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)", 54824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner name.AsCString(), 54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symbol_type); 55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ObjectFile *objfile = GetObjectFile(); 55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (objfile) 55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 55324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Symtab *symtab = objfile->GetSymtab(); 55424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symtab) 5557c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny); 55624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 55724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return NULL; 55824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 55924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 56024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list) 56124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 56224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // No need to protect this call using m_mutex all other method calls are 56324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // already thread safe. 56424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 56524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t num_indices = symbol_indexes.size(); 56624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_indices > 0) 56724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 56824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolContext sc; 56924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CalculateSymbolContext (&sc); 57024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (size_t i = 0; i < num_indices; i++) 57124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 57224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]); 57324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (sc.symbol) 57424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sc_list.Append (sc); 57524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 57624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 57724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 57824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 57924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 58024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list) 58124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 58224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // No need to protect this call using m_mutex all other method calls are 58324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // already thread safe. 58424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 58524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 58624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer(__PRETTY_FUNCTION__, 58724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "Module::FindSymbolsWithNameAndType (name = %s, type = %i)", 58824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner name.AsCString(), 58924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symbol_type); 59024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const size_t initial_size = sc_list.GetSize(); 59124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ObjectFile *objfile = GetObjectFile (); 59224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (objfile) 59324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 59424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Symtab *symtab = objfile->GetSymtab(); 59524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symtab) 59624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 59724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::vector<uint32_t> symbol_indexes; 59824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes); 59924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); 60024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 60124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 60224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return sc_list.GetSize() - initial_size; 60324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 60424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 60524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 60624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::FindSymbolsMatchingRegExAndType (const RegularExpression ®ex, SymbolType symbol_type, SymbolContextList &sc_list) 60724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 60824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // No need to protect this call using m_mutex all other method calls are 60924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // already thread safe. 61024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 61124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Timer scoped_timer(__PRETTY_FUNCTION__, 61224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)", 61324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner regex.GetText(), 61424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner symbol_type); 61524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const size_t initial_size = sc_list.GetSize(); 61624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ObjectFile *objfile = GetObjectFile (); 61724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (objfile) 61824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 61924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Symtab *symtab = objfile->GetSymtab(); 62024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (symtab) 62124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 62224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::vector<uint32_t> symbol_indexes; 6237c36fa07bc2c2c7efc4a28ad540f7711491f379dGreg Clayton symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes); 62424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); 62524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 62624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 62724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return sc_list.GetSize() - initial_size; 62824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 62924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 63024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst TimeValue & 63124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerModule::GetModificationTime () const 63224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 63324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_mod_time; 63424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 6357508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham 6367508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Inghambool 6377508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim InghamModule::IsExecutable () 6387508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham{ 6397508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham if (GetObjectFile() == NULL) 6407508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham return false; 6417508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham else 6427508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham return GetObjectFile()->IsExecutable(); 6437508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham} 6447508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham 6457508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Inghambool 6467508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim InghamModule::SetArchitecture (const ArchSpec &new_arch) 6477508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham{ 648940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton if (!m_arch.IsValid()) 6497508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham { 6507508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham m_arch = new_arch; 6517508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham return true; 652940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton } 653940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton return m_arch == new_arch; 6547508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham} 6557508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham 656