blob: e42553f155265111b42dce6afc02bf162f9dcaa6 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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/ObjectFile.h"
16#include "lldb/Symbol/Symtab.h"
17#include "lldb/Symbol/ObjectFile.h"
18#include "lldb/Symbol/Symbol.h"
19#include "lldb/Symbol/CompileUnit.h"
20#include "lldb/Symbol/SymbolContext.h"
21#include "lldb/Symbol/Function.h"
22
23using namespace lldb;
24using namespace lldb_private;
25
26void
27SymbolFileSymtab::Initialize()
28{
29 PluginManager::RegisterPlugin (GetPluginNameStatic(),
30 GetPluginDescriptionStatic(),
31 CreateInstance);
32}
33
34void
35SymbolFileSymtab::Terminate()
36{
37 PluginManager::UnregisterPlugin (CreateInstance);
38}
39
40
41const char *
42SymbolFileSymtab::GetPluginNameStatic()
43{
44 return "symbol-file.symtab";
45}
46
47const char *
48SymbolFileSymtab::GetPluginDescriptionStatic()
49{
50 return "Reads debug symbols from an object file's symbol table.";
51}
52
53
54SymbolFile*
55SymbolFileSymtab::CreateInstance (ObjectFile* obj_file)
56{
57 return new SymbolFileSymtab(obj_file);
58}
59
60SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) :
61 SymbolFile(obj_file),
62 m_source_indexes(),
63 m_func_indexes(),
64 m_code_indexes(),
65 m_data_indexes(),
66 m_addr_indexes()
67{
68}
69
70SymbolFileSymtab::~SymbolFileSymtab()
71{
72}
73
74
75uint32_t
76SymbolFileSymtab::GetAbilities ()
77{
78 uint32_t abilities = 0;
79 const Symtab *symtab = m_obj_file->GetSymtab();
80 if (symtab)
81 {
82
83 //----------------------------------------------------------------------
84 // The snippet of code below will get the indexes the module symbol
85 // table entries that are code, data, or function related (debug info),
86 // sort them by value (address) and dump the sorted symbols.
87 //----------------------------------------------------------------------
88 symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes);
89 if (!m_source_indexes.empty())
90 {
91 abilities |= CompileUnits;
92 }
Greg Clayton7c36fa02010-09-11 03:13:28 +000093 symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
Chris Lattner24943d22010-06-08 16:52:24 +000094 if (!m_func_indexes.empty())
95 {
96 symtab->SortSymbolIndexesByValue(m_func_indexes, true);
97 abilities |= Functions;
98 }
99
Greg Clayton7c36fa02010-09-11 03:13:28 +0000100 symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes);
Chris Lattner24943d22010-06-08 16:52:24 +0000101 if (!m_code_indexes.empty())
102 {
103 symtab->SortSymbolIndexesByValue(m_code_indexes, true);
104 abilities |= Labels;
105 }
106
107 symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes);
108
109 if (!m_data_indexes.empty())
110 {
111 symtab->SortSymbolIndexesByValue(m_data_indexes, true);
112 abilities |= GlobalVariables;
113 }
114 }
115
116 return abilities;
117}
118
119uint32_t
120SymbolFileSymtab::GetNumCompileUnits()
121{
122 // If we don't have any source file symbols we will just have one compile unit for
123 // the entire object file
124 if (m_source_indexes.empty())
125 return 1;
126
127 // If we have any source file symbols we will logically orgnize the object symbols
128 // using these.
129 return m_source_indexes.size();
130}
131
132CompUnitSP
133SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
134{
135 CompUnitSP cu_sp;
136
137 // If we don't have any source file symbols we will just have one compile unit for
138 // the entire object file
139 if (m_source_indexes.empty())
140 {
141 const FileSpec &obj_file_spec = m_obj_file->GetFileSpec();
142 if (obj_file_spec)
Greg Clayton9488b742010-07-28 02:04:09 +0000143 cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, eLanguageTypeUnknown));
Chris Lattner24943d22010-06-08 16:52:24 +0000144
145 }
146 else if (idx < m_source_indexes.size())
147 {
148 const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
149 if (cu_symbol)
Greg Clayton9488b742010-07-28 02:04:09 +0000150 cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown));
Chris Lattner24943d22010-06-08 16:52:24 +0000151 }
152 return cu_sp;
153}
154
155size_t
156SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
157{
158 size_t num_added = 0;
159 // We must at least have a valid compile unit
160 assert (sc.comp_unit != NULL);
161 const Symtab *symtab = m_obj_file->GetSymtab();
162 const Symbol *curr_symbol = NULL;
163 const Symbol *next_symbol = NULL;
164// const char *prefix = m_obj_file->SymbolPrefix();
165// if (prefix == NULL)
166// prefix == "";
167//
168// const uint32_t prefix_len = strlen(prefix);
169
170 // If we don't have any source file symbols we will just have one compile unit for
171 // the entire object file
172 if (m_source_indexes.empty())
173 {
174 // The only time we will have a user ID of zero is when we don't have
175 // and source file symbols and we declare one compile unit for the
176 // entire object file
177 if (!m_func_indexes.empty())
178 {
179
180 }
181
182 if (!m_code_indexes.empty())
183 {
184// StreamFile s(stdout);
185// symtab->Dump(&s, m_code_indexes);
186
187 uint32_t idx = 0; // Index into the indexes
188 const uint32_t num_indexes = m_code_indexes.size();
189 for (idx = 0; idx < num_indexes; ++idx)
190 {
191 uint32_t symbol_idx = m_code_indexes[idx];
192 curr_symbol = symtab->SymbolAtIndex(symbol_idx);
193 if (curr_symbol)
194 {
195 // Union of all ranges in the function DIE (if the function is discontiguous)
196 AddressRange func_range(curr_symbol->GetValue(), 0);
197 if (func_range.GetBaseAddress().IsSectionOffset())
198 {
199 uint32_t symbol_size = curr_symbol->GetByteSize();
200 if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
201 func_range.SetByteSize(symbol_size);
202 else if (idx + 1 < num_indexes)
203 {
204 next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
205 if (next_symbol)
206 {
207 func_range.SetByteSize(next_symbol->GetValue().GetOffset() - curr_symbol->GetValue().GetOffset());
208 }
209 }
210
211 FunctionSP func_sp(new Function(sc.comp_unit,
212 symbol_idx, // UserID is the DIE offset
213 LLDB_INVALID_UID, // We don't have any type info for this function
214 curr_symbol->GetMangled(), // Linker/mangled name
215 NULL, // no return type for a code symbol...
216 func_range)); // first address range
217
218 if (func_sp.get() != NULL)
219 {
220 sc.comp_unit->AddFunction(func_sp);
221 ++num_added;
222 }
223 }
224 }
225 }
226
227 }
228 }
229 else
230 {
231 // We assume we
232 }
233 return num_added;
234}
235
236bool
237SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc)
238{
239 return false;
240}
241
242bool
243SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
244{
245 return false;
246}
247
248size_t
249SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
250{
251 return 0;
252}
253
254
255size_t
256SymbolFileSymtab::ParseTypes (const SymbolContext &sc)
257{
258 return 0;
259}
260
261
262size_t
263SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc)
264{
265 return 0;
266}
267
268Type*
269SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid)
270{
271 return NULL;
272}
273
Greg Clayton462d4142010-09-29 01:12:09 +0000274lldb::clang_type_t
275SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type)
276{
277 return NULL;
278}
Chris Lattner24943d22010-06-08 16:52:24 +0000279
280
281uint32_t
282SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
283{
284 if (m_obj_file->GetSymtab() == NULL)
285 return 0;
286
287 uint32_t resolved_flags = 0;
288 if (resolve_scope & eSymbolContextSymbol)
289 {
290 sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
291 if (sc.symbol)
292 resolved_flags |= eSymbolContextSymbol;
293 }
294 return resolved_flags;
295}
296
297uint32_t
298SymbolFileSymtab::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
299{
300 return 0;
301}
302
303uint32_t
304SymbolFileSymtab::FindGlobalVariables(const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
305{
306 return 0;
307}
308
309uint32_t
310SymbolFileSymtab::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
311{
312 return 0;
313}
314
315uint32_t
Greg Clayton12bec712010-06-28 21:30:43 +0000316SymbolFileSymtab::FindFunctions(const ConstString &name, uint32_t name_type_mask, bool append, SymbolContextList& sc_list)
Chris Lattner24943d22010-06-08 16:52:24 +0000317{
318 Timer scoped_timer (__PRETTY_FUNCTION__,
319 "SymbolFileSymtab::FindFunctions (name = '%s')",
320 name.GetCString());
321
322 Symtab *symtab = m_obj_file->GetSymtab();
323 if (symtab)
324 {
325 const uint32_t start_size = sc_list.GetSize();
326 std::vector<uint32_t> symbol_indexes;
Greg Clayton7c36fa02010-09-11 03:13:28 +0000327 symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
Chris Lattner24943d22010-06-08 16:52:24 +0000328 const uint32_t num_matches = symbol_indexes.size();
329 if (num_matches)
330 {
331 SymbolContext sc(m_obj_file->GetModule());
332 for (uint32_t i=0; i<num_matches; i++)
333 {
334 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
335 sc_list.Append(sc);
336 }
337 }
338 return sc_list.GetSize() - start_size;
339 }
340 return 0;
341}
342
343uint32_t
344SymbolFileSymtab::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
345{
346 Timer scoped_timer (__PRETTY_FUNCTION__,
347 "SymbolFileSymtab::FindFunctions (regex = '%s')",
348 regex.GetText());
349
350 return 0;
351}
352
Greg Clayton960d6a42010-08-03 00:35:52 +0000353uint32_t
354SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::TypeList& types)
355{
356 if (!append)
357 types.Clear();
358
359 return 0;
360}
Chris Lattner24943d22010-06-08 16:52:24 +0000361//
362//uint32_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000363//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner24943d22010-06-08 16:52:24 +0000364//{
365// return 0;
366//}
367
368
369//------------------------------------------------------------------
370// PluginInterface protocol
371//------------------------------------------------------------------
372const char *
373SymbolFileSymtab::GetPluginName()
374{
375 return "SymbolFileSymtab";
376}
377
378const char *
379SymbolFileSymtab::GetShortPluginName()
380{
381 return GetPluginNameStatic();
382}
383
384uint32_t
385SymbolFileSymtab::GetPluginVersion()
386{
387 return 1;
388}
389
390void
391SymbolFileSymtab::GetPluginCommandHelp (const char *command, Stream *strm)
392{
393}
394
395Error
396SymbolFileSymtab::ExecutePluginCommand (Args &command, Stream *strm)
397{
398 Error error;
399 error.SetErrorString("No plug-in command are currently supported.");
400 return error;
401}
402
403Log *
404SymbolFileSymtab::EnablePluginLogging (Stream *strm, Args &command)
405{
406 return NULL;
407}
408