blob: 44f567e3c013e1c3536aa863a6abf27da252d0c8 [file] [log] [blame]
Chris Lattner30fdc8d2010-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(),
Greg Clayton1075aca2011-12-03 20:02:42 +000065 m_objc_class_name_to_index ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066{
67}
68
69SymbolFileSymtab::~SymbolFileSymtab()
70{
71}
72
Sean Callanan09ab4b72011-11-30 22:11:59 +000073ClangASTContext &
74SymbolFileSymtab::GetClangASTContext ()
75{
76 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
77
78 return ast;
79}
80
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081uint32_t
Sean Callananbfaf54d2011-12-03 04:38:43 +000082SymbolFileSymtab::CalculateAbilities ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083{
84 uint32_t abilities = 0;
Greg Clayton5861d3e2011-06-19 04:02:02 +000085 if (m_obj_file)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000086 {
Greg Clayton5861d3e2011-06-19 04:02:02 +000087 const Symtab *symtab = m_obj_file->GetSymtab();
88 if (symtab)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000089 {
Greg Clayton5861d3e2011-06-19 04:02:02 +000090 //----------------------------------------------------------------------
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 //----------------------------------------------------------------------
Greg Clayton1075aca2011-12-03 20:02:42 +000095 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes))
Greg Clayton5861d3e2011-06-19 04:02:02 +000096 {
97 abilities |= CompileUnits;
98 }
Greg Clayton1075aca2011-12-03 20:02:42 +000099
100 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes))
Greg Clayton5861d3e2011-06-19 04:02:02 +0000101 {
102 symtab->SortSymbolIndexesByValue(m_func_indexes, true);
103 abilities |= Functions;
104 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105
Greg Clayton1075aca2011-12-03 20:02:42 +0000106 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes))
Greg Clayton5861d3e2011-06-19 04:02:02 +0000107 {
108 symtab->SortSymbolIndexesByValue(m_code_indexes, true);
109 abilities |= Labels;
110 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111
Greg Clayton1075aca2011-12-03 20:02:42 +0000112 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes))
Greg Clayton5861d3e2011-06-19 04:02:02 +0000113 {
114 symtab->SortSymbolIndexesByValue(m_data_indexes, true);
115 abilities |= GlobalVariables;
116 }
Sean Callanan09ab4b72011-11-30 22:11:59 +0000117
Greg Clayton1075aca2011-12-03 20:02:42 +0000118 lldb_private::Symtab::IndexCollection objc_class_indexes;
119 if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes))
Sean Callanan09ab4b72011-11-30 22:11:59 +0000120 {
121 abilities |= RuntimeTypes;
Greg Clayton1075aca2011-12-03 20:02:42 +0000122 symtab->AppendSymbolNamesToMap (objc_class_indexes,
123 true,
124 true,
125 m_objc_class_name_to_index);
126 m_objc_class_name_to_index.Sort();
Sean Callanan09ab4b72011-11-30 22:11:59 +0000127 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128 }
129 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130 return abilities;
131}
132
133uint32_t
134SymbolFileSymtab::GetNumCompileUnits()
135{
136 // If we don't have any source file symbols we will just have one compile unit for
137 // the entire object file
138 if (m_source_indexes.empty())
Jim Ingham969795f2011-09-21 01:17:13 +0000139 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140
141 // If we have any source file symbols we will logically orgnize the object symbols
142 // using these.
143 return m_source_indexes.size();
144}
145
146CompUnitSP
147SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
148{
149 CompUnitSP cu_sp;
150
151 // If we don't have any source file symbols we will just have one compile unit for
152 // the entire object file
Jim Ingham969795f2011-09-21 01:17:13 +0000153// if (m_source_indexes.empty())
154// {
155// const FileSpec &obj_file_spec = m_obj_file->GetFileSpec();
156// if (obj_file_spec)
157// cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, eLanguageTypeUnknown));
158//
159// }
160 /* else */ if (idx < m_source_indexes.size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161 {
162 const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
163 if (cu_symbol)
Greg Clayton9e409562010-07-28 02:04:09 +0000164 cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165 }
166 return cu_sp;
167}
168
169size_t
170SymbolFileSymtab::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->GetValue(), 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->GetValue().GetOffset() - curr_symbol->GetValue().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
250bool
251SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc)
252{
253 return false;
254}
255
256bool
257SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
258{
259 return false;
260}
261
262size_t
263SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
264{
265 return 0;
266}
267
268
269size_t
270SymbolFileSymtab::ParseTypes (const SymbolContext &sc)
271{
272 return 0;
273}
274
275
276size_t
277SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc)
278{
279 return 0;
280}
281
282Type*
283SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid)
284{
285 return NULL;
286}
287
Greg Clayton1be10fc2010-09-29 01:12:09 +0000288lldb::clang_type_t
289SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type)
290{
291 return NULL;
292}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293
Greg Clayton526e5af2010-11-13 03:52:47 +0000294ClangNamespaceDecl
Sean Callanan213fdb82011-10-13 01:49:10 +0000295SymbolFileSymtab::FindNamespace (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +0000296{
Greg Clayton526e5af2010-11-13 03:52:47 +0000297 return ClangNamespaceDecl();
Greg Clayton96d7d742010-11-10 23:42:09 +0000298}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000299
300uint32_t
301SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
302{
303 if (m_obj_file->GetSymtab() == NULL)
304 return 0;
305
306 uint32_t resolved_flags = 0;
307 if (resolve_scope & eSymbolContextSymbol)
308 {
309 sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
310 if (sc.symbol)
311 resolved_flags |= eSymbolContextSymbol;
312 }
313 return resolved_flags;
314}
315
316uint32_t
317SymbolFileSymtab::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
318{
319 return 0;
320}
321
322uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +0000323SymbolFileSymtab::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000324{
325 return 0;
326}
327
328uint32_t
329SymbolFileSymtab::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
330{
331 return 0;
332}
333
334uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +0000335SymbolFileSymtab::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336{
337 Timer scoped_timer (__PRETTY_FUNCTION__,
338 "SymbolFileSymtab::FindFunctions (name = '%s')",
339 name.GetCString());
Greg Clayton931180e2011-01-27 06:44:37 +0000340 // If we ever support finding STABS or COFF debug info symbols,
341 // we will need to add support here. We are not trying to find symbols
342 // here, just "lldb_private::Function" objects that come from complete
343 // debug information. Any symbol queries should go through the symbol
344 // table itself in the module's object file.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345 return 0;
346}
347
348uint32_t
349SymbolFileSymtab::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
350{
351 Timer scoped_timer (__PRETTY_FUNCTION__,
352 "SymbolFileSymtab::FindFunctions (regex = '%s')",
353 regex.GetText());
Greg Clayton931180e2011-01-27 06:44:37 +0000354 // If we ever support finding STABS or COFF debug info symbols,
355 // we will need to add support here. We are not trying to find symbols
356 // here, just "lldb_private::Function" objects that come from complete
357 // debug information. Any symbol queries should go through the symbol
358 // table itself in the module's object file.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359 return 0;
360}
361
Sean Callanan596ab8e2011-12-02 03:41:39 +0000362static int CountMethodArgs(const char *method_signature)
363{
364 int num_args = 0;
365
366 for (const char *colon_pos = strchr(method_signature, ':');
367 colon_pos != NULL;
368 colon_pos = strchr(colon_pos + 1, ':'))
369 {
370 num_args++;
371 }
372
373 return num_args;
374}
375
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000376uint32_t
Greg Clayton1075aca2011-12-03 20:02:42 +0000377SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc,
378 const lldb_private::ConstString &name,
379 const ClangNamespaceDecl *namespace_decl,
380 bool append,
381 uint32_t max_matches,
382 lldb_private::TypeList& types)
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000383{
384 if (!append)
385 types.Clear();
Sean Callanan6c62c832011-12-08 02:08:40 +0000386
Greg Clayton1075aca2011-12-03 20:02:42 +0000387 if (!m_objc_class_name_to_index.IsEmpty())
Sean Callanan09ab4b72011-11-30 22:11:59 +0000388 {
Sean Callanan3ed3bca2011-12-02 18:06:45 +0000389 TypeMap::iterator iter = m_objc_class_types.find(name);
Sean Callanan596ab8e2011-12-02 03:41:39 +0000390
391 if (iter != m_objc_class_types.end())
392 {
393 types.Insert(iter->second);
394 return 1;
395 }
Sean Callanan09ab4b72011-11-30 22:11:59 +0000396
Greg Clayton1075aca2011-12-03 20:02:42 +0000397 const Symtab::NameToIndexMap::Entry *match = m_objc_class_name_to_index.FindFirstValueForName(name.GetCString());
398
399 if (match == NULL)
400 return 0;
401
Sean Callanan6c62c832011-12-08 02:08:40 +0000402 const bool isForwardDecl = false;
Sean Callanan09ab4b72011-11-30 22:11:59 +0000403 const bool isInternal = true;
404
Greg Clayton1075aca2011-12-03 20:02:42 +0000405 ClangASTContext &ast = GetClangASTContext();
Sean Callanan09ab4b72011-11-30 22:11:59 +0000406
Greg Clayton1075aca2011-12-03 20:02:42 +0000407 lldb::clang_type_t objc_object_type = ast.CreateObjCClass (name.AsCString(),
408 ast.GetTranslationUnitDecl(),
409 isForwardDecl,
410 isInternal);
Sean Callanan596ab8e2011-12-02 03:41:39 +0000411
Sean Callanan09ab4b72011-11-30 22:11:59 +0000412 Declaration decl;
413
Sean Callanan6c62c832011-12-08 02:08:40 +0000414 lldb::TypeSP type(new Type (iter->second,
Sean Callanan09ab4b72011-11-30 22:11:59 +0000415 this,
416 name,
Greg Clayton1075aca2011-12-03 20:02:42 +0000417 0, // byte_size
418 NULL, // SymbolContextScope*
419 0, // encoding_uid
Sean Callanan09ab4b72011-11-30 22:11:59 +0000420 Type::eEncodingInvalid,
421 decl,
422 objc_object_type,
Sean Callanan596ab8e2011-12-02 03:41:39 +0000423 Type::eResolveStateFull));
424
Sean Callanan3ed3bca2011-12-02 18:06:45 +0000425 m_objc_class_types[name] = type;
Sean Callanan09ab4b72011-11-30 22:11:59 +0000426
427 types.Insert(type);
428
429 return 1;
430 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000431
432 return 0;
433}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000434//
435//uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000436//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437//{
438// return 0;
439//}
440
441
442//------------------------------------------------------------------
443// PluginInterface protocol
444//------------------------------------------------------------------
445const char *
446SymbolFileSymtab::GetPluginName()
447{
448 return "SymbolFileSymtab";
449}
450
451const char *
452SymbolFileSymtab::GetShortPluginName()
453{
454 return GetPluginNameStatic();
455}
456
457uint32_t
458SymbolFileSymtab::GetPluginVersion()
459{
460 return 1;
461}