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