blob: 5404ab0f8fd7cc59c902fb0267d3c9e3d9c338b9 [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);
Greg Clayton5861d3e2011-06-19 04:02:02 +0000109 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110
Greg Clayton1075aca2011-12-03 20:02:42 +0000111 if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes))
Greg Clayton5861d3e2011-06-19 04:02:02 +0000112 {
113 symtab->SortSymbolIndexesByValue(m_data_indexes, true);
114 abilities |= GlobalVariables;
115 }
Sean Callanan09ab4b72011-11-30 22:11:59 +0000116
Greg Clayton1075aca2011-12-03 20:02:42 +0000117 lldb_private::Symtab::IndexCollection objc_class_indexes;
118 if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes))
Sean Callanan09ab4b72011-11-30 22:11:59 +0000119 {
Greg Clayton1075aca2011-12-03 20:02:42 +0000120 symtab->AppendSymbolNamesToMap (objc_class_indexes,
121 true,
122 true,
123 m_objc_class_name_to_index);
124 m_objc_class_name_to_index.Sort();
Sean Callanan09ab4b72011-11-30 22:11:59 +0000125 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126 }
127 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128 return abilities;
129}
130
131uint32_t
132SymbolFileSymtab::GetNumCompileUnits()
133{
134 // If we don't have any source file symbols we will just have one compile unit for
135 // the entire object file
136 if (m_source_indexes.empty())
Jim Ingham969795f2011-09-21 01:17:13 +0000137 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000138
139 // If we have any source file symbols we will logically orgnize the object symbols
140 // using these.
141 return m_source_indexes.size();
142}
143
144CompUnitSP
145SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
146{
147 CompUnitSP cu_sp;
148
149 // If we don't have any source file symbols we will just have one compile unit for
150 // the entire object file
Greg Clayton9efa0762012-04-26 16:53:42 +0000151 if (idx < m_source_indexes.size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152 {
153 const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
154 if (cu_symbol)
Greg Claytone72dfb32012-02-24 01:59:29 +0000155 cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156 }
157 return cu_sp;
158}
159
160size_t
161SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
162{
163 size_t num_added = 0;
164 // We must at least have a valid compile unit
165 assert (sc.comp_unit != NULL);
166 const Symtab *symtab = m_obj_file->GetSymtab();
167 const Symbol *curr_symbol = NULL;
168 const Symbol *next_symbol = NULL;
169// const char *prefix = m_obj_file->SymbolPrefix();
170// if (prefix == NULL)
171// prefix == "";
172//
173// const uint32_t prefix_len = strlen(prefix);
174
175 // If we don't have any source file symbols we will just have one compile unit for
176 // the entire object file
177 if (m_source_indexes.empty())
178 {
179 // The only time we will have a user ID of zero is when we don't have
180 // and source file symbols and we declare one compile unit for the
181 // entire object file
182 if (!m_func_indexes.empty())
183 {
184
185 }
186
187 if (!m_code_indexes.empty())
188 {
189// StreamFile s(stdout);
190// symtab->Dump(&s, m_code_indexes);
191
192 uint32_t idx = 0; // Index into the indexes
193 const uint32_t num_indexes = m_code_indexes.size();
194 for (idx = 0; idx < num_indexes; ++idx)
195 {
196 uint32_t symbol_idx = m_code_indexes[idx];
197 curr_symbol = symtab->SymbolAtIndex(symbol_idx);
198 if (curr_symbol)
199 {
200 // Union of all ranges in the function DIE (if the function is discontiguous)
Greg Claytone7612132012-03-07 21:03:09 +0000201 AddressRange func_range(curr_symbol->GetAddress(), 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000202 if (func_range.GetBaseAddress().IsSectionOffset())
203 {
204 uint32_t symbol_size = curr_symbol->GetByteSize();
205 if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
206 func_range.SetByteSize(symbol_size);
207 else if (idx + 1 < num_indexes)
208 {
209 next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
210 if (next_symbol)
211 {
Greg Claytone7612132012-03-07 21:03:09 +0000212 func_range.SetByteSize(next_symbol->GetAddress().GetOffset() - curr_symbol->GetAddress().GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213 }
214 }
215
216 FunctionSP func_sp(new Function(sc.comp_unit,
217 symbol_idx, // UserID is the DIE offset
218 LLDB_INVALID_UID, // We don't have any type info for this function
219 curr_symbol->GetMangled(), // Linker/mangled name
220 NULL, // no return type for a code symbol...
221 func_range)); // first address range
222
223 if (func_sp.get() != NULL)
224 {
225 sc.comp_unit->AddFunction(func_sp);
226 ++num_added;
227 }
228 }
229 }
230 }
231
232 }
233 }
234 else
235 {
236 // We assume we
237 }
238 return num_added;
239}
240
241bool
242SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc)
243{
244 return false;
245}
246
247bool
248SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
249{
250 return false;
251}
252
253size_t
254SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
255{
256 return 0;
257}
258
259
260size_t
261SymbolFileSymtab::ParseTypes (const SymbolContext &sc)
262{
263 return 0;
264}
265
266
267size_t
268SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc)
269{
270 return 0;
271}
272
273Type*
274SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid)
275{
276 return NULL;
277}
278
Greg Clayton1be10fc2010-09-29 01:12:09 +0000279lldb::clang_type_t
280SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type)
281{
282 return NULL;
283}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284
Greg Clayton526e5af2010-11-13 03:52:47 +0000285ClangNamespaceDecl
Sean Callanan213fdb82011-10-13 01:49:10 +0000286SymbolFileSymtab::FindNamespace (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +0000287{
Greg Clayton526e5af2010-11-13 03:52:47 +0000288 return ClangNamespaceDecl();
Greg Clayton96d7d742010-11-10 23:42:09 +0000289}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290
291uint32_t
292SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
293{
294 if (m_obj_file->GetSymtab() == NULL)
295 return 0;
296
297 uint32_t resolved_flags = 0;
298 if (resolve_scope & eSymbolContextSymbol)
299 {
300 sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
301 if (sc.symbol)
302 resolved_flags |= eSymbolContextSymbol;
303 }
304 return resolved_flags;
305}
306
307uint32_t
308SymbolFileSymtab::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
309{
310 return 0;
311}
312
313uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +0000314SymbolFileSymtab::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315{
316 return 0;
317}
318
319uint32_t
320SymbolFileSymtab::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
321{
322 return 0;
323}
324
325uint32_t
Sean Callanan9df05fb2012-02-10 22:52:19 +0000326SymbolFileSymtab::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327{
328 Timer scoped_timer (__PRETTY_FUNCTION__,
329 "SymbolFileSymtab::FindFunctions (name = '%s')",
330 name.GetCString());
Greg Clayton931180e2011-01-27 06:44:37 +0000331 // If we ever support finding STABS or COFF debug info symbols,
332 // we will need to add support here. We are not trying to find symbols
333 // here, just "lldb_private::Function" objects that come from complete
334 // debug information. Any symbol queries should go through the symbol
335 // table itself in the module's object file.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336 return 0;
337}
338
339uint32_t
Sean Callanan9df05fb2012-02-10 22:52:19 +0000340SymbolFileSymtab::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341{
342 Timer scoped_timer (__PRETTY_FUNCTION__,
343 "SymbolFileSymtab::FindFunctions (regex = '%s')",
344 regex.GetText());
Greg Clayton931180e2011-01-27 06:44:37 +0000345 // If we ever support finding STABS or COFF debug info symbols,
346 // we will need to add support here. We are not trying to find symbols
347 // here, just "lldb_private::Function" objects that come from complete
348 // debug information. Any symbol queries should go through the symbol
349 // table itself in the module's object file.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350 return 0;
351}
352
Sean Callanan596ab8e2011-12-02 03:41:39 +0000353static int CountMethodArgs(const char *method_signature)
354{
355 int num_args = 0;
356
357 for (const char *colon_pos = strchr(method_signature, ':');
358 colon_pos != NULL;
359 colon_pos = strchr(colon_pos + 1, ':'))
360 {
361 num_args++;
362 }
363
364 return num_args;
365}
366
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000367uint32_t
Greg Clayton1075aca2011-12-03 20:02:42 +0000368SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc,
369 const lldb_private::ConstString &name,
370 const ClangNamespaceDecl *namespace_decl,
371 bool append,
372 uint32_t max_matches,
373 lldb_private::TypeList& types)
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000374{
375 if (!append)
376 types.Clear();
Sean Callanan6c62c832011-12-08 02:08:40 +0000377
Greg Clayton1075aca2011-12-03 20:02:42 +0000378 if (!m_objc_class_name_to_index.IsEmpty())
Sean Callanan09ab4b72011-11-30 22:11:59 +0000379 {
Sean Callanan3ed3bca2011-12-02 18:06:45 +0000380 TypeMap::iterator iter = m_objc_class_types.find(name);
Sean Callanan596ab8e2011-12-02 03:41:39 +0000381
382 if (iter != m_objc_class_types.end())
383 {
384 types.Insert(iter->second);
385 return 1;
386 }
Sean Callanan09ab4b72011-11-30 22:11:59 +0000387
Greg Clayton1075aca2011-12-03 20:02:42 +0000388 const Symtab::NameToIndexMap::Entry *match = m_objc_class_name_to_index.FindFirstValueForName(name.GetCString());
389
390 if (match == NULL)
391 return 0;
392
Sean Callanan6c62c832011-12-08 02:08:40 +0000393 const bool isForwardDecl = false;
Sean Callanan09ab4b72011-11-30 22:11:59 +0000394 const bool isInternal = true;
395
Greg Clayton1075aca2011-12-03 20:02:42 +0000396 ClangASTContext &ast = GetClangASTContext();
Sean Callanan09ab4b72011-11-30 22:11:59 +0000397
Greg Clayton1075aca2011-12-03 20:02:42 +0000398 lldb::clang_type_t objc_object_type = ast.CreateObjCClass (name.AsCString(),
399 ast.GetTranslationUnitDecl(),
400 isForwardDecl,
Sean Callananad880762012-04-18 01:06:17 +0000401 isInternal,
402 0xffaaffaaffaaffaall);
Sean Callanan596ab8e2011-12-02 03:41:39 +0000403
Sean Callanan09ab4b72011-11-30 22:11:59 +0000404 Declaration decl;
405
Greg Claytone1cd1be2012-01-29 20:56:30 +0000406 lldb::TypeSP type(new Type (match->value,
Sean Callanan09ab4b72011-11-30 22:11:59 +0000407 this,
408 name,
Jim Ingham18f46292012-01-12 22:45:31 +0000409 0, // byte_size - don't change this from 0, we currently use that to identify these "synthetic" ObjC class types.
Greg Clayton1075aca2011-12-03 20:02:42 +0000410 NULL, // SymbolContextScope*
411 0, // encoding_uid
Sean Callanan09ab4b72011-11-30 22:11:59 +0000412 Type::eEncodingInvalid,
413 decl,
414 objc_object_type,
Sean Callanan596ab8e2011-12-02 03:41:39 +0000415 Type::eResolveStateFull));
416
Sean Callanan3ed3bca2011-12-02 18:06:45 +0000417 m_objc_class_types[name] = type;
Sean Callanan09ab4b72011-11-30 22:11:59 +0000418
419 types.Insert(type);
420
421 return 1;
422 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000423
424 return 0;
425}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000426//
427//uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000428//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429//{
430// return 0;
431//}
432
433
434//------------------------------------------------------------------
435// PluginInterface protocol
436//------------------------------------------------------------------
437const char *
438SymbolFileSymtab::GetPluginName()
439{
440 return "SymbolFileSymtab";
441}
442
443const char *
444SymbolFileSymtab::GetShortPluginName()
445{
446 return GetPluginNameStatic();
447}
448
449uint32_t
450SymbolFileSymtab::GetPluginVersion()
451{
452 return 1;
453}