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 abilities |= Functions; 119 } 120 121 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes)) 122 { 123 symtab->SortSymbolIndexesByValue(m_data_indexes, true); 124 abilities |= GlobalVariables; 125 } 126 127 lldb_private::Symtab::IndexCollection objc_class_indexes; 128 if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes)) 129 { 130 symtab->AppendSymbolNamesToMap (objc_class_indexes, 131 true, 132 true, 133 m_objc_class_name_to_index); 134 m_objc_class_name_to_index.Sort(); 135 } 136 } 137 } 138 return abilities; 139 } 140 141 uint32_t 142 SymbolFileSymtab::GetNumCompileUnits() 143 { 144 // If we don't have any source file symbols we will just have one compile unit for 145 // the entire object file 146 if (m_source_indexes.empty()) 147 return 0; 148 149 // If we have any source file symbols we will logically organize the object symbols 150 // using these. 151 return m_source_indexes.size(); 152 } 153 154 CompUnitSP 155 SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) 156 { 157 CompUnitSP cu_sp; 158 159 // If we don't have any source file symbols we will just have one compile unit for 160 // the entire object file 161 if (idx < m_source_indexes.size()) 162 { 163 const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); 164 if (cu_symbol) 165 cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0, eLanguageTypeUnknown, false)); 166 } 167 return cu_sp; 168 } 169 170 lldb::LanguageType 171 SymbolFileSymtab::ParseCompileUnitLanguage (const SymbolContext& sc) 172 { 173 return eLanguageTypeUnknown; 174 } 175 176 177 size_t 178 SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc) 179 { 180 size_t num_added = 0; 181 // We must at least have a valid compile unit 182 assert (sc.comp_unit != NULL); 183 const Symtab *symtab = m_obj_file->GetSymtab(); 184 const Symbol *curr_symbol = NULL; 185 const Symbol *next_symbol = NULL; 186 // const char *prefix = m_obj_file->SymbolPrefix(); 187 // if (prefix == NULL) 188 // prefix == ""; 189 // 190 // const uint32_t prefix_len = strlen(prefix); 191 192 // If we don't have any source file symbols we will just have one compile unit for 193 // the entire object file 194 if (m_source_indexes.empty()) 195 { 196 // The only time we will have a user ID of zero is when we don't have 197 // and source file symbols and we declare one compile unit for the 198 // entire object file 199 if (!m_func_indexes.empty()) 200 { 201 202 } 203 204 if (!m_code_indexes.empty()) 205 { 206 // StreamFile s(stdout); 207 // symtab->Dump(&s, m_code_indexes); 208 209 uint32_t idx = 0; // Index into the indexes 210 const uint32_t num_indexes = m_code_indexes.size(); 211 for (idx = 0; idx < num_indexes; ++idx) 212 { 213 uint32_t symbol_idx = m_code_indexes[idx]; 214 curr_symbol = symtab->SymbolAtIndex(symbol_idx); 215 if (curr_symbol) 216 { 217 // Union of all ranges in the function DIE (if the function is discontiguous) 218 AddressRange func_range(curr_symbol->GetAddress(), 0); 219 if (func_range.GetBaseAddress().IsSectionOffset()) 220 { 221 uint32_t symbol_size = curr_symbol->GetByteSize(); 222 if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling()) 223 func_range.SetByteSize(symbol_size); 224 else if (idx + 1 < num_indexes) 225 { 226 next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]); 227 if (next_symbol) 228 { 229 func_range.SetByteSize(next_symbol->GetAddressRef().GetOffset() - curr_symbol->GetAddressRef().GetOffset()); 230 } 231 } 232 233 FunctionSP func_sp(new Function(sc.comp_unit, 234 symbol_idx, // UserID is the DIE offset 235 LLDB_INVALID_UID, // We don't have any type info for this function 236 curr_symbol->GetMangled(), // Linker/mangled name 237 NULL, // no return type for a code symbol... 238 func_range)); // first address range 239 240 if (func_sp.get() != NULL) 241 { 242 sc.comp_unit->AddFunction(func_sp); 243 ++num_added; 244 } 245 } 246 } 247 } 248 249 } 250 } 251 else 252 { 253 // We assume we 254 } 255 return num_added; 256 } 257 258 bool 259 SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc) 260 { 261 return false; 262 } 263 264 bool 265 SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files) 266 { 267 return false; 268 } 269 270 bool 271 SymbolFileSymtab::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules) 272 { 273 return false; 274 } 275 276 size_t 277 SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc) 278 { 279 return 0; 280 } 281 282 283 size_t 284 SymbolFileSymtab::ParseTypes (const SymbolContext &sc) 285 { 286 return 0; 287 } 288 289 290 size_t 291 SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc) 292 { 293 return 0; 294 } 295 296 Type* 297 SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) 298 { 299 return NULL; 300 } 301 302 bool 303 SymbolFileSymtab::CompleteType (lldb_private::CompilerType& clang_opaque_type) 304 { 305 return false; 306 } 307 308 uint32_t 309 SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 310 { 311 if (m_obj_file->GetSymtab() == NULL) 312 return 0; 313 314 uint32_t resolved_flags = 0; 315 if (resolve_scope & eSymbolContextSymbol) 316 { 317 sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); 318 if (sc.symbol) 319 resolved_flags |= eSymbolContextSymbol; 320 } 321 return resolved_flags; 322 } 323 324 //------------------------------------------------------------------ 325 // PluginInterface protocol 326 //------------------------------------------------------------------ 327 lldb_private::ConstString 328 SymbolFileSymtab::GetPluginName() 329 { 330 return GetPluginNameStatic(); 331 } 332 333 uint32_t 334 SymbolFileSymtab::GetPluginVersion() 335 { 336 return 1; 337 } 338