blob: b7ee57dc991febf977bc9e26129bd54d09d2fe32 [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
12#include <string>
13#include <vector>
14
Greg Clayton4272cc72011-02-02 02:24:04 +000015#include "lldb/Core/Error.h"
Greg Clayton53239f02011-02-08 05:05:52 +000016#include "lldb/Host/FileSpec.h"
Greg Clayton4272cc72011-02-02 02:24:04 +000017#include "lldb/Host/Host.h"
18#include "lldb/Host/Mutex.h"
19
20using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021using namespace lldb_private;
22
Jason Molenda743e86a2010-06-11 23:44:18 +000023enum PluginAction
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024{
25 ePluginRegisterInstance,
26 ePluginUnregisterInstance,
27 ePluginGetInstanceAtIndex
28};
29
Greg Clayton4272cc72011-02-02 02:24:04 +000030struct PluginInfo
31{
32 void *plugin_handle;
33 void *plugin_init_callback;
34 void *plugin_term_callback;
35};
36
37typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
38
39static Mutex &
40GetPluginMapMutex ()
41{
42 static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
43 return g_plugin_map_mutex;
44}
45
46static PluginTerminateMap &
47GetPluginMap ()
48{
49 static PluginTerminateMap g_plugin_map;
50 return g_plugin_map;
51}
52
53static bool
54PluginIsLoaded (const FileSpec &plugin_file_spec)
55{
56 Mutex::Locker locker (GetPluginMapMutex ());
57 PluginTerminateMap &plugin_map = GetPluginMap ();
58 return plugin_map.find (plugin_file_spec) != plugin_map.end();
59}
60
61static void
62SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
63{
64 Mutex::Locker locker (GetPluginMapMutex ());
65 PluginTerminateMap &plugin_map = GetPluginMap ();
66 assert (plugin_map.find (plugin_file_spec) != plugin_map.end());
67 plugin_map[plugin_file_spec] = plugin_info;
68}
69
70
71static FileSpec::EnumerateDirectoryResult
72LoadPluginCallback
73(
74 void *baton,
75 FileSpec::FileType file_type,
76 const FileSpec &file_spec
77)
78{
79// PluginManager *plugin_manager = (PluginManager *)baton;
80 Error error;
81
82 // If we have a regular file, a symbolic link or unknown file type, try
83 // and process the file. We must handle unknown as sometimes the directory
84 // enumeration might be enumerating a file system that doesn't have correct
85 // file type information.
86 if (file_type == FileSpec::eFileTypeRegular ||
87 file_type == FileSpec::eFileTypeSymbolicLink ||
88 file_type == FileSpec::eFileTypeUnknown )
89 {
90 FileSpec plugin_file_spec (file_spec);
91 plugin_file_spec.ResolvePath();
92
93 if (PluginIsLoaded (plugin_file_spec))
94 return FileSpec::eEnumerateDirectoryResultNext;
95 else
96 {
97 PluginInfo plugin_info = { NULL, NULL, NULL };
Greg Clayton45319462011-02-08 00:35:34 +000098 uint32_t flags = Host::eDynamicLibraryOpenOptionLazy |
99 Host::eDynamicLibraryOpenOptionLocal |
100 Host::eDynamicLibraryOpenOptionLimitGetSymbol;
101
102 plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, flags, error);
Greg Clayton4272cc72011-02-02 02:24:04 +0000103 if (plugin_info.plugin_handle)
104 {
105 bool success = false;
106 plugin_info.plugin_init_callback = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error);
107 if (plugin_info.plugin_init_callback)
108 {
109 // Call the plug-in "bool LLDBPluginInitialize(void)" function
110 success = ((bool (*)(void))plugin_info.plugin_init_callback)();
111 }
112
113 if (success)
114 {
115 // It is ok for the "LLDBPluginTerminate" symbol to be NULL
116 plugin_info.plugin_term_callback = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error);
117 }
118 else
119 {
120 // The initialize function returned FALSE which means the
121 // plug-in might not be compatible, or might be too new or
122 // too old, or might not want to run on this machine.
123 Host::DynamicLibraryClose (plugin_info.plugin_handle);
124 plugin_info.plugin_handle = NULL;
125 plugin_info.plugin_init_callback = NULL;
126 }
127
128 // Regardless of success or failure, cache the plug-in load
129 // in our plug-in info so we don't try to load it again and
130 // again.
131 SetPluginInfo (plugin_file_spec, plugin_info);
132
133 return FileSpec::eEnumerateDirectoryResultNext;
134 }
135 }
136 }
137
138 if (file_type == FileSpec::eFileTypeUnknown ||
139 file_type == FileSpec::eFileTypeDirectory ||
140 file_type == FileSpec::eFileTypeSymbolicLink )
141 {
142 // Try and recurse into anything that a directory or symbolic link.
143 // We must also do this for unknown as sometimes the directory enumeration
144 // might be enurating a file system that doesn't have correct file type
145 // information.
146 return FileSpec::eEnumerateDirectoryResultEnter;
147 }
148
149 return FileSpec::eEnumerateDirectoryResultNext;
150}
151
152
153void
154PluginManager::Initialize ()
155{
156 FileSpec dir_spec;
157 const bool find_directories = true;
158 const bool find_files = true;
159 const bool find_other = true;
160 char dir_path[PATH_MAX];
161 if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
162 {
163 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
164 {
165 FileSpec::EnumerateDirectory (dir_path,
166 find_directories,
167 find_files,
168 find_other,
169 LoadPluginCallback,
170 NULL);
171 }
172 }
173
174 if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
175 {
176 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
177 {
178 FileSpec::EnumerateDirectory (dir_path,
179 find_directories,
180 find_files,
181 find_other,
182 LoadPluginCallback,
183 NULL);
184 }
185 }
186}
187
188void
189PluginManager::Terminate ()
190{
191 Mutex::Locker locker (GetPluginMapMutex ());
192 PluginTerminateMap &plugin_map = GetPluginMap ();
193
194 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
195 for (pos = plugin_map.begin(); pos != end; ++pos)
196 {
197 // Call the plug-in "void LLDBPluginTerminate (void)" function if there
198 // is one (if the symbol was not NULL).
199 if (pos->second.plugin_handle)
200 {
201 if (pos->second.plugin_term_callback)
202 ((void (*)(void))pos->second.plugin_term_callback)();
203 Host::DynamicLibraryClose (pos->second.plugin_handle);
204 }
205 }
206 plugin_map.clear();
207}
208
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209
210#pragma mark ABI
211
212
Jason Molenda743e86a2010-06-11 23:44:18 +0000213struct ABIInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214{
215 ABIInstance() :
216 name(),
217 description(),
218 create_callback(NULL)
219 {
220 }
221
222 std::string name;
223 std::string description;
224 ABICreateInstance create_callback;
225};
226
227typedef std::vector<ABIInstance> ABIInstances;
228
Greg Claytonded470d2011-03-19 01:12:21 +0000229static Mutex &
230GetABIInstancesMutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000231{
Greg Claytonded470d2011-03-19 01:12:21 +0000232 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
233 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000234}
235
Greg Claytonded470d2011-03-19 01:12:21 +0000236static ABIInstances &
237GetABIInstances ()
238{
239 static ABIInstances g_instances;
240 return g_instances;
241}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242
243bool
244PluginManager::RegisterPlugin
Greg Clayton4272cc72011-02-02 02:24:04 +0000245(
246 const char *name,
247 const char *description,
248 ABICreateInstance create_callback
249)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250{
251 if (create_callback)
252 {
253 ABIInstance instance;
254 assert (name && name[0]);
255 instance.name = name;
256 if (description && description[0])
257 instance.description = description;
258 instance.create_callback = create_callback;
Greg Claytonded470d2011-03-19 01:12:21 +0000259 Mutex::Locker locker (GetABIInstancesMutex ());
260 GetABIInstances ().push_back (instance);
261 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262 }
263 return false;
264}
265
266bool
267PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
268{
269 if (create_callback)
270 {
Greg Claytonded470d2011-03-19 01:12:21 +0000271 Mutex::Locker locker (GetABIInstancesMutex ());
272 ABIInstances &instances = GetABIInstances ();
273
274 ABIInstances::iterator pos, end = instances.end();
275 for (pos = instances.begin(); pos != end; ++ pos)
276 {
277 if (pos->create_callback == create_callback)
278 {
279 instances.erase(pos);
280 return true;
281 }
282 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283 }
284 return false;
285}
286
287ABICreateInstance
288PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
289{
Greg Claytonded470d2011-03-19 01:12:21 +0000290 Mutex::Locker locker (GetABIInstancesMutex ());
291 ABIInstances &instances = GetABIInstances ();
292
293 if (idx < instances.size())
294 return instances[idx].create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000295 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296}
297
298ABICreateInstance
299PluginManager::GetABICreateCallbackForPluginName (const char *name)
300{
301 if (name && name[0])
302 {
Greg Claytonded470d2011-03-19 01:12:21 +0000303 Mutex::Locker locker (GetABIInstancesMutex ());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000304 std::string ss_name(name);
Greg Claytonded470d2011-03-19 01:12:21 +0000305 ABIInstances &instances = GetABIInstances ();
306
307 ABIInstances::iterator pos, end = instances.end();
308 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000309 {
Greg Claytonded470d2011-03-19 01:12:21 +0000310 if (pos->name == ss_name)
311 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312 }
313 }
314 return NULL;
315}
316
317
318#pragma mark Disassembler
319
320
Jason Molenda743e86a2010-06-11 23:44:18 +0000321struct DisassemblerInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322{
323 DisassemblerInstance() :
324 name(),
325 description(),
326 create_callback(NULL)
327 {
328 }
329
330 std::string name;
331 std::string description;
332 DisassemblerCreateInstance create_callback;
333};
334
335typedef std::vector<DisassemblerInstance> DisassemblerInstances;
336
337static bool
338AccessDisassemblerInstances (PluginAction action, DisassemblerInstance &instance, uint32_t index)
339{
340 static DisassemblerInstances g_plugin_instances;
341
342 switch (action)
343 {
344 case ePluginRegisterInstance:
345 if (instance.create_callback)
346 {
347 g_plugin_instances.push_back (instance);
348 return true;
349 }
350 break;
351
352 case ePluginUnregisterInstance:
353 if (instance.create_callback)
354 {
355 DisassemblerInstances::iterator pos, end = g_plugin_instances.end();
356 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
357 {
358 if (pos->create_callback == instance.create_callback)
359 {
360 g_plugin_instances.erase(pos);
361 return true;
362 }
363 }
364 }
365 break;
366
367 case ePluginGetInstanceAtIndex:
368 if (index < g_plugin_instances.size())
369 {
370 instance = g_plugin_instances[index];
371 return true;
372 }
373 break;
374
375 default:
376 break;
377 }
378 return false;
379}
380
381
382bool
383PluginManager::RegisterPlugin
384(
385 const char *name,
386 const char *description,
387 DisassemblerCreateInstance create_callback
388)
389{
390 if (create_callback)
391 {
392 DisassemblerInstance instance;
393 assert (name && name[0]);
394 instance.name = name;
395 if (description && description[0])
396 instance.description = description;
397 instance.create_callback = create_callback;
398 return AccessDisassemblerInstances (ePluginRegisterInstance, instance, 0);
399 }
400 return false;
401}
402
403bool
404PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
405{
406 if (create_callback)
407 {
408 DisassemblerInstance instance;
409 instance.create_callback = create_callback;
410 return AccessDisassemblerInstances (ePluginUnregisterInstance, instance, 0);
411 }
412 return false;
413}
414
415DisassemblerCreateInstance
416PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
417{
418 DisassemblerInstance instance;
419 if (AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx))
420 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000421 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422}
423
424DisassemblerCreateInstance
425PluginManager::GetDisassemblerCreateCallbackForPluginName (const char *name)
426{
427 if (name && name[0])
428 {
429 DisassemblerInstance instance;
430 std::string ss_name(name);
431 for (uint32_t idx = 0; AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
432 {
433 if (instance.name == ss_name)
434 return instance.create_callback;
435 }
436 }
437 return NULL;
438}
439
440
441
442#pragma mark DynamicLoader
443
444
Jason Molenda743e86a2010-06-11 23:44:18 +0000445struct DynamicLoaderInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446{
447 DynamicLoaderInstance() :
448 name(),
449 description(),
450 create_callback(NULL)
451 {
452 }
453
454 std::string name;
455 std::string description;
456 DynamicLoaderCreateInstance create_callback;
457};
458
459typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
460
461static bool
462AccessDynamicLoaderInstances (PluginAction action, DynamicLoaderInstance &instance, uint32_t index)
463{
464 static DynamicLoaderInstances g_plugin_instances;
465
466 switch (action)
467 {
468 case ePluginRegisterInstance:
469 if (instance.create_callback)
470 {
471 g_plugin_instances.push_back (instance);
472 return true;
473 }
474 break;
475
476 case ePluginUnregisterInstance:
477 if (instance.create_callback)
478 {
479 DynamicLoaderInstances::iterator pos, end = g_plugin_instances.end();
480 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
481 {
482 if (pos->create_callback == instance.create_callback)
483 {
484 g_plugin_instances.erase(pos);
485 return true;
486 }
487 }
488 }
489 break;
490
491 case ePluginGetInstanceAtIndex:
492 if (index < g_plugin_instances.size())
493 {
494 instance = g_plugin_instances[index];
495 return true;
496 }
497 break;
498
499 default:
500 break;
501 }
502 return false;
503}
504
505
506bool
507PluginManager::RegisterPlugin
508(
509 const char *name,
510 const char *description,
511 DynamicLoaderCreateInstance create_callback
512)
513{
514 if (create_callback)
515 {
516 DynamicLoaderInstance instance;
517 assert (name && name[0]);
518 instance.name = name;
519 if (description && description[0])
520 instance.description = description;
521 instance.create_callback = create_callback;
522 return AccessDynamicLoaderInstances (ePluginRegisterInstance, instance, 0);
523 }
524 return false;
525}
526
527bool
528PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
529{
530 if (create_callback)
531 {
532 DynamicLoaderInstance instance;
533 instance.create_callback = create_callback;
534 return AccessDynamicLoaderInstances (ePluginUnregisterInstance, instance, 0);
535 }
536 return false;
537}
538
539DynamicLoaderCreateInstance
540PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
541{
542 DynamicLoaderInstance instance;
543 if (AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx))
544 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000545 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000546}
547
548DynamicLoaderCreateInstance
549PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const char *name)
550{
551 if (name && name[0])
552 {
553 DynamicLoaderInstance instance;
554 std::string ss_name(name);
555 for (uint32_t idx = 0; AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
556 {
557 if (instance.name == ss_name)
558 return instance.create_callback;
559 }
560 }
561 return NULL;
562}
563
Greg Claytonf03bbe22011-02-01 01:37:45 +0000564#pragma mark EmulateInstruction
565
566
567struct EmulateInstructionInstance
568{
569 EmulateInstructionInstance() :
570 name(),
571 description(),
572 create_callback(NULL)
573 {
574 }
575
576 std::string name;
577 std::string description;
578 EmulateInstructionCreateInstance create_callback;
579};
580
581typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
582
583static bool
584AccessEmulateInstructionInstances (PluginAction action, EmulateInstructionInstance &instance, uint32_t index)
585{
586 static EmulateInstructionInstances g_plugin_instances;
587
588 switch (action)
589 {
590 case ePluginRegisterInstance:
591 if (instance.create_callback)
592 {
593 g_plugin_instances.push_back (instance);
594 return true;
595 }
596 break;
597
598 case ePluginUnregisterInstance:
599 if (instance.create_callback)
600 {
601 EmulateInstructionInstances::iterator pos, end = g_plugin_instances.end();
602 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
603 {
604 if (pos->create_callback == instance.create_callback)
605 {
606 g_plugin_instances.erase(pos);
607 return true;
608 }
609 }
610 }
611 break;
612
613 case ePluginGetInstanceAtIndex:
614 if (index < g_plugin_instances.size())
615 {
616 instance = g_plugin_instances[index];
617 return true;
618 }
619 break;
620
621 default:
622 break;
623 }
624 return false;
625}
626
627
628bool
629PluginManager::RegisterPlugin
630(
Greg Clayton4272cc72011-02-02 02:24:04 +0000631 const char *name,
632 const char *description,
633 EmulateInstructionCreateInstance create_callback
634)
Greg Claytonf03bbe22011-02-01 01:37:45 +0000635{
636 if (create_callback)
637 {
638 EmulateInstructionInstance instance;
639 assert (name && name[0]);
640 instance.name = name;
641 if (description && description[0])
642 instance.description = description;
643 instance.create_callback = create_callback;
644 return AccessEmulateInstructionInstances (ePluginRegisterInstance, instance, 0);
645 }
646 return false;
647}
648
649bool
650PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
651{
652 if (create_callback)
653 {
654 EmulateInstructionInstance instance;
655 instance.create_callback = create_callback;
656 return AccessEmulateInstructionInstances (ePluginUnregisterInstance, instance, 0);
657 }
658 return false;
659}
660
661EmulateInstructionCreateInstance
662PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
663{
664 EmulateInstructionInstance instance;
665 if (AccessEmulateInstructionInstances (ePluginGetInstanceAtIndex, instance, idx))
666 return instance.create_callback;
667 return NULL;
668}
669
670EmulateInstructionCreateInstance
671PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const char *name)
672{
673 if (name && name[0])
674 {
675 EmulateInstructionInstance instance;
676 std::string ss_name(name);
677 for (uint32_t idx = 0; AccessEmulateInstructionInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
678 {
679 if (instance.name == ss_name)
680 return instance.create_callback;
681 }
682 }
683 return NULL;
684}
685
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000686
Jim Ingham22777012010-09-23 02:01:19 +0000687#pragma mark LanguageRuntime
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000688
689
Jim Ingham22777012010-09-23 02:01:19 +0000690struct LanguageRuntimeInstance
691{
692 LanguageRuntimeInstance() :
693 name(),
694 description(),
695 create_callback(NULL)
696 {
697 }
698
699 std::string name;
700 std::string description;
701 LanguageRuntimeCreateInstance create_callback;
702};
703
704typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
705
706static bool
707AccessLanguageRuntimeInstances (PluginAction action, LanguageRuntimeInstance &instance, uint32_t index)
708{
709 static LanguageRuntimeInstances g_plugin_instances;
710
711 switch (action)
712 {
713 case ePluginRegisterInstance:
714 if (instance.create_callback)
715 {
716 g_plugin_instances.push_back (instance);
717 return true;
718 }
719 break;
720
721 case ePluginUnregisterInstance:
722 if (instance.create_callback)
723 {
724 LanguageRuntimeInstances::iterator pos, end = g_plugin_instances.end();
725 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
726 {
727 if (pos->create_callback == instance.create_callback)
728 {
729 g_plugin_instances.erase(pos);
730 return true;
731 }
732 }
733 }
734 break;
735
736 case ePluginGetInstanceAtIndex:
737 if (index < g_plugin_instances.size())
738 {
739 instance = g_plugin_instances[index];
740 return true;
741 }
742 break;
743
744 default:
745 break;
746 }
747 return false;
748}
749
750
751bool
752PluginManager::RegisterPlugin
Greg Clayton4272cc72011-02-02 02:24:04 +0000753(
754 const char *name,
755 const char *description,
756 LanguageRuntimeCreateInstance create_callback
757)
Jim Ingham22777012010-09-23 02:01:19 +0000758{
759 if (create_callback)
760 {
761 LanguageRuntimeInstance instance;
762 assert (name && name[0]);
763 instance.name = name;
764 if (description && description[0])
765 instance.description = description;
766 instance.create_callback = create_callback;
767 return AccessLanguageRuntimeInstances (ePluginRegisterInstance, instance, 0);
768 }
769 return false;
770}
771
772bool
773PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
774{
775 if (create_callback)
776 {
777 LanguageRuntimeInstance instance;
778 instance.create_callback = create_callback;
779 return AccessLanguageRuntimeInstances (ePluginUnregisterInstance, instance, 0);
780 }
781 return false;
782}
783
784LanguageRuntimeCreateInstance
785PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
786{
787 LanguageRuntimeInstance instance;
788 if (AccessLanguageRuntimeInstances (ePluginGetInstanceAtIndex, instance, idx))
789 return instance.create_callback;
790 return NULL;
791}
792
793LanguageRuntimeCreateInstance
794PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const char *name)
795{
796 if (name && name[0])
797 {
798 LanguageRuntimeInstance instance;
799 std::string ss_name(name);
800 for (uint32_t idx = 0; AccessLanguageRuntimeInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
801 {
802 if (instance.name == ss_name)
803 return instance.create_callback;
804 }
805 }
806 return NULL;
807}
808
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000809#pragma mark ObjectFile
810
Jason Molenda743e86a2010-06-11 23:44:18 +0000811struct ObjectFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000812{
813 ObjectFileInstance() :
814 name(),
815 description(),
816 create_callback(NULL)
817 {
818 }
819
820 std::string name;
821 std::string description;
822 ObjectFileCreateInstance create_callback;
823};
824
825typedef std::vector<ObjectFileInstance> ObjectFileInstances;
826
827static bool
828AccessObjectFileInstances (PluginAction action, ObjectFileInstance &instance, uint32_t index)
829{
830 static ObjectFileInstances g_plugin_instances;
831
832 switch (action)
833 {
834 case ePluginRegisterInstance:
835 if (instance.create_callback)
836 {
837 g_plugin_instances.push_back (instance);
838 return true;
839 }
840 break;
841
842 case ePluginUnregisterInstance:
843 if (instance.create_callback)
844 {
845 ObjectFileInstances::iterator pos, end = g_plugin_instances.end();
846 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
847 {
848 if (pos->create_callback == instance.create_callback)
849 {
850 g_plugin_instances.erase(pos);
851 return true;
852 }
853 }
854 }
855 break;
856
857 case ePluginGetInstanceAtIndex:
858 if (index < g_plugin_instances.size())
859 {
860 instance = g_plugin_instances[index];
861 return true;
862 }
863 break;
864
865 default:
866 break;
867 }
868 return false;
869}
870
871
872bool
873PluginManager::RegisterPlugin
874(
875 const char *name,
876 const char *description,
877 ObjectFileCreateInstance create_callback
878)
879{
880 if (create_callback)
881 {
882 ObjectFileInstance instance;
883 assert (name && name[0]);
884 instance.name = name;
885 if (description && description[0])
886 instance.description = description;
887 instance.create_callback = create_callback;
888 return AccessObjectFileInstances (ePluginRegisterInstance, instance, 0);
889 }
890 return false;
891}
892
893bool
894PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
895{
896 if (create_callback)
897 {
898 ObjectFileInstance instance;
899 instance.create_callback = create_callback;
900 return AccessObjectFileInstances (ePluginUnregisterInstance, instance, 0);
901 }
902 return false;
903}
904
905ObjectFileCreateInstance
906PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
907{
908 ObjectFileInstance instance;
909 if (AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx))
910 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000911 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000912}
913ObjectFileCreateInstance
914PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name)
915{
916 if (name && name[0])
917 {
918 ObjectFileInstance instance;
919 std::string ss_name(name);
920 for (uint32_t idx = 0; AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
921 {
922 if (instance.name == ss_name)
923 return instance.create_callback;
924 }
925 }
926 return NULL;
927}
928
929
930
931#pragma mark ObjectContainer
932
Jason Molenda743e86a2010-06-11 23:44:18 +0000933struct ObjectContainerInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934{
935 ObjectContainerInstance() :
936 name(),
937 description(),
938 create_callback(NULL)
939 {
940 }
941
942 std::string name;
943 std::string description;
944 ObjectContainerCreateInstance create_callback;
945};
946
947typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
948
949static bool
950AccessObjectContainerInstances (PluginAction action, ObjectContainerInstance &instance, uint32_t index)
951{
952 static ObjectContainerInstances g_plugin_instances;
953
954 switch (action)
955 {
956 case ePluginRegisterInstance:
957 if (instance.create_callback)
958 {
959 g_plugin_instances.push_back (instance);
960 return true;
961 }
962 break;
963
964 case ePluginUnregisterInstance:
965 if (instance.create_callback)
966 {
967 ObjectContainerInstances::iterator pos, end = g_plugin_instances.end();
968 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
969 {
970 if (pos->create_callback == instance.create_callback)
971 {
972 g_plugin_instances.erase(pos);
973 return true;
974 }
975 }
976 }
977 break;
978
979 case ePluginGetInstanceAtIndex:
980 if (index < g_plugin_instances.size())
981 {
982 instance = g_plugin_instances[index];
983 return true;
984 }
985 break;
986
987 default:
988 break;
989 }
990 return false;
991}
992
993
994bool
995PluginManager::RegisterPlugin
996(
997 const char *name,
998 const char *description,
999 ObjectContainerCreateInstance create_callback
1000)
1001{
1002 if (create_callback)
1003 {
1004 ObjectContainerInstance instance;
1005 assert (name && name[0]);
1006 instance.name = name;
1007 if (description && description[0])
1008 instance.description = description;
1009 instance.create_callback = create_callback;
1010 return AccessObjectContainerInstances (ePluginRegisterInstance, instance, 0);
1011 }
1012 return false;
1013}
1014
1015bool
1016PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1017{
1018 if (create_callback)
1019 {
1020 ObjectContainerInstance instance;
1021 instance.create_callback = create_callback;
1022 return AccessObjectContainerInstances (ePluginUnregisterInstance, instance, 0);
1023 }
1024 return false;
1025}
1026
1027ObjectContainerCreateInstance
1028PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1029{
1030 ObjectContainerInstance instance;
1031 if (AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx))
1032 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001033 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001034}
1035ObjectContainerCreateInstance
1036PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name)
1037{
1038 if (name && name[0])
1039 {
1040 ObjectContainerInstance instance;
1041 std::string ss_name(name);
1042 for (uint32_t idx = 0; AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1043 {
1044 if (instance.name == ss_name)
1045 return instance.create_callback;
1046 }
1047 }
1048 return NULL;
1049}
1050
1051#pragma mark LogChannel
1052
Jason Molenda743e86a2010-06-11 23:44:18 +00001053struct LogChannelInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054{
1055 LogChannelInstance() :
1056 name(),
1057 description(),
1058 create_callback(NULL)
1059 {
1060 }
1061
1062 std::string name;
1063 std::string description;
1064 LogChannelCreateInstance create_callback;
1065};
1066
1067typedef std::vector<LogChannelInstance> LogChannelInstances;
1068
1069static bool
1070AccessLogChannelInstances (PluginAction action, LogChannelInstance &instance, uint32_t index)
1071{
1072 static LogChannelInstances g_plugin_instances;
1073
1074 switch (action)
1075 {
1076 case ePluginRegisterInstance:
1077 if (instance.create_callback)
1078 {
1079 g_plugin_instances.push_back (instance);
1080 return true;
1081 }
1082 break;
1083
1084 case ePluginUnregisterInstance:
1085 if (instance.create_callback)
1086 {
1087 LogChannelInstances::iterator pos, end = g_plugin_instances.end();
1088 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1089 {
1090 if (pos->create_callback == instance.create_callback)
1091 {
1092 g_plugin_instances.erase(pos);
1093 return true;
1094 }
1095 }
1096 }
1097 break;
1098
1099 case ePluginGetInstanceAtIndex:
1100 if (index < g_plugin_instances.size())
1101 {
1102 instance = g_plugin_instances[index];
1103 return true;
1104 }
1105 break;
1106
1107 default:
1108 break;
1109 }
1110 return false;
1111}
1112
1113
1114bool
1115PluginManager::RegisterPlugin
1116(
1117 const char *name,
1118 const char *description,
1119 LogChannelCreateInstance create_callback
1120)
1121{
1122 if (create_callback)
1123 {
1124 LogChannelInstance instance;
1125 assert (name && name[0]);
1126 instance.name = name;
1127 if (description && description[0])
1128 instance.description = description;
1129 instance.create_callback = create_callback;
1130 return AccessLogChannelInstances (ePluginRegisterInstance, instance, 0);
1131 }
1132 return false;
1133}
1134
1135bool
1136PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1137{
1138 if (create_callback)
1139 {
1140 LogChannelInstance instance;
1141 instance.create_callback = create_callback;
1142 return AccessLogChannelInstances (ePluginUnregisterInstance, instance, 0);
1143 }
1144 return false;
1145}
1146
1147const char *
1148PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1149{
1150 LogChannelInstance instance;
1151 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx))
1152 return instance.name.c_str();
1153 return NULL;
1154}
1155
1156
1157LogChannelCreateInstance
1158PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1159{
1160 LogChannelInstance instance;
1161 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx))
1162 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001163 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001164}
1165
1166LogChannelCreateInstance
1167PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name)
1168{
1169 if (name && name[0])
1170 {
1171 LogChannelInstance instance;
1172 std::string ss_name(name);
1173 for (uint32_t idx = 0; AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1174 {
1175 if (instance.name == ss_name)
1176 return instance.create_callback;
1177 }
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
1214bool
1215PluginManager::RegisterPlugin (const char *name,
1216 const char *description,
1217 PlatformCreateInstance create_callback)
1218{
1219 if (create_callback)
1220 {
Greg Claytonded470d2011-03-19 01:12:21 +00001221 Mutex::Locker locker (GetPlatformInstancesMutex ());
1222
Greg Claytone996fd32011-03-08 22:40:15 +00001223 PlatformInstance instance;
1224 assert (name && name[0]);
1225 instance.name = name;
1226 if (description && description[0])
1227 instance.description = description;
1228 instance.create_callback = create_callback;
Greg Claytonded470d2011-03-19 01:12:21 +00001229 GetPlatformInstances ().push_back (instance);
1230 return true;
Greg Claytone996fd32011-03-08 22:40:15 +00001231 }
1232 return false;
1233}
1234
1235const char *
1236PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1237{
Greg Claytonded470d2011-03-19 01:12:21 +00001238 Mutex::Locker locker (GetPlatformInstancesMutex ());
1239 PlatformInstances &platform_instances = GetPlatformInstances ();
1240 if (idx < platform_instances.size())
1241 return platform_instances[idx].name.c_str();
Greg Claytone996fd32011-03-08 22:40:15 +00001242 return NULL;
1243}
1244
1245const char *
1246PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1247{
Greg Claytonded470d2011-03-19 01:12:21 +00001248 Mutex::Locker locker (GetPlatformInstancesMutex ());
1249 PlatformInstances &platform_instances = GetPlatformInstances ();
1250 if (idx < platform_instances.size())
1251 return platform_instances[idx].description.c_str();
Greg Claytone996fd32011-03-08 22:40:15 +00001252 return NULL;
1253}
1254
1255bool
1256PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1257{
1258 if (create_callback)
1259 {
Greg Claytonded470d2011-03-19 01:12:21 +00001260 Mutex::Locker locker (GetPlatformInstancesMutex ());
1261 PlatformInstances &platform_instances = GetPlatformInstances ();
1262
1263 PlatformInstances::iterator pos, end = platform_instances.end();
1264 for (pos = platform_instances.begin(); pos != end; ++ pos)
1265 {
1266 if (pos->create_callback == create_callback)
1267 {
1268 platform_instances.erase(pos);
1269 return true;
1270 }
1271 }
Greg Claytone996fd32011-03-08 22:40:15 +00001272 }
1273 return false;
1274}
1275
1276PlatformCreateInstance
1277PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1278{
Greg Claytonded470d2011-03-19 01:12:21 +00001279 Mutex::Locker locker (GetPlatformInstancesMutex ());
1280 PlatformInstances &platform_instances = GetPlatformInstances ();
1281 if (idx < platform_instances.size())
1282 return platform_instances[idx].create_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001283 return NULL;
1284}
1285
1286PlatformCreateInstance
1287PluginManager::GetPlatformCreateCallbackForPluginName (const char *name)
1288{
1289 if (name && name[0])
1290 {
Greg Claytonded470d2011-03-19 01:12:21 +00001291 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Claytone996fd32011-03-08 22:40:15 +00001292 std::string ss_name(name);
Greg Claytonded470d2011-03-19 01:12:21 +00001293 PlatformInstances &platform_instances = GetPlatformInstances ();
1294
1295 PlatformInstances::iterator pos, end = platform_instances.end();
1296 for (pos = platform_instances.begin(); pos != end; ++ pos)
Greg Claytone996fd32011-03-08 22:40:15 +00001297 {
Greg Claytonded470d2011-03-19 01:12:21 +00001298 if (pos->name == ss_name)
1299 return pos->create_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001300 }
1301 }
1302 return NULL;
1303}
1304
1305#pragma mark Process
1306
1307struct ProcessInstance
1308{
1309 ProcessInstance() :
1310 name(),
1311 description(),
1312 create_callback(NULL)
1313 {
1314 }
1315
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001316 std::string name;
1317 std::string description;
1318 ProcessCreateInstance create_callback;
1319};
1320
1321typedef std::vector<ProcessInstance> ProcessInstances;
1322
1323static bool
1324AccessProcessInstances (PluginAction action, ProcessInstance &instance, uint32_t index)
1325{
1326 static ProcessInstances g_plugin_instances;
Greg Claytone996fd32011-03-08 22:40:15 +00001327
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001328 switch (action)
1329 {
Greg Claytone996fd32011-03-08 22:40:15 +00001330 case ePluginRegisterInstance:
1331 if (instance.create_callback)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001332 {
Greg Claytone996fd32011-03-08 22:40:15 +00001333 g_plugin_instances.push_back (instance);
1334 return true;
1335 }
1336 break;
1337
1338 case ePluginUnregisterInstance:
1339 if (instance.create_callback)
1340 {
1341 ProcessInstances::iterator pos, end = g_plugin_instances.end();
1342 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001343 {
Greg Claytone996fd32011-03-08 22:40:15 +00001344 if (pos->create_callback == instance.create_callback)
1345 {
1346 g_plugin_instances.erase(pos);
1347 return true;
1348 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001349 }
1350 }
Greg Claytone996fd32011-03-08 22:40:15 +00001351 break;
1352
1353 case ePluginGetInstanceAtIndex:
1354 if (index < g_plugin_instances.size())
1355 {
1356 instance = g_plugin_instances[index];
1357 return true;
1358 }
1359 break;
1360
1361 default:
1362 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001363 }
1364 return false;
1365}
1366
1367
1368bool
1369PluginManager::RegisterPlugin
1370(
Greg Claytone996fd32011-03-08 22:40:15 +00001371 const char *name,
1372 const char *description,
1373 ProcessCreateInstance create_callback
1374 )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001375{
1376 if (create_callback)
1377 {
1378 ProcessInstance instance;
1379 assert (name && name[0]);
1380 instance.name = name;
1381 if (description && description[0])
1382 instance.description = description;
1383 instance.create_callback = create_callback;
1384 return AccessProcessInstances (ePluginRegisterInstance, instance, 0);
1385 }
1386 return false;
1387}
1388
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001389const char *
1390PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1391{
1392 ProcessInstance instance;
1393 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1394 return instance.name.c_str();
1395 return NULL;
1396}
1397
1398const char *
1399PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1400{
1401 ProcessInstance instance;
1402 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1403 return instance.description.c_str();
1404 return NULL;
1405}
1406
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001407bool
1408PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1409{
1410 if (create_callback)
1411 {
1412 ProcessInstance instance;
1413 instance.create_callback = create_callback;
1414 return AccessProcessInstances (ePluginUnregisterInstance, instance, 0);
1415 }
1416 return false;
1417}
1418
1419ProcessCreateInstance
1420PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1421{
1422 ProcessInstance instance;
1423 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1424 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001425 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001426}
1427
1428ProcessCreateInstance
1429PluginManager::GetProcessCreateCallbackForPluginName (const char *name)
1430{
1431 if (name && name[0])
1432 {
1433 ProcessInstance instance;
1434 std::string ss_name(name);
1435 for (uint32_t idx = 0; AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1436 {
1437 if (instance.name == ss_name)
1438 return instance.create_callback;
1439 }
1440 }
1441 return NULL;
1442}
1443
1444#pragma mark SymbolFile
1445
Jason Molenda743e86a2010-06-11 23:44:18 +00001446struct SymbolFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001447{
1448 SymbolFileInstance() :
1449 name(),
1450 description(),
1451 create_callback(NULL)
1452 {
1453 }
1454
1455 std::string name;
1456 std::string description;
1457 SymbolFileCreateInstance create_callback;
1458};
1459
1460typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1461
1462static bool
1463AccessSymbolFileInstances (PluginAction action, SymbolFileInstance &instance, uint32_t index)
1464{
1465 static SymbolFileInstances g_plugin_instances;
1466
1467 switch (action)
1468 {
1469 case ePluginRegisterInstance:
1470 if (instance.create_callback)
1471 {
1472 g_plugin_instances.push_back (instance);
1473 return true;
1474 }
1475 break;
1476
1477 case ePluginUnregisterInstance:
1478 if (instance.create_callback)
1479 {
1480 SymbolFileInstances::iterator pos, end = g_plugin_instances.end();
1481 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1482 {
1483 if (pos->create_callback == instance.create_callback)
1484 {
1485 g_plugin_instances.erase(pos);
1486 return true;
1487 }
1488 }
1489 }
1490 break;
1491
1492 case ePluginGetInstanceAtIndex:
1493 if (index < g_plugin_instances.size())
1494 {
1495 instance = g_plugin_instances[index];
1496 return true;
1497 }
1498 break;
1499
1500 default:
1501 break;
1502 }
1503 return false;
1504}
1505
1506
1507bool
1508PluginManager::RegisterPlugin
1509(
1510 const char *name,
1511 const char *description,
1512 SymbolFileCreateInstance create_callback
1513)
1514{
1515 if (create_callback)
1516 {
1517 SymbolFileInstance instance;
1518 assert (name && name[0]);
1519 instance.name = name;
1520 if (description && description[0])
1521 instance.description = description;
1522 instance.create_callback = create_callback;
1523 return AccessSymbolFileInstances (ePluginRegisterInstance, instance, 0);
1524 }
1525 return false;
1526}
1527
1528bool
1529PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1530{
1531 if (create_callback)
1532 {
1533 SymbolFileInstance instance;
1534 instance.create_callback = create_callback;
1535 return AccessSymbolFileInstances (ePluginUnregisterInstance, instance, 0);
1536 }
1537 return false;
1538}
1539
1540SymbolFileCreateInstance
1541PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1542{
1543 SymbolFileInstance instance;
1544 if (AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx))
1545 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001546 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001547}
1548SymbolFileCreateInstance
1549PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name)
1550{
1551 if (name && name[0])
1552 {
1553 SymbolFileInstance instance;
1554 std::string ss_name(name);
1555 for (uint32_t idx = 0; AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1556 {
1557 if (instance.name == ss_name)
1558 return instance.create_callback;
1559 }
1560 }
1561 return NULL;
1562}
1563
1564
1565
1566#pragma mark SymbolVendor
1567
Jason Molenda743e86a2010-06-11 23:44:18 +00001568struct SymbolVendorInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001569{
1570 SymbolVendorInstance() :
1571 name(),
1572 description(),
1573 create_callback(NULL)
1574 {
1575 }
1576
1577 std::string name;
1578 std::string description;
1579 SymbolVendorCreateInstance create_callback;
1580};
1581
1582typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1583
1584static bool
1585AccessSymbolVendorInstances (PluginAction action, SymbolVendorInstance &instance, uint32_t index)
1586{
1587 static SymbolVendorInstances g_plugin_instances;
1588
1589 switch (action)
1590 {
1591 case ePluginRegisterInstance:
1592 if (instance.create_callback)
1593 {
1594 g_plugin_instances.push_back (instance);
1595 return true;
1596 }
1597 break;
1598
1599 case ePluginUnregisterInstance:
1600 if (instance.create_callback)
1601 {
1602 SymbolVendorInstances::iterator pos, end = g_plugin_instances.end();
1603 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1604 {
1605 if (pos->create_callback == instance.create_callback)
1606 {
1607 g_plugin_instances.erase(pos);
1608 return true;
1609 }
1610 }
1611 }
1612 break;
1613
1614 case ePluginGetInstanceAtIndex:
1615 if (index < g_plugin_instances.size())
1616 {
1617 instance = g_plugin_instances[index];
1618 return true;
1619 }
1620 break;
1621
1622 default:
1623 break;
1624 }
1625 return false;
1626}
1627
1628bool
1629PluginManager::RegisterPlugin
1630(
1631 const char *name,
1632 const char *description,
1633 SymbolVendorCreateInstance create_callback
1634)
1635{
1636 if (create_callback)
1637 {
1638 SymbolVendorInstance instance;
1639 assert (name && name[0]);
1640 instance.name = name;
1641 if (description && description[0])
1642 instance.description = description;
1643 instance.create_callback = create_callback;
1644 return AccessSymbolVendorInstances (ePluginRegisterInstance, instance, 0);
1645 }
1646 return false;
1647}
1648
1649bool
1650PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1651{
1652 if (create_callback)
1653 {
1654 SymbolVendorInstance instance;
1655 instance.create_callback = create_callback;
1656 return AccessSymbolVendorInstances (ePluginUnregisterInstance, instance, 0);
1657 }
1658 return false;
1659}
1660
1661SymbolVendorCreateInstance
1662PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1663{
1664 SymbolVendorInstance instance;
1665 if (AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx))
1666 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001667 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001668}
1669
1670SymbolVendorCreateInstance
1671PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name)
1672{
1673 if (name && name[0])
1674 {
1675 SymbolVendorInstance instance;
1676 std::string ss_name(name);
1677 for (uint32_t idx = 0; AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1678 {
1679 if (instance.name == ss_name)
1680 return instance.create_callback;
1681 }
1682 }
1683 return NULL;
1684}
1685
1686
Jason Molendafbcb7f22010-09-10 07:49:16 +00001687#pragma mark UnwindAssemblyProfiler
1688
1689struct UnwindAssemblyProfilerInstance
1690{
1691 UnwindAssemblyProfilerInstance() :
1692 name(),
1693 description(),
1694 create_callback(NULL)
1695 {
1696 }
1697
1698 std::string name;
1699 std::string description;
1700 UnwindAssemblyProfilerCreateInstance create_callback;
1701};
1702
1703typedef std::vector<UnwindAssemblyProfilerInstance> UnwindAssemblyProfilerInstances;
1704
1705static bool
1706AccessUnwindAssemblyProfilerInstances (PluginAction action, UnwindAssemblyProfilerInstance &instance, uint32_t index)
1707{
1708 static UnwindAssemblyProfilerInstances g_plugin_instances;
1709
1710 switch (action)
1711 {
1712 case ePluginRegisterInstance:
1713 if (instance.create_callback)
1714 {
1715 g_plugin_instances.push_back (instance);
1716 return true;
1717 }
1718 break;
1719
1720 case ePluginUnregisterInstance:
1721 if (instance.create_callback)
1722 {
1723 UnwindAssemblyProfilerInstances::iterator pos, end = g_plugin_instances.end();
1724 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1725 {
1726 if (pos->create_callback == instance.create_callback)
1727 {
1728 g_plugin_instances.erase(pos);
1729 return true;
1730 }
1731 }
1732 }
1733 break;
1734
1735 case ePluginGetInstanceAtIndex:
1736 if (index < g_plugin_instances.size())
1737 {
1738 instance = g_plugin_instances[index];
1739 return true;
1740 }
1741 break;
1742
1743 default:
1744 break;
1745 }
1746 return false;
1747}
1748
1749bool
1750PluginManager::RegisterPlugin
1751(
1752 const char *name,
1753 const char *description,
1754 UnwindAssemblyProfilerCreateInstance create_callback
1755)
1756{
1757 if (create_callback)
1758 {
1759 UnwindAssemblyProfilerInstance instance;
1760 assert (name && name[0]);
1761 instance.name = name;
1762 if (description && description[0])
1763 instance.description = description;
1764 instance.create_callback = create_callback;
1765 return AccessUnwindAssemblyProfilerInstances (ePluginRegisterInstance, instance, 0);
1766 }
1767 return false;
1768}
1769
1770bool
1771PluginManager::UnregisterPlugin (UnwindAssemblyProfilerCreateInstance create_callback)
1772{
1773 if (create_callback)
1774 {
1775 UnwindAssemblyProfilerInstance instance;
1776 instance.create_callback = create_callback;
1777 return AccessUnwindAssemblyProfilerInstances (ePluginUnregisterInstance, instance, 0);
1778 }
1779 return false;
1780}
1781
1782UnwindAssemblyProfilerCreateInstance
1783PluginManager::GetUnwindAssemblyProfilerCreateCallbackAtIndex (uint32_t idx)
1784{
1785 UnwindAssemblyProfilerInstance instance;
1786 if (AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx))
1787 return instance.create_callback;
1788 return NULL;
1789}
1790
1791UnwindAssemblyProfilerCreateInstance
1792PluginManager::GetUnwindAssemblyProfilerCreateCallbackForPluginName (const char *name)
1793{
1794 if (name && name[0])
1795 {
1796 UnwindAssemblyProfilerInstance instance;
1797 std::string ss_name(name);
1798 for (uint32_t idx = 0; AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1799 {
1800 if (instance.name == ss_name)
1801 return instance.create_callback;
1802 }
1803 }
1804 return NULL;
1805}
1806
1807#pragma mark ArchDefaultUnwindPlan
1808
1809struct ArchDefaultUnwindPlanInstance
1810{
1811 ArchDefaultUnwindPlanInstance() :
1812 name(),
1813 description(),
1814 create_callback(NULL)
1815 {
1816 }
1817
1818 std::string name;
1819 std::string description;
1820 ArchDefaultUnwindPlanCreateInstance create_callback;
1821};
1822
1823typedef std::vector<ArchDefaultUnwindPlanInstance> ArchDefaultUnwindPlanInstances;
1824
1825static bool
1826AccessArchDefaultUnwindPlanInstances (PluginAction action, ArchDefaultUnwindPlanInstance &instance, uint32_t index)
1827{
1828 static ArchDefaultUnwindPlanInstances g_plugin_instances;
1829
1830 switch (action)
1831 {
1832 case ePluginRegisterInstance:
1833 if (instance.create_callback)
1834 {
1835 g_plugin_instances.push_back (instance);
1836 return true;
1837 }
1838 break;
1839
1840 case ePluginUnregisterInstance:
1841 if (instance.create_callback)
1842 {
1843 ArchDefaultUnwindPlanInstances::iterator pos, end = g_plugin_instances.end();
1844 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1845 {
1846 if (pos->create_callback == instance.create_callback)
1847 {
1848 g_plugin_instances.erase(pos);
1849 return true;
1850 }
1851 }
1852 }
1853 break;
1854
1855 case ePluginGetInstanceAtIndex:
1856 if (index < g_plugin_instances.size())
1857 {
1858 instance = g_plugin_instances[index];
1859 return true;
1860 }
1861 break;
1862
1863 default:
1864 break;
1865 }
1866 return false;
1867}
1868
1869bool
1870PluginManager::RegisterPlugin
1871(
1872 const char *name,
1873 const char *description,
1874 ArchDefaultUnwindPlanCreateInstance create_callback
1875)
1876{
1877 if (create_callback)
1878 {
1879 ArchDefaultUnwindPlanInstance instance;
1880 assert (name && name[0]);
1881 instance.name = name;
1882 if (description && description[0])
1883 instance.description = description;
1884 instance.create_callback = create_callback;
1885 return AccessArchDefaultUnwindPlanInstances (ePluginRegisterInstance, instance, 0);
1886 }
1887 return false;
1888}
1889
1890bool
1891PluginManager::UnregisterPlugin (ArchDefaultUnwindPlanCreateInstance create_callback)
1892{
1893 if (create_callback)
1894 {
1895 ArchDefaultUnwindPlanInstance instance;
1896 instance.create_callback = create_callback;
1897 return AccessArchDefaultUnwindPlanInstances (ePluginUnregisterInstance, instance, 0);
1898 }
1899 return false;
1900}
1901
1902ArchDefaultUnwindPlanCreateInstance
1903PluginManager::GetArchDefaultUnwindPlanCreateCallbackAtIndex (uint32_t idx)
1904{
1905 ArchDefaultUnwindPlanInstance instance;
1906 if (AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx))
1907 return instance.create_callback;
1908 return NULL;
1909}
1910
1911ArchDefaultUnwindPlanCreateInstance
1912PluginManager::GetArchDefaultUnwindPlanCreateCallbackForPluginName (const char *name)
1913{
1914 if (name && name[0])
1915 {
1916 ArchDefaultUnwindPlanInstance instance;
1917 std::string ss_name(name);
1918 for (uint32_t idx = 0; AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1919 {
1920 if (instance.name == ss_name)
1921 return instance.create_callback;
1922 }
1923 }
1924 return NULL;
1925}
1926
Jason Molenda0c7cc852010-09-22 07:37:07 +00001927#pragma mark ArchVolatileRegs
1928
1929struct ArchVolatileRegsInstance
1930{
1931 ArchVolatileRegsInstance() :
1932 name(),
1933 description(),
1934 create_callback(NULL)
1935 {
1936 }
1937
1938 std::string name;
1939 std::string description;
1940 ArchVolatileRegsCreateInstance create_callback;
1941};
1942
1943typedef std::vector<ArchVolatileRegsInstance> ArchVolatileRegsInstances;
1944
1945static bool
1946AccessArchVolatileRegsInstances (PluginAction action, ArchVolatileRegsInstance &instance, uint32_t index)
1947{
1948 static ArchVolatileRegsInstances g_plugin_instances;
1949
1950 switch (action)
1951 {
1952 case ePluginRegisterInstance:
1953 if (instance.create_callback)
1954 {
1955 g_plugin_instances.push_back (instance);
1956 return true;
1957 }
1958 break;
1959
1960 case ePluginUnregisterInstance:
1961 if (instance.create_callback)
1962 {
1963 ArchVolatileRegsInstances::iterator pos, end = g_plugin_instances.end();
1964 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1965 {
1966 if (pos->create_callback == instance.create_callback)
1967 {
1968 g_plugin_instances.erase(pos);
1969 return true;
1970 }
1971 }
1972 }
1973 break;
1974
1975 case ePluginGetInstanceAtIndex:
1976 if (index < g_plugin_instances.size())
1977 {
1978 instance = g_plugin_instances[index];
1979 return true;
1980 }
1981 break;
1982
1983 default:
1984 break;
1985 }
1986 return false;
1987}
1988
1989bool
1990PluginManager::RegisterPlugin
1991(
1992 const char *name,
1993 const char *description,
1994 ArchVolatileRegsCreateInstance create_callback
1995)
1996{
1997 if (create_callback)
1998 {
1999 ArchVolatileRegsInstance instance;
2000 assert (name && name[0]);
2001 instance.name = name;
2002 if (description && description[0])
2003 instance.description = description;
2004 instance.create_callback = create_callback;
2005 return AccessArchVolatileRegsInstances (ePluginRegisterInstance, instance, 0);
2006 }
2007 return false;
2008}
2009
2010bool
2011PluginManager::UnregisterPlugin (ArchVolatileRegsCreateInstance create_callback)
2012{
2013 if (create_callback)
2014 {
2015 ArchVolatileRegsInstance instance;
2016 instance.create_callback = create_callback;
2017 return AccessArchVolatileRegsInstances (ePluginUnregisterInstance, instance, 0);
2018 }
2019 return false;
2020}
2021
2022ArchVolatileRegsCreateInstance
2023PluginManager::GetArchVolatileRegsCreateCallbackAtIndex (uint32_t idx)
2024{
2025 ArchVolatileRegsInstance instance;
2026 if (AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx))
2027 return instance.create_callback;
2028 return NULL;
2029}
2030
2031ArchVolatileRegsCreateInstance
2032PluginManager::GetArchVolatileRegsCreateCallbackForPluginName (const char *name)
2033{
2034 if (name && name[0])
2035 {
2036 ArchVolatileRegsInstance instance;
2037 std::string ss_name(name);
2038 for (uint32_t idx = 0; AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
2039 {
2040 if (instance.name == ss_name)
2041 return instance.create_callback;
2042 }
2043 }
2044 return NULL;
2045}
Jason Molendafbcb7f22010-09-10 07:49:16 +00002046