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