1 //===-- SymbolFileSymtab.cpp ------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "SymbolFileSymtab.h" 11 #include "lldb/Core/Module.h" 12 #include "lldb/Core/PluginManager.h" 13 #include "lldb/Core/RegularExpression.h" 14 #include "lldb/Core/Timer.h" 15 #include "lldb/Symbol/CompileUnit.h" 16 #include "lldb/Symbol/Function.h" 17 #include "lldb/Symbol/ObjectFile.h" 18 #include "lldb/Symbol/ObjectFile.h" 19 #include "lldb/Symbol/Symbol.h" 20 #include "lldb/Symbol/SymbolContext.h" 21 #include "lldb/Symbol/Symtab.h" 22 #include "lldb/Symbol/TypeList.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 void 28 SymbolFileSymtab::Initialize() 29 { 30 PluginManager::RegisterPlugin (GetPluginNameStatic(), 31 GetPluginDescriptionStatic(), 32 CreateInstance); 33 } 34 35 void 36 SymbolFileSymtab::Terminate() 37 { 38 PluginManager::UnregisterPlugin (CreateInstance); 39 } 40 41 42 const char * 43 SymbolFileSymtab::GetPluginNameStatic() 44 { 45 return "symbol-file.symtab"; 46 } 47 48 const char * 49 SymbolFileSymtab::GetPluginDescriptionStatic() 50 { 51 return "Reads debug symbols from an object file's symbol table."; 52 } 53 54 55 SymbolFile* 56 SymbolFileSymtab::CreateInstance (ObjectFile* obj_file) 57 { 58 return new SymbolFileSymtab(obj_file); 59 } 60 61 SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) : 62 SymbolFile(obj_file), 63 m_source_indexes(), 64 m_func_indexes(), 65 m_code_indexes(), 66 m_objc_class_name_to_index () 67 { 68 } 69 70 SymbolFileSymtab::~SymbolFileSymtab() 71 { 72 } 73 74 ClangASTContext & 75 SymbolFileSymtab::GetClangASTContext () 76 { 77 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext(); 78 79 return ast; 80 } 81 82 uint32_t 83 SymbolFileSymtab::CalculateAbilities () 84 { 85 uint32_t abilities = 0; 86 if (m_obj_file) 87 { 88 const Symtab *symtab = m_obj_file->GetSymtab(); 89 if (symtab) 90 { 91 //---------------------------------------------------------------------- 92 // The snippet of code below will get the indexes the module symbol 93 // table entries that are code, data, or function related (debug info), 94 // sort them by value (address) and dump the sorted symbols. 95 //---------------------------------------------------------------------- 96 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes)) 97 { 98 abilities |= CompileUnits; 99 } 100 101 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes)) 102 { 103 symtab->SortSymbolIndexesByValue(m_func_indexes, true); 104 abilities |= Functions; 105 } 106 107 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes)) 108 { 109 symtab->SortSymbolIndexesByValue(m_code_indexes, true); 110 } 111 112 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes)) 113 { 114 symtab->SortSymbolIndexesByValue(m_data_indexes, true); 115 abilities |= GlobalVariables; 116 } 117 118 lldb_private::Symtab::IndexCollection objc_class_indexes; 119 if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes)) 120 { 121 symtab->AppendSymbolNamesToMap (objc_class_indexes, 122 true, 123 true, 124 m_objc_class_name_to_index); 125 m_objc_class_name_to_index.Sort(); 126 } 127 } 128 } 129 return abilities; 130 } 131 132 uint32_t 133 SymbolFileSymtab::GetNumCompileUnits() 134 { 135 // If we don't have any source file symbols we will just have one compile unit for 136 // the entire object file 137 if (m_source_indexes.empty()) 138 return 0; 139 140 // If we have any source file symbols we will logically orgnize the object symbols 141 // using these. 142 return m_source_indexes.size(); 143 } 144 145 CompUnitSP 146 SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) 147 { 148 CompUnitSP cu_sp; 149 150 // If we don't have any source file symbols we will just have one compile unit for 151 // the entire object file 152 if (idx < m_source_indexes.size()) 153 { 154 const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); 155 if (cu_symbol) 156 cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown)); 157 } 158 return cu_sp; 159 } 160 161 lldb::LanguageType 162 SymbolFileSymtab::ParseCompileUnitLanguage (const SymbolContext& sc) 163 { 164 return eLanguageTypeUnknown; 165 } 166 167 168 size_t 169 SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc) 170 { 171 size_t num_added = 0; 172 // We must at least have a valid compile unit 173 assert (sc.comp_unit != NULL); 174 const Symtab *symtab = m_obj_file->GetSymtab(); 175 const Symbol *curr_symbol = NULL; 176 const Symbol *next_symbol = NULL; 177 // const char *prefix = m_obj_file->SymbolPrefix(); 178 // if (prefix == NULL) 179 // prefix == ""; 180 // 181 // const uint32_t prefix_len = strlen(prefix); 182 183 // If we don't have any source file symbols we will just have one compile unit for 184 // the entire object file 185 if (m_source_indexes.empty()) 186 { 187 // The only time we will have a user ID of zero is when we don't have 188 // and source file symbols and we declare one compile unit for the 189 // entire object file 190 if (!m_func_indexes.empty()) 191 { 192 193 } 194 195 if (!m_code_indexes.empty()) 196 { 197 // StreamFile s(stdout); 198 // symtab->Dump(&s, m_code_indexes); 199 200 uint32_t idx = 0; // Index into the indexes 201 const uint32_t num_indexes = m_code_indexes.size(); 202 for (idx = 0; idx < num_indexes; ++idx) 203 { 204 uint32_t symbol_idx = m_code_indexes[idx]; 205 curr_symbol = symtab->SymbolAtIndex(symbol_idx); 206 if (curr_symbol) 207 { 208 // Union of all ranges in the function DIE (if the function is discontiguous) 209 AddressRange func_range(curr_symbol->GetAddress(), 0); 210 if (func_range.GetBaseAddress().IsSectionOffset()) 211 { 212 uint32_t symbol_size = curr_symbol->GetByteSize(); 213 if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling()) 214 func_range.SetByteSize(symbol_size); 215 else if (idx + 1 < num_indexes) 216 { 217 next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]); 218 if (next_symbol) 219 { 220 func_range.SetByteSize(next_symbol->GetAddress().GetOffset() - curr_symbol->GetAddress().GetOffset()); 221 } 222 } 223 224 FunctionSP func_sp(new Function(sc.comp_unit, 225 symbol_idx, // UserID is the DIE offset 226 LLDB_INVALID_UID, // We don't have any type info for this function 227 curr_symbol->GetMangled(), // Linker/mangled name 228 NULL, // no return type for a code symbol... 229 func_range)); // first address range 230 231 if (func_sp.get() != NULL) 232 { 233 sc.comp_unit->AddFunction(func_sp); 234 ++num_added; 235 } 236 } 237 } 238 } 239 240 } 241 } 242 else 243 { 244 // We assume we 245 } 246 return num_added; 247 } 248 249 bool 250 SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc) 251 { 252 return false; 253 } 254 255 bool 256 SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files) 257 { 258 return false; 259 } 260 261 size_t 262 SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc) 263 { 264 return 0; 265 } 266 267 268 size_t 269 SymbolFileSymtab::ParseTypes (const SymbolContext &sc) 270 { 271 return 0; 272 } 273 274 275 size_t 276 SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc) 277 { 278 return 0; 279 } 280 281 Type* 282 SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) 283 { 284 return NULL; 285 } 286 287 lldb::clang_type_t 288 SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type) 289 { 290 return NULL; 291 } 292 293 ClangNamespaceDecl 294 SymbolFileSymtab::FindNamespace (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl) 295 { 296 return ClangNamespaceDecl(); 297 } 298 299 uint32_t 300 SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 301 { 302 if (m_obj_file->GetSymtab() == NULL) 303 return 0; 304 305 uint32_t resolved_flags = 0; 306 if (resolve_scope & eSymbolContextSymbol) 307 { 308 sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); 309 if (sc.symbol) 310 resolved_flags |= eSymbolContextSymbol; 311 } 312 return resolved_flags; 313 } 314 315 uint32_t 316 SymbolFileSymtab::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 317 { 318 return 0; 319 } 320 321 uint32_t 322 SymbolFileSymtab::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables) 323 { 324 return 0; 325 } 326 327 uint32_t 328 SymbolFileSymtab::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 329 { 330 return 0; 331 } 332 333 uint32_t 334 SymbolFileSymtab::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list) 335 { 336 Timer scoped_timer (__PRETTY_FUNCTION__, 337 "SymbolFileSymtab::FindFunctions (name = '%s')", 338 name.GetCString()); 339 // If we ever support finding STABS or COFF debug info symbols, 340 // we will need to add support here. We are not trying to find symbols 341 // here, just "lldb_private::Function" objects that come from complete 342 // debug information. Any symbol queries should go through the symbol 343 // table itself in the module's object file. 344 return 0; 345 } 346 347 uint32_t 348 SymbolFileSymtab::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) 349 { 350 Timer scoped_timer (__PRETTY_FUNCTION__, 351 "SymbolFileSymtab::FindFunctions (regex = '%s')", 352 regex.GetText()); 353 // If we ever support finding STABS or COFF debug info symbols, 354 // we will need to add support here. We are not trying to find symbols 355 // here, just "lldb_private::Function" objects that come from complete 356 // debug information. Any symbol queries should go through the symbol 357 // table itself in the module's object file. 358 return 0; 359 } 360 361 static int CountMethodArgs(const char *method_signature) 362 { 363 int num_args = 0; 364 365 for (const char *colon_pos = strchr(method_signature, ':'); 366 colon_pos != NULL; 367 colon_pos = strchr(colon_pos + 1, ':')) 368 { 369 num_args++; 370 } 371 372 return num_args; 373 } 374 375 uint32_t 376 SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc, 377 const lldb_private::ConstString &name, 378 const ClangNamespaceDecl *namespace_decl, 379 bool append, 380 uint32_t max_matches, 381 lldb_private::TypeList& types) 382 { 383 if (!append) 384 types.Clear(); 385 386 if (!m_objc_class_name_to_index.IsEmpty()) 387 { 388 TypeMap::iterator iter = m_objc_class_types.find(name); 389 390 if (iter != m_objc_class_types.end()) 391 { 392 types.Insert(iter->second); 393 return 1; 394 } 395 396 const Symtab::NameToIndexMap::Entry *match = m_objc_class_name_to_index.FindFirstValueForName(name.GetCString()); 397 398 if (match == NULL) 399 return 0; 400 401 const bool isForwardDecl = false; 402 const bool isInternal = true; 403 404 ClangASTContext &ast = GetClangASTContext(); 405 406 lldb::clang_type_t objc_object_type = ast.CreateObjCClass (name.AsCString(), 407 ast.GetTranslationUnitDecl(), 408 isForwardDecl, 409 isInternal, 410 0xffaaffaaffaaffaall); 411 412 Declaration decl; 413 414 lldb::TypeSP type(new Type (match->value, 415 this, 416 name, 417 0, // byte_size - don't change this from 0, we currently use that to identify these "synthetic" ObjC class types. 418 NULL, // SymbolContextScope* 419 0, // encoding_uid 420 Type::eEncodingInvalid, 421 decl, 422 objc_object_type, 423 Type::eResolveStateFull)); 424 425 m_objc_class_types[name] = type; 426 427 types.Insert(type); 428 429 return 1; 430 } 431 432 return 0; 433 } 434 // 435 //uint32_t 436 //SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) 437 //{ 438 // return 0; 439 //} 440 441 442 //------------------------------------------------------------------ 443 // PluginInterface protocol 444 //------------------------------------------------------------------ 445 const char * 446 SymbolFileSymtab::GetPluginName() 447 { 448 return "SymbolFileSymtab"; 449 } 450 451 const char * 452 SymbolFileSymtab::GetShortPluginName() 453 { 454 return GetPluginNameStatic(); 455 } 456 457 uint32_t 458 SymbolFileSymtab::GetPluginVersion() 459 { 460 return 1; 461 } 462