blob: 19e300b72c24d74e1e82cd6d6648cc43b74acec1 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- PluginManager.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 "lldb/Core/PluginManager.h"
11
Stephen Wilson8acdbb82011-04-08 13:36:44 +000012#include <limits.h>
13
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014#include <string>
15#include <vector>
16
Greg Clayton4272cc72011-02-02 02:24:04 +000017#include "lldb/Core/Error.h"
Greg Clayton53239f02011-02-08 05:05:52 +000018#include "lldb/Host/FileSpec.h"
Greg Clayton4272cc72011-02-02 02:24:04 +000019#include "lldb/Host/Host.h"
20#include "lldb/Host/Mutex.h"
21
Greg Claytonab65b342011-04-13 22:47:15 +000022#include "llvm/ADT/StringRef.h"
23
Greg Clayton4272cc72011-02-02 02:24:04 +000024using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025using namespace lldb_private;
26
Jason Molenda743e86a2010-06-11 23:44:18 +000027enum PluginAction
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028{
29 ePluginRegisterInstance,
30 ePluginUnregisterInstance,
31 ePluginGetInstanceAtIndex
32};
33
Greg Clayton4272cc72011-02-02 02:24:04 +000034struct PluginInfo
35{
36 void *plugin_handle;
37 void *plugin_init_callback;
38 void *plugin_term_callback;
39};
40
41typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
42
43static Mutex &
44GetPluginMapMutex ()
45{
46 static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
47 return g_plugin_map_mutex;
48}
49
50static PluginTerminateMap &
51GetPluginMap ()
52{
53 static PluginTerminateMap g_plugin_map;
54 return g_plugin_map;
55}
56
57static bool
58PluginIsLoaded (const FileSpec &plugin_file_spec)
59{
60 Mutex::Locker locker (GetPluginMapMutex ());
61 PluginTerminateMap &plugin_map = GetPluginMap ();
62 return plugin_map.find (plugin_file_spec) != plugin_map.end();
63}
64
65static void
66SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
67{
68 Mutex::Locker locker (GetPluginMapMutex ());
69 PluginTerminateMap &plugin_map = GetPluginMap ();
70 assert (plugin_map.find (plugin_file_spec) != plugin_map.end());
71 plugin_map[plugin_file_spec] = plugin_info;
72}
73
74
75static FileSpec::EnumerateDirectoryResult
76LoadPluginCallback
77(
78 void *baton,
79 FileSpec::FileType file_type,
80 const FileSpec &file_spec
81)
82{
83// PluginManager *plugin_manager = (PluginManager *)baton;
84 Error error;
85
86 // If we have a regular file, a symbolic link or unknown file type, try
87 // and process the file. We must handle unknown as sometimes the directory
88 // enumeration might be enumerating a file system that doesn't have correct
89 // file type information.
90 if (file_type == FileSpec::eFileTypeRegular ||
91 file_type == FileSpec::eFileTypeSymbolicLink ||
92 file_type == FileSpec::eFileTypeUnknown )
93 {
94 FileSpec plugin_file_spec (file_spec);
95 plugin_file_spec.ResolvePath();
96
97 if (PluginIsLoaded (plugin_file_spec))
98 return FileSpec::eEnumerateDirectoryResultNext;
99 else
100 {
101 PluginInfo plugin_info = { NULL, NULL, NULL };
Greg Clayton45319462011-02-08 00:35:34 +0000102 uint32_t flags = Host::eDynamicLibraryOpenOptionLazy |
103 Host::eDynamicLibraryOpenOptionLocal |
104 Host::eDynamicLibraryOpenOptionLimitGetSymbol;
105
106 plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, flags, error);
Greg Clayton4272cc72011-02-02 02:24:04 +0000107 if (plugin_info.plugin_handle)
108 {
109 bool success = false;
110 plugin_info.plugin_init_callback = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error);
111 if (plugin_info.plugin_init_callback)
112 {
113 // Call the plug-in "bool LLDBPluginInitialize(void)" function
114 success = ((bool (*)(void))plugin_info.plugin_init_callback)();
115 }
116
117 if (success)
118 {
119 // It is ok for the "LLDBPluginTerminate" symbol to be NULL
120 plugin_info.plugin_term_callback = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error);
121 }
122 else
123 {
124 // The initialize function returned FALSE which means the
125 // plug-in might not be compatible, or might be too new or
126 // too old, or might not want to run on this machine.
127 Host::DynamicLibraryClose (plugin_info.plugin_handle);
128 plugin_info.plugin_handle = NULL;
129 plugin_info.plugin_init_callback = NULL;
130 }
131
132 // Regardless of success or failure, cache the plug-in load
133 // in our plug-in info so we don't try to load it again and
134 // again.
135 SetPluginInfo (plugin_file_spec, plugin_info);
136
137 return FileSpec::eEnumerateDirectoryResultNext;
138 }
139 }
140 }
141
142 if (file_type == FileSpec::eFileTypeUnknown ||
143 file_type == FileSpec::eFileTypeDirectory ||
144 file_type == FileSpec::eFileTypeSymbolicLink )
145 {
146 // Try and recurse into anything that a directory or symbolic link.
147 // We must also do this for unknown as sometimes the directory enumeration
148 // might be enurating a file system that doesn't have correct file type
149 // information.
150 return FileSpec::eEnumerateDirectoryResultEnter;
151 }
152
153 return FileSpec::eEnumerateDirectoryResultNext;
154}
155
156
157void
158PluginManager::Initialize ()
159{
Greg Clayton1cb64962011-03-24 04:28:38 +0000160#if 1
Greg Clayton4272cc72011-02-02 02:24:04 +0000161 FileSpec dir_spec;
162 const bool find_directories = true;
163 const bool find_files = true;
164 const bool find_other = true;
165 char dir_path[PATH_MAX];
166 if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
167 {
168 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
169 {
170 FileSpec::EnumerateDirectory (dir_path,
171 find_directories,
172 find_files,
173 find_other,
174 LoadPluginCallback,
175 NULL);
176 }
177 }
178
179 if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
180 {
181 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
182 {
183 FileSpec::EnumerateDirectory (dir_path,
184 find_directories,
185 find_files,
186 find_other,
187 LoadPluginCallback,
188 NULL);
189 }
190 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000191#endif
Greg Clayton4272cc72011-02-02 02:24:04 +0000192}
193
194void
195PluginManager::Terminate ()
196{
197 Mutex::Locker locker (GetPluginMapMutex ());
198 PluginTerminateMap &plugin_map = GetPluginMap ();
199
200 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
201 for (pos = plugin_map.begin(); pos != end; ++pos)
202 {
203 // Call the plug-in "void LLDBPluginTerminate (void)" function if there
204 // is one (if the symbol was not NULL).
205 if (pos->second.plugin_handle)
206 {
207 if (pos->second.plugin_term_callback)
208 ((void (*)(void))pos->second.plugin_term_callback)();
209 Host::DynamicLibraryClose (pos->second.plugin_handle);
210 }
211 }
212 plugin_map.clear();
213}
214
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215
216#pragma mark ABI
217
218
Jason Molenda743e86a2010-06-11 23:44:18 +0000219struct ABIInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220{
221 ABIInstance() :
222 name(),
223 description(),
224 create_callback(NULL)
225 {
226 }
227
228 std::string name;
229 std::string description;
230 ABICreateInstance create_callback;
231};
232
233typedef std::vector<ABIInstance> ABIInstances;
234
Greg Claytonded470d2011-03-19 01:12:21 +0000235static Mutex &
236GetABIInstancesMutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237{
Greg Claytonded470d2011-03-19 01:12:21 +0000238 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
239 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240}
241
Greg Claytonded470d2011-03-19 01:12:21 +0000242static ABIInstances &
243GetABIInstances ()
244{
245 static ABIInstances g_instances;
246 return g_instances;
247}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248
249bool
250PluginManager::RegisterPlugin
Greg Clayton4272cc72011-02-02 02:24:04 +0000251(
252 const char *name,
253 const char *description,
254 ABICreateInstance create_callback
255)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000256{
257 if (create_callback)
258 {
259 ABIInstance instance;
260 assert (name && name[0]);
Greg Claytonab65b342011-04-13 22:47:15 +0000261 instance.name.assign (name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262 if (description && description[0])
263 instance.description = description;
264 instance.create_callback = create_callback;
Greg Claytonded470d2011-03-19 01:12:21 +0000265 Mutex::Locker locker (GetABIInstancesMutex ());
266 GetABIInstances ().push_back (instance);
267 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268 }
269 return false;
270}
271
272bool
273PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
274{
275 if (create_callback)
276 {
Greg Claytonded470d2011-03-19 01:12:21 +0000277 Mutex::Locker locker (GetABIInstancesMutex ());
278 ABIInstances &instances = GetABIInstances ();
279
280 ABIInstances::iterator pos, end = instances.end();
281 for (pos = instances.begin(); pos != end; ++ pos)
282 {
283 if (pos->create_callback == create_callback)
284 {
285 instances.erase(pos);
286 return true;
287 }
288 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289 }
290 return false;
291}
292
293ABICreateInstance
294PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
295{
Greg Claytonded470d2011-03-19 01:12:21 +0000296 Mutex::Locker locker (GetABIInstancesMutex ());
297 ABIInstances &instances = GetABIInstances ();
Greg Claytonded470d2011-03-19 01:12:21 +0000298 if (idx < instances.size())
299 return instances[idx].create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000300 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301}
302
303ABICreateInstance
304PluginManager::GetABICreateCallbackForPluginName (const char *name)
305{
306 if (name && name[0])
307 {
Greg Claytonded470d2011-03-19 01:12:21 +0000308 Mutex::Locker locker (GetABIInstancesMutex ());
Greg Claytonab65b342011-04-13 22:47:15 +0000309 llvm::StringRef name_sref(name);
Greg Claytonded470d2011-03-19 01:12:21 +0000310 ABIInstances &instances = GetABIInstances ();
311
312 ABIInstances::iterator pos, end = instances.end();
313 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 {
Greg Claytonab65b342011-04-13 22:47:15 +0000315 if (name_sref.equals (pos->name))
Greg Claytonded470d2011-03-19 01:12:21 +0000316 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317 }
318 }
319 return NULL;
320}
321
322
323#pragma mark Disassembler
324
325
Jason Molenda743e86a2010-06-11 23:44:18 +0000326struct DisassemblerInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327{
328 DisassemblerInstance() :
329 name(),
330 description(),
331 create_callback(NULL)
332 {
333 }
334
335 std::string name;
336 std::string description;
337 DisassemblerCreateInstance create_callback;
338};
339
340typedef std::vector<DisassemblerInstance> DisassemblerInstances;
341
Greg Claytonab65b342011-04-13 22:47:15 +0000342static Mutex &
343GetDisassemblerMutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344{
Greg Claytonab65b342011-04-13 22:47:15 +0000345 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
346 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347}
348
Greg Claytonab65b342011-04-13 22:47:15 +0000349static DisassemblerInstances &
350GetDisassemblerInstances ()
351{
352 static DisassemblerInstances g_instances;
353 return g_instances;
354}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355
356bool
357PluginManager::RegisterPlugin
358(
359 const char *name,
360 const char *description,
361 DisassemblerCreateInstance create_callback
362)
363{
364 if (create_callback)
365 {
366 DisassemblerInstance instance;
367 assert (name && name[0]);
368 instance.name = name;
369 if (description && description[0])
370 instance.description = description;
371 instance.create_callback = create_callback;
Greg Claytonab65b342011-04-13 22:47:15 +0000372 Mutex::Locker locker (GetDisassemblerMutex ());
373 GetDisassemblerInstances ().push_back (instance);
374 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375 }
376 return false;
377}
378
379bool
380PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
381{
382 if (create_callback)
383 {
Greg Claytonab65b342011-04-13 22:47:15 +0000384 Mutex::Locker locker (GetDisassemblerMutex ());
385 DisassemblerInstances &instances = GetDisassemblerInstances ();
386
387 DisassemblerInstances::iterator pos, end = instances.end();
388 for (pos = instances.begin(); pos != end; ++ pos)
389 {
390 if (pos->create_callback == create_callback)
391 {
392 instances.erase(pos);
393 return true;
394 }
395 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396 }
397 return false;
398}
399
400DisassemblerCreateInstance
401PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
402{
Greg Claytonab65b342011-04-13 22:47:15 +0000403 Mutex::Locker locker (GetDisassemblerMutex ());
404 DisassemblerInstances &instances = GetDisassemblerInstances ();
405 if (idx < instances.size())
406 return instances[idx].create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000407 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000408}
409
410DisassemblerCreateInstance
411PluginManager::GetDisassemblerCreateCallbackForPluginName (const char *name)
412{
413 if (name && name[0])
414 {
Greg Claytonab65b342011-04-13 22:47:15 +0000415 llvm::StringRef name_sref(name);
416 Mutex::Locker locker (GetDisassemblerMutex ());
417 DisassemblerInstances &instances = GetDisassemblerInstances ();
418
419 DisassemblerInstances::iterator pos, end = instances.end();
420 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421 {
Greg Claytonab65b342011-04-13 22:47:15 +0000422 if (name_sref.equals (pos->name))
423 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424 }
425 }
426 return NULL;
427}
428
429
430
431#pragma mark DynamicLoader
432
433
Jason Molenda743e86a2010-06-11 23:44:18 +0000434struct DynamicLoaderInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435{
436 DynamicLoaderInstance() :
437 name(),
438 description(),
439 create_callback(NULL)
440 {
441 }
442
443 std::string name;
444 std::string description;
445 DynamicLoaderCreateInstance create_callback;
446};
447
448typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
449
Greg Claytonab65b342011-04-13 22:47:15 +0000450
451static Mutex &
452GetDynamicLoaderMutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453{
Greg Claytonab65b342011-04-13 22:47:15 +0000454 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
455 return g_instances_mutex;
456}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457
Greg Claytonab65b342011-04-13 22:47:15 +0000458static DynamicLoaderInstances &
459GetDynamicLoaderInstances ()
460{
461 static DynamicLoaderInstances g_instances;
462 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463}
464
465
466bool
467PluginManager::RegisterPlugin
468(
469 const char *name,
470 const char *description,
471 DynamicLoaderCreateInstance create_callback
472)
473{
474 if (create_callback)
475 {
476 DynamicLoaderInstance instance;
477 assert (name && name[0]);
478 instance.name = name;
479 if (description && description[0])
480 instance.description = description;
481 instance.create_callback = create_callback;
Greg Claytonab65b342011-04-13 22:47:15 +0000482 Mutex::Locker locker (GetDynamicLoaderMutex ());
483 GetDynamicLoaderInstances ().push_back (instance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484 }
485 return false;
486}
487
488bool
489PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
490{
491 if (create_callback)
492 {
Greg Claytonab65b342011-04-13 22:47:15 +0000493 Mutex::Locker locker (GetDynamicLoaderMutex ());
494 DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
495
496 DynamicLoaderInstances::iterator pos, end = instances.end();
497 for (pos = instances.begin(); pos != end; ++ pos)
498 {
499 if (pos->create_callback == create_callback)
500 {
501 instances.erase(pos);
502 return true;
503 }
504 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000505 }
506 return false;
507}
508
509DynamicLoaderCreateInstance
510PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
511{
Greg Claytonab65b342011-04-13 22:47:15 +0000512 Mutex::Locker locker (GetDynamicLoaderMutex ());
513 DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
514 if (idx < instances.size())
515 return instances[idx].create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000516 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517}
518
519DynamicLoaderCreateInstance
520PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const char *name)
521{
522 if (name && name[0])
523 {
Greg Claytonab65b342011-04-13 22:47:15 +0000524 llvm::StringRef name_sref(name);
525 Mutex::Locker locker (GetDynamicLoaderMutex ());
526 DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
527
528 DynamicLoaderInstances::iterator pos, end = instances.end();
529 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000530 {
Greg Claytonab65b342011-04-13 22:47:15 +0000531 if (name_sref.equals (pos->name))
532 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533 }
534 }
535 return NULL;
536}
537
Greg Claytonf03bbe22011-02-01 01:37:45 +0000538#pragma mark EmulateInstruction
539
540
541struct EmulateInstructionInstance
542{
543 EmulateInstructionInstance() :
544 name(),
545 description(),
546 create_callback(NULL)
547 {
548 }
549
550 std::string name;
551 std::string description;
552 EmulateInstructionCreateInstance create_callback;
553};
554
555typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
556
Greg Claytonab65b342011-04-13 22:47:15 +0000557static Mutex &
558GetEmulateInstructionMutex ()
Greg Claytonf03bbe22011-02-01 01:37:45 +0000559{
Greg Claytonab65b342011-04-13 22:47:15 +0000560 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
561 return g_instances_mutex;
562}
563
564static EmulateInstructionInstances &
565GetEmulateInstructionInstances ()
566{
567 static EmulateInstructionInstances g_instances;
568 return g_instances;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000569}
570
571
572bool
573PluginManager::RegisterPlugin
574(
Greg Clayton4272cc72011-02-02 02:24:04 +0000575 const char *name,
576 const char *description,
577 EmulateInstructionCreateInstance create_callback
578)
Greg Claytonf03bbe22011-02-01 01:37:45 +0000579{
580 if (create_callback)
581 {
582 EmulateInstructionInstance instance;
583 assert (name && name[0]);
584 instance.name = name;
585 if (description && description[0])
586 instance.description = description;
587 instance.create_callback = create_callback;
Greg Claytonab65b342011-04-13 22:47:15 +0000588 Mutex::Locker locker (GetEmulateInstructionMutex ());
589 GetEmulateInstructionInstances ().push_back (instance);
Greg Claytonf03bbe22011-02-01 01:37:45 +0000590 }
591 return false;
592}
593
594bool
595PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
596{
597 if (create_callback)
598 {
Greg Claytonab65b342011-04-13 22:47:15 +0000599 Mutex::Locker locker (GetEmulateInstructionMutex ());
600 EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
601
602 EmulateInstructionInstances::iterator pos, end = instances.end();
603 for (pos = instances.begin(); pos != end; ++ pos)
604 {
605 if (pos->create_callback == create_callback)
606 {
607 instances.erase(pos);
608 return true;
609 }
610 }
Greg Claytonf03bbe22011-02-01 01:37:45 +0000611 }
612 return false;
613}
614
615EmulateInstructionCreateInstance
616PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
617{
Greg Claytonab65b342011-04-13 22:47:15 +0000618 Mutex::Locker locker (GetEmulateInstructionMutex ());
619 EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
620 if (idx < instances.size())
621 return instances[idx].create_callback;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000622 return NULL;
623}
624
625EmulateInstructionCreateInstance
626PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const char *name)
627{
628 if (name && name[0])
629 {
Greg Claytonab65b342011-04-13 22:47:15 +0000630 llvm::StringRef name_sref(name);
631 Mutex::Locker locker (GetEmulateInstructionMutex ());
632 EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
633
634 EmulateInstructionInstances::iterator pos, end = instances.end();
635 for (pos = instances.begin(); pos != end; ++ pos)
Greg Claytonf03bbe22011-02-01 01:37:45 +0000636 {
Greg Claytonab65b342011-04-13 22:47:15 +0000637 if (name_sref.equals (pos->name))
638 return pos->create_callback;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000639 }
640 }
641 return NULL;
642}
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000643#pragma mark OperatingSystem
644
645
646struct OperatingSystemInstance
647{
648 OperatingSystemInstance() :
649 name(),
650 description(),
651 create_callback(NULL)
652 {
653 }
654
655 std::string name;
656 std::string description;
657 OperatingSystemCreateInstance create_callback;
658};
659
660typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
661
662static Mutex &
663GetOperatingSystemMutex ()
664{
665 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
666 return g_instances_mutex;
667}
668
669static OperatingSystemInstances &
670GetOperatingSystemInstances ()
671{
672 static OperatingSystemInstances g_instances;
673 return g_instances;
674}
675
676bool
677PluginManager::RegisterPlugin
678(
679 const char *name,
680 const char *description,
681 OperatingSystemCreateInstance create_callback
682 )
683{
684 if (create_callback)
685 {
686 OperatingSystemInstance instance;
687 assert (name && name[0]);
688 instance.name = name;
689 if (description && description[0])
690 instance.description = description;
691 instance.create_callback = create_callback;
692 Mutex::Locker locker (GetOperatingSystemMutex ());
693 GetOperatingSystemInstances ().push_back (instance);
694 }
695 return false;
696}
697
698bool
699PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
700{
701 if (create_callback)
702 {
703 Mutex::Locker locker (GetOperatingSystemMutex ());
704 OperatingSystemInstances &instances = GetOperatingSystemInstances ();
705
706 OperatingSystemInstances::iterator pos, end = instances.end();
707 for (pos = instances.begin(); pos != end; ++ pos)
708 {
709 if (pos->create_callback == create_callback)
710 {
711 instances.erase(pos);
712 return true;
713 }
714 }
715 }
716 return false;
717}
718
719OperatingSystemCreateInstance
720PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
721{
722 Mutex::Locker locker (GetOperatingSystemMutex ());
723 OperatingSystemInstances &instances = GetOperatingSystemInstances ();
724 if (idx < instances.size())
725 return instances[idx].create_callback;
726 return NULL;
727}
728
729OperatingSystemCreateInstance
730PluginManager::GetOperatingSystemCreateCallbackForPluginName (const char *name)
731{
732 if (name && name[0])
733 {
734 llvm::StringRef name_sref(name);
735 Mutex::Locker locker (GetOperatingSystemMutex ());
736 OperatingSystemInstances &instances = GetOperatingSystemInstances ();
737
738 OperatingSystemInstances::iterator pos, end = instances.end();
739 for (pos = instances.begin(); pos != end; ++ pos)
740 {
741 if (name_sref.equals (pos->name))
742 return pos->create_callback;
743 }
744 }
745 return NULL;
746}
Greg Claytonf03bbe22011-02-01 01:37:45 +0000747
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000748
Jim Ingham22777012010-09-23 02:01:19 +0000749#pragma mark LanguageRuntime
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000750
751
Jim Ingham22777012010-09-23 02:01:19 +0000752struct LanguageRuntimeInstance
753{
754 LanguageRuntimeInstance() :
755 name(),
756 description(),
757 create_callback(NULL)
758 {
759 }
760
761 std::string name;
762 std::string description;
763 LanguageRuntimeCreateInstance create_callback;
764};
765
766typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
767
Greg Claytonab65b342011-04-13 22:47:15 +0000768static Mutex &
769GetLanguageRuntimeMutex ()
Jim Ingham22777012010-09-23 02:01:19 +0000770{
Greg Claytonab65b342011-04-13 22:47:15 +0000771 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
772 return g_instances_mutex;
Jim Ingham22777012010-09-23 02:01:19 +0000773}
774
Greg Claytonab65b342011-04-13 22:47:15 +0000775static LanguageRuntimeInstances &
776GetLanguageRuntimeInstances ()
777{
778 static LanguageRuntimeInstances g_instances;
779 return g_instances;
780}
Jim Ingham22777012010-09-23 02:01:19 +0000781
782bool
783PluginManager::RegisterPlugin
Greg Clayton4272cc72011-02-02 02:24:04 +0000784(
785 const char *name,
786 const char *description,
787 LanguageRuntimeCreateInstance create_callback
788)
Jim Ingham22777012010-09-23 02:01:19 +0000789{
790 if (create_callback)
791 {
792 LanguageRuntimeInstance instance;
793 assert (name && name[0]);
794 instance.name = name;
795 if (description && description[0])
796 instance.description = description;
797 instance.create_callback = create_callback;
Greg Claytonab65b342011-04-13 22:47:15 +0000798 Mutex::Locker locker (GetLanguageRuntimeMutex ());
799 GetLanguageRuntimeInstances ().push_back (instance);
Jim Ingham22777012010-09-23 02:01:19 +0000800 }
801 return false;
802}
803
804bool
805PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
806{
807 if (create_callback)
808 {
Greg Claytonab65b342011-04-13 22:47:15 +0000809 Mutex::Locker locker (GetLanguageRuntimeMutex ());
810 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
811
812 LanguageRuntimeInstances::iterator pos, end = instances.end();
813 for (pos = instances.begin(); pos != end; ++ pos)
814 {
815 if (pos->create_callback == create_callback)
816 {
817 instances.erase(pos);
818 return true;
819 }
820 }
Jim Ingham22777012010-09-23 02:01:19 +0000821 }
822 return false;
823}
824
825LanguageRuntimeCreateInstance
826PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
827{
Greg Claytonab65b342011-04-13 22:47:15 +0000828 Mutex::Locker locker (GetLanguageRuntimeMutex ());
829 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
830 if (idx < instances.size())
831 return instances[idx].create_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000832 return NULL;
833}
834
835LanguageRuntimeCreateInstance
836PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const char *name)
837{
838 if (name && name[0])
839 {
Greg Claytonab65b342011-04-13 22:47:15 +0000840 llvm::StringRef name_sref(name);
841 Mutex::Locker locker (GetLanguageRuntimeMutex ());
842 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
843
844 LanguageRuntimeInstances::iterator pos, end = instances.end();
845 for (pos = instances.begin(); pos != end; ++ pos)
Jim Ingham22777012010-09-23 02:01:19 +0000846 {
Greg Claytonab65b342011-04-13 22:47:15 +0000847 if (name_sref.equals (pos->name))
848 return pos->create_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000849 }
850 }
851 return NULL;
852}
853
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000854#pragma mark ObjectFile
855
Jason Molenda743e86a2010-06-11 23:44:18 +0000856struct ObjectFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857{
858 ObjectFileInstance() :
859 name(),
860 description(),
861 create_callback(NULL)
862 {
863 }
864
865 std::string name;
866 std::string description;
867 ObjectFileCreateInstance create_callback;
868};
869
870typedef std::vector<ObjectFileInstance> ObjectFileInstances;
871
Greg Claytonab65b342011-04-13 22:47:15 +0000872static Mutex &
873GetObjectFileMutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874{
Greg Claytonab65b342011-04-13 22:47:15 +0000875 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
876 return g_instances_mutex;
877}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000878
Greg Claytonab65b342011-04-13 22:47:15 +0000879static ObjectFileInstances &
880GetObjectFileInstances ()
881{
882 static ObjectFileInstances g_instances;
883 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000884}
885
886
887bool
888PluginManager::RegisterPlugin
889(
890 const char *name,
891 const char *description,
892 ObjectFileCreateInstance create_callback
893)
894{
895 if (create_callback)
896 {
897 ObjectFileInstance instance;
898 assert (name && name[0]);
899 instance.name = name;
900 if (description && description[0])
901 instance.description = description;
902 instance.create_callback = create_callback;
Greg Claytonab65b342011-04-13 22:47:15 +0000903 Mutex::Locker locker (GetObjectFileMutex ());
904 GetObjectFileInstances ().push_back (instance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000905 }
906 return false;
907}
908
909bool
910PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
911{
912 if (create_callback)
913 {
Greg Claytonab65b342011-04-13 22:47:15 +0000914 Mutex::Locker locker (GetObjectFileMutex ());
915 ObjectFileInstances &instances = GetObjectFileInstances ();
916
917 ObjectFileInstances::iterator pos, end = instances.end();
918 for (pos = instances.begin(); pos != end; ++ pos)
919 {
920 if (pos->create_callback == create_callback)
921 {
922 instances.erase(pos);
923 return true;
924 }
925 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000926 }
927 return false;
928}
929
930ObjectFileCreateInstance
931PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
932{
Greg Claytonab65b342011-04-13 22:47:15 +0000933 Mutex::Locker locker (GetObjectFileMutex ());
934 ObjectFileInstances &instances = GetObjectFileInstances ();
935 if (idx < instances.size())
936 return instances[idx].create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000937 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000938}
Greg Claytonab65b342011-04-13 22:47:15 +0000939
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000940ObjectFileCreateInstance
941PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name)
942{
943 if (name && name[0])
944 {
Greg Claytonab65b342011-04-13 22:47:15 +0000945 llvm::StringRef name_sref(name);
946 Mutex::Locker locker (GetObjectFileMutex ());
947 ObjectFileInstances &instances = GetObjectFileInstances ();
948
949 ObjectFileInstances::iterator pos, end = instances.end();
950 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000951 {
Greg Claytonab65b342011-04-13 22:47:15 +0000952 if (name_sref.equals (pos->name))
953 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000954 }
955 }
956 return NULL;
957}
958
959
960
961#pragma mark ObjectContainer
962
Jason Molenda743e86a2010-06-11 23:44:18 +0000963struct ObjectContainerInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000964{
965 ObjectContainerInstance() :
966 name(),
967 description(),
968 create_callback(NULL)
969 {
970 }
971
972 std::string name;
973 std::string description;
974 ObjectContainerCreateInstance create_callback;
975};
976
977typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
978
Greg Claytonab65b342011-04-13 22:47:15 +0000979static Mutex &
980GetObjectContainerMutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981{
Greg Claytonab65b342011-04-13 22:47:15 +0000982 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
983 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000984}
985
Greg Claytonab65b342011-04-13 22:47:15 +0000986static ObjectContainerInstances &
987GetObjectContainerInstances ()
988{
989 static ObjectContainerInstances g_instances;
990 return g_instances;
991}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000992
993bool
994PluginManager::RegisterPlugin
995(
996 const char *name,
997 const char *description,
998 ObjectContainerCreateInstance create_callback
999)
1000{
1001 if (create_callback)
1002 {
1003 ObjectContainerInstance instance;
1004 assert (name && name[0]);
1005 instance.name = name;
1006 if (description && description[0])
1007 instance.description = description;
1008 instance.create_callback = create_callback;
Greg Claytonab65b342011-04-13 22:47:15 +00001009 Mutex::Locker locker (GetObjectContainerMutex ());
1010 GetObjectContainerInstances ().push_back (instance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011 }
1012 return false;
1013}
1014
1015bool
1016PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1017{
1018 if (create_callback)
1019 {
Greg Claytonab65b342011-04-13 22:47:15 +00001020 Mutex::Locker locker (GetObjectContainerMutex ());
1021 ObjectContainerInstances &instances = GetObjectContainerInstances ();
1022
1023 ObjectContainerInstances::iterator pos, end = instances.end();
1024 for (pos = instances.begin(); pos != end; ++ pos)
1025 {
1026 if (pos->create_callback == create_callback)
1027 {
1028 instances.erase(pos);
1029 return true;
1030 }
1031 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001032 }
1033 return false;
1034}
1035
1036ObjectContainerCreateInstance
1037PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1038{
Greg Claytonab65b342011-04-13 22:47:15 +00001039 Mutex::Locker locker (GetObjectContainerMutex ());
1040 ObjectContainerInstances &instances = GetObjectContainerInstances ();
1041 if (idx < instances.size())
1042 return instances[idx].create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001043 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001044}
Greg Claytonab65b342011-04-13 22:47:15 +00001045
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046ObjectContainerCreateInstance
1047PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name)
1048{
1049 if (name && name[0])
1050 {
Greg Claytonab65b342011-04-13 22:47:15 +00001051 llvm::StringRef name_sref(name);
1052 Mutex::Locker locker (GetObjectContainerMutex ());
1053 ObjectContainerInstances &instances = GetObjectContainerInstances ();
1054
1055 ObjectContainerInstances::iterator pos, end = instances.end();
1056 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001057 {
Greg Claytonab65b342011-04-13 22:47:15 +00001058 if (name_sref.equals (pos->name))
1059 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001060 }
1061 }
1062 return NULL;
1063}
1064
1065#pragma mark LogChannel
1066
Greg Claytonab65b342011-04-13 22:47:15 +00001067struct LogInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001068{
Greg Claytonab65b342011-04-13 22:47:15 +00001069 LogInstance() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001070 name(),
1071 description(),
1072 create_callback(NULL)
1073 {
1074 }
1075
1076 std::string name;
1077 std::string description;
1078 LogChannelCreateInstance create_callback;
1079};
1080
Greg Claytonab65b342011-04-13 22:47:15 +00001081typedef std::vector<LogInstance> LogInstances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082
Greg Claytonab65b342011-04-13 22:47:15 +00001083static Mutex &
1084GetLogMutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001085{
Greg Claytonab65b342011-04-13 22:47:15 +00001086 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1087 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001088}
1089
Greg Claytonab65b342011-04-13 22:47:15 +00001090static LogInstances &
1091GetLogInstances ()
1092{
1093 static LogInstances g_instances;
1094 return g_instances;
1095}
1096
1097
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001098
1099bool
1100PluginManager::RegisterPlugin
1101(
1102 const char *name,
1103 const char *description,
1104 LogChannelCreateInstance create_callback
1105)
1106{
1107 if (create_callback)
1108 {
Greg Claytonab65b342011-04-13 22:47:15 +00001109 LogInstance instance;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001110 assert (name && name[0]);
1111 instance.name = name;
1112 if (description && description[0])
1113 instance.description = description;
1114 instance.create_callback = create_callback;
Greg Claytonab65b342011-04-13 22:47:15 +00001115 Mutex::Locker locker (GetLogMutex ());
1116 GetLogInstances ().push_back (instance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001117 }
1118 return false;
1119}
1120
1121bool
1122PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1123{
1124 if (create_callback)
1125 {
Greg Claytonab65b342011-04-13 22:47:15 +00001126 Mutex::Locker locker (GetLogMutex ());
1127 LogInstances &instances = GetLogInstances ();
1128
1129 LogInstances::iterator pos, end = instances.end();
1130 for (pos = instances.begin(); pos != end; ++ pos)
1131 {
1132 if (pos->create_callback == create_callback)
1133 {
1134 instances.erase(pos);
1135 return true;
1136 }
1137 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001138 }
1139 return false;
1140}
1141
1142const char *
1143PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1144{
Greg Claytonab65b342011-04-13 22:47:15 +00001145 Mutex::Locker locker (GetLogMutex ());
1146 LogInstances &instances = GetLogInstances ();
1147 if (idx < instances.size())
1148 return instances[idx].name.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001149 return NULL;
1150}
1151
1152
1153LogChannelCreateInstance
1154PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1155{
Greg Claytonab65b342011-04-13 22:47:15 +00001156 Mutex::Locker locker (GetLogMutex ());
1157 LogInstances &instances = GetLogInstances ();
1158 if (idx < instances.size())
1159 return instances[idx].create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001160 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001161}
1162
1163LogChannelCreateInstance
1164PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name)
1165{
1166 if (name && name[0])
1167 {
Greg Claytonab65b342011-04-13 22:47:15 +00001168 llvm::StringRef name_sref(name);
1169 Mutex::Locker locker (GetLogMutex ());
1170 LogInstances &instances = GetLogInstances ();
1171
1172 LogInstances::iterator pos, end = instances.end();
1173 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001174 {
Greg Claytonab65b342011-04-13 22:47:15 +00001175 if (name_sref.equals (pos->name))
1176 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001177 }
1178 }
1179 return NULL;
1180}
1181
Greg Claytone996fd32011-03-08 22:40:15 +00001182#pragma mark Platform
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001183
Greg Claytone996fd32011-03-08 22:40:15 +00001184struct PlatformInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185{
Greg Claytone996fd32011-03-08 22:40:15 +00001186 PlatformInstance() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001187 name(),
1188 description(),
1189 create_callback(NULL)
1190 {
1191 }
Greg Claytone996fd32011-03-08 22:40:15 +00001192
1193 std::string name;
1194 std::string description;
1195 PlatformCreateInstance create_callback;
1196};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001197
Greg Claytone996fd32011-03-08 22:40:15 +00001198typedef std::vector<PlatformInstance> PlatformInstances;
1199
Greg Claytonded470d2011-03-19 01:12:21 +00001200static Mutex &
1201GetPlatformInstancesMutex ()
Greg Claytone996fd32011-03-08 22:40:15 +00001202{
Greg Claytonded470d2011-03-19 01:12:21 +00001203 static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1204 return g_platform_instances_mutex;
Greg Claytone996fd32011-03-08 22:40:15 +00001205}
1206
Greg Claytonded470d2011-03-19 01:12:21 +00001207static PlatformInstances &
1208GetPlatformInstances ()
1209{
1210 static PlatformInstances g_platform_instances;
1211 return g_platform_instances;
1212}
Greg Claytone996fd32011-03-08 22:40:15 +00001213
Greg Claytonab65b342011-04-13 22:47:15 +00001214
Greg Claytone996fd32011-03-08 22:40:15 +00001215bool
1216PluginManager::RegisterPlugin (const char *name,
1217 const char *description,
1218 PlatformCreateInstance create_callback)
1219{
1220 if (create_callback)
1221 {
Greg Claytonded470d2011-03-19 01:12:21 +00001222 Mutex::Locker locker (GetPlatformInstancesMutex ());
1223
Greg Claytone996fd32011-03-08 22:40:15 +00001224 PlatformInstance instance;
1225 assert (name && name[0]);
1226 instance.name = name;
1227 if (description && description[0])
1228 instance.description = description;
1229 instance.create_callback = create_callback;
Greg Claytonded470d2011-03-19 01:12:21 +00001230 GetPlatformInstances ().push_back (instance);
1231 return true;
Greg Claytone996fd32011-03-08 22:40:15 +00001232 }
1233 return false;
1234}
1235
1236const char *
1237PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1238{
Greg Claytonded470d2011-03-19 01:12:21 +00001239 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Claytonab65b342011-04-13 22:47:15 +00001240 PlatformInstances &instances = GetPlatformInstances ();
1241 if (idx < instances.size())
1242 return instances[idx].name.c_str();
Greg Claytone996fd32011-03-08 22:40:15 +00001243 return NULL;
1244}
1245
1246const char *
1247PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1248{
Greg Claytonded470d2011-03-19 01:12:21 +00001249 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Claytonab65b342011-04-13 22:47:15 +00001250 PlatformInstances &instances = GetPlatformInstances ();
1251 if (idx < instances.size())
1252 return instances[idx].description.c_str();
Greg Claytone996fd32011-03-08 22:40:15 +00001253 return NULL;
1254}
1255
1256bool
1257PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1258{
1259 if (create_callback)
1260 {
Greg Claytonded470d2011-03-19 01:12:21 +00001261 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Claytonab65b342011-04-13 22:47:15 +00001262 PlatformInstances &instances = GetPlatformInstances ();
Greg Claytonded470d2011-03-19 01:12:21 +00001263
Greg Claytonab65b342011-04-13 22:47:15 +00001264 PlatformInstances::iterator pos, end = instances.end();
1265 for (pos = instances.begin(); pos != end; ++ pos)
Greg Claytonded470d2011-03-19 01:12:21 +00001266 {
1267 if (pos->create_callback == create_callback)
1268 {
Greg Claytonab65b342011-04-13 22:47:15 +00001269 instances.erase(pos);
Greg Claytonded470d2011-03-19 01:12:21 +00001270 return true;
1271 }
1272 }
Greg Claytone996fd32011-03-08 22:40:15 +00001273 }
1274 return false;
1275}
1276
1277PlatformCreateInstance
1278PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1279{
Greg Claytonded470d2011-03-19 01:12:21 +00001280 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Claytonab65b342011-04-13 22:47:15 +00001281 PlatformInstances &instances = GetPlatformInstances ();
1282 if (idx < instances.size())
1283 return instances[idx].create_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001284 return NULL;
1285}
1286
1287PlatformCreateInstance
1288PluginManager::GetPlatformCreateCallbackForPluginName (const char *name)
1289{
1290 if (name && name[0])
1291 {
Greg Claytonded470d2011-03-19 01:12:21 +00001292 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Claytonab65b342011-04-13 22:47:15 +00001293 PlatformInstances &instances = GetPlatformInstances ();
1294 llvm::StringRef name_sref(name);
Greg Claytonded470d2011-03-19 01:12:21 +00001295
Greg Claytonab65b342011-04-13 22:47:15 +00001296 PlatformInstances::iterator pos, end = instances.end();
1297 for (pos = instances.begin(); pos != end; ++ pos)
Greg Claytone996fd32011-03-08 22:40:15 +00001298 {
Greg Clayton7260f622011-04-18 08:33:37 +00001299 if (name_sref.equals (pos->name))
Greg Claytonded470d2011-03-19 01:12:21 +00001300 return pos->create_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001301 }
1302 }
1303 return NULL;
1304}
1305
Greg Claytonab65b342011-04-13 22:47:15 +00001306uint32_t
1307PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1308{
1309 if (name && name[0])
1310 {
1311 Mutex::Locker locker (GetPlatformInstancesMutex ());
1312 PlatformInstances &instances = GetPlatformInstances ();
1313 llvm::StringRef name_sref(name);
1314
1315 PlatformInstances::iterator pos, end = instances.end();
1316 for (pos = instances.begin(); pos != end; ++ pos)
1317 {
Greg Clayton7260f622011-04-18 08:33:37 +00001318 llvm::StringRef plugin_name (pos->name);
1319 if (plugin_name.startswith(name_sref))
1320 matches.AppendString (plugin_name.data());
Greg Claytonab65b342011-04-13 22:47:15 +00001321 }
1322 }
1323 return matches.GetSize();
1324}
1325
Greg Claytone996fd32011-03-08 22:40:15 +00001326#pragma mark Process
1327
1328struct ProcessInstance
1329{
1330 ProcessInstance() :
1331 name(),
1332 description(),
1333 create_callback(NULL)
1334 {
1335 }
1336
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001337 std::string name;
1338 std::string description;
1339 ProcessCreateInstance create_callback;
1340};
1341
1342typedef std::vector<ProcessInstance> ProcessInstances;
1343
Greg Claytonab65b342011-04-13 22:47:15 +00001344static Mutex &
1345GetProcessMutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001346{
Greg Claytonab65b342011-04-13 22:47:15 +00001347 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1348 return g_instances_mutex;
1349}
1350
1351static ProcessInstances &
1352GetProcessInstances ()
1353{
1354 static ProcessInstances g_instances;
1355 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001356}
1357
1358
1359bool
1360PluginManager::RegisterPlugin
1361(
Greg Claytone996fd32011-03-08 22:40:15 +00001362 const char *name,
1363 const char *description,
1364 ProcessCreateInstance create_callback
1365 )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001366{
1367 if (create_callback)
1368 {
1369 ProcessInstance instance;
1370 assert (name && name[0]);
1371 instance.name = name;
1372 if (description && description[0])
1373 instance.description = description;
1374 instance.create_callback = create_callback;
Greg Claytonab65b342011-04-13 22:47:15 +00001375 Mutex::Locker locker (GetProcessMutex ());
1376 GetProcessInstances ().push_back (instance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001377 }
1378 return false;
1379}
1380
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001381const char *
1382PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1383{
Greg Claytonab65b342011-04-13 22:47:15 +00001384 Mutex::Locker locker (GetProcessMutex ());
1385 ProcessInstances &instances = GetProcessInstances ();
1386 if (idx < instances.size())
1387 return instances[idx].name.c_str();
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001388 return NULL;
1389}
1390
1391const char *
1392PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1393{
Greg Claytonab65b342011-04-13 22:47:15 +00001394 Mutex::Locker locker (GetProcessMutex ());
1395 ProcessInstances &instances = GetProcessInstances ();
1396 if (idx < instances.size())
1397 return instances[idx].description.c_str();
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001398 return NULL;
1399}
1400
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001401bool
1402PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1403{
1404 if (create_callback)
1405 {
Greg Claytonab65b342011-04-13 22:47:15 +00001406 Mutex::Locker locker (GetProcessMutex ());
1407 ProcessInstances &instances = GetProcessInstances ();
1408
1409 ProcessInstances::iterator pos, end = instances.end();
1410 for (pos = instances.begin(); pos != end; ++ pos)
1411 {
1412 if (pos->create_callback == create_callback)
1413 {
1414 instances.erase(pos);
1415 return true;
1416 }
1417 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001418 }
1419 return false;
1420}
1421
1422ProcessCreateInstance
1423PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1424{
Greg Claytonab65b342011-04-13 22:47:15 +00001425 Mutex::Locker locker (GetProcessMutex ());
1426 ProcessInstances &instances = GetProcessInstances ();
1427 if (idx < instances.size())
1428 return instances[idx].create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001429 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001430}
1431
Greg Claytonab65b342011-04-13 22:47:15 +00001432
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001433ProcessCreateInstance
1434PluginManager::GetProcessCreateCallbackForPluginName (const char *name)
1435{
1436 if (name && name[0])
1437 {
Greg Claytonab65b342011-04-13 22:47:15 +00001438 llvm::StringRef name_sref(name);
1439 Mutex::Locker locker (GetProcessMutex ());
1440 ProcessInstances &instances = GetProcessInstances ();
1441
1442 ProcessInstances::iterator pos, end = instances.end();
1443 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001444 {
Greg Claytonab65b342011-04-13 22:47:15 +00001445 if (name_sref.equals (pos->name))
1446 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001447 }
1448 }
1449 return NULL;
1450}
1451
1452#pragma mark SymbolFile
1453
Jason Molenda743e86a2010-06-11 23:44:18 +00001454struct SymbolFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001455{
1456 SymbolFileInstance() :
1457 name(),
1458 description(),
1459 create_callback(NULL)
1460 {
1461 }
1462
1463 std::string name;
1464 std::string description;
1465 SymbolFileCreateInstance create_callback;
1466};
1467
1468typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1469
Greg Claytonab65b342011-04-13 22:47:15 +00001470static Mutex &
1471GetSymbolFileMutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001472{
Greg Claytonab65b342011-04-13 22:47:15 +00001473 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1474 return g_instances_mutex;
1475}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001476
Greg Claytonab65b342011-04-13 22:47:15 +00001477static SymbolFileInstances &
1478GetSymbolFileInstances ()
1479{
1480 static SymbolFileInstances g_instances;
1481 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001482}
1483
1484
1485bool
1486PluginManager::RegisterPlugin
1487(
1488 const char *name,
1489 const char *description,
1490 SymbolFileCreateInstance create_callback
1491)
1492{
1493 if (create_callback)
1494 {
1495 SymbolFileInstance instance;
1496 assert (name && name[0]);
1497 instance.name = name;
1498 if (description && description[0])
1499 instance.description = description;
1500 instance.create_callback = create_callback;
Greg Claytonab65b342011-04-13 22:47:15 +00001501 Mutex::Locker locker (GetSymbolFileMutex ());
1502 GetSymbolFileInstances ().push_back (instance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001503 }
1504 return false;
1505}
1506
1507bool
1508PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1509{
1510 if (create_callback)
1511 {
Greg Claytonab65b342011-04-13 22:47:15 +00001512 Mutex::Locker locker (GetSymbolFileMutex ());
1513 SymbolFileInstances &instances = GetSymbolFileInstances ();
1514
1515 SymbolFileInstances::iterator pos, end = instances.end();
1516 for (pos = instances.begin(); pos != end; ++ pos)
1517 {
1518 if (pos->create_callback == create_callback)
1519 {
1520 instances.erase(pos);
1521 return true;
1522 }
1523 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001524 }
1525 return false;
1526}
1527
1528SymbolFileCreateInstance
1529PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1530{
Greg Claytonab65b342011-04-13 22:47:15 +00001531 Mutex::Locker locker (GetSymbolFileMutex ());
1532 SymbolFileInstances &instances = GetSymbolFileInstances ();
1533 if (idx < instances.size())
1534 return instances[idx].create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001535 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001536}
Greg Claytonab65b342011-04-13 22:47:15 +00001537
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001538SymbolFileCreateInstance
1539PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name)
1540{
1541 if (name && name[0])
1542 {
Greg Claytonab65b342011-04-13 22:47:15 +00001543 llvm::StringRef name_sref(name);
1544 Mutex::Locker locker (GetSymbolFileMutex ());
1545 SymbolFileInstances &instances = GetSymbolFileInstances ();
1546
1547 SymbolFileInstances::iterator pos, end = instances.end();
1548 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001549 {
Greg Claytonab65b342011-04-13 22:47:15 +00001550 if (name_sref.equals (pos->name))
1551 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001552 }
1553 }
1554 return NULL;
1555}
1556
1557
1558
1559#pragma mark SymbolVendor
1560
Jason Molenda743e86a2010-06-11 23:44:18 +00001561struct SymbolVendorInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001562{
1563 SymbolVendorInstance() :
1564 name(),
1565 description(),
1566 create_callback(NULL)
1567 {
1568 }
1569
1570 std::string name;
1571 std::string description;
1572 SymbolVendorCreateInstance create_callback;
1573};
1574
1575typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1576
Greg Claytonab65b342011-04-13 22:47:15 +00001577static Mutex &
1578GetSymbolVendorMutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001579{
Greg Claytonab65b342011-04-13 22:47:15 +00001580 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1581 return g_instances_mutex;
1582}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001583
Greg Claytonab65b342011-04-13 22:47:15 +00001584static SymbolVendorInstances &
1585GetSymbolVendorInstances ()
1586{
1587 static SymbolVendorInstances g_instances;
1588 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001589}
1590
1591bool
1592PluginManager::RegisterPlugin
1593(
1594 const char *name,
1595 const char *description,
1596 SymbolVendorCreateInstance create_callback
1597)
1598{
1599 if (create_callback)
1600 {
1601 SymbolVendorInstance instance;
1602 assert (name && name[0]);
1603 instance.name = name;
1604 if (description && description[0])
1605 instance.description = description;
1606 instance.create_callback = create_callback;
Greg Claytonab65b342011-04-13 22:47:15 +00001607 Mutex::Locker locker (GetSymbolVendorMutex ());
1608 GetSymbolVendorInstances ().push_back (instance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001609 }
1610 return false;
1611}
1612
1613bool
1614PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1615{
1616 if (create_callback)
1617 {
Greg Claytonab65b342011-04-13 22:47:15 +00001618 Mutex::Locker locker (GetSymbolVendorMutex ());
1619 SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1620
1621 SymbolVendorInstances::iterator pos, end = instances.end();
1622 for (pos = instances.begin(); pos != end; ++ pos)
1623 {
1624 if (pos->create_callback == create_callback)
1625 {
1626 instances.erase(pos);
1627 return true;
1628 }
1629 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001630 }
1631 return false;
1632}
1633
1634SymbolVendorCreateInstance
1635PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1636{
Greg Claytonab65b342011-04-13 22:47:15 +00001637 Mutex::Locker locker (GetSymbolVendorMutex ());
1638 SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1639 if (idx < instances.size())
1640 return instances[idx].create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001641 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001642}
1643
Greg Claytonab65b342011-04-13 22:47:15 +00001644
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001645SymbolVendorCreateInstance
1646PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name)
1647{
1648 if (name && name[0])
1649 {
Greg Claytonab65b342011-04-13 22:47:15 +00001650 llvm::StringRef name_sref(name);
1651 Mutex::Locker locker (GetSymbolVendorMutex ());
1652 SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1653
1654 SymbolVendorInstances::iterator pos, end = instances.end();
1655 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001656 {
Greg Claytonab65b342011-04-13 22:47:15 +00001657 if (name_sref.equals (pos->name))
1658 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001659 }
1660 }
1661 return NULL;
1662}
1663
1664
Greg Clayton7be25422011-04-25 21:14:26 +00001665#pragma mark UnwindAssembly
Jason Molendafbcb7f22010-09-10 07:49:16 +00001666
Greg Clayton7be25422011-04-25 21:14:26 +00001667struct UnwindAssemblyInstance
Jason Molendafbcb7f22010-09-10 07:49:16 +00001668{
Greg Clayton7be25422011-04-25 21:14:26 +00001669 UnwindAssemblyInstance() :
Jason Molendafbcb7f22010-09-10 07:49:16 +00001670 name(),
1671 description(),
1672 create_callback(NULL)
1673 {
1674 }
1675
1676 std::string name;
1677 std::string description;
Greg Clayton7be25422011-04-25 21:14:26 +00001678 UnwindAssemblyCreateInstance create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001679};
1680
Greg Clayton7be25422011-04-25 21:14:26 +00001681typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001682
Greg Claytonab65b342011-04-13 22:47:15 +00001683static Mutex &
Greg Clayton7be25422011-04-25 21:14:26 +00001684GetUnwindAssemblyMutex ()
Jason Molendafbcb7f22010-09-10 07:49:16 +00001685{
Greg Claytonab65b342011-04-13 22:47:15 +00001686 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1687 return g_instances_mutex;
1688}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001689
Greg Clayton7be25422011-04-25 21:14:26 +00001690static UnwindAssemblyInstances &
1691GetUnwindAssemblyInstances ()
Greg Claytonab65b342011-04-13 22:47:15 +00001692{
Greg Clayton7be25422011-04-25 21:14:26 +00001693 static UnwindAssemblyInstances g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +00001694 return g_instances;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001695}
1696
1697bool
1698PluginManager::RegisterPlugin
1699(
1700 const char *name,
1701 const char *description,
Greg Clayton7be25422011-04-25 21:14:26 +00001702 UnwindAssemblyCreateInstance create_callback
Jason Molendafbcb7f22010-09-10 07:49:16 +00001703)
1704{
1705 if (create_callback)
1706 {
Greg Clayton7be25422011-04-25 21:14:26 +00001707 UnwindAssemblyInstance instance;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001708 assert (name && name[0]);
1709 instance.name = name;
1710 if (description && description[0])
1711 instance.description = description;
1712 instance.create_callback = create_callback;
Greg Clayton7be25422011-04-25 21:14:26 +00001713 Mutex::Locker locker (GetUnwindAssemblyMutex ());
1714 GetUnwindAssemblyInstances ().push_back (instance);
Jason Molendafbcb7f22010-09-10 07:49:16 +00001715 }
1716 return false;
1717}
1718
1719bool
Greg Clayton7be25422011-04-25 21:14:26 +00001720PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
Jason Molendafbcb7f22010-09-10 07:49:16 +00001721{
1722 if (create_callback)
1723 {
Greg Clayton7be25422011-04-25 21:14:26 +00001724 Mutex::Locker locker (GetUnwindAssemblyMutex ());
1725 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
Greg Claytonab65b342011-04-13 22:47:15 +00001726
Greg Clayton7be25422011-04-25 21:14:26 +00001727 UnwindAssemblyInstances::iterator pos, end = instances.end();
Greg Claytonab65b342011-04-13 22:47:15 +00001728 for (pos = instances.begin(); pos != end; ++ pos)
1729 {
1730 if (pos->create_callback == create_callback)
1731 {
1732 instances.erase(pos);
1733 return true;
1734 }
1735 }
Jason Molendafbcb7f22010-09-10 07:49:16 +00001736 }
1737 return false;
1738}
1739
Greg Clayton7be25422011-04-25 21:14:26 +00001740UnwindAssemblyCreateInstance
1741PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
Jason Molendafbcb7f22010-09-10 07:49:16 +00001742{
Greg Clayton7be25422011-04-25 21:14:26 +00001743 Mutex::Locker locker (GetUnwindAssemblyMutex ());
1744 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
Greg Claytonab65b342011-04-13 22:47:15 +00001745 if (idx < instances.size())
1746 return instances[idx].create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001747 return NULL;
1748}
1749
Greg Claytonab65b342011-04-13 22:47:15 +00001750
Greg Clayton7be25422011-04-25 21:14:26 +00001751UnwindAssemblyCreateInstance
1752PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const char *name)
Jason Molendafbcb7f22010-09-10 07:49:16 +00001753{
1754 if (name && name[0])
1755 {
Greg Claytonab65b342011-04-13 22:47:15 +00001756 llvm::StringRef name_sref(name);
Greg Clayton7be25422011-04-25 21:14:26 +00001757 Mutex::Locker locker (GetUnwindAssemblyMutex ());
1758 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
Greg Claytonab65b342011-04-13 22:47:15 +00001759
Greg Clayton7be25422011-04-25 21:14:26 +00001760 UnwindAssemblyInstances::iterator pos, end = instances.end();
Greg Claytonab65b342011-04-13 22:47:15 +00001761 for (pos = instances.begin(); pos != end; ++ pos)
Jason Molendafbcb7f22010-09-10 07:49:16 +00001762 {
Greg Claytonab65b342011-04-13 22:47:15 +00001763 if (name_sref.equals (pos->name))
1764 return pos->create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001765 }
1766 }
1767 return NULL;
1768}
1769