1 //===-- SymbolVendor.mm -----------------------------------------*- 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/Symbol/SymbolVendor.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Symbol/ObjectFile.h" 19 #include "lldb/Symbol/SymbolFile.h" 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 25 //---------------------------------------------------------------------- 26 // FindPlugin 27 // 28 // Platforms can register a callback to use when creating symbol 29 // vendors to allow for complex debug information file setups, and to 30 // also allow for finding separate debug information files. 31 //---------------------------------------------------------------------- 32 SymbolVendor* 33 SymbolVendor::FindPlugin (Module* module) 34 { 35 std::auto_ptr<SymbolVendor> instance_ap; 36 //---------------------------------------------------------------------- 37 // We currently only have one debug symbol parser... 38 //---------------------------------------------------------------------- 39 SymbolVendorCreateInstance create_callback; 40 for (uint32_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(idx)) != NULL; ++idx) 41 { 42 instance_ap.reset(create_callback(module)); 43 44 if (instance_ap.get()) 45 { 46 // TODO: make sure this symbol vendor is what we want. We 47 // currently are just returning the first one we find, but 48 // we may want to call this function only when we have our 49 // main executable module and then give all symbol vendor 50 // plug-ins a chance to compete for who wins. 51 return instance_ap.release(); 52 } 53 } 54 // The default implementation just tries to create debug information using the 55 // file representation for the module. 56 instance_ap.reset(new SymbolVendor(module)); 57 if (instance_ap.get()) 58 instance_ap->AddSymbolFileRepresendation(module->GetObjectFile()); 59 return instance_ap.release(); 60 } 61 62 //---------------------------------------------------------------------- 63 // SymbolVendor constructor 64 //---------------------------------------------------------------------- 65 SymbolVendor::SymbolVendor(Module *module) : 66 ModuleChild(module), 67 m_mutex (Mutex::eMutexTypeRecursive), 68 m_type_list(), 69 m_compile_units(), 70 m_sym_file_ap() 71 { 72 } 73 74 //---------------------------------------------------------------------- 75 // Destructor 76 //---------------------------------------------------------------------- 77 SymbolVendor::~SymbolVendor() 78 { 79 } 80 81 //---------------------------------------------------------------------- 82 // Add a represantion given an object file. 83 //---------------------------------------------------------------------- 84 void 85 SymbolVendor::AddSymbolFileRepresendation(ObjectFile *obj_file) 86 { 87 Mutex::Locker locker(m_mutex); 88 if (obj_file != NULL) 89 m_sym_file_ap.reset(SymbolFile::FindPlugin(obj_file)); 90 } 91 92 bool 93 SymbolVendor::SetCompileUnitAtIndex (CompUnitSP& cu, uint32_t idx) 94 { 95 Mutex::Locker locker(m_mutex); 96 const uint32_t num_compile_units = GetNumCompileUnits(); 97 if (idx < num_compile_units) 98 { 99 // Fire off an assertion if this compile unit already exists for now. 100 // The partial parsing should take care of only setting the compile 101 // unit once, so if this assertion fails, we need to make sure that 102 // we don't have a race condition, or have a second parse of the same 103 // compile unit. 104 assert(m_compile_units[idx].get() == NULL); 105 m_compile_units[idx] = cu; 106 return true; 107 } 108 return false; 109 } 110 111 uint32_t 112 SymbolVendor::GetNumCompileUnits() 113 { 114 Mutex::Locker locker(m_mutex); 115 if (m_compile_units.empty()) 116 { 117 if (m_sym_file_ap.get()) 118 { 119 // Resize our array of compile unit shared pointers -- which will 120 // each remain NULL until someone asks for the actual compile unit 121 // information. When this happens, the symbol file will be asked 122 // to parse this compile unit information. 123 m_compile_units.resize(m_sym_file_ap->GetNumCompileUnits()); 124 } 125 } 126 return m_compile_units.size(); 127 } 128 129 size_t 130 SymbolVendor::ParseCompileUnitFunctions (const SymbolContext &sc) 131 { 132 Mutex::Locker locker(m_mutex); 133 if (m_sym_file_ap.get()) 134 return m_sym_file_ap->ParseCompileUnitFunctions(sc); 135 return 0; 136 } 137 138 bool 139 SymbolVendor::ParseCompileUnitLineTable (const SymbolContext &sc) 140 { 141 Mutex::Locker locker(m_mutex); 142 if (m_sym_file_ap.get()) 143 return m_sym_file_ap->ParseCompileUnitLineTable(sc); 144 return false; 145 } 146 147 bool 148 SymbolVendor::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) 149 { 150 Mutex::Locker locker(m_mutex); 151 if (m_sym_file_ap.get()) 152 return m_sym_file_ap->ParseCompileUnitSupportFiles(sc, support_files); 153 return false; 154 } 155 156 size_t 157 SymbolVendor::ParseFunctionBlocks (const SymbolContext &sc) 158 { 159 Mutex::Locker locker(m_mutex); 160 if (m_sym_file_ap.get()) 161 return m_sym_file_ap->ParseFunctionBlocks(sc); 162 return 0; 163 } 164 165 size_t 166 SymbolVendor::ParseTypes (const SymbolContext &sc) 167 { 168 Mutex::Locker locker(m_mutex); 169 if (m_sym_file_ap.get()) 170 return m_sym_file_ap->ParseTypes(sc); 171 return 0; 172 } 173 174 size_t 175 SymbolVendor::ParseVariablesForContext (const SymbolContext& sc) 176 { 177 Mutex::Locker locker(m_mutex); 178 if (m_sym_file_ap.get()) 179 return m_sym_file_ap->ParseVariablesForContext(sc); 180 return 0; 181 } 182 183 Type* 184 SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) 185 { 186 Mutex::Locker locker(m_mutex); 187 if (m_sym_file_ap.get()) 188 return m_sym_file_ap->ResolveTypeUID(type_uid); 189 return NULL; 190 } 191 192 193 uint32_t 194 SymbolVendor::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 195 { 196 Mutex::Locker locker(m_mutex); 197 if (m_sym_file_ap.get()) 198 return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc); 199 return 0; 200 } 201 202 uint32_t 203 SymbolVendor::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 204 { 205 Mutex::Locker locker(m_mutex); 206 if (m_sym_file_ap.get()) 207 return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list); 208 return 0; 209 } 210 211 uint32_t 212 SymbolVendor::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) 213 { 214 Mutex::Locker locker(m_mutex); 215 if (m_sym_file_ap.get()) 216 return m_sym_file_ap->FindGlobalVariables(name, append, max_matches, variables); 217 return 0; 218 } 219 220 uint32_t 221 SymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 222 { 223 Mutex::Locker locker(m_mutex); 224 if (m_sym_file_ap.get()) 225 return m_sym_file_ap->FindGlobalVariables(regex, append, max_matches, variables); 226 return 0; 227 } 228 229 uint32_t 230 SymbolVendor::FindFunctions(const ConstString &name, uint32_t name_type_mask, bool append, SymbolContextList& sc_list) 231 { 232 Mutex::Locker locker(m_mutex); 233 if (m_sym_file_ap.get()) 234 return m_sym_file_ap->FindFunctions(name, name_type_mask, append, sc_list); 235 return 0; 236 } 237 238 uint32_t 239 SymbolVendor::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list) 240 { 241 Mutex::Locker locker(m_mutex); 242 if (m_sym_file_ap.get()) 243 return m_sym_file_ap->FindFunctions(regex, append, sc_list); 244 return 0; 245 } 246 247 248 uint32_t 249 SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) 250 { 251 Mutex::Locker locker(m_mutex); 252 if (m_sym_file_ap.get()) 253 return m_sym_file_ap->FindTypes(sc, name, append, max_matches, types); 254 if (!append) 255 types.Clear(); 256 return 0; 257 } 258 259 ClangNamespaceDecl 260 SymbolVendor::FindNamespace(const SymbolContext& sc, const ConstString &name) 261 { 262 Mutex::Locker locker(m_mutex); 263 ClangNamespaceDecl namespace_decl; 264 if (m_sym_file_ap.get()) 265 namespace_decl = m_sym_file_ap->FindNamespace (sc, name); 266 return namespace_decl; 267 } 268 269 void 270 SymbolVendor::Dump(Stream *s) 271 { 272 Mutex::Locker locker(m_mutex); 273 bool show_context = false; 274 275 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 276 s->Indent(); 277 s->PutCString("SymbolVendor"); 278 if (m_sym_file_ap.get()) 279 { 280 ObjectFile *objfile = m_sym_file_ap->GetObjectFile(); 281 if (objfile) 282 { 283 const FileSpec &objfile_file_spec = objfile->GetFileSpec(); 284 if (objfile_file_spec) 285 { 286 s->PutCString(" ("); 287 objfile_file_spec.Dump(s); 288 s->PutChar(')'); 289 } 290 } 291 } 292 s->EOL(); 293 s->IndentMore(); 294 m_type_list.Dump(s, show_context); 295 296 CompileUnitConstIter cu_pos, cu_end; 297 cu_end = m_compile_units.end(); 298 for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos) 299 { 300 // We currently only dump the compile units that have been parsed 301 if (cu_pos->get()) 302 (*cu_pos)->Dump(s, show_context); 303 } 304 305 s->IndentLess(); 306 307 } 308 309 CompUnitSP 310 SymbolVendor::GetCompileUnitAtIndex(uint32_t idx) 311 { 312 Mutex::Locker locker(m_mutex); 313 CompUnitSP cu_sp; 314 const uint32_t num_compile_units = GetNumCompileUnits(); 315 if (idx < num_compile_units) 316 { 317 cu_sp = m_compile_units[idx]; 318 if (cu_sp.get() == NULL) 319 { 320 m_compile_units[idx] = m_sym_file_ap->ParseCompileUnitAtIndex(idx); 321 cu_sp = m_compile_units[idx]; 322 } 323 } 324 return cu_sp; 325 } 326 327 328 //------------------------------------------------------------------ 329 // PluginInterface protocol 330 //------------------------------------------------------------------ 331 const char * 332 SymbolVendor::GetPluginName() 333 { 334 return "SymbolVendor"; 335 } 336 337 const char * 338 SymbolVendor::GetShortPluginName() 339 { 340 return "vendor-default"; 341 } 342 343 uint32_t 344 SymbolVendor::GetPluginVersion() 345 { 346 return 1; 347 } 348 349