blob: 3c2907ed239cc2f23b51c2ba9a502a3a96be54ef [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
1197#pragma mark Process
1198
Jason Molenda743e86a2010-06-11 23:44:18 +00001199struct ProcessInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001200{
1201 ProcessInstance() :
1202 name(),
1203 description(),
1204 create_callback(NULL)
1205 {
1206 }
1207
1208 std::string name;
1209 std::string description;
1210 ProcessCreateInstance create_callback;
1211};
1212
1213typedef std::vector<ProcessInstance> ProcessInstances;
1214
1215static bool
1216AccessProcessInstances (PluginAction action, ProcessInstance &instance, uint32_t index)
1217{
1218 static ProcessInstances 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 ProcessInstances::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
1262(
1263 const char *name,
1264 const char *description,
1265 ProcessCreateInstance create_callback
1266)
1267{
1268 if (create_callback)
1269 {
1270 ProcessInstance instance;
1271 assert (name && name[0]);
1272 instance.name = name;
1273 if (description && description[0])
1274 instance.description = description;
1275 instance.create_callback = create_callback;
1276 return AccessProcessInstances (ePluginRegisterInstance, instance, 0);
1277 }
1278 return false;
1279}
1280
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001281const char *
1282PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1283{
1284 ProcessInstance instance;
1285 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1286 return instance.name.c_str();
1287 return NULL;
1288}
1289
1290const char *
1291PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1292{
1293 ProcessInstance instance;
1294 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1295 return instance.description.c_str();
1296 return NULL;
1297}
1298
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001299bool
1300PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1301{
1302 if (create_callback)
1303 {
1304 ProcessInstance instance;
1305 instance.create_callback = create_callback;
1306 return AccessProcessInstances (ePluginUnregisterInstance, instance, 0);
1307 }
1308 return false;
1309}
1310
1311ProcessCreateInstance
1312PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1313{
1314 ProcessInstance instance;
1315 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1316 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001317 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001318}
1319
1320ProcessCreateInstance
1321PluginManager::GetProcessCreateCallbackForPluginName (const char *name)
1322{
1323 if (name && name[0])
1324 {
1325 ProcessInstance instance;
1326 std::string ss_name(name);
1327 for (uint32_t idx = 0; AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1328 {
1329 if (instance.name == ss_name)
1330 return instance.create_callback;
1331 }
1332 }
1333 return NULL;
1334}
1335
1336#pragma mark SymbolFile
1337
Jason Molenda743e86a2010-06-11 23:44:18 +00001338struct SymbolFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001339{
1340 SymbolFileInstance() :
1341 name(),
1342 description(),
1343 create_callback(NULL)
1344 {
1345 }
1346
1347 std::string name;
1348 std::string description;
1349 SymbolFileCreateInstance create_callback;
1350};
1351
1352typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1353
1354static bool
1355AccessSymbolFileInstances (PluginAction action, SymbolFileInstance &instance, uint32_t index)
1356{
1357 static SymbolFileInstances g_plugin_instances;
1358
1359 switch (action)
1360 {
1361 case ePluginRegisterInstance:
1362 if (instance.create_callback)
1363 {
1364 g_plugin_instances.push_back (instance);
1365 return true;
1366 }
1367 break;
1368
1369 case ePluginUnregisterInstance:
1370 if (instance.create_callback)
1371 {
1372 SymbolFileInstances::iterator pos, end = g_plugin_instances.end();
1373 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1374 {
1375 if (pos->create_callback == instance.create_callback)
1376 {
1377 g_plugin_instances.erase(pos);
1378 return true;
1379 }
1380 }
1381 }
1382 break;
1383
1384 case ePluginGetInstanceAtIndex:
1385 if (index < g_plugin_instances.size())
1386 {
1387 instance = g_plugin_instances[index];
1388 return true;
1389 }
1390 break;
1391
1392 default:
1393 break;
1394 }
1395 return false;
1396}
1397
1398
1399bool
1400PluginManager::RegisterPlugin
1401(
1402 const char *name,
1403 const char *description,
1404 SymbolFileCreateInstance create_callback
1405)
1406{
1407 if (create_callback)
1408 {
1409 SymbolFileInstance instance;
1410 assert (name && name[0]);
1411 instance.name = name;
1412 if (description && description[0])
1413 instance.description = description;
1414 instance.create_callback = create_callback;
1415 return AccessSymbolFileInstances (ePluginRegisterInstance, instance, 0);
1416 }
1417 return false;
1418}
1419
1420bool
1421PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1422{
1423 if (create_callback)
1424 {
1425 SymbolFileInstance instance;
1426 instance.create_callback = create_callback;
1427 return AccessSymbolFileInstances (ePluginUnregisterInstance, instance, 0);
1428 }
1429 return false;
1430}
1431
1432SymbolFileCreateInstance
1433PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1434{
1435 SymbolFileInstance instance;
1436 if (AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx))
1437 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001438 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001439}
1440SymbolFileCreateInstance
1441PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name)
1442{
1443 if (name && name[0])
1444 {
1445 SymbolFileInstance instance;
1446 std::string ss_name(name);
1447 for (uint32_t idx = 0; AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1448 {
1449 if (instance.name == ss_name)
1450 return instance.create_callback;
1451 }
1452 }
1453 return NULL;
1454}
1455
1456
1457
1458#pragma mark SymbolVendor
1459
Jason Molenda743e86a2010-06-11 23:44:18 +00001460struct SymbolVendorInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001461{
1462 SymbolVendorInstance() :
1463 name(),
1464 description(),
1465 create_callback(NULL)
1466 {
1467 }
1468
1469 std::string name;
1470 std::string description;
1471 SymbolVendorCreateInstance create_callback;
1472};
1473
1474typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1475
1476static bool
1477AccessSymbolVendorInstances (PluginAction action, SymbolVendorInstance &instance, uint32_t index)
1478{
1479 static SymbolVendorInstances g_plugin_instances;
1480
1481 switch (action)
1482 {
1483 case ePluginRegisterInstance:
1484 if (instance.create_callback)
1485 {
1486 g_plugin_instances.push_back (instance);
1487 return true;
1488 }
1489 break;
1490
1491 case ePluginUnregisterInstance:
1492 if (instance.create_callback)
1493 {
1494 SymbolVendorInstances::iterator pos, end = g_plugin_instances.end();
1495 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1496 {
1497 if (pos->create_callback == instance.create_callback)
1498 {
1499 g_plugin_instances.erase(pos);
1500 return true;
1501 }
1502 }
1503 }
1504 break;
1505
1506 case ePluginGetInstanceAtIndex:
1507 if (index < g_plugin_instances.size())
1508 {
1509 instance = g_plugin_instances[index];
1510 return true;
1511 }
1512 break;
1513
1514 default:
1515 break;
1516 }
1517 return false;
1518}
1519
1520bool
1521PluginManager::RegisterPlugin
1522(
1523 const char *name,
1524 const char *description,
1525 SymbolVendorCreateInstance create_callback
1526)
1527{
1528 if (create_callback)
1529 {
1530 SymbolVendorInstance instance;
1531 assert (name && name[0]);
1532 instance.name = name;
1533 if (description && description[0])
1534 instance.description = description;
1535 instance.create_callback = create_callback;
1536 return AccessSymbolVendorInstances (ePluginRegisterInstance, instance, 0);
1537 }
1538 return false;
1539}
1540
1541bool
1542PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1543{
1544 if (create_callback)
1545 {
1546 SymbolVendorInstance instance;
1547 instance.create_callback = create_callback;
1548 return AccessSymbolVendorInstances (ePluginUnregisterInstance, instance, 0);
1549 }
1550 return false;
1551}
1552
1553SymbolVendorCreateInstance
1554PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1555{
1556 SymbolVendorInstance instance;
1557 if (AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx))
1558 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001559 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001560}
1561
1562SymbolVendorCreateInstance
1563PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name)
1564{
1565 if (name && name[0])
1566 {
1567 SymbolVendorInstance instance;
1568 std::string ss_name(name);
1569 for (uint32_t idx = 0; AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1570 {
1571 if (instance.name == ss_name)
1572 return instance.create_callback;
1573 }
1574 }
1575 return NULL;
1576}
1577
1578
Jason Molendafbcb7f22010-09-10 07:49:16 +00001579#pragma mark UnwindAssemblyProfiler
1580
1581struct UnwindAssemblyProfilerInstance
1582{
1583 UnwindAssemblyProfilerInstance() :
1584 name(),
1585 description(),
1586 create_callback(NULL)
1587 {
1588 }
1589
1590 std::string name;
1591 std::string description;
1592 UnwindAssemblyProfilerCreateInstance create_callback;
1593};
1594
1595typedef std::vector<UnwindAssemblyProfilerInstance> UnwindAssemblyProfilerInstances;
1596
1597static bool
1598AccessUnwindAssemblyProfilerInstances (PluginAction action, UnwindAssemblyProfilerInstance &instance, uint32_t index)
1599{
1600 static UnwindAssemblyProfilerInstances g_plugin_instances;
1601
1602 switch (action)
1603 {
1604 case ePluginRegisterInstance:
1605 if (instance.create_callback)
1606 {
1607 g_plugin_instances.push_back (instance);
1608 return true;
1609 }
1610 break;
1611
1612 case ePluginUnregisterInstance:
1613 if (instance.create_callback)
1614 {
1615 UnwindAssemblyProfilerInstances::iterator pos, end = g_plugin_instances.end();
1616 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1617 {
1618 if (pos->create_callback == instance.create_callback)
1619 {
1620 g_plugin_instances.erase(pos);
1621 return true;
1622 }
1623 }
1624 }
1625 break;
1626
1627 case ePluginGetInstanceAtIndex:
1628 if (index < g_plugin_instances.size())
1629 {
1630 instance = g_plugin_instances[index];
1631 return true;
1632 }
1633 break;
1634
1635 default:
1636 break;
1637 }
1638 return false;
1639}
1640
1641bool
1642PluginManager::RegisterPlugin
1643(
1644 const char *name,
1645 const char *description,
1646 UnwindAssemblyProfilerCreateInstance create_callback
1647)
1648{
1649 if (create_callback)
1650 {
1651 UnwindAssemblyProfilerInstance instance;
1652 assert (name && name[0]);
1653 instance.name = name;
1654 if (description && description[0])
1655 instance.description = description;
1656 instance.create_callback = create_callback;
1657 return AccessUnwindAssemblyProfilerInstances (ePluginRegisterInstance, instance, 0);
1658 }
1659 return false;
1660}
1661
1662bool
1663PluginManager::UnregisterPlugin (UnwindAssemblyProfilerCreateInstance create_callback)
1664{
1665 if (create_callback)
1666 {
1667 UnwindAssemblyProfilerInstance instance;
1668 instance.create_callback = create_callback;
1669 return AccessUnwindAssemblyProfilerInstances (ePluginUnregisterInstance, instance, 0);
1670 }
1671 return false;
1672}
1673
1674UnwindAssemblyProfilerCreateInstance
1675PluginManager::GetUnwindAssemblyProfilerCreateCallbackAtIndex (uint32_t idx)
1676{
1677 UnwindAssemblyProfilerInstance instance;
1678 if (AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx))
1679 return instance.create_callback;
1680 return NULL;
1681}
1682
1683UnwindAssemblyProfilerCreateInstance
1684PluginManager::GetUnwindAssemblyProfilerCreateCallbackForPluginName (const char *name)
1685{
1686 if (name && name[0])
1687 {
1688 UnwindAssemblyProfilerInstance instance;
1689 std::string ss_name(name);
1690 for (uint32_t idx = 0; AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1691 {
1692 if (instance.name == ss_name)
1693 return instance.create_callback;
1694 }
1695 }
1696 return NULL;
1697}
1698
1699#pragma mark ArchDefaultUnwindPlan
1700
1701struct ArchDefaultUnwindPlanInstance
1702{
1703 ArchDefaultUnwindPlanInstance() :
1704 name(),
1705 description(),
1706 create_callback(NULL)
1707 {
1708 }
1709
1710 std::string name;
1711 std::string description;
1712 ArchDefaultUnwindPlanCreateInstance create_callback;
1713};
1714
1715typedef std::vector<ArchDefaultUnwindPlanInstance> ArchDefaultUnwindPlanInstances;
1716
1717static bool
1718AccessArchDefaultUnwindPlanInstances (PluginAction action, ArchDefaultUnwindPlanInstance &instance, uint32_t index)
1719{
1720 static ArchDefaultUnwindPlanInstances g_plugin_instances;
1721
1722 switch (action)
1723 {
1724 case ePluginRegisterInstance:
1725 if (instance.create_callback)
1726 {
1727 g_plugin_instances.push_back (instance);
1728 return true;
1729 }
1730 break;
1731
1732 case ePluginUnregisterInstance:
1733 if (instance.create_callback)
1734 {
1735 ArchDefaultUnwindPlanInstances::iterator pos, end = g_plugin_instances.end();
1736 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1737 {
1738 if (pos->create_callback == instance.create_callback)
1739 {
1740 g_plugin_instances.erase(pos);
1741 return true;
1742 }
1743 }
1744 }
1745 break;
1746
1747 case ePluginGetInstanceAtIndex:
1748 if (index < g_plugin_instances.size())
1749 {
1750 instance = g_plugin_instances[index];
1751 return true;
1752 }
1753 break;
1754
1755 default:
1756 break;
1757 }
1758 return false;
1759}
1760
1761bool
1762PluginManager::RegisterPlugin
1763(
1764 const char *name,
1765 const char *description,
1766 ArchDefaultUnwindPlanCreateInstance create_callback
1767)
1768{
1769 if (create_callback)
1770 {
1771 ArchDefaultUnwindPlanInstance instance;
1772 assert (name && name[0]);
1773 instance.name = name;
1774 if (description && description[0])
1775 instance.description = description;
1776 instance.create_callback = create_callback;
1777 return AccessArchDefaultUnwindPlanInstances (ePluginRegisterInstance, instance, 0);
1778 }
1779 return false;
1780}
1781
1782bool
1783PluginManager::UnregisterPlugin (ArchDefaultUnwindPlanCreateInstance create_callback)
1784{
1785 if (create_callback)
1786 {
1787 ArchDefaultUnwindPlanInstance instance;
1788 instance.create_callback = create_callback;
1789 return AccessArchDefaultUnwindPlanInstances (ePluginUnregisterInstance, instance, 0);
1790 }
1791 return false;
1792}
1793
1794ArchDefaultUnwindPlanCreateInstance
1795PluginManager::GetArchDefaultUnwindPlanCreateCallbackAtIndex (uint32_t idx)
1796{
1797 ArchDefaultUnwindPlanInstance instance;
1798 if (AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx))
1799 return instance.create_callback;
1800 return NULL;
1801}
1802
1803ArchDefaultUnwindPlanCreateInstance
1804PluginManager::GetArchDefaultUnwindPlanCreateCallbackForPluginName (const char *name)
1805{
1806 if (name && name[0])
1807 {
1808 ArchDefaultUnwindPlanInstance instance;
1809 std::string ss_name(name);
1810 for (uint32_t idx = 0; AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1811 {
1812 if (instance.name == ss_name)
1813 return instance.create_callback;
1814 }
1815 }
1816 return NULL;
1817}
1818
Jason Molenda0c7cc852010-09-22 07:37:07 +00001819#pragma mark ArchVolatileRegs
1820
1821struct ArchVolatileRegsInstance
1822{
1823 ArchVolatileRegsInstance() :
1824 name(),
1825 description(),
1826 create_callback(NULL)
1827 {
1828 }
1829
1830 std::string name;
1831 std::string description;
1832 ArchVolatileRegsCreateInstance create_callback;
1833};
1834
1835typedef std::vector<ArchVolatileRegsInstance> ArchVolatileRegsInstances;
1836
1837static bool
1838AccessArchVolatileRegsInstances (PluginAction action, ArchVolatileRegsInstance &instance, uint32_t index)
1839{
1840 static ArchVolatileRegsInstances g_plugin_instances;
1841
1842 switch (action)
1843 {
1844 case ePluginRegisterInstance:
1845 if (instance.create_callback)
1846 {
1847 g_plugin_instances.push_back (instance);
1848 return true;
1849 }
1850 break;
1851
1852 case ePluginUnregisterInstance:
1853 if (instance.create_callback)
1854 {
1855 ArchVolatileRegsInstances::iterator pos, end = g_plugin_instances.end();
1856 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1857 {
1858 if (pos->create_callback == instance.create_callback)
1859 {
1860 g_plugin_instances.erase(pos);
1861 return true;
1862 }
1863 }
1864 }
1865 break;
1866
1867 case ePluginGetInstanceAtIndex:
1868 if (index < g_plugin_instances.size())
1869 {
1870 instance = g_plugin_instances[index];
1871 return true;
1872 }
1873 break;
1874
1875 default:
1876 break;
1877 }
1878 return false;
1879}
1880
1881bool
1882PluginManager::RegisterPlugin
1883(
1884 const char *name,
1885 const char *description,
1886 ArchVolatileRegsCreateInstance create_callback
1887)
1888{
1889 if (create_callback)
1890 {
1891 ArchVolatileRegsInstance instance;
1892 assert (name && name[0]);
1893 instance.name = name;
1894 if (description && description[0])
1895 instance.description = description;
1896 instance.create_callback = create_callback;
1897 return AccessArchVolatileRegsInstances (ePluginRegisterInstance, instance, 0);
1898 }
1899 return false;
1900}
1901
1902bool
1903PluginManager::UnregisterPlugin (ArchVolatileRegsCreateInstance create_callback)
1904{
1905 if (create_callback)
1906 {
1907 ArchVolatileRegsInstance instance;
1908 instance.create_callback = create_callback;
1909 return AccessArchVolatileRegsInstances (ePluginUnregisterInstance, instance, 0);
1910 }
1911 return false;
1912}
1913
1914ArchVolatileRegsCreateInstance
1915PluginManager::GetArchVolatileRegsCreateCallbackAtIndex (uint32_t idx)
1916{
1917 ArchVolatileRegsInstance instance;
1918 if (AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx))
1919 return instance.create_callback;
1920 return NULL;
1921}
1922
1923ArchVolatileRegsCreateInstance
1924PluginManager::GetArchVolatileRegsCreateCallbackForPluginName (const char *name)
1925{
1926 if (name && name[0])
1927 {
1928 ArchVolatileRegsInstance instance;
1929 std::string ss_name(name);
1930 for (uint32_t idx = 0; AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1931 {
1932 if (instance.name == ss_name)
1933 return instance.create_callback;
1934 }
1935 }
1936 return NULL;
1937}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001938