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