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