blob: 12bb486865278612f8a2d683cfad4826b1df2ee5 [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
229static bool
230AccessABIInstances (PluginAction action, ABIInstance &instance, uint32_t index)
231{
232 static ABIInstances g_plugin_instances;
233
234 switch (action)
235 {
236 case ePluginRegisterInstance:
237 if (instance.create_callback)
238 {
239 g_plugin_instances.push_back (instance);
240 return true;
241 }
242 break;
243
244 case ePluginUnregisterInstance:
245 if (instance.create_callback)
246 {
247 ABIInstances::iterator pos, end = g_plugin_instances.end();
248 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
249 {
250 if (pos->create_callback == instance.create_callback)
251 {
252 g_plugin_instances.erase(pos);
253 return true;
254 }
255 }
256 }
257 break;
258
259 case ePluginGetInstanceAtIndex:
260 if (index < g_plugin_instances.size())
261 {
262 instance = g_plugin_instances[index];
263 return true;
264 }
265 break;
266
267 default:
268 break;
269 }
270 return false;
271}
272
273
274bool
275PluginManager::RegisterPlugin
Greg Clayton4272cc72011-02-02 02:24:04 +0000276(
277 const char *name,
278 const char *description,
279 ABICreateInstance create_callback
280)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281{
282 if (create_callback)
283 {
284 ABIInstance instance;
285 assert (name && name[0]);
286 instance.name = name;
287 if (description && description[0])
288 instance.description = description;
289 instance.create_callback = create_callback;
290 return AccessABIInstances (ePluginRegisterInstance, instance, 0);
291 }
292 return false;
293}
294
295bool
296PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
297{
298 if (create_callback)
299 {
300 ABIInstance instance;
301 instance.create_callback = create_callback;
302 return AccessABIInstances (ePluginUnregisterInstance, instance, 0);
303 }
304 return false;
305}
306
307ABICreateInstance
308PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
309{
310 ABIInstance instance;
311 if (AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx))
312 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000313 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314}
315
316ABICreateInstance
317PluginManager::GetABICreateCallbackForPluginName (const char *name)
318{
319 if (name && name[0])
320 {
321 ABIInstance instance;
322 std::string ss_name(name);
323 for (uint32_t idx = 0; AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
324 {
325 if (instance.name == ss_name)
326 return instance.create_callback;
327 }
328 }
329 return NULL;
330}
331
332
333#pragma mark Disassembler
334
335
Jason Molenda743e86a2010-06-11 23:44:18 +0000336struct DisassemblerInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337{
338 DisassemblerInstance() :
339 name(),
340 description(),
341 create_callback(NULL)
342 {
343 }
344
345 std::string name;
346 std::string description;
347 DisassemblerCreateInstance create_callback;
348};
349
350typedef std::vector<DisassemblerInstance> DisassemblerInstances;
351
352static bool
353AccessDisassemblerInstances (PluginAction action, DisassemblerInstance &instance, uint32_t index)
354{
355 static DisassemblerInstances g_plugin_instances;
356
357 switch (action)
358 {
359 case ePluginRegisterInstance:
360 if (instance.create_callback)
361 {
362 g_plugin_instances.push_back (instance);
363 return true;
364 }
365 break;
366
367 case ePluginUnregisterInstance:
368 if (instance.create_callback)
369 {
370 DisassemblerInstances::iterator pos, end = g_plugin_instances.end();
371 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
372 {
373 if (pos->create_callback == instance.create_callback)
374 {
375 g_plugin_instances.erase(pos);
376 return true;
377 }
378 }
379 }
380 break;
381
382 case ePluginGetInstanceAtIndex:
383 if (index < g_plugin_instances.size())
384 {
385 instance = g_plugin_instances[index];
386 return true;
387 }
388 break;
389
390 default:
391 break;
392 }
393 return false;
394}
395
396
397bool
398PluginManager::RegisterPlugin
399(
400 const char *name,
401 const char *description,
402 DisassemblerCreateInstance create_callback
403)
404{
405 if (create_callback)
406 {
407 DisassemblerInstance instance;
408 assert (name && name[0]);
409 instance.name = name;
410 if (description && description[0])
411 instance.description = description;
412 instance.create_callback = create_callback;
413 return AccessDisassemblerInstances (ePluginRegisterInstance, instance, 0);
414 }
415 return false;
416}
417
418bool
419PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
420{
421 if (create_callback)
422 {
423 DisassemblerInstance instance;
424 instance.create_callback = create_callback;
425 return AccessDisassemblerInstances (ePluginUnregisterInstance, instance, 0);
426 }
427 return false;
428}
429
430DisassemblerCreateInstance
431PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
432{
433 DisassemblerInstance instance;
434 if (AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx))
435 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000436 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437}
438
439DisassemblerCreateInstance
440PluginManager::GetDisassemblerCreateCallbackForPluginName (const char *name)
441{
442 if (name && name[0])
443 {
444 DisassemblerInstance instance;
445 std::string ss_name(name);
446 for (uint32_t idx = 0; AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
447 {
448 if (instance.name == ss_name)
449 return instance.create_callback;
450 }
451 }
452 return NULL;
453}
454
455
456
457#pragma mark DynamicLoader
458
459
Jason Molenda743e86a2010-06-11 23:44:18 +0000460struct DynamicLoaderInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461{
462 DynamicLoaderInstance() :
463 name(),
464 description(),
465 create_callback(NULL)
466 {
467 }
468
469 std::string name;
470 std::string description;
471 DynamicLoaderCreateInstance create_callback;
472};
473
474typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
475
476static bool
477AccessDynamicLoaderInstances (PluginAction action, DynamicLoaderInstance &instance, uint32_t index)
478{
479 static DynamicLoaderInstances g_plugin_instances;
480
481 switch (action)
482 {
483 case ePluginRegisterInstance:
484 if (instance.create_callback)
485 {
486 g_plugin_instances.push_back (instance);
487 return true;
488 }
489 break;
490
491 case ePluginUnregisterInstance:
492 if (instance.create_callback)
493 {
494 DynamicLoaderInstances::iterator pos, end = g_plugin_instances.end();
495 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
496 {
497 if (pos->create_callback == instance.create_callback)
498 {
499 g_plugin_instances.erase(pos);
500 return true;
501 }
502 }
503 }
504 break;
505
506 case ePluginGetInstanceAtIndex:
507 if (index < g_plugin_instances.size())
508 {
509 instance = g_plugin_instances[index];
510 return true;
511 }
512 break;
513
514 default:
515 break;
516 }
517 return false;
518}
519
520
521bool
522PluginManager::RegisterPlugin
523(
524 const char *name,
525 const char *description,
526 DynamicLoaderCreateInstance create_callback
527)
528{
529 if (create_callback)
530 {
531 DynamicLoaderInstance instance;
532 assert (name && name[0]);
533 instance.name = name;
534 if (description && description[0])
535 instance.description = description;
536 instance.create_callback = create_callback;
537 return AccessDynamicLoaderInstances (ePluginRegisterInstance, instance, 0);
538 }
539 return false;
540}
541
542bool
543PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
544{
545 if (create_callback)
546 {
547 DynamicLoaderInstance instance;
548 instance.create_callback = create_callback;
549 return AccessDynamicLoaderInstances (ePluginUnregisterInstance, instance, 0);
550 }
551 return false;
552}
553
554DynamicLoaderCreateInstance
555PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
556{
557 DynamicLoaderInstance instance;
558 if (AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx))
559 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000560 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000561}
562
563DynamicLoaderCreateInstance
564PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const char *name)
565{
566 if (name && name[0])
567 {
568 DynamicLoaderInstance instance;
569 std::string ss_name(name);
570 for (uint32_t idx = 0; AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
571 {
572 if (instance.name == ss_name)
573 return instance.create_callback;
574 }
575 }
576 return NULL;
577}
578
Greg Claytonf03bbe22011-02-01 01:37:45 +0000579#pragma mark EmulateInstruction
580
581
582struct EmulateInstructionInstance
583{
584 EmulateInstructionInstance() :
585 name(),
586 description(),
587 create_callback(NULL)
588 {
589 }
590
591 std::string name;
592 std::string description;
593 EmulateInstructionCreateInstance create_callback;
594};
595
596typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
597
598static bool
599AccessEmulateInstructionInstances (PluginAction action, EmulateInstructionInstance &instance, uint32_t index)
600{
601 static EmulateInstructionInstances g_plugin_instances;
602
603 switch (action)
604 {
605 case ePluginRegisterInstance:
606 if (instance.create_callback)
607 {
608 g_plugin_instances.push_back (instance);
609 return true;
610 }
611 break;
612
613 case ePluginUnregisterInstance:
614 if (instance.create_callback)
615 {
616 EmulateInstructionInstances::iterator pos, end = g_plugin_instances.end();
617 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
618 {
619 if (pos->create_callback == instance.create_callback)
620 {
621 g_plugin_instances.erase(pos);
622 return true;
623 }
624 }
625 }
626 break;
627
628 case ePluginGetInstanceAtIndex:
629 if (index < g_plugin_instances.size())
630 {
631 instance = g_plugin_instances[index];
632 return true;
633 }
634 break;
635
636 default:
637 break;
638 }
639 return false;
640}
641
642
643bool
644PluginManager::RegisterPlugin
645(
Greg Clayton4272cc72011-02-02 02:24:04 +0000646 const char *name,
647 const char *description,
648 EmulateInstructionCreateInstance create_callback
649)
Greg Claytonf03bbe22011-02-01 01:37:45 +0000650{
651 if (create_callback)
652 {
653 EmulateInstructionInstance instance;
654 assert (name && name[0]);
655 instance.name = name;
656 if (description && description[0])
657 instance.description = description;
658 instance.create_callback = create_callback;
659 return AccessEmulateInstructionInstances (ePluginRegisterInstance, instance, 0);
660 }
661 return false;
662}
663
664bool
665PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
666{
667 if (create_callback)
668 {
669 EmulateInstructionInstance instance;
670 instance.create_callback = create_callback;
671 return AccessEmulateInstructionInstances (ePluginUnregisterInstance, instance, 0);
672 }
673 return false;
674}
675
676EmulateInstructionCreateInstance
677PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
678{
679 EmulateInstructionInstance instance;
680 if (AccessEmulateInstructionInstances (ePluginGetInstanceAtIndex, instance, idx))
681 return instance.create_callback;
682 return NULL;
683}
684
685EmulateInstructionCreateInstance
686PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const char *name)
687{
688 if (name && name[0])
689 {
690 EmulateInstructionInstance instance;
691 std::string ss_name(name);
692 for (uint32_t idx = 0; AccessEmulateInstructionInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
693 {
694 if (instance.name == ss_name)
695 return instance.create_callback;
696 }
697 }
698 return NULL;
699}
700
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000701
Jim Ingham22777012010-09-23 02:01:19 +0000702#pragma mark LanguageRuntime
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703
704
Jim Ingham22777012010-09-23 02:01:19 +0000705struct LanguageRuntimeInstance
706{
707 LanguageRuntimeInstance() :
708 name(),
709 description(),
710 create_callback(NULL)
711 {
712 }
713
714 std::string name;
715 std::string description;
716 LanguageRuntimeCreateInstance create_callback;
717};
718
719typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
720
721static bool
722AccessLanguageRuntimeInstances (PluginAction action, LanguageRuntimeInstance &instance, uint32_t index)
723{
724 static LanguageRuntimeInstances g_plugin_instances;
725
726 switch (action)
727 {
728 case ePluginRegisterInstance:
729 if (instance.create_callback)
730 {
731 g_plugin_instances.push_back (instance);
732 return true;
733 }
734 break;
735
736 case ePluginUnregisterInstance:
737 if (instance.create_callback)
738 {
739 LanguageRuntimeInstances::iterator pos, end = g_plugin_instances.end();
740 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
741 {
742 if (pos->create_callback == instance.create_callback)
743 {
744 g_plugin_instances.erase(pos);
745 return true;
746 }
747 }
748 }
749 break;
750
751 case ePluginGetInstanceAtIndex:
752 if (index < g_plugin_instances.size())
753 {
754 instance = g_plugin_instances[index];
755 return true;
756 }
757 break;
758
759 default:
760 break;
761 }
762 return false;
763}
764
765
766bool
767PluginManager::RegisterPlugin
Greg Clayton4272cc72011-02-02 02:24:04 +0000768(
769 const char *name,
770 const char *description,
771 LanguageRuntimeCreateInstance create_callback
772)
Jim Ingham22777012010-09-23 02:01:19 +0000773{
774 if (create_callback)
775 {
776 LanguageRuntimeInstance instance;
777 assert (name && name[0]);
778 instance.name = name;
779 if (description && description[0])
780 instance.description = description;
781 instance.create_callback = create_callback;
782 return AccessLanguageRuntimeInstances (ePluginRegisterInstance, instance, 0);
783 }
784 return false;
785}
786
787bool
788PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
789{
790 if (create_callback)
791 {
792 LanguageRuntimeInstance instance;
793 instance.create_callback = create_callback;
794 return AccessLanguageRuntimeInstances (ePluginUnregisterInstance, instance, 0);
795 }
796 return false;
797}
798
799LanguageRuntimeCreateInstance
800PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
801{
802 LanguageRuntimeInstance instance;
803 if (AccessLanguageRuntimeInstances (ePluginGetInstanceAtIndex, instance, idx))
804 return instance.create_callback;
805 return NULL;
806}
807
808LanguageRuntimeCreateInstance
809PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const char *name)
810{
811 if (name && name[0])
812 {
813 LanguageRuntimeInstance instance;
814 std::string ss_name(name);
815 for (uint32_t idx = 0; AccessLanguageRuntimeInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
816 {
817 if (instance.name == ss_name)
818 return instance.create_callback;
819 }
820 }
821 return NULL;
822}
823
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000824#pragma mark ObjectFile
825
Jason Molenda743e86a2010-06-11 23:44:18 +0000826struct ObjectFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000827{
828 ObjectFileInstance() :
829 name(),
830 description(),
831 create_callback(NULL)
832 {
833 }
834
835 std::string name;
836 std::string description;
837 ObjectFileCreateInstance create_callback;
838};
839
840typedef std::vector<ObjectFileInstance> ObjectFileInstances;
841
842static bool
843AccessObjectFileInstances (PluginAction action, ObjectFileInstance &instance, uint32_t index)
844{
845 static ObjectFileInstances g_plugin_instances;
846
847 switch (action)
848 {
849 case ePluginRegisterInstance:
850 if (instance.create_callback)
851 {
852 g_plugin_instances.push_back (instance);
853 return true;
854 }
855 break;
856
857 case ePluginUnregisterInstance:
858 if (instance.create_callback)
859 {
860 ObjectFileInstances::iterator pos, end = g_plugin_instances.end();
861 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
862 {
863 if (pos->create_callback == instance.create_callback)
864 {
865 g_plugin_instances.erase(pos);
866 return true;
867 }
868 }
869 }
870 break;
871
872 case ePluginGetInstanceAtIndex:
873 if (index < g_plugin_instances.size())
874 {
875 instance = g_plugin_instances[index];
876 return true;
877 }
878 break;
879
880 default:
881 break;
882 }
883 return false;
884}
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;
903 return AccessObjectFileInstances (ePluginRegisterInstance, instance, 0);
904 }
905 return false;
906}
907
908bool
909PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
910{
911 if (create_callback)
912 {
913 ObjectFileInstance instance;
914 instance.create_callback = create_callback;
915 return AccessObjectFileInstances (ePluginUnregisterInstance, instance, 0);
916 }
917 return false;
918}
919
920ObjectFileCreateInstance
921PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
922{
923 ObjectFileInstance instance;
924 if (AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx))
925 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000926 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000927}
928ObjectFileCreateInstance
929PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name)
930{
931 if (name && name[0])
932 {
933 ObjectFileInstance instance;
934 std::string ss_name(name);
935 for (uint32_t idx = 0; AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
936 {
937 if (instance.name == ss_name)
938 return instance.create_callback;
939 }
940 }
941 return NULL;
942}
943
944
945
946#pragma mark ObjectContainer
947
Jason Molenda743e86a2010-06-11 23:44:18 +0000948struct ObjectContainerInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000949{
950 ObjectContainerInstance() :
951 name(),
952 description(),
953 create_callback(NULL)
954 {
955 }
956
957 std::string name;
958 std::string description;
959 ObjectContainerCreateInstance create_callback;
960};
961
962typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
963
964static bool
965AccessObjectContainerInstances (PluginAction action, ObjectContainerInstance &instance, uint32_t index)
966{
967 static ObjectContainerInstances g_plugin_instances;
968
969 switch (action)
970 {
971 case ePluginRegisterInstance:
972 if (instance.create_callback)
973 {
974 g_plugin_instances.push_back (instance);
975 return true;
976 }
977 break;
978
979 case ePluginUnregisterInstance:
980 if (instance.create_callback)
981 {
982 ObjectContainerInstances::iterator pos, end = g_plugin_instances.end();
983 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
984 {
985 if (pos->create_callback == instance.create_callback)
986 {
987 g_plugin_instances.erase(pos);
988 return true;
989 }
990 }
991 }
992 break;
993
994 case ePluginGetInstanceAtIndex:
995 if (index < g_plugin_instances.size())
996 {
997 instance = g_plugin_instances[index];
998 return true;
999 }
1000 break;
1001
1002 default:
1003 break;
1004 }
1005 return false;
1006}
1007
1008
1009bool
1010PluginManager::RegisterPlugin
1011(
1012 const char *name,
1013 const char *description,
1014 ObjectContainerCreateInstance create_callback
1015)
1016{
1017 if (create_callback)
1018 {
1019 ObjectContainerInstance instance;
1020 assert (name && name[0]);
1021 instance.name = name;
1022 if (description && description[0])
1023 instance.description = description;
1024 instance.create_callback = create_callback;
1025 return AccessObjectContainerInstances (ePluginRegisterInstance, instance, 0);
1026 }
1027 return false;
1028}
1029
1030bool
1031PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1032{
1033 if (create_callback)
1034 {
1035 ObjectContainerInstance instance;
1036 instance.create_callback = create_callback;
1037 return AccessObjectContainerInstances (ePluginUnregisterInstance, instance, 0);
1038 }
1039 return false;
1040}
1041
1042ObjectContainerCreateInstance
1043PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1044{
1045 ObjectContainerInstance instance;
1046 if (AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx))
1047 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001048 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001049}
1050ObjectContainerCreateInstance
1051PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name)
1052{
1053 if (name && name[0])
1054 {
1055 ObjectContainerInstance instance;
1056 std::string ss_name(name);
1057 for (uint32_t idx = 0; AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1058 {
1059 if (instance.name == ss_name)
1060 return instance.create_callback;
1061 }
1062 }
1063 return NULL;
1064}
1065
1066#pragma mark LogChannel
1067
Jason Molenda743e86a2010-06-11 23:44:18 +00001068struct LogChannelInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001069{
1070 LogChannelInstance() :
1071 name(),
1072 description(),
1073 create_callback(NULL)
1074 {
1075 }
1076
1077 std::string name;
1078 std::string description;
1079 LogChannelCreateInstance create_callback;
1080};
1081
1082typedef std::vector<LogChannelInstance> LogChannelInstances;
1083
1084static bool
1085AccessLogChannelInstances (PluginAction action, LogChannelInstance &instance, uint32_t index)
1086{
1087 static LogChannelInstances g_plugin_instances;
1088
1089 switch (action)
1090 {
1091 case ePluginRegisterInstance:
1092 if (instance.create_callback)
1093 {
1094 g_plugin_instances.push_back (instance);
1095 return true;
1096 }
1097 break;
1098
1099 case ePluginUnregisterInstance:
1100 if (instance.create_callback)
1101 {
1102 LogChannelInstances::iterator pos, end = g_plugin_instances.end();
1103 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1104 {
1105 if (pos->create_callback == instance.create_callback)
1106 {
1107 g_plugin_instances.erase(pos);
1108 return true;
1109 }
1110 }
1111 }
1112 break;
1113
1114 case ePluginGetInstanceAtIndex:
1115 if (index < g_plugin_instances.size())
1116 {
1117 instance = g_plugin_instances[index];
1118 return true;
1119 }
1120 break;
1121
1122 default:
1123 break;
1124 }
1125 return false;
1126}
1127
1128
1129bool
1130PluginManager::RegisterPlugin
1131(
1132 const char *name,
1133 const char *description,
1134 LogChannelCreateInstance create_callback
1135)
1136{
1137 if (create_callback)
1138 {
1139 LogChannelInstance instance;
1140 assert (name && name[0]);
1141 instance.name = name;
1142 if (description && description[0])
1143 instance.description = description;
1144 instance.create_callback = create_callback;
1145 return AccessLogChannelInstances (ePluginRegisterInstance, instance, 0);
1146 }
1147 return false;
1148}
1149
1150bool
1151PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1152{
1153 if (create_callback)
1154 {
1155 LogChannelInstance instance;
1156 instance.create_callback = create_callback;
1157 return AccessLogChannelInstances (ePluginUnregisterInstance, instance, 0);
1158 }
1159 return false;
1160}
1161
1162const char *
1163PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1164{
1165 LogChannelInstance instance;
1166 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx))
1167 return instance.name.c_str();
1168 return NULL;
1169}
1170
1171
1172LogChannelCreateInstance
1173PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1174{
1175 LogChannelInstance instance;
1176 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx))
1177 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001178 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179}
1180
1181LogChannelCreateInstance
1182PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name)
1183{
1184 if (name && name[0])
1185 {
1186 LogChannelInstance instance;
1187 std::string ss_name(name);
1188 for (uint32_t idx = 0; AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1189 {
1190 if (instance.name == ss_name)
1191 return instance.create_callback;
1192 }
1193 }
1194 return NULL;
1195}
1196
Greg Claytone996fd32011-03-08 22:40:15 +00001197#pragma mark Platform
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001198
Greg Claytone996fd32011-03-08 22:40:15 +00001199struct PlatformInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001200{
Greg Claytone996fd32011-03-08 22:40:15 +00001201 PlatformInstance() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001202 name(),
1203 description(),
1204 create_callback(NULL)
1205 {
1206 }
Greg Claytone996fd32011-03-08 22:40:15 +00001207
1208 std::string name;
1209 std::string description;
1210 PlatformCreateInstance create_callback;
1211};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001212
Greg Claytone996fd32011-03-08 22:40:15 +00001213typedef std::vector<PlatformInstance> PlatformInstances;
1214
1215static bool
1216AccessPlatformInstances (PluginAction action, PlatformInstance &instance, uint32_t index)
1217{
1218 static PlatformInstances g_plugin_instances;
1219
1220 switch (action)
1221 {
1222 case ePluginRegisterInstance:
1223 if (instance.create_callback)
1224 {
1225 g_plugin_instances.push_back (instance);
1226 return true;
1227 }
1228 break;
1229
1230 case ePluginUnregisterInstance:
1231 if (instance.create_callback)
1232 {
1233 PlatformInstances::iterator pos, end = g_plugin_instances.end();
1234 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1235 {
1236 if (pos->create_callback == instance.create_callback)
1237 {
1238 g_plugin_instances.erase(pos);
1239 return true;
1240 }
1241 }
1242 }
1243 break;
1244
1245 case ePluginGetInstanceAtIndex:
1246 if (index < g_plugin_instances.size())
1247 {
1248 instance = g_plugin_instances[index];
1249 return true;
1250 }
1251 break;
1252
1253 default:
1254 break;
1255 }
1256 return false;
1257}
1258
1259
1260bool
1261PluginManager::RegisterPlugin (const char *name,
1262 const char *description,
1263 PlatformCreateInstance create_callback)
1264{
1265 if (create_callback)
1266 {
1267 PlatformInstance instance;
1268 assert (name && name[0]);
1269 instance.name = name;
1270 if (description && description[0])
1271 instance.description = description;
1272 instance.create_callback = create_callback;
1273 return AccessPlatformInstances (ePluginRegisterInstance, instance, 0);
1274 }
1275 return false;
1276}
1277
1278const char *
1279PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1280{
1281 PlatformInstance instance;
1282 if (AccessPlatformInstances (ePluginGetInstanceAtIndex, instance, idx))
1283 return instance.name.c_str();
1284 return NULL;
1285}
1286
1287const char *
1288PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1289{
1290 PlatformInstance instance;
1291 if (AccessPlatformInstances (ePluginGetInstanceAtIndex, instance, idx))
1292 return instance.description.c_str();
1293 return NULL;
1294}
1295
1296bool
1297PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1298{
1299 if (create_callback)
1300 {
1301 PlatformInstance instance;
1302 instance.create_callback = create_callback;
1303 return AccessPlatformInstances (ePluginUnregisterInstance, instance, 0);
1304 }
1305 return false;
1306}
1307
1308PlatformCreateInstance
1309PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1310{
1311 PlatformInstance instance;
1312 if (AccessPlatformInstances (ePluginGetInstanceAtIndex, instance, idx))
1313 return instance.create_callback;
1314 return NULL;
1315}
1316
1317PlatformCreateInstance
1318PluginManager::GetPlatformCreateCallbackForPluginName (const char *name)
1319{
1320 if (name && name[0])
1321 {
1322 PlatformInstance instance;
1323 std::string ss_name(name);
1324 for (uint32_t idx = 0; AccessPlatformInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1325 {
1326 if (instance.name == ss_name)
1327 return instance.create_callback;
1328 }
1329 }
1330 return NULL;
1331}
1332
1333#pragma mark Process
1334
1335struct ProcessInstance
1336{
1337 ProcessInstance() :
1338 name(),
1339 description(),
1340 create_callback(NULL)
1341 {
1342 }
1343
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001344 std::string name;
1345 std::string description;
1346 ProcessCreateInstance create_callback;
1347};
1348
1349typedef std::vector<ProcessInstance> ProcessInstances;
1350
1351static bool
1352AccessProcessInstances (PluginAction action, ProcessInstance &instance, uint32_t index)
1353{
1354 static ProcessInstances g_plugin_instances;
Greg Claytone996fd32011-03-08 22:40:15 +00001355
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001356 switch (action)
1357 {
Greg Claytone996fd32011-03-08 22:40:15 +00001358 case ePluginRegisterInstance:
1359 if (instance.create_callback)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001360 {
Greg Claytone996fd32011-03-08 22:40:15 +00001361 g_plugin_instances.push_back (instance);
1362 return true;
1363 }
1364 break;
1365
1366 case ePluginUnregisterInstance:
1367 if (instance.create_callback)
1368 {
1369 ProcessInstances::iterator pos, end = g_plugin_instances.end();
1370 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001371 {
Greg Claytone996fd32011-03-08 22:40:15 +00001372 if (pos->create_callback == instance.create_callback)
1373 {
1374 g_plugin_instances.erase(pos);
1375 return true;
1376 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001377 }
1378 }
Greg Claytone996fd32011-03-08 22:40:15 +00001379 break;
1380
1381 case ePluginGetInstanceAtIndex:
1382 if (index < g_plugin_instances.size())
1383 {
1384 instance = g_plugin_instances[index];
1385 return true;
1386 }
1387 break;
1388
1389 default:
1390 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001391 }
1392 return false;
1393}
1394
1395
1396bool
1397PluginManager::RegisterPlugin
1398(
Greg Claytone996fd32011-03-08 22:40:15 +00001399 const char *name,
1400 const char *description,
1401 ProcessCreateInstance create_callback
1402 )
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001403{
1404 if (create_callback)
1405 {
1406 ProcessInstance instance;
1407 assert (name && name[0]);
1408 instance.name = name;
1409 if (description && description[0])
1410 instance.description = description;
1411 instance.create_callback = create_callback;
1412 return AccessProcessInstances (ePluginRegisterInstance, instance, 0);
1413 }
1414 return false;
1415}
1416
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001417const char *
1418PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1419{
1420 ProcessInstance instance;
1421 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1422 return instance.name.c_str();
1423 return NULL;
1424}
1425
1426const char *
1427PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1428{
1429 ProcessInstance instance;
1430 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1431 return instance.description.c_str();
1432 return NULL;
1433}
1434
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001435bool
1436PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1437{
1438 if (create_callback)
1439 {
1440 ProcessInstance instance;
1441 instance.create_callback = create_callback;
1442 return AccessProcessInstances (ePluginUnregisterInstance, instance, 0);
1443 }
1444 return false;
1445}
1446
1447ProcessCreateInstance
1448PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1449{
1450 ProcessInstance instance;
1451 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1452 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001453 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001454}
1455
1456ProcessCreateInstance
1457PluginManager::GetProcessCreateCallbackForPluginName (const char *name)
1458{
1459 if (name && name[0])
1460 {
1461 ProcessInstance instance;
1462 std::string ss_name(name);
1463 for (uint32_t idx = 0; AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1464 {
1465 if (instance.name == ss_name)
1466 return instance.create_callback;
1467 }
1468 }
1469 return NULL;
1470}
1471
1472#pragma mark SymbolFile
1473
Jason Molenda743e86a2010-06-11 23:44:18 +00001474struct SymbolFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001475{
1476 SymbolFileInstance() :
1477 name(),
1478 description(),
1479 create_callback(NULL)
1480 {
1481 }
1482
1483 std::string name;
1484 std::string description;
1485 SymbolFileCreateInstance create_callback;
1486};
1487
1488typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1489
1490static bool
1491AccessSymbolFileInstances (PluginAction action, SymbolFileInstance &instance, uint32_t index)
1492{
1493 static SymbolFileInstances g_plugin_instances;
1494
1495 switch (action)
1496 {
1497 case ePluginRegisterInstance:
1498 if (instance.create_callback)
1499 {
1500 g_plugin_instances.push_back (instance);
1501 return true;
1502 }
1503 break;
1504
1505 case ePluginUnregisterInstance:
1506 if (instance.create_callback)
1507 {
1508 SymbolFileInstances::iterator pos, end = g_plugin_instances.end();
1509 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1510 {
1511 if (pos->create_callback == instance.create_callback)
1512 {
1513 g_plugin_instances.erase(pos);
1514 return true;
1515 }
1516 }
1517 }
1518 break;
1519
1520 case ePluginGetInstanceAtIndex:
1521 if (index < g_plugin_instances.size())
1522 {
1523 instance = g_plugin_instances[index];
1524 return true;
1525 }
1526 break;
1527
1528 default:
1529 break;
1530 }
1531 return false;
1532}
1533
1534
1535bool
1536PluginManager::RegisterPlugin
1537(
1538 const char *name,
1539 const char *description,
1540 SymbolFileCreateInstance create_callback
1541)
1542{
1543 if (create_callback)
1544 {
1545 SymbolFileInstance instance;
1546 assert (name && name[0]);
1547 instance.name = name;
1548 if (description && description[0])
1549 instance.description = description;
1550 instance.create_callback = create_callback;
1551 return AccessSymbolFileInstances (ePluginRegisterInstance, instance, 0);
1552 }
1553 return false;
1554}
1555
1556bool
1557PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1558{
1559 if (create_callback)
1560 {
1561 SymbolFileInstance instance;
1562 instance.create_callback = create_callback;
1563 return AccessSymbolFileInstances (ePluginUnregisterInstance, instance, 0);
1564 }
1565 return false;
1566}
1567
1568SymbolFileCreateInstance
1569PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1570{
1571 SymbolFileInstance instance;
1572 if (AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx))
1573 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001574 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001575}
1576SymbolFileCreateInstance
1577PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name)
1578{
1579 if (name && name[0])
1580 {
1581 SymbolFileInstance instance;
1582 std::string ss_name(name);
1583 for (uint32_t idx = 0; AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1584 {
1585 if (instance.name == ss_name)
1586 return instance.create_callback;
1587 }
1588 }
1589 return NULL;
1590}
1591
1592
1593
1594#pragma mark SymbolVendor
1595
Jason Molenda743e86a2010-06-11 23:44:18 +00001596struct SymbolVendorInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001597{
1598 SymbolVendorInstance() :
1599 name(),
1600 description(),
1601 create_callback(NULL)
1602 {
1603 }
1604
1605 std::string name;
1606 std::string description;
1607 SymbolVendorCreateInstance create_callback;
1608};
1609
1610typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1611
1612static bool
1613AccessSymbolVendorInstances (PluginAction action, SymbolVendorInstance &instance, uint32_t index)
1614{
1615 static SymbolVendorInstances g_plugin_instances;
1616
1617 switch (action)
1618 {
1619 case ePluginRegisterInstance:
1620 if (instance.create_callback)
1621 {
1622 g_plugin_instances.push_back (instance);
1623 return true;
1624 }
1625 break;
1626
1627 case ePluginUnregisterInstance:
1628 if (instance.create_callback)
1629 {
1630 SymbolVendorInstances::iterator pos, end = g_plugin_instances.end();
1631 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1632 {
1633 if (pos->create_callback == instance.create_callback)
1634 {
1635 g_plugin_instances.erase(pos);
1636 return true;
1637 }
1638 }
1639 }
1640 break;
1641
1642 case ePluginGetInstanceAtIndex:
1643 if (index < g_plugin_instances.size())
1644 {
1645 instance = g_plugin_instances[index];
1646 return true;
1647 }
1648 break;
1649
1650 default:
1651 break;
1652 }
1653 return false;
1654}
1655
1656bool
1657PluginManager::RegisterPlugin
1658(
1659 const char *name,
1660 const char *description,
1661 SymbolVendorCreateInstance create_callback
1662)
1663{
1664 if (create_callback)
1665 {
1666 SymbolVendorInstance instance;
1667 assert (name && name[0]);
1668 instance.name = name;
1669 if (description && description[0])
1670 instance.description = description;
1671 instance.create_callback = create_callback;
1672 return AccessSymbolVendorInstances (ePluginRegisterInstance, instance, 0);
1673 }
1674 return false;
1675}
1676
1677bool
1678PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1679{
1680 if (create_callback)
1681 {
1682 SymbolVendorInstance instance;
1683 instance.create_callback = create_callback;
1684 return AccessSymbolVendorInstances (ePluginUnregisterInstance, instance, 0);
1685 }
1686 return false;
1687}
1688
1689SymbolVendorCreateInstance
1690PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1691{
1692 SymbolVendorInstance instance;
1693 if (AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx))
1694 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001695 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001696}
1697
1698SymbolVendorCreateInstance
1699PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name)
1700{
1701 if (name && name[0])
1702 {
1703 SymbolVendorInstance instance;
1704 std::string ss_name(name);
1705 for (uint32_t idx = 0; AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1706 {
1707 if (instance.name == ss_name)
1708 return instance.create_callback;
1709 }
1710 }
1711 return NULL;
1712}
1713
1714
Jason Molendafbcb7f22010-09-10 07:49:16 +00001715#pragma mark UnwindAssemblyProfiler
1716
1717struct UnwindAssemblyProfilerInstance
1718{
1719 UnwindAssemblyProfilerInstance() :
1720 name(),
1721 description(),
1722 create_callback(NULL)
1723 {
1724 }
1725
1726 std::string name;
1727 std::string description;
1728 UnwindAssemblyProfilerCreateInstance create_callback;
1729};
1730
1731typedef std::vector<UnwindAssemblyProfilerInstance> UnwindAssemblyProfilerInstances;
1732
1733static bool
1734AccessUnwindAssemblyProfilerInstances (PluginAction action, UnwindAssemblyProfilerInstance &instance, uint32_t index)
1735{
1736 static UnwindAssemblyProfilerInstances g_plugin_instances;
1737
1738 switch (action)
1739 {
1740 case ePluginRegisterInstance:
1741 if (instance.create_callback)
1742 {
1743 g_plugin_instances.push_back (instance);
1744 return true;
1745 }
1746 break;
1747
1748 case ePluginUnregisterInstance:
1749 if (instance.create_callback)
1750 {
1751 UnwindAssemblyProfilerInstances::iterator pos, end = g_plugin_instances.end();
1752 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1753 {
1754 if (pos->create_callback == instance.create_callback)
1755 {
1756 g_plugin_instances.erase(pos);
1757 return true;
1758 }
1759 }
1760 }
1761 break;
1762
1763 case ePluginGetInstanceAtIndex:
1764 if (index < g_plugin_instances.size())
1765 {
1766 instance = g_plugin_instances[index];
1767 return true;
1768 }
1769 break;
1770
1771 default:
1772 break;
1773 }
1774 return false;
1775}
1776
1777bool
1778PluginManager::RegisterPlugin
1779(
1780 const char *name,
1781 const char *description,
1782 UnwindAssemblyProfilerCreateInstance create_callback
1783)
1784{
1785 if (create_callback)
1786 {
1787 UnwindAssemblyProfilerInstance instance;
1788 assert (name && name[0]);
1789 instance.name = name;
1790 if (description && description[0])
1791 instance.description = description;
1792 instance.create_callback = create_callback;
1793 return AccessUnwindAssemblyProfilerInstances (ePluginRegisterInstance, instance, 0);
1794 }
1795 return false;
1796}
1797
1798bool
1799PluginManager::UnregisterPlugin (UnwindAssemblyProfilerCreateInstance create_callback)
1800{
1801 if (create_callback)
1802 {
1803 UnwindAssemblyProfilerInstance instance;
1804 instance.create_callback = create_callback;
1805 return AccessUnwindAssemblyProfilerInstances (ePluginUnregisterInstance, instance, 0);
1806 }
1807 return false;
1808}
1809
1810UnwindAssemblyProfilerCreateInstance
1811PluginManager::GetUnwindAssemblyProfilerCreateCallbackAtIndex (uint32_t idx)
1812{
1813 UnwindAssemblyProfilerInstance instance;
1814 if (AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx))
1815 return instance.create_callback;
1816 return NULL;
1817}
1818
1819UnwindAssemblyProfilerCreateInstance
1820PluginManager::GetUnwindAssemblyProfilerCreateCallbackForPluginName (const char *name)
1821{
1822 if (name && name[0])
1823 {
1824 UnwindAssemblyProfilerInstance instance;
1825 std::string ss_name(name);
1826 for (uint32_t idx = 0; AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1827 {
1828 if (instance.name == ss_name)
1829 return instance.create_callback;
1830 }
1831 }
1832 return NULL;
1833}
1834
1835#pragma mark ArchDefaultUnwindPlan
1836
1837struct ArchDefaultUnwindPlanInstance
1838{
1839 ArchDefaultUnwindPlanInstance() :
1840 name(),
1841 description(),
1842 create_callback(NULL)
1843 {
1844 }
1845
1846 std::string name;
1847 std::string description;
1848 ArchDefaultUnwindPlanCreateInstance create_callback;
1849};
1850
1851typedef std::vector<ArchDefaultUnwindPlanInstance> ArchDefaultUnwindPlanInstances;
1852
1853static bool
1854AccessArchDefaultUnwindPlanInstances (PluginAction action, ArchDefaultUnwindPlanInstance &instance, uint32_t index)
1855{
1856 static ArchDefaultUnwindPlanInstances g_plugin_instances;
1857
1858 switch (action)
1859 {
1860 case ePluginRegisterInstance:
1861 if (instance.create_callback)
1862 {
1863 g_plugin_instances.push_back (instance);
1864 return true;
1865 }
1866 break;
1867
1868 case ePluginUnregisterInstance:
1869 if (instance.create_callback)
1870 {
1871 ArchDefaultUnwindPlanInstances::iterator pos, end = g_plugin_instances.end();
1872 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1873 {
1874 if (pos->create_callback == instance.create_callback)
1875 {
1876 g_plugin_instances.erase(pos);
1877 return true;
1878 }
1879 }
1880 }
1881 break;
1882
1883 case ePluginGetInstanceAtIndex:
1884 if (index < g_plugin_instances.size())
1885 {
1886 instance = g_plugin_instances[index];
1887 return true;
1888 }
1889 break;
1890
1891 default:
1892 break;
1893 }
1894 return false;
1895}
1896
1897bool
1898PluginManager::RegisterPlugin
1899(
1900 const char *name,
1901 const char *description,
1902 ArchDefaultUnwindPlanCreateInstance create_callback
1903)
1904{
1905 if (create_callback)
1906 {
1907 ArchDefaultUnwindPlanInstance instance;
1908 assert (name && name[0]);
1909 instance.name = name;
1910 if (description && description[0])
1911 instance.description = description;
1912 instance.create_callback = create_callback;
1913 return AccessArchDefaultUnwindPlanInstances (ePluginRegisterInstance, instance, 0);
1914 }
1915 return false;
1916}
1917
1918bool
1919PluginManager::UnregisterPlugin (ArchDefaultUnwindPlanCreateInstance create_callback)
1920{
1921 if (create_callback)
1922 {
1923 ArchDefaultUnwindPlanInstance instance;
1924 instance.create_callback = create_callback;
1925 return AccessArchDefaultUnwindPlanInstances (ePluginUnregisterInstance, instance, 0);
1926 }
1927 return false;
1928}
1929
1930ArchDefaultUnwindPlanCreateInstance
1931PluginManager::GetArchDefaultUnwindPlanCreateCallbackAtIndex (uint32_t idx)
1932{
1933 ArchDefaultUnwindPlanInstance instance;
1934 if (AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx))
1935 return instance.create_callback;
1936 return NULL;
1937}
1938
1939ArchDefaultUnwindPlanCreateInstance
1940PluginManager::GetArchDefaultUnwindPlanCreateCallbackForPluginName (const char *name)
1941{
1942 if (name && name[0])
1943 {
1944 ArchDefaultUnwindPlanInstance instance;
1945 std::string ss_name(name);
1946 for (uint32_t idx = 0; AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1947 {
1948 if (instance.name == ss_name)
1949 return instance.create_callback;
1950 }
1951 }
1952 return NULL;
1953}
1954
Jason Molenda0c7cc852010-09-22 07:37:07 +00001955#pragma mark ArchVolatileRegs
1956
1957struct ArchVolatileRegsInstance
1958{
1959 ArchVolatileRegsInstance() :
1960 name(),
1961 description(),
1962 create_callback(NULL)
1963 {
1964 }
1965
1966 std::string name;
1967 std::string description;
1968 ArchVolatileRegsCreateInstance create_callback;
1969};
1970
1971typedef std::vector<ArchVolatileRegsInstance> ArchVolatileRegsInstances;
1972
1973static bool
1974AccessArchVolatileRegsInstances (PluginAction action, ArchVolatileRegsInstance &instance, uint32_t index)
1975{
1976 static ArchVolatileRegsInstances g_plugin_instances;
1977
1978 switch (action)
1979 {
1980 case ePluginRegisterInstance:
1981 if (instance.create_callback)
1982 {
1983 g_plugin_instances.push_back (instance);
1984 return true;
1985 }
1986 break;
1987
1988 case ePluginUnregisterInstance:
1989 if (instance.create_callback)
1990 {
1991 ArchVolatileRegsInstances::iterator pos, end = g_plugin_instances.end();
1992 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1993 {
1994 if (pos->create_callback == instance.create_callback)
1995 {
1996 g_plugin_instances.erase(pos);
1997 return true;
1998 }
1999 }
2000 }
2001 break;
2002
2003 case ePluginGetInstanceAtIndex:
2004 if (index < g_plugin_instances.size())
2005 {
2006 instance = g_plugin_instances[index];
2007 return true;
2008 }
2009 break;
2010
2011 default:
2012 break;
2013 }
2014 return false;
2015}
2016
2017bool
2018PluginManager::RegisterPlugin
2019(
2020 const char *name,
2021 const char *description,
2022 ArchVolatileRegsCreateInstance create_callback
2023)
2024{
2025 if (create_callback)
2026 {
2027 ArchVolatileRegsInstance instance;
2028 assert (name && name[0]);
2029 instance.name = name;
2030 if (description && description[0])
2031 instance.description = description;
2032 instance.create_callback = create_callback;
2033 return AccessArchVolatileRegsInstances (ePluginRegisterInstance, instance, 0);
2034 }
2035 return false;
2036}
2037
2038bool
2039PluginManager::UnregisterPlugin (ArchVolatileRegsCreateInstance create_callback)
2040{
2041 if (create_callback)
2042 {
2043 ArchVolatileRegsInstance instance;
2044 instance.create_callback = create_callback;
2045 return AccessArchVolatileRegsInstances (ePluginUnregisterInstance, instance, 0);
2046 }
2047 return false;
2048}
2049
2050ArchVolatileRegsCreateInstance
2051PluginManager::GetArchVolatileRegsCreateCallbackAtIndex (uint32_t idx)
2052{
2053 ArchVolatileRegsInstance instance;
2054 if (AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx))
2055 return instance.create_callback;
2056 return NULL;
2057}
2058
2059ArchVolatileRegsCreateInstance
2060PluginManager::GetArchVolatileRegsCreateCallbackForPluginName (const char *name)
2061{
2062 if (name && name[0])
2063 {
2064 ArchVolatileRegsInstance instance;
2065 std::string ss_name(name);
2066 for (uint32_t idx = 0; AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
2067 {
2068 if (instance.name == ss_name)
2069 return instance.create_callback;
2070 }
2071 }
2072 return NULL;
2073}
Jason Molendafbcb7f22010-09-10 07:49:16 +00002074