blob: a44d092f7df612e924c4c4dc68e7131926fbf55b [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(),
65 m_data_indexes(),
Sean Callanan09ab4b72011-11-30 22:11:59 +000066 m_addr_indexes(),
67 m_has_objc_symbols(eLazyBoolCalculate)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068{
69}
70
71SymbolFileSymtab::~SymbolFileSymtab()
72{
73}
74
Sean Callanan09ab4b72011-11-30 22:11:59 +000075ClangASTContext &
76SymbolFileSymtab::GetClangASTContext ()
77{
78 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
79
80 return ast;
81}
82
83bool
84SymbolFileSymtab::HasObjCSymbols ()
85{
86 if (m_has_objc_symbols == eLazyBoolCalculate)
87 {
88 if (m_obj_file->GetSectionList()->FindSectionByName(ConstString("__objc_data")))
89 m_has_objc_symbols = eLazyBoolYes;
90 else
91 m_has_objc_symbols = eLazyBoolNo;
92 }
93
94 return m_has_objc_symbols == eLazyBoolYes;
95}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096
97uint32_t
98SymbolFileSymtab::GetAbilities ()
99{
100 uint32_t abilities = 0;
Greg Clayton5861d3e2011-06-19 04:02:02 +0000101 if (m_obj_file)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000102 {
Greg Clayton5861d3e2011-06-19 04:02:02 +0000103 const Symtab *symtab = m_obj_file->GetSymtab();
104 if (symtab)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106
Greg Clayton5861d3e2011-06-19 04:02:02 +0000107 //----------------------------------------------------------------------
108 // The snippet of code below will get the indexes the module symbol
109 // table entries that are code, data, or function related (debug info),
110 // sort them by value (address) and dump the sorted symbols.
111 //----------------------------------------------------------------------
112 symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes);
113 if (!m_source_indexes.empty())
114 {
115 abilities |= CompileUnits;
116 }
117 symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
118 if (!m_func_indexes.empty())
119 {
120 symtab->SortSymbolIndexesByValue(m_func_indexes, true);
121 abilities |= Functions;
122 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000123
Greg Clayton5861d3e2011-06-19 04:02:02 +0000124 symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes);
125 if (!m_code_indexes.empty())
126 {
127 symtab->SortSymbolIndexesByValue(m_code_indexes, true);
128 abilities |= Labels;
129 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130
Greg Clayton5861d3e2011-06-19 04:02:02 +0000131 symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes);
132
133 if (!m_data_indexes.empty())
134 {
135 symtab->SortSymbolIndexesByValue(m_data_indexes, true);
136 abilities |= GlobalVariables;
137 }
Sean Callanan09ab4b72011-11-30 22:11:59 +0000138
139 if (HasObjCSymbols())
140 {
141 abilities |= RuntimeTypes;
142 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000143 }
144 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145 return abilities;
146}
147
148uint32_t
149SymbolFileSymtab::GetNumCompileUnits()
150{
151 // If we don't have any source file symbols we will just have one compile unit for
152 // the entire object file
153 if (m_source_indexes.empty())
Jim Ingham969795f2011-09-21 01:17:13 +0000154 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155
156 // If we have any source file symbols we will logically orgnize the object symbols
157 // using these.
158 return m_source_indexes.size();
159}
160
161CompUnitSP
162SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
163{
164 CompUnitSP cu_sp;
165
166 // If we don't have any source file symbols we will just have one compile unit for
167 // the entire object file
Jim Ingham969795f2011-09-21 01:17:13 +0000168// if (m_source_indexes.empty())
169// {
170// const FileSpec &obj_file_spec = m_obj_file->GetFileSpec();
171// if (obj_file_spec)
172// cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, eLanguageTypeUnknown));
173//
174// }
175 /* else */ if (idx < m_source_indexes.size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176 {
177 const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
178 if (cu_symbol)
Greg Clayton9e409562010-07-28 02:04:09 +0000179 cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180 }
181 return cu_sp;
182}
183
184size_t
185SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
186{
187 size_t num_added = 0;
188 // We must at least have a valid compile unit
189 assert (sc.comp_unit != NULL);
190 const Symtab *symtab = m_obj_file->GetSymtab();
191 const Symbol *curr_symbol = NULL;
192 const Symbol *next_symbol = NULL;
193// const char *prefix = m_obj_file->SymbolPrefix();
194// if (prefix == NULL)
195// prefix == "";
196//
197// const uint32_t prefix_len = strlen(prefix);
198
199 // If we don't have any source file symbols we will just have one compile unit for
200 // the entire object file
201 if (m_source_indexes.empty())
202 {
203 // The only time we will have a user ID of zero is when we don't have
204 // and source file symbols and we declare one compile unit for the
205 // entire object file
206 if (!m_func_indexes.empty())
207 {
208
209 }
210
211 if (!m_code_indexes.empty())
212 {
213// StreamFile s(stdout);
214// symtab->Dump(&s, m_code_indexes);
215
216 uint32_t idx = 0; // Index into the indexes
217 const uint32_t num_indexes = m_code_indexes.size();
218 for (idx = 0; idx < num_indexes; ++idx)
219 {
220 uint32_t symbol_idx = m_code_indexes[idx];
221 curr_symbol = symtab->SymbolAtIndex(symbol_idx);
222 if (curr_symbol)
223 {
224 // Union of all ranges in the function DIE (if the function is discontiguous)
225 AddressRange func_range(curr_symbol->GetValue(), 0);
226 if (func_range.GetBaseAddress().IsSectionOffset())
227 {
228 uint32_t symbol_size = curr_symbol->GetByteSize();
229 if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
230 func_range.SetByteSize(symbol_size);
231 else if (idx + 1 < num_indexes)
232 {
233 next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
234 if (next_symbol)
235 {
236 func_range.SetByteSize(next_symbol->GetValue().GetOffset() - curr_symbol->GetValue().GetOffset());
237 }
238 }
239
240 FunctionSP func_sp(new Function(sc.comp_unit,
241 symbol_idx, // UserID is the DIE offset
242 LLDB_INVALID_UID, // We don't have any type info for this function
243 curr_symbol->GetMangled(), // Linker/mangled name
244 NULL, // no return type for a code symbol...
245 func_range)); // first address range
246
247 if (func_sp.get() != NULL)
248 {
249 sc.comp_unit->AddFunction(func_sp);
250 ++num_added;
251 }
252 }
253 }
254 }
255
256 }
257 }
258 else
259 {
260 // We assume we
261 }
262 return num_added;
263}
264
265bool
266SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc)
267{
268 return false;
269}
270
271bool
272SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
273{
274 return false;
275}
276
277size_t
278SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
279{
280 return 0;
281}
282
283
284size_t
285SymbolFileSymtab::ParseTypes (const SymbolContext &sc)
286{
287 return 0;
288}
289
290
291size_t
292SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc)
293{
294 return 0;
295}
296
297Type*
298SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid)
299{
300 return NULL;
301}
302
Greg Clayton1be10fc2010-09-29 01:12:09 +0000303lldb::clang_type_t
304SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type)
305{
306 return NULL;
307}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000308
Greg Clayton526e5af2010-11-13 03:52:47 +0000309ClangNamespaceDecl
Sean Callanan213fdb82011-10-13 01:49:10 +0000310SymbolFileSymtab::FindNamespace (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +0000311{
Greg Clayton526e5af2010-11-13 03:52:47 +0000312 return ClangNamespaceDecl();
Greg Clayton96d7d742010-11-10 23:42:09 +0000313}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314
315uint32_t
316SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
317{
318 if (m_obj_file->GetSymtab() == NULL)
319 return 0;
320
321 uint32_t resolved_flags = 0;
322 if (resolve_scope & eSymbolContextSymbol)
323 {
324 sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
325 if (sc.symbol)
326 resolved_flags |= eSymbolContextSymbol;
327 }
328 return resolved_flags;
329}
330
331uint32_t
332SymbolFileSymtab::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
333{
334 return 0;
335}
336
337uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +0000338SymbolFileSymtab::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339{
340 return 0;
341}
342
343uint32_t
344SymbolFileSymtab::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
345{
346 return 0;
347}
348
349uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +0000350SymbolFileSymtab::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 +0000351{
352 Timer scoped_timer (__PRETTY_FUNCTION__,
353 "SymbolFileSymtab::FindFunctions (name = '%s')",
354 name.GetCString());
Greg Clayton931180e2011-01-27 06:44:37 +0000355 // If we ever support finding STABS or COFF debug info symbols,
356 // we will need to add support here. We are not trying to find symbols
357 // here, just "lldb_private::Function" objects that come from complete
358 // debug information. Any symbol queries should go through the symbol
359 // table itself in the module's object file.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360 return 0;
361}
362
363uint32_t
364SymbolFileSymtab::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
365{
366 Timer scoped_timer (__PRETTY_FUNCTION__,
367 "SymbolFileSymtab::FindFunctions (regex = '%s')",
368 regex.GetText());
Greg Clayton931180e2011-01-27 06:44:37 +0000369 // If we ever support finding STABS or COFF debug info symbols,
370 // we will need to add support here. We are not trying to find symbols
371 // here, just "lldb_private::Function" objects that come from complete
372 // debug information. Any symbol queries should go through the symbol
373 // table itself in the module's object file.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374 return 0;
375}
376
Sean Callanan596ab8e2011-12-02 03:41:39 +0000377static int CountMethodArgs(const char *method_signature)
378{
379 int num_args = 0;
380
381 for (const char *colon_pos = strchr(method_signature, ':');
382 colon_pos != NULL;
383 colon_pos = strchr(colon_pos + 1, ':'))
384 {
385 num_args++;
386 }
387
388 return num_args;
389}
390
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000391uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +0000392SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::TypeList& types)
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000393{
394 if (!append)
395 types.Clear();
Sean Callanan09ab4b72011-11-30 22:11:59 +0000396
397 if (HasObjCSymbols())
398 {
Sean Callanan3ed3bca2011-12-02 18:06:45 +0000399 TypeMap::iterator iter = m_objc_class_types.find(name);
Sean Callanan596ab8e2011-12-02 03:41:39 +0000400
401 if (iter != m_objc_class_types.end())
402 {
403 types.Insert(iter->second);
404 return 1;
405 }
406
Sean Callanan09ab4b72011-11-30 22:11:59 +0000407 std::string symbol_name("OBJC_CLASS_$_");
408 symbol_name.append(name.AsCString());
409 ConstString symbol_const_string(symbol_name.c_str());
410
411 std::vector<uint32_t> indices;
412
413 if (m_obj_file->GetSymtab()->FindAllSymbolsWithNameAndType(symbol_const_string, lldb::eSymbolTypeRuntime, indices) == 0)
414 return 0;
415
416 const bool isForwardDecl = false;
417 const bool isInternal = true;
418
419 ClangASTContext &clang_ast_ctx = GetClangASTContext();
420
421 lldb::clang_type_t objc_object_type = clang_ast_ctx.CreateObjCClass(name.AsCString(), clang_ast_ctx.GetTranslationUnitDecl(), isForwardDecl, isInternal);
Sean Callanan596ab8e2011-12-02 03:41:39 +0000422
423 const char *class_method_prefix = "^\\+\\[";
424 const char *instance_method_prefix = "^\\-\\[";
425 const char *method_suffix = " [a-zA-Z0-9:]+\\]$";
426
427 std::string class_method_regexp_str(class_method_prefix);
428 class_method_regexp_str.append(name.AsCString());
429 class_method_regexp_str.append(method_suffix);
430
431 RegularExpression class_method_regexp(class_method_regexp_str.c_str());
432
433 indices.clear();
434
435 lldb::clang_type_t unknown_type = clang_ast_ctx.GetUnknownAnyType();
436 std::vector<lldb::clang_type_t> arg_types;
437
438 if (m_obj_file->GetSymtab()->FindAllSymbolsMatchingRexExAndType(class_method_regexp, eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, indices) != 0)
439 {
440 for (std::vector<uint32_t>::iterator ii = indices.begin(), ie = indices.end();
441 ii != ie;
442 ++ii)
443 {
444 Symbol *symbol = m_obj_file->GetSymtab()->SymbolAtIndex(*ii);
445
446 if (!symbol)
447 continue;
448
449 const char *signature = symbol->GetName().AsCString();
450
451 int num_args = CountMethodArgs(signature);
452
453 while (arg_types.size() < num_args)
454 arg_types.push_back(unknown_type);
455
456 bool is_variadic = false;
457 unsigned type_quals = 0;
458
459 lldb::clang_type_t method_type = clang_ast_ctx.CreateFunctionType(unknown_type, arg_types.data(), num_args, is_variadic, type_quals);
460
461 clang_ast_ctx.AddMethodToObjCObjectType(objc_object_type, signature, method_type, eAccessPublic);
462 }
463 }
464
465 std::string instance_method_regexp_str(instance_method_prefix);
466 instance_method_regexp_str.append(name.AsCString());
467 instance_method_regexp_str.append(method_suffix);
468
469 RegularExpression instance_method_regexp(instance_method_regexp_str.c_str());
470
471 indices.clear();
472
473 if (m_obj_file->GetSymtab()->FindAllSymbolsMatchingRexExAndType(instance_method_regexp, eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, indices) != 0)
474 {
475 for (std::vector<uint32_t>::iterator ii = indices.begin(), ie = indices.end();
476 ii != ie;
477 ++ii)
478 {
479 Symbol *symbol = m_obj_file->GetSymtab()->SymbolAtIndex(*ii);
480
481 if (!symbol)
482 continue;
483
484 const char *signature = symbol->GetName().AsCString();
485
486 int num_args = CountMethodArgs(signature);
487
488 while (arg_types.size() < num_args)
489 arg_types.push_back(unknown_type);
490
491 bool is_variadic = false;
492 unsigned type_quals = 0;
493
494 lldb::clang_type_t method_type = clang_ast_ctx.CreateFunctionType(unknown_type, arg_types.data(), num_args, is_variadic, type_quals);
495
496 clang_ast_ctx.AddMethodToObjCObjectType(objc_object_type, signature, method_type, eAccessPublic);
497 }
498 }
Sean Callanan09ab4b72011-11-30 22:11:59 +0000499
500 Declaration decl;
501
502 lldb::TypeSP type(new Type (indices[0],
503 this,
504 name,
505 0 /*byte_size*/,
506 NULL /*SymbolContextScope*/,
507 0 /*encoding_uid*/,
508 Type::eEncodingInvalid,
509 decl,
510 objc_object_type,
Sean Callanan596ab8e2011-12-02 03:41:39 +0000511 Type::eResolveStateFull));
512
Sean Callanan3ed3bca2011-12-02 18:06:45 +0000513 m_objc_class_types[name] = type;
Sean Callanan09ab4b72011-11-30 22:11:59 +0000514
515 types.Insert(type);
516
517 return 1;
518 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000519
520 return 0;
521}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000522//
523//uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000524//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525//{
526// return 0;
527//}
528
529
530//------------------------------------------------------------------
531// PluginInterface protocol
532//------------------------------------------------------------------
533const char *
534SymbolFileSymtab::GetPluginName()
535{
536 return "SymbolFileSymtab";
537}
538
539const char *
540SymbolFileSymtab::GetShortPluginName()
541{
542 return GetPluginNameStatic();
543}
544
545uint32_t
546SymbolFileSymtab::GetPluginVersion()
547{
548 return 1;
549}