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