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