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