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