| Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 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()) | 
| Greg Clayton | 762f713 | 2011-09-18 18:59:15 +0000 | [diff] [blame^] | 58 | { | 
|  | 59 | ObjectFile *objfile = module->GetObjectFile(); | 
|  | 60 | if (objfile) | 
|  | 61 | instance_ap->AddSymbolFileRepresendation(objfile->GetSP()); | 
|  | 62 | } | 
| Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 63 | return instance_ap.release(); | 
|  | 64 | } | 
|  | 65 |  | 
|  | 66 | //---------------------------------------------------------------------- | 
|  | 67 | // SymbolVendor constructor | 
|  | 68 | //---------------------------------------------------------------------- | 
|  | 69 | SymbolVendor::SymbolVendor(Module *module) : | 
|  | 70 | ModuleChild(module), | 
|  | 71 | m_mutex (Mutex::eMutexTypeRecursive), | 
|  | 72 | m_type_list(), | 
|  | 73 | m_compile_units(), | 
|  | 74 | m_sym_file_ap() | 
|  | 75 | { | 
| Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 76 | } | 
|  | 77 |  | 
|  | 78 | //---------------------------------------------------------------------- | 
|  | 79 | // Destructor | 
|  | 80 | //---------------------------------------------------------------------- | 
|  | 81 | SymbolVendor::~SymbolVendor() | 
|  | 82 | { | 
|  | 83 | } | 
|  | 84 |  | 
|  | 85 | //---------------------------------------------------------------------- | 
|  | 86 | // Add a represantion given an object file. | 
|  | 87 | //---------------------------------------------------------------------- | 
|  | 88 | void | 
| Greg Clayton | 762f713 | 2011-09-18 18:59:15 +0000 | [diff] [blame^] | 89 | SymbolVendor::AddSymbolFileRepresendation(const ObjectFileSP &objfile_sp) | 
| Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 90 | { | 
|  | 91 | Mutex::Locker locker(m_mutex); | 
| Greg Clayton | 762f713 | 2011-09-18 18:59:15 +0000 | [diff] [blame^] | 92 | if (objfile_sp) | 
|  | 93 | { | 
|  | 94 | m_objfile_sp = objfile_sp; | 
|  | 95 | m_sym_file_ap.reset(SymbolFile::FindPlugin(objfile_sp.get())); | 
|  | 96 | } | 
| Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 97 | } | 
|  | 98 |  | 
|  | 99 | bool | 
| Greg Clayton | 450e3f3 | 2010-10-12 02:24:53 +0000 | [diff] [blame] | 100 | SymbolVendor::SetCompileUnitAtIndex (CompUnitSP& cu, uint32_t idx) | 
| Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 101 | { | 
|  | 102 | Mutex::Locker locker(m_mutex); | 
|  | 103 | const uint32_t num_compile_units = GetNumCompileUnits(); | 
|  | 104 | if (idx < num_compile_units) | 
|  | 105 | { | 
|  | 106 | // Fire off an assertion if this compile unit already exists for now. | 
|  | 107 | // The partial parsing should take care of only setting the compile | 
|  | 108 | // unit once, so if this assertion fails, we need to make sure that | 
|  | 109 | // we don't have a race condition, or have a second parse of the same | 
|  | 110 | // compile unit. | 
|  | 111 | assert(m_compile_units[idx].get() == NULL); | 
|  | 112 | m_compile_units[idx] = cu; | 
|  | 113 | return true; | 
|  | 114 | } | 
|  | 115 | return false; | 
|  | 116 | } | 
|  | 117 |  | 
|  | 118 | uint32_t | 
|  | 119 | SymbolVendor::GetNumCompileUnits() | 
|  | 120 | { | 
|  | 121 | Mutex::Locker locker(m_mutex); | 
|  | 122 | if (m_compile_units.empty()) | 
|  | 123 | { | 
|  | 124 | if (m_sym_file_ap.get()) | 
|  | 125 | { | 
|  | 126 | // Resize our array of compile unit shared pointers -- which will | 
|  | 127 | // each remain NULL until someone asks for the actual compile unit | 
|  | 128 | // information. When this happens, the symbol file will be asked | 
|  | 129 | // to parse this compile unit information. | 
|  | 130 | m_compile_units.resize(m_sym_file_ap->GetNumCompileUnits()); | 
|  | 131 | } | 
|  | 132 | } | 
|  | 133 | return m_compile_units.size(); | 
|  | 134 | } | 
|  | 135 |  | 
|  | 136 | size_t | 
|  | 137 | SymbolVendor::ParseCompileUnitFunctions (const SymbolContext &sc) | 
|  | 138 | { | 
|  | 139 | Mutex::Locker locker(m_mutex); | 
|  | 140 | if (m_sym_file_ap.get()) | 
|  | 141 | return m_sym_file_ap->ParseCompileUnitFunctions(sc); | 
|  | 142 | return 0; | 
|  | 143 | } | 
|  | 144 |  | 
|  | 145 | bool | 
|  | 146 | SymbolVendor::ParseCompileUnitLineTable (const SymbolContext &sc) | 
|  | 147 | { | 
|  | 148 | Mutex::Locker locker(m_mutex); | 
|  | 149 | if (m_sym_file_ap.get()) | 
|  | 150 | return m_sym_file_ap->ParseCompileUnitLineTable(sc); | 
|  | 151 | return false; | 
|  | 152 | } | 
|  | 153 |  | 
|  | 154 | bool | 
|  | 155 | SymbolVendor::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) | 
|  | 156 | { | 
|  | 157 | Mutex::Locker locker(m_mutex); | 
|  | 158 | if (m_sym_file_ap.get()) | 
|  | 159 | return m_sym_file_ap->ParseCompileUnitSupportFiles(sc, support_files); | 
|  | 160 | return false; | 
|  | 161 | } | 
|  | 162 |  | 
|  | 163 | size_t | 
|  | 164 | SymbolVendor::ParseFunctionBlocks (const SymbolContext &sc) | 
|  | 165 | { | 
|  | 166 | Mutex::Locker locker(m_mutex); | 
|  | 167 | if (m_sym_file_ap.get()) | 
|  | 168 | return m_sym_file_ap->ParseFunctionBlocks(sc); | 
|  | 169 | return 0; | 
|  | 170 | } | 
|  | 171 |  | 
|  | 172 | size_t | 
|  | 173 | SymbolVendor::ParseTypes (const SymbolContext &sc) | 
|  | 174 | { | 
|  | 175 | Mutex::Locker locker(m_mutex); | 
|  | 176 | if (m_sym_file_ap.get()) | 
|  | 177 | return m_sym_file_ap->ParseTypes(sc); | 
|  | 178 | return 0; | 
|  | 179 | } | 
|  | 180 |  | 
|  | 181 | size_t | 
|  | 182 | SymbolVendor::ParseVariablesForContext (const SymbolContext& sc) | 
|  | 183 | { | 
|  | 184 | Mutex::Locker locker(m_mutex); | 
|  | 185 | if (m_sym_file_ap.get()) | 
|  | 186 | return m_sym_file_ap->ParseVariablesForContext(sc); | 
|  | 187 | return 0; | 
|  | 188 | } | 
|  | 189 |  | 
|  | 190 | Type* | 
|  | 191 | SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) | 
|  | 192 | { | 
|  | 193 | Mutex::Locker locker(m_mutex); | 
|  | 194 | if (m_sym_file_ap.get()) | 
|  | 195 | return m_sym_file_ap->ResolveTypeUID(type_uid); | 
|  | 196 | return NULL; | 
|  | 197 | } | 
|  | 198 |  | 
|  | 199 |  | 
|  | 200 | uint32_t | 
|  | 201 | SymbolVendor::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) | 
|  | 202 | { | 
|  | 203 | Mutex::Locker locker(m_mutex); | 
|  | 204 | if (m_sym_file_ap.get()) | 
|  | 205 | return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc); | 
|  | 206 | return 0; | 
|  | 207 | } | 
|  | 208 |  | 
|  | 209 | uint32_t | 
|  | 210 | SymbolVendor::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) | 
|  | 211 | { | 
|  | 212 | Mutex::Locker locker(m_mutex); | 
|  | 213 | if (m_sym_file_ap.get()) | 
|  | 214 | return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list); | 
|  | 215 | return 0; | 
|  | 216 | } | 
|  | 217 |  | 
|  | 218 | uint32_t | 
|  | 219 | SymbolVendor::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) | 
|  | 220 | { | 
|  | 221 | Mutex::Locker locker(m_mutex); | 
|  | 222 | if (m_sym_file_ap.get()) | 
|  | 223 | return m_sym_file_ap->FindGlobalVariables(name, append, max_matches, variables); | 
|  | 224 | return 0; | 
|  | 225 | } | 
|  | 226 |  | 
|  | 227 | uint32_t | 
|  | 228 | SymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) | 
|  | 229 | { | 
|  | 230 | Mutex::Locker locker(m_mutex); | 
|  | 231 | if (m_sym_file_ap.get()) | 
|  | 232 | return m_sym_file_ap->FindGlobalVariables(regex, append, max_matches, variables); | 
|  | 233 | return 0; | 
|  | 234 | } | 
|  | 235 |  | 
|  | 236 | uint32_t | 
| Greg Clayton | 0c5cd90 | 2010-06-28 21:30:43 +0000 | [diff] [blame] | 237 | SymbolVendor::FindFunctions(const ConstString &name, uint32_t name_type_mask, bool append, SymbolContextList& sc_list) | 
| Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 238 | { | 
|  | 239 | Mutex::Locker locker(m_mutex); | 
|  | 240 | if (m_sym_file_ap.get()) | 
| Greg Clayton | 0c5cd90 | 2010-06-28 21:30:43 +0000 | [diff] [blame] | 241 | return m_sym_file_ap->FindFunctions(name, name_type_mask, append, sc_list); | 
| Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 242 | return 0; | 
|  | 243 | } | 
|  | 244 |  | 
|  | 245 | uint32_t | 
|  | 246 | SymbolVendor::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list) | 
|  | 247 | { | 
|  | 248 | Mutex::Locker locker(m_mutex); | 
|  | 249 | if (m_sym_file_ap.get()) | 
|  | 250 | return m_sym_file_ap->FindFunctions(regex, append, sc_list); | 
|  | 251 | return 0; | 
|  | 252 | } | 
|  | 253 |  | 
|  | 254 |  | 
| Greg Clayton | b0b9fe6 | 2010-08-03 00:35:52 +0000 | [diff] [blame] | 255 | uint32_t | 
|  | 256 | SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) | 
|  | 257 | { | 
|  | 258 | Mutex::Locker locker(m_mutex); | 
|  | 259 | if (m_sym_file_ap.get()) | 
|  | 260 | return m_sym_file_ap->FindTypes(sc, name, append, max_matches, types); | 
|  | 261 | if (!append) | 
|  | 262 | types.Clear(); | 
|  | 263 | return 0; | 
|  | 264 | } | 
| Greg Clayton | 526e5af | 2010-11-13 03:52:47 +0000 | [diff] [blame] | 265 |  | 
|  | 266 | ClangNamespaceDecl | 
|  | 267 | SymbolVendor::FindNamespace(const SymbolContext& sc, const ConstString &name) | 
|  | 268 | { | 
|  | 269 | Mutex::Locker locker(m_mutex); | 
|  | 270 | ClangNamespaceDecl namespace_decl; | 
|  | 271 | if (m_sym_file_ap.get()) | 
|  | 272 | namespace_decl = m_sym_file_ap->FindNamespace (sc, name); | 
|  | 273 | return namespace_decl; | 
|  | 274 | } | 
| Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 275 |  | 
|  | 276 | void | 
|  | 277 | SymbolVendor::Dump(Stream *s) | 
|  | 278 | { | 
|  | 279 | Mutex::Locker locker(m_mutex); | 
|  | 280 | bool show_context = false; | 
|  | 281 |  | 
|  | 282 | s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); | 
|  | 283 | s->Indent(); | 
|  | 284 | s->PutCString("SymbolVendor"); | 
|  | 285 | if (m_sym_file_ap.get()) | 
|  | 286 | { | 
|  | 287 | ObjectFile *objfile = m_sym_file_ap->GetObjectFile(); | 
|  | 288 | if (objfile) | 
|  | 289 | { | 
|  | 290 | const FileSpec &objfile_file_spec = objfile->GetFileSpec(); | 
|  | 291 | if (objfile_file_spec) | 
|  | 292 | { | 
|  | 293 | s->PutCString(" ("); | 
|  | 294 | objfile_file_spec.Dump(s); | 
|  | 295 | s->PutChar(')'); | 
|  | 296 | } | 
|  | 297 | } | 
|  | 298 | } | 
|  | 299 | s->EOL(); | 
|  | 300 | s->IndentMore(); | 
|  | 301 | m_type_list.Dump(s, show_context); | 
|  | 302 |  | 
|  | 303 | CompileUnitConstIter cu_pos, cu_end; | 
|  | 304 | cu_end = m_compile_units.end(); | 
|  | 305 | for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos) | 
|  | 306 | { | 
|  | 307 | // We currently only dump the compile units that have been parsed | 
|  | 308 | if (cu_pos->get()) | 
|  | 309 | (*cu_pos)->Dump(s, show_context); | 
|  | 310 | } | 
|  | 311 |  | 
|  | 312 | s->IndentLess(); | 
|  | 313 |  | 
|  | 314 | } | 
|  | 315 |  | 
|  | 316 | CompUnitSP | 
|  | 317 | SymbolVendor::GetCompileUnitAtIndex(uint32_t idx) | 
|  | 318 | { | 
|  | 319 | Mutex::Locker locker(m_mutex); | 
|  | 320 | CompUnitSP cu_sp; | 
|  | 321 | const uint32_t num_compile_units = GetNumCompileUnits(); | 
|  | 322 | if (idx < num_compile_units) | 
|  | 323 | { | 
|  | 324 | cu_sp = m_compile_units[idx]; | 
|  | 325 | if (cu_sp.get() == NULL) | 
|  | 326 | { | 
|  | 327 | m_compile_units[idx] = m_sym_file_ap->ParseCompileUnitAtIndex(idx); | 
|  | 328 | cu_sp = m_compile_units[idx]; | 
|  | 329 | } | 
|  | 330 | } | 
|  | 331 | return cu_sp; | 
|  | 332 | } | 
|  | 333 |  | 
|  | 334 |  | 
|  | 335 | //------------------------------------------------------------------ | 
|  | 336 | // PluginInterface protocol | 
|  | 337 | //------------------------------------------------------------------ | 
|  | 338 | const char * | 
|  | 339 | SymbolVendor::GetPluginName() | 
|  | 340 | { | 
|  | 341 | return "SymbolVendor"; | 
|  | 342 | } | 
|  | 343 |  | 
|  | 344 | const char * | 
|  | 345 | SymbolVendor::GetShortPluginName() | 
|  | 346 | { | 
|  | 347 | return "vendor-default"; | 
|  | 348 | } | 
|  | 349 |  | 
|  | 350 | uint32_t | 
|  | 351 | SymbolVendor::GetPluginVersion() | 
|  | 352 | { | 
|  | 353 | return 1; | 
|  | 354 | } | 
|  | 355 |  |