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/CompileUnit.h" 16 #include "lldb/Symbol/Function.h" 17 #include "lldb/Symbol/ObjectFile.h" 18 #include "lldb/Symbol/ObjectFile.h" 19 #include "lldb/Symbol/Symbol.h" 20 #include "lldb/Symbol/SymbolContext.h" 21 #include "lldb/Symbol/Symtab.h" 22 #include "lldb/Symbol/TypeList.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 void 28 SymbolFileSymtab::Initialize() 29 { 30 PluginManager::RegisterPlugin (GetPluginNameStatic(), 31 GetPluginDescriptionStatic(), 32 CreateInstance); 33 } 34 35 void 36 SymbolFileSymtab::Terminate() 37 { 38 PluginManager::UnregisterPlugin (CreateInstance); 39 } 40 41 42 lldb_private::ConstString 43 SymbolFileSymtab::GetPluginNameStatic() 44 { 45 static ConstString g_name("symtab"); 46 return g_name; 47 } 48 49 const char * 50 SymbolFileSymtab::GetPluginDescriptionStatic() 51 { 52 return "Reads debug symbols from an object file's symbol table."; 53 } 54 55 56 SymbolFile* 57 SymbolFileSymtab::CreateInstance (ObjectFile* obj_file) 58 { 59 return new SymbolFileSymtab(obj_file); 60 } 61 62 size_t 63 SymbolFileSymtab::GetTypes (SymbolContextScope *sc_scope, uint32_t type_mask, lldb_private::TypeList &type_list) 64 { 65 return 0; 66 } 67 68 SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) : 69 SymbolFile(obj_file), 70 m_source_indexes(), 71 m_func_indexes(), 72 m_code_indexes(), 73 m_objc_class_name_to_index () 74 { 75 } 76 77 SymbolFileSymtab::~SymbolFileSymtab() 78 { 79 } 80 81 uint32_t 82 SymbolFileSymtab::CalculateAbilities () 83 { 84 uint32_t abilities = 0; 85 if (m_obj_file) 86 { 87 const Symtab *symtab = m_obj_file->GetSymtab(); 88 if (symtab) 89 { 90 //---------------------------------------------------------------------- 91 // The snippet of code below will get the indexes the module symbol 92 // table entries that are code, data, or function related (debug info), 93 // sort them by value (address) and dump the sorted symbols. 94 //---------------------------------------------------------------------- 95 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes)) 96 { 97 abilities |= CompileUnits; 98 } 99 100 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes)) 101 { 102 symtab->SortSymbolIndexesByValue(m_func_indexes, true); 103 abilities |= Functions; 104 } 105 106 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes)) 107 { 108 symtab->SortSymbolIndexesByValue(m_code_indexes, true); 109 abilities |= Functions; 110 } 111 112 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes)) 113 { 114 symtab->SortSymbolIndexesByValue(m_data_indexes, true); 115 abilities |= GlobalVariables; 116 } 117 118 lldb_private::Symtab::IndexCollection objc_class_indexes; 119 if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes)) 120 { 121 symtab->AppendSymbolNamesToMap (objc_class_indexes, 122 true, 123 true, 124 m_objc_class_name_to_index); 125 m_objc_class_name_to_index.Sort(); 126 } 127 } 128 } 129 return abilities; 130 } 131 132 uint32_t 133 SymbolFileSymtab::GetNumCompileUnits() 134 { 135 // If we don't have any source file symbols we will just have one compile unit for 136 // the entire object file 137 if (m_source_indexes.empty()) 138 return 0; 139 140 // If we have any source file symbols we will logically organize the object symbols 141 // using these. 142 return m_source_indexes.size(); 143 } 144 145 CompUnitSP 146 SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) 147 { 148 CompUnitSP cu_sp; 149 150 // If we don't have any source file symbols we will just have one compile unit for 151 // the entire object file 152 if (idx < m_source_indexes.size()) 153 { 154 const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); 155 if (cu_symbol) 156 cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0, eLanguageTypeUnknown, false)); 157 } 158 return cu_sp; 159 } 160 161 lldb::LanguageType 162 SymbolFileSymtab::ParseCompileUnitLanguage (const SymbolContext& sc) 163 { 164 return eLanguageTypeUnknown; 165 } 166 167 168 size_t 169 SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc) 170 { 171 size_t num_added = 0; 172 // We must at least have a valid compile unit 173 assert (sc.comp_unit != NULL); 174 const Symtab *symtab = m_obj_file->GetSymtab(); 175 const Symbol *curr_symbol = NULL; 176 const Symbol *next_symbol = NULL; 177 // const char *prefix = m_obj_file->SymbolPrefix(); 178 // if (prefix == NULL) 179 // prefix == ""; 180 // 181 // const uint32_t prefix_len = strlen(prefix); 182 183 // If we don't have any source file symbols we will just have one compile unit for 184 // the entire object file 185 if (m_source_indexes.empty()) 186 { 187 // The only time we will have a user ID of zero is when we don't have 188 // and source file symbols and we declare one compile unit for the 189 // entire object file 190 if (!m_func_indexes.empty()) 191 { 192 193 } 194 195 if (!m_code_indexes.empty()) 196 { 197 // StreamFile s(stdout); 198 // symtab->Dump(&s, m_code_indexes); 199 200 uint32_t idx = 0; // Index into the indexes 201 const uint32_t num_indexes = m_code_indexes.size(); 202 for (idx = 0; idx < num_indexes; ++idx) 203 { 204 uint32_t symbol_idx = m_code_indexes[idx]; 205 curr_symbol = symtab->SymbolAtIndex(symbol_idx); 206 if (curr_symbol) 207 { 208 // Union of all ranges in the function DIE (if the function is discontiguous) 209 AddressRange func_range(curr_symbol->GetAddress(), 0); 210 if (func_range.GetBaseAddress().IsSectionOffset()) 211 { 212 uint32_t symbol_size = curr_symbol->GetByteSize(); 213 if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling()) 214 func_range.SetByteSize(symbol_size); 215 else if (idx + 1 < num_indexes) 216 { 217 next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]); 218 if (next_symbol) 219 { 220 func_range.SetByteSize(next_symbol->GetAddressRef().GetOffset() - curr_symbol->GetAddressRef().GetOffset()); 221 } 222 } 223 224 FunctionSP func_sp(new Function(sc.comp_unit, 225 symbol_idx, // UserID is the DIE offset 226 LLDB_INVALID_UID, // We don't have any type info for this function 227 curr_symbol->GetMangled(), // Linker/mangled name 228 NULL, // no return type for a code symbol... 229 func_range)); // first address range 230 231 if (func_sp.get() != NULL) 232 { 233 sc.comp_unit->AddFunction(func_sp); 234 ++num_added; 235 } 236 } 237 } 238 } 239 240 } 241 } 242 else 243 { 244 // We assume we 245 } 246 return num_added; 247 } 248 249 bool 250 SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc) 251 { 252 return false; 253 } 254 255 bool 256 SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files) 257 { 258 return false; 259 } 260 261 bool 262 SymbolFileSymtab::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules) 263 { 264 return false; 265 } 266 267 size_t 268 SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc) 269 { 270 return 0; 271 } 272 273 274 size_t 275 SymbolFileSymtab::ParseTypes (const SymbolContext &sc) 276 { 277 return 0; 278 } 279 280 281 size_t 282 SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc) 283 { 284 return 0; 285 } 286 287 Type* 288 SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) 289 { 290 return NULL; 291 } 292 293 bool 294 SymbolFileSymtab::CompleteType (lldb_private::CompilerType& compiler_type) 295 { 296 return false; 297 } 298 299 uint32_t 300 SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 301 { 302 if (m_obj_file->GetSymtab() == NULL) 303 return 0; 304 305 uint32_t resolved_flags = 0; 306 if (resolve_scope & eSymbolContextSymbol) 307 { 308 sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); 309 if (sc.symbol) 310 resolved_flags |= eSymbolContextSymbol; 311 } 312 return resolved_flags; 313 } 314 315 //------------------------------------------------------------------ 316 // PluginInterface protocol 317 //------------------------------------------------------------------ 318 lldb_private::ConstString 319 SymbolFileSymtab::GetPluginName() 320 { 321 return GetPluginNameStatic(); 322 } 323 324 uint32_t 325 SymbolFileSymtab::GetPluginVersion() 326 { 327 return 1; 328 } 329