1 //===-- SymbolFileSymtab.cpp ------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
25 using namespace lldb_private;
28 SymbolFileSymtab::Initialize()
30 PluginManager::RegisterPlugin (GetPluginNameStatic(),
31 GetPluginDescriptionStatic(),
36 SymbolFileSymtab::Terminate()
38 PluginManager::UnregisterPlugin (CreateInstance);
42 lldb_private::ConstString
43 SymbolFileSymtab::GetPluginNameStatic()
45 static ConstString g_name("symtab");
50 SymbolFileSymtab::GetPluginDescriptionStatic()
52 return "Reads debug symbols from an object file's symbol table.";
57 SymbolFileSymtab::CreateInstance (ObjectFile* obj_file)
59 return new SymbolFileSymtab(obj_file);
63 SymbolFileSymtab::GetTypes (SymbolContextScope *sc_scope, uint32_t type_mask, lldb_private::TypeList &type_list)
68 SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) :
73 m_objc_class_name_to_index ()
77 SymbolFileSymtab::~SymbolFileSymtab()
82 SymbolFileSymtab::CalculateAbilities ()
84 uint32_t abilities = 0;
87 const Symtab *symtab = m_obj_file->GetSymtab();
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))
97 abilities |= CompileUnits;
100 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes))
102 symtab->SortSymbolIndexesByValue(m_func_indexes, true);
103 abilities |= Functions;
106 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes))
108 symtab->SortSymbolIndexesByValue(m_code_indexes, true);
109 abilities |= Functions;
112 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes))
114 symtab->SortSymbolIndexesByValue(m_data_indexes, true);
115 abilities |= GlobalVariables;
118 lldb_private::Symtab::IndexCollection objc_class_indexes;
119 if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes))
121 symtab->AppendSymbolNamesToMap (objc_class_indexes,
124 m_objc_class_name_to_index);
125 m_objc_class_name_to_index.Sort();
133 SymbolFileSymtab::GetNumCompileUnits()
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())
140 // If we have any source file symbols we will logically organize the object symbols
142 return m_source_indexes.size();
146 SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
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())
154 const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
156 cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0,
157 eLanguageTypeUnknown, eLazyBoolNo));
163 SymbolFileSymtab::ParseCompileUnitLanguage (const SymbolContext& sc)
165 return eLanguageTypeUnknown;
170 SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
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)
182 // const uint32_t prefix_len = strlen(prefix);
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())
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())
196 if (!m_code_indexes.empty())
198 // StreamFile s(stdout);
199 // symtab->Dump(&s, m_code_indexes);
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)
205 uint32_t symbol_idx = m_code_indexes[idx];
206 curr_symbol = symtab->SymbolAtIndex(symbol_idx);
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())
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)
218 next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
221 func_range.SetByteSize(next_symbol->GetAddressRef().GetOffset() - curr_symbol->GetAddressRef().GetOffset());
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
232 if (func_sp.get() != NULL)
234 sc.comp_unit->AddFunction(func_sp);
251 SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc)
257 SymbolFileSymtab::ParseCompileUnitDebugMacros (const SymbolContext &sc)
263 SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
269 SymbolFileSymtab::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules)
275 SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
282 SymbolFileSymtab::ParseTypes (const SymbolContext &sc)
289 SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc)
295 SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid)
301 SymbolFileSymtab::CompleteType (lldb_private::CompilerType& compiler_type)
307 SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
309 if (m_obj_file->GetSymtab() == NULL)
312 uint32_t resolved_flags = 0;
313 if (resolve_scope & eSymbolContextSymbol)
315 sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
317 resolved_flags |= eSymbolContextSymbol;
319 return resolved_flags;
322 //------------------------------------------------------------------
323 // PluginInterface protocol
324 //------------------------------------------------------------------
325 lldb_private::ConstString
326 SymbolFileSymtab::GetPluginName()
328 return GetPluginNameStatic();
332 SymbolFileSymtab::GetPluginVersion()