blob: d960dde30e6b949a40d635a28f41d1a6cd80e6a5 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- SymbolVendor.mm -----------------------------------------*- 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 "lldb/Symbol/SymbolVendor.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Module.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Symbol/ObjectFile.h"
19#include "lldb/Symbol/SymbolFile.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
24
25//----------------------------------------------------------------------
26// FindPlugin
27//
28// Platforms can register a callback to use when creating symbol
29// vendors to allow for complex debug information file setups, and to
30// also allow for finding separate debug information files.
31//----------------------------------------------------------------------
32SymbolVendor*
33SymbolVendor::FindPlugin (Module* module)
34{
35 std::auto_ptr<SymbolVendor> instance_ap;
36 //----------------------------------------------------------------------
37 // We currently only have one debug symbol parser...
38 //----------------------------------------------------------------------
39 SymbolVendorCreateInstance create_callback;
40 for (uint32_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(idx)) != NULL; ++idx)
41 {
42 instance_ap.reset(create_callback(module));
43
44 if (instance_ap.get())
45 {
46 // TODO: make sure this symbol vendor is what we want. We
47 // currently are just returning the first one we find, but
48 // we may want to call this function only when we have our
49 // main executable module and then give all symbol vendor
50 // plug-ins a chance to compete for who wins.
51 return instance_ap.release();
52 }
53 }
54 // The default implementation just tries to create debug information using the
55 // file representation for the module.
56 instance_ap.reset(new SymbolVendor(module));
57 if (instance_ap.get())
58 instance_ap->AddSymbolFileRepresendation(module->GetObjectFile());
59 return instance_ap.release();
60}
61
62//----------------------------------------------------------------------
63// SymbolVendor constructor
64//----------------------------------------------------------------------
65SymbolVendor::SymbolVendor(Module *module) :
66 ModuleChild(module),
67 m_mutex (Mutex::eMutexTypeRecursive),
68 m_type_list(),
69 m_compile_units(),
70 m_sym_file_ap()
71{
72 ObjectFile * objfile = module->GetObjectFile();
73 ConstString target_triple;
74 if (objfile && objfile->GetTargetTriple(target_triple))
75 {
76 m_type_list.GetClangASTContext().SetTargetTriple (target_triple.AsCString());
77 }
78}
79
80//----------------------------------------------------------------------
81// Destructor
82//----------------------------------------------------------------------
83SymbolVendor::~SymbolVendor()
84{
85}
86
87//----------------------------------------------------------------------
88// Add a represantion given an object file.
89//----------------------------------------------------------------------
90void
91SymbolVendor::AddSymbolFileRepresendation(ObjectFile *obj_file)
92{
93 Mutex::Locker locker(m_mutex);
94 if (obj_file != NULL)
95 m_sym_file_ap.reset(SymbolFile::FindPlugin(obj_file));
96}
97
98bool
Greg Claytonad60bf42010-10-12 02:24:53 +000099SymbolVendor::SetCompileUnitAtIndex (CompUnitSP& cu, uint32_t idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000100{
101 Mutex::Locker locker(m_mutex);
102 const uint32_t num_compile_units = GetNumCompileUnits();
103 if (idx < num_compile_units)
104 {
105 // Fire off an assertion if this compile unit already exists for now.
106 // The partial parsing should take care of only setting the compile
107 // unit once, so if this assertion fails, we need to make sure that
108 // we don't have a race condition, or have a second parse of the same
109 // compile unit.
110 assert(m_compile_units[idx].get() == NULL);
111 m_compile_units[idx] = cu;
112 return true;
113 }
114 return false;
115}
116
117uint32_t
118SymbolVendor::GetNumCompileUnits()
119{
120 Mutex::Locker locker(m_mutex);
121 if (m_compile_units.empty())
122 {
123 if (m_sym_file_ap.get())
124 {
125 // Resize our array of compile unit shared pointers -- which will
126 // each remain NULL until someone asks for the actual compile unit
127 // information. When this happens, the symbol file will be asked
128 // to parse this compile unit information.
129 m_compile_units.resize(m_sym_file_ap->GetNumCompileUnits());
130 }
131 }
132 return m_compile_units.size();
133}
134
135size_t
136SymbolVendor::ParseCompileUnitFunctions (const SymbolContext &sc)
137{
138 Mutex::Locker locker(m_mutex);
139 if (m_sym_file_ap.get())
140 return m_sym_file_ap->ParseCompileUnitFunctions(sc);
141 return 0;
142}
143
144bool
145SymbolVendor::ParseCompileUnitLineTable (const SymbolContext &sc)
146{
147 Mutex::Locker locker(m_mutex);
148 if (m_sym_file_ap.get())
149 return m_sym_file_ap->ParseCompileUnitLineTable(sc);
150 return false;
151}
152
153bool
154SymbolVendor::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
155{
156 Mutex::Locker locker(m_mutex);
157 if (m_sym_file_ap.get())
158 return m_sym_file_ap->ParseCompileUnitSupportFiles(sc, support_files);
159 return false;
160}
161
162size_t
163SymbolVendor::ParseFunctionBlocks (const SymbolContext &sc)
164{
165 Mutex::Locker locker(m_mutex);
166 if (m_sym_file_ap.get())
167 return m_sym_file_ap->ParseFunctionBlocks(sc);
168 return 0;
169}
170
171size_t
172SymbolVendor::ParseTypes (const SymbolContext &sc)
173{
174 Mutex::Locker locker(m_mutex);
175 if (m_sym_file_ap.get())
176 return m_sym_file_ap->ParseTypes(sc);
177 return 0;
178}
179
180size_t
181SymbolVendor::ParseVariablesForContext (const SymbolContext& sc)
182{
183 Mutex::Locker locker(m_mutex);
184 if (m_sym_file_ap.get())
185 return m_sym_file_ap->ParseVariablesForContext(sc);
186 return 0;
187}
188
189Type*
190SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid)
191{
192 Mutex::Locker locker(m_mutex);
193 if (m_sym_file_ap.get())
194 return m_sym_file_ap->ResolveTypeUID(type_uid);
195 return NULL;
196}
197
198
199uint32_t
200SymbolVendor::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
201{
202 Mutex::Locker locker(m_mutex);
203 if (m_sym_file_ap.get())
204 return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc);
205 return 0;
206}
207
208uint32_t
209SymbolVendor::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
210{
211 Mutex::Locker locker(m_mutex);
212 if (m_sym_file_ap.get())
213 return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
214 return 0;
215}
216
217uint32_t
218SymbolVendor::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
219{
220 Mutex::Locker locker(m_mutex);
221 if (m_sym_file_ap.get())
222 return m_sym_file_ap->FindGlobalVariables(name, append, max_matches, variables);
223 return 0;
224}
225
226uint32_t
227SymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
228{
229 Mutex::Locker locker(m_mutex);
230 if (m_sym_file_ap.get())
231 return m_sym_file_ap->FindGlobalVariables(regex, append, max_matches, variables);
232 return 0;
233}
234
235uint32_t
Greg Clayton12bec712010-06-28 21:30:43 +0000236SymbolVendor::FindFunctions(const ConstString &name, uint32_t name_type_mask, bool append, SymbolContextList& sc_list)
Chris Lattner24943d22010-06-08 16:52:24 +0000237{
238 Mutex::Locker locker(m_mutex);
239 if (m_sym_file_ap.get())
Greg Clayton12bec712010-06-28 21:30:43 +0000240 return m_sym_file_ap->FindFunctions(name, name_type_mask, append, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000241 return 0;
242}
243
244uint32_t
245SymbolVendor::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
246{
247 Mutex::Locker locker(m_mutex);
248 if (m_sym_file_ap.get())
249 return m_sym_file_ap->FindFunctions(regex, append, sc_list);
250 return 0;
251}
252
253
Greg Clayton960d6a42010-08-03 00:35:52 +0000254uint32_t
255SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
256{
257 Mutex::Locker locker(m_mutex);
258 if (m_sym_file_ap.get())
259 return m_sym_file_ap->FindTypes(sc, name, append, max_matches, types);
260 if (!append)
261 types.Clear();
262 return 0;
263}
Chris Lattner24943d22010-06-08 16:52:24 +0000264//
265//uint32_t
266//SymbolVendor::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types)
267//{
268// Mutex::Locker locker(m_mutex);
269// if (m_sym_file_ap.get())
270// {
271// lldb::user_id_t udt_uid = LLDB_INVALID_UID;
272//
273// if (encoding == Type::user_defined_type)
274// udt_uid = UserDefType::GetUserDefTypeUID(udt_name);
275//
276// return m_sym_file_ap->FindTypes(sc, regex, append, max_matches, encoding, udt_uid, types);
277// }
278// return 0;
279//}
280
281void
282SymbolVendor::Dump(Stream *s)
283{
284 Mutex::Locker locker(m_mutex);
285 bool show_context = false;
286
287 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
288 s->Indent();
289 s->PutCString("SymbolVendor");
290 if (m_sym_file_ap.get())
291 {
292 ObjectFile *objfile = m_sym_file_ap->GetObjectFile();
293 if (objfile)
294 {
295 const FileSpec &objfile_file_spec = objfile->GetFileSpec();
296 if (objfile_file_spec)
297 {
298 s->PutCString(" (");
299 objfile_file_spec.Dump(s);
300 s->PutChar(')');
301 }
302 }
303 }
304 s->EOL();
305 s->IndentMore();
306 m_type_list.Dump(s, show_context);
307
308 CompileUnitConstIter cu_pos, cu_end;
309 cu_end = m_compile_units.end();
310 for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos)
311 {
312 // We currently only dump the compile units that have been parsed
313 if (cu_pos->get())
314 (*cu_pos)->Dump(s, show_context);
315 }
316
317 s->IndentLess();
318
319}
320
321CompUnitSP
322SymbolVendor::GetCompileUnitAtIndex(uint32_t idx)
323{
324 Mutex::Locker locker(m_mutex);
325 CompUnitSP cu_sp;
326 const uint32_t num_compile_units = GetNumCompileUnits();
327 if (idx < num_compile_units)
328 {
329 cu_sp = m_compile_units[idx];
330 if (cu_sp.get() == NULL)
331 {
332 m_compile_units[idx] = m_sym_file_ap->ParseCompileUnitAtIndex(idx);
333 cu_sp = m_compile_units[idx];
334 }
335 }
336 return cu_sp;
337}
338
339
340//------------------------------------------------------------------
341// PluginInterface protocol
342//------------------------------------------------------------------
343const char *
344SymbolVendor::GetPluginName()
345{
346 return "SymbolVendor";
347}
348
349const char *
350SymbolVendor::GetShortPluginName()
351{
352 return "vendor-default";
353}
354
355uint32_t
356SymbolVendor::GetPluginVersion()
357{
358 return 1;
359}
360
361void
362SymbolVendor::GetPluginCommandHelp (const char *command, Stream *strm)
363{
364}
365
366Error
367SymbolVendor::ExecutePluginCommand (Args &command, Stream *strm)
368{
369 Error error;
370 error.SetErrorString("No plug-in command are currently supported.");
371 return error;
372}
373
374Log *
375SymbolVendor::EnablePluginLogging (Stream *strm, Args &command)
376{
377 return NULL;
378}
379
380