blob: 9117754fa2f644ab4cd583cdccc0e91316779f17 [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"
16#include "lldb/Core/FileSpec.h"
17#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 };
98 plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, error);
99 if (plugin_info.plugin_handle)
100 {
101 bool success = false;
102 plugin_info.plugin_init_callback = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error);
103 if (plugin_info.plugin_init_callback)
104 {
105 // Call the plug-in "bool LLDBPluginInitialize(void)" function
106 success = ((bool (*)(void))plugin_info.plugin_init_callback)();
107 }
108
109 if (success)
110 {
111 // It is ok for the "LLDBPluginTerminate" symbol to be NULL
112 plugin_info.plugin_term_callback = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error);
113 }
114 else
115 {
116 // The initialize function returned FALSE which means the
117 // plug-in might not be compatible, or might be too new or
118 // too old, or might not want to run on this machine.
119 Host::DynamicLibraryClose (plugin_info.plugin_handle);
120 plugin_info.plugin_handle = NULL;
121 plugin_info.plugin_init_callback = NULL;
122 }
123
124 // Regardless of success or failure, cache the plug-in load
125 // in our plug-in info so we don't try to load it again and
126 // again.
127 SetPluginInfo (plugin_file_spec, plugin_info);
128
129 return FileSpec::eEnumerateDirectoryResultNext;
130 }
131 }
132 }
133
134 if (file_type == FileSpec::eFileTypeUnknown ||
135 file_type == FileSpec::eFileTypeDirectory ||
136 file_type == FileSpec::eFileTypeSymbolicLink )
137 {
138 // Try and recurse into anything that a directory or symbolic link.
139 // We must also do this for unknown as sometimes the directory enumeration
140 // might be enurating a file system that doesn't have correct file type
141 // information.
142 return FileSpec::eEnumerateDirectoryResultEnter;
143 }
144
145 return FileSpec::eEnumerateDirectoryResultNext;
146}
147
148
149void
150PluginManager::Initialize ()
151{
152 FileSpec dir_spec;
153 const bool find_directories = true;
154 const bool find_files = true;
155 const bool find_other = true;
156 char dir_path[PATH_MAX];
157 if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
158 {
159 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
160 {
161 FileSpec::EnumerateDirectory (dir_path,
162 find_directories,
163 find_files,
164 find_other,
165 LoadPluginCallback,
166 NULL);
167 }
168 }
169
170 if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
171 {
172 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
173 {
174 FileSpec::EnumerateDirectory (dir_path,
175 find_directories,
176 find_files,
177 find_other,
178 LoadPluginCallback,
179 NULL);
180 }
181 }
182}
183
184void
185PluginManager::Terminate ()
186{
187 Mutex::Locker locker (GetPluginMapMutex ());
188 PluginTerminateMap &plugin_map = GetPluginMap ();
189
190 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
191 for (pos = plugin_map.begin(); pos != end; ++pos)
192 {
193 // Call the plug-in "void LLDBPluginTerminate (void)" function if there
194 // is one (if the symbol was not NULL).
195 if (pos->second.plugin_handle)
196 {
197 if (pos->second.plugin_term_callback)
198 ((void (*)(void))pos->second.plugin_term_callback)();
199 Host::DynamicLibraryClose (pos->second.plugin_handle);
200 }
201 }
202 plugin_map.clear();
203}
204
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205
206#pragma mark ABI
207
208
Jason Molenda743e86a2010-06-11 23:44:18 +0000209struct ABIInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000210{
211 ABIInstance() :
212 name(),
213 description(),
214 create_callback(NULL)
215 {
216 }
217
218 std::string name;
219 std::string description;
220 ABICreateInstance create_callback;
221};
222
223typedef std::vector<ABIInstance> ABIInstances;
224
225static bool
226AccessABIInstances (PluginAction action, ABIInstance &instance, uint32_t index)
227{
228 static ABIInstances g_plugin_instances;
229
230 switch (action)
231 {
232 case ePluginRegisterInstance:
233 if (instance.create_callback)
234 {
235 g_plugin_instances.push_back (instance);
236 return true;
237 }
238 break;
239
240 case ePluginUnregisterInstance:
241 if (instance.create_callback)
242 {
243 ABIInstances::iterator pos, end = g_plugin_instances.end();
244 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
245 {
246 if (pos->create_callback == instance.create_callback)
247 {
248 g_plugin_instances.erase(pos);
249 return true;
250 }
251 }
252 }
253 break;
254
255 case ePluginGetInstanceAtIndex:
256 if (index < g_plugin_instances.size())
257 {
258 instance = g_plugin_instances[index];
259 return true;
260 }
261 break;
262
263 default:
264 break;
265 }
266 return false;
267}
268
269
270bool
271PluginManager::RegisterPlugin
Greg Clayton4272cc72011-02-02 02:24:04 +0000272(
273 const char *name,
274 const char *description,
275 ABICreateInstance create_callback
276)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277{
278 if (create_callback)
279 {
280 ABIInstance instance;
281 assert (name && name[0]);
282 instance.name = name;
283 if (description && description[0])
284 instance.description = description;
285 instance.create_callback = create_callback;
286 return AccessABIInstances (ePluginRegisterInstance, instance, 0);
287 }
288 return false;
289}
290
291bool
292PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
293{
294 if (create_callback)
295 {
296 ABIInstance instance;
297 instance.create_callback = create_callback;
298 return AccessABIInstances (ePluginUnregisterInstance, instance, 0);
299 }
300 return false;
301}
302
303ABICreateInstance
304PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
305{
306 ABIInstance instance;
307 if (AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx))
308 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000309 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310}
311
312ABICreateInstance
313PluginManager::GetABICreateCallbackForPluginName (const char *name)
314{
315 if (name && name[0])
316 {
317 ABIInstance instance;
318 std::string ss_name(name);
319 for (uint32_t idx = 0; AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
320 {
321 if (instance.name == ss_name)
322 return instance.create_callback;
323 }
324 }
325 return NULL;
326}
327
328
329#pragma mark Disassembler
330
331
Jason Molenda743e86a2010-06-11 23:44:18 +0000332struct DisassemblerInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333{
334 DisassemblerInstance() :
335 name(),
336 description(),
337 create_callback(NULL)
338 {
339 }
340
341 std::string name;
342 std::string description;
343 DisassemblerCreateInstance create_callback;
344};
345
346typedef std::vector<DisassemblerInstance> DisassemblerInstances;
347
348static bool
349AccessDisassemblerInstances (PluginAction action, DisassemblerInstance &instance, uint32_t index)
350{
351 static DisassemblerInstances g_plugin_instances;
352
353 switch (action)
354 {
355 case ePluginRegisterInstance:
356 if (instance.create_callback)
357 {
358 g_plugin_instances.push_back (instance);
359 return true;
360 }
361 break;
362
363 case ePluginUnregisterInstance:
364 if (instance.create_callback)
365 {
366 DisassemblerInstances::iterator pos, end = g_plugin_instances.end();
367 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
368 {
369 if (pos->create_callback == instance.create_callback)
370 {
371 g_plugin_instances.erase(pos);
372 return true;
373 }
374 }
375 }
376 break;
377
378 case ePluginGetInstanceAtIndex:
379 if (index < g_plugin_instances.size())
380 {
381 instance = g_plugin_instances[index];
382 return true;
383 }
384 break;
385
386 default:
387 break;
388 }
389 return false;
390}
391
392
393bool
394PluginManager::RegisterPlugin
395(
396 const char *name,
397 const char *description,
398 DisassemblerCreateInstance create_callback
399)
400{
401 if (create_callback)
402 {
403 DisassemblerInstance instance;
404 assert (name && name[0]);
405 instance.name = name;
406 if (description && description[0])
407 instance.description = description;
408 instance.create_callback = create_callback;
409 return AccessDisassemblerInstances (ePluginRegisterInstance, instance, 0);
410 }
411 return false;
412}
413
414bool
415PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
416{
417 if (create_callback)
418 {
419 DisassemblerInstance instance;
420 instance.create_callback = create_callback;
421 return AccessDisassemblerInstances (ePluginUnregisterInstance, instance, 0);
422 }
423 return false;
424}
425
426DisassemblerCreateInstance
427PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
428{
429 DisassemblerInstance instance;
430 if (AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx))
431 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000432 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000433}
434
435DisassemblerCreateInstance
436PluginManager::GetDisassemblerCreateCallbackForPluginName (const char *name)
437{
438 if (name && name[0])
439 {
440 DisassemblerInstance instance;
441 std::string ss_name(name);
442 for (uint32_t idx = 0; AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
443 {
444 if (instance.name == ss_name)
445 return instance.create_callback;
446 }
447 }
448 return NULL;
449}
450
451
452
453#pragma mark DynamicLoader
454
455
Jason Molenda743e86a2010-06-11 23:44:18 +0000456struct DynamicLoaderInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457{
458 DynamicLoaderInstance() :
459 name(),
460 description(),
461 create_callback(NULL)
462 {
463 }
464
465 std::string name;
466 std::string description;
467 DynamicLoaderCreateInstance create_callback;
468};
469
470typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
471
472static bool
473AccessDynamicLoaderInstances (PluginAction action, DynamicLoaderInstance &instance, uint32_t index)
474{
475 static DynamicLoaderInstances g_plugin_instances;
476
477 switch (action)
478 {
479 case ePluginRegisterInstance:
480 if (instance.create_callback)
481 {
482 g_plugin_instances.push_back (instance);
483 return true;
484 }
485 break;
486
487 case ePluginUnregisterInstance:
488 if (instance.create_callback)
489 {
490 DynamicLoaderInstances::iterator pos, end = g_plugin_instances.end();
491 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
492 {
493 if (pos->create_callback == instance.create_callback)
494 {
495 g_plugin_instances.erase(pos);
496 return true;
497 }
498 }
499 }
500 break;
501
502 case ePluginGetInstanceAtIndex:
503 if (index < g_plugin_instances.size())
504 {
505 instance = g_plugin_instances[index];
506 return true;
507 }
508 break;
509
510 default:
511 break;
512 }
513 return false;
514}
515
516
517bool
518PluginManager::RegisterPlugin
519(
520 const char *name,
521 const char *description,
522 DynamicLoaderCreateInstance create_callback
523)
524{
525 if (create_callback)
526 {
527 DynamicLoaderInstance instance;
528 assert (name && name[0]);
529 instance.name = name;
530 if (description && description[0])
531 instance.description = description;
532 instance.create_callback = create_callback;
533 return AccessDynamicLoaderInstances (ePluginRegisterInstance, instance, 0);
534 }
535 return false;
536}
537
538bool
539PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
540{
541 if (create_callback)
542 {
543 DynamicLoaderInstance instance;
544 instance.create_callback = create_callback;
545 return AccessDynamicLoaderInstances (ePluginUnregisterInstance, instance, 0);
546 }
547 return false;
548}
549
550DynamicLoaderCreateInstance
551PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
552{
553 DynamicLoaderInstance instance;
554 if (AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx))
555 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000556 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557}
558
559DynamicLoaderCreateInstance
560PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const char *name)
561{
562 if (name && name[0])
563 {
564 DynamicLoaderInstance instance;
565 std::string ss_name(name);
566 for (uint32_t idx = 0; AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
567 {
568 if (instance.name == ss_name)
569 return instance.create_callback;
570 }
571 }
572 return NULL;
573}
574
Greg Claytonf03bbe22011-02-01 01:37:45 +0000575#pragma mark EmulateInstruction
576
577
578struct EmulateInstructionInstance
579{
580 EmulateInstructionInstance() :
581 name(),
582 description(),
583 create_callback(NULL)
584 {
585 }
586
587 std::string name;
588 std::string description;
589 EmulateInstructionCreateInstance create_callback;
590};
591
592typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
593
594static bool
595AccessEmulateInstructionInstances (PluginAction action, EmulateInstructionInstance &instance, uint32_t index)
596{
597 static EmulateInstructionInstances g_plugin_instances;
598
599 switch (action)
600 {
601 case ePluginRegisterInstance:
602 if (instance.create_callback)
603 {
604 g_plugin_instances.push_back (instance);
605 return true;
606 }
607 break;
608
609 case ePluginUnregisterInstance:
610 if (instance.create_callback)
611 {
612 EmulateInstructionInstances::iterator pos, end = g_plugin_instances.end();
613 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
614 {
615 if (pos->create_callback == instance.create_callback)
616 {
617 g_plugin_instances.erase(pos);
618 return true;
619 }
620 }
621 }
622 break;
623
624 case ePluginGetInstanceAtIndex:
625 if (index < g_plugin_instances.size())
626 {
627 instance = g_plugin_instances[index];
628 return true;
629 }
630 break;
631
632 default:
633 break;
634 }
635 return false;
636}
637
638
639bool
640PluginManager::RegisterPlugin
641(
Greg Clayton4272cc72011-02-02 02:24:04 +0000642 const char *name,
643 const char *description,
644 EmulateInstructionCreateInstance create_callback
645)
Greg Claytonf03bbe22011-02-01 01:37:45 +0000646{
647 if (create_callback)
648 {
649 EmulateInstructionInstance instance;
650 assert (name && name[0]);
651 instance.name = name;
652 if (description && description[0])
653 instance.description = description;
654 instance.create_callback = create_callback;
655 return AccessEmulateInstructionInstances (ePluginRegisterInstance, instance, 0);
656 }
657 return false;
658}
659
660bool
661PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
662{
663 if (create_callback)
664 {
665 EmulateInstructionInstance instance;
666 instance.create_callback = create_callback;
667 return AccessEmulateInstructionInstances (ePluginUnregisterInstance, instance, 0);
668 }
669 return false;
670}
671
672EmulateInstructionCreateInstance
673PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
674{
675 EmulateInstructionInstance instance;
676 if (AccessEmulateInstructionInstances (ePluginGetInstanceAtIndex, instance, idx))
677 return instance.create_callback;
678 return NULL;
679}
680
681EmulateInstructionCreateInstance
682PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const char *name)
683{
684 if (name && name[0])
685 {
686 EmulateInstructionInstance instance;
687 std::string ss_name(name);
688 for (uint32_t idx = 0; AccessEmulateInstructionInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
689 {
690 if (instance.name == ss_name)
691 return instance.create_callback;
692 }
693 }
694 return NULL;
695}
696
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697
Jim Ingham22777012010-09-23 02:01:19 +0000698#pragma mark LanguageRuntime
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000699
700
Jim Ingham22777012010-09-23 02:01:19 +0000701struct LanguageRuntimeInstance
702{
703 LanguageRuntimeInstance() :
704 name(),
705 description(),
706 create_callback(NULL)
707 {
708 }
709
710 std::string name;
711 std::string description;
712 LanguageRuntimeCreateInstance create_callback;
713};
714
715typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
716
717static bool
718AccessLanguageRuntimeInstances (PluginAction action, LanguageRuntimeInstance &instance, uint32_t index)
719{
720 static LanguageRuntimeInstances g_plugin_instances;
721
722 switch (action)
723 {
724 case ePluginRegisterInstance:
725 if (instance.create_callback)
726 {
727 g_plugin_instances.push_back (instance);
728 return true;
729 }
730 break;
731
732 case ePluginUnregisterInstance:
733 if (instance.create_callback)
734 {
735 LanguageRuntimeInstances::iterator pos, end = g_plugin_instances.end();
736 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
737 {
738 if (pos->create_callback == instance.create_callback)
739 {
740 g_plugin_instances.erase(pos);
741 return true;
742 }
743 }
744 }
745 break;
746
747 case ePluginGetInstanceAtIndex:
748 if (index < g_plugin_instances.size())
749 {
750 instance = g_plugin_instances[index];
751 return true;
752 }
753 break;
754
755 default:
756 break;
757 }
758 return false;
759}
760
761
762bool
763PluginManager::RegisterPlugin
Greg Clayton4272cc72011-02-02 02:24:04 +0000764(
765 const char *name,
766 const char *description,
767 LanguageRuntimeCreateInstance create_callback
768)
Jim Ingham22777012010-09-23 02:01:19 +0000769{
770 if (create_callback)
771 {
772 LanguageRuntimeInstance instance;
773 assert (name && name[0]);
774 instance.name = name;
775 if (description && description[0])
776 instance.description = description;
777 instance.create_callback = create_callback;
778 return AccessLanguageRuntimeInstances (ePluginRegisterInstance, instance, 0);
779 }
780 return false;
781}
782
783bool
784PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
785{
786 if (create_callback)
787 {
788 LanguageRuntimeInstance instance;
789 instance.create_callback = create_callback;
790 return AccessLanguageRuntimeInstances (ePluginUnregisterInstance, instance, 0);
791 }
792 return false;
793}
794
795LanguageRuntimeCreateInstance
796PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
797{
798 LanguageRuntimeInstance instance;
799 if (AccessLanguageRuntimeInstances (ePluginGetInstanceAtIndex, instance, idx))
800 return instance.create_callback;
801 return NULL;
802}
803
804LanguageRuntimeCreateInstance
805PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const char *name)
806{
807 if (name && name[0])
808 {
809 LanguageRuntimeInstance instance;
810 std::string ss_name(name);
811 for (uint32_t idx = 0; AccessLanguageRuntimeInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
812 {
813 if (instance.name == ss_name)
814 return instance.create_callback;
815 }
816 }
817 return NULL;
818}
819
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000820#pragma mark ObjectFile
821
Jason Molenda743e86a2010-06-11 23:44:18 +0000822struct ObjectFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000823{
824 ObjectFileInstance() :
825 name(),
826 description(),
827 create_callback(NULL)
828 {
829 }
830
831 std::string name;
832 std::string description;
833 ObjectFileCreateInstance create_callback;
834};
835
836typedef std::vector<ObjectFileInstance> ObjectFileInstances;
837
838static bool
839AccessObjectFileInstances (PluginAction action, ObjectFileInstance &instance, uint32_t index)
840{
841 static ObjectFileInstances g_plugin_instances;
842
843 switch (action)
844 {
845 case ePluginRegisterInstance:
846 if (instance.create_callback)
847 {
848 g_plugin_instances.push_back (instance);
849 return true;
850 }
851 break;
852
853 case ePluginUnregisterInstance:
854 if (instance.create_callback)
855 {
856 ObjectFileInstances::iterator pos, end = g_plugin_instances.end();
857 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
858 {
859 if (pos->create_callback == instance.create_callback)
860 {
861 g_plugin_instances.erase(pos);
862 return true;
863 }
864 }
865 }
866 break;
867
868 case ePluginGetInstanceAtIndex:
869 if (index < g_plugin_instances.size())
870 {
871 instance = g_plugin_instances[index];
872 return true;
873 }
874 break;
875
876 default:
877 break;
878 }
879 return false;
880}
881
882
883bool
884PluginManager::RegisterPlugin
885(
886 const char *name,
887 const char *description,
888 ObjectFileCreateInstance create_callback
889)
890{
891 if (create_callback)
892 {
893 ObjectFileInstance instance;
894 assert (name && name[0]);
895 instance.name = name;
896 if (description && description[0])
897 instance.description = description;
898 instance.create_callback = create_callback;
899 return AccessObjectFileInstances (ePluginRegisterInstance, instance, 0);
900 }
901 return false;
902}
903
904bool
905PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
906{
907 if (create_callback)
908 {
909 ObjectFileInstance instance;
910 instance.create_callback = create_callback;
911 return AccessObjectFileInstances (ePluginUnregisterInstance, instance, 0);
912 }
913 return false;
914}
915
916ObjectFileCreateInstance
917PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
918{
919 ObjectFileInstance instance;
920 if (AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx))
921 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000922 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000923}
924ObjectFileCreateInstance
925PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name)
926{
927 if (name && name[0])
928 {
929 ObjectFileInstance instance;
930 std::string ss_name(name);
931 for (uint32_t idx = 0; AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
932 {
933 if (instance.name == ss_name)
934 return instance.create_callback;
935 }
936 }
937 return NULL;
938}
939
940
941
942#pragma mark ObjectContainer
943
Jason Molenda743e86a2010-06-11 23:44:18 +0000944struct ObjectContainerInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000945{
946 ObjectContainerInstance() :
947 name(),
948 description(),
949 create_callback(NULL)
950 {
951 }
952
953 std::string name;
954 std::string description;
955 ObjectContainerCreateInstance create_callback;
956};
957
958typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
959
960static bool
961AccessObjectContainerInstances (PluginAction action, ObjectContainerInstance &instance, uint32_t index)
962{
963 static ObjectContainerInstances g_plugin_instances;
964
965 switch (action)
966 {
967 case ePluginRegisterInstance:
968 if (instance.create_callback)
969 {
970 g_plugin_instances.push_back (instance);
971 return true;
972 }
973 break;
974
975 case ePluginUnregisterInstance:
976 if (instance.create_callback)
977 {
978 ObjectContainerInstances::iterator pos, end = g_plugin_instances.end();
979 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
980 {
981 if (pos->create_callback == instance.create_callback)
982 {
983 g_plugin_instances.erase(pos);
984 return true;
985 }
986 }
987 }
988 break;
989
990 case ePluginGetInstanceAtIndex:
991 if (index < g_plugin_instances.size())
992 {
993 instance = g_plugin_instances[index];
994 return true;
995 }
996 break;
997
998 default:
999 break;
1000 }
1001 return false;
1002}
1003
1004
1005bool
1006PluginManager::RegisterPlugin
1007(
1008 const char *name,
1009 const char *description,
1010 ObjectContainerCreateInstance create_callback
1011)
1012{
1013 if (create_callback)
1014 {
1015 ObjectContainerInstance instance;
1016 assert (name && name[0]);
1017 instance.name = name;
1018 if (description && description[0])
1019 instance.description = description;
1020 instance.create_callback = create_callback;
1021 return AccessObjectContainerInstances (ePluginRegisterInstance, instance, 0);
1022 }
1023 return false;
1024}
1025
1026bool
1027PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1028{
1029 if (create_callback)
1030 {
1031 ObjectContainerInstance instance;
1032 instance.create_callback = create_callback;
1033 return AccessObjectContainerInstances (ePluginUnregisterInstance, instance, 0);
1034 }
1035 return false;
1036}
1037
1038ObjectContainerCreateInstance
1039PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1040{
1041 ObjectContainerInstance instance;
1042 if (AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx))
1043 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001044 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001045}
1046ObjectContainerCreateInstance
1047PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name)
1048{
1049 if (name && name[0])
1050 {
1051 ObjectContainerInstance instance;
1052 std::string ss_name(name);
1053 for (uint32_t idx = 0; AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1054 {
1055 if (instance.name == ss_name)
1056 return instance.create_callback;
1057 }
1058 }
1059 return NULL;
1060}
1061
1062#pragma mark LogChannel
1063
Jason Molenda743e86a2010-06-11 23:44:18 +00001064struct LogChannelInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001065{
1066 LogChannelInstance() :
1067 name(),
1068 description(),
1069 create_callback(NULL)
1070 {
1071 }
1072
1073 std::string name;
1074 std::string description;
1075 LogChannelCreateInstance create_callback;
1076};
1077
1078typedef std::vector<LogChannelInstance> LogChannelInstances;
1079
1080static bool
1081AccessLogChannelInstances (PluginAction action, LogChannelInstance &instance, uint32_t index)
1082{
1083 static LogChannelInstances g_plugin_instances;
1084
1085 switch (action)
1086 {
1087 case ePluginRegisterInstance:
1088 if (instance.create_callback)
1089 {
1090 g_plugin_instances.push_back (instance);
1091 return true;
1092 }
1093 break;
1094
1095 case ePluginUnregisterInstance:
1096 if (instance.create_callback)
1097 {
1098 LogChannelInstances::iterator pos, end = g_plugin_instances.end();
1099 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1100 {
1101 if (pos->create_callback == instance.create_callback)
1102 {
1103 g_plugin_instances.erase(pos);
1104 return true;
1105 }
1106 }
1107 }
1108 break;
1109
1110 case ePluginGetInstanceAtIndex:
1111 if (index < g_plugin_instances.size())
1112 {
1113 instance = g_plugin_instances[index];
1114 return true;
1115 }
1116 break;
1117
1118 default:
1119 break;
1120 }
1121 return false;
1122}
1123
1124
1125bool
1126PluginManager::RegisterPlugin
1127(
1128 const char *name,
1129 const char *description,
1130 LogChannelCreateInstance create_callback
1131)
1132{
1133 if (create_callback)
1134 {
1135 LogChannelInstance instance;
1136 assert (name && name[0]);
1137 instance.name = name;
1138 if (description && description[0])
1139 instance.description = description;
1140 instance.create_callback = create_callback;
1141 return AccessLogChannelInstances (ePluginRegisterInstance, instance, 0);
1142 }
1143 return false;
1144}
1145
1146bool
1147PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1148{
1149 if (create_callback)
1150 {
1151 LogChannelInstance instance;
1152 instance.create_callback = create_callback;
1153 return AccessLogChannelInstances (ePluginUnregisterInstance, instance, 0);
1154 }
1155 return false;
1156}
1157
1158const char *
1159PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1160{
1161 LogChannelInstance instance;
1162 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx))
1163 return instance.name.c_str();
1164 return NULL;
1165}
1166
1167
1168LogChannelCreateInstance
1169PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1170{
1171 LogChannelInstance instance;
1172 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx))
1173 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001174 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001175}
1176
1177LogChannelCreateInstance
1178PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name)
1179{
1180 if (name && name[0])
1181 {
1182 LogChannelInstance instance;
1183 std::string ss_name(name);
1184 for (uint32_t idx = 0; AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1185 {
1186 if (instance.name == ss_name)
1187 return instance.create_callback;
1188 }
1189 }
1190 return NULL;
1191}
1192
1193#pragma mark Process
1194
Jason Molenda743e86a2010-06-11 23:44:18 +00001195struct ProcessInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001196{
1197 ProcessInstance() :
1198 name(),
1199 description(),
1200 create_callback(NULL)
1201 {
1202 }
1203
1204 std::string name;
1205 std::string description;
1206 ProcessCreateInstance create_callback;
1207};
1208
1209typedef std::vector<ProcessInstance> ProcessInstances;
1210
1211static bool
1212AccessProcessInstances (PluginAction action, ProcessInstance &instance, uint32_t index)
1213{
1214 static ProcessInstances g_plugin_instances;
1215
1216 switch (action)
1217 {
1218 case ePluginRegisterInstance:
1219 if (instance.create_callback)
1220 {
1221 g_plugin_instances.push_back (instance);
1222 return true;
1223 }
1224 break;
1225
1226 case ePluginUnregisterInstance:
1227 if (instance.create_callback)
1228 {
1229 ProcessInstances::iterator pos, end = g_plugin_instances.end();
1230 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1231 {
1232 if (pos->create_callback == instance.create_callback)
1233 {
1234 g_plugin_instances.erase(pos);
1235 return true;
1236 }
1237 }
1238 }
1239 break;
1240
1241 case ePluginGetInstanceAtIndex:
1242 if (index < g_plugin_instances.size())
1243 {
1244 instance = g_plugin_instances[index];
1245 return true;
1246 }
1247 break;
1248
1249 default:
1250 break;
1251 }
1252 return false;
1253}
1254
1255
1256bool
1257PluginManager::RegisterPlugin
1258(
1259 const char *name,
1260 const char *description,
1261 ProcessCreateInstance create_callback
1262)
1263{
1264 if (create_callback)
1265 {
1266 ProcessInstance instance;
1267 assert (name && name[0]);
1268 instance.name = name;
1269 if (description && description[0])
1270 instance.description = description;
1271 instance.create_callback = create_callback;
1272 return AccessProcessInstances (ePluginRegisterInstance, instance, 0);
1273 }
1274 return false;
1275}
1276
1277bool
1278PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1279{
1280 if (create_callback)
1281 {
1282 ProcessInstance instance;
1283 instance.create_callback = create_callback;
1284 return AccessProcessInstances (ePluginUnregisterInstance, instance, 0);
1285 }
1286 return false;
1287}
1288
1289ProcessCreateInstance
1290PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1291{
1292 ProcessInstance instance;
1293 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1294 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001295 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296}
1297
1298ProcessCreateInstance
1299PluginManager::GetProcessCreateCallbackForPluginName (const char *name)
1300{
1301 if (name && name[0])
1302 {
1303 ProcessInstance instance;
1304 std::string ss_name(name);
1305 for (uint32_t idx = 0; AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1306 {
1307 if (instance.name == ss_name)
1308 return instance.create_callback;
1309 }
1310 }
1311 return NULL;
1312}
1313
1314#pragma mark SymbolFile
1315
Jason Molenda743e86a2010-06-11 23:44:18 +00001316struct SymbolFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001317{
1318 SymbolFileInstance() :
1319 name(),
1320 description(),
1321 create_callback(NULL)
1322 {
1323 }
1324
1325 std::string name;
1326 std::string description;
1327 SymbolFileCreateInstance create_callback;
1328};
1329
1330typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1331
1332static bool
1333AccessSymbolFileInstances (PluginAction action, SymbolFileInstance &instance, uint32_t index)
1334{
1335 static SymbolFileInstances g_plugin_instances;
1336
1337 switch (action)
1338 {
1339 case ePluginRegisterInstance:
1340 if (instance.create_callback)
1341 {
1342 g_plugin_instances.push_back (instance);
1343 return true;
1344 }
1345 break;
1346
1347 case ePluginUnregisterInstance:
1348 if (instance.create_callback)
1349 {
1350 SymbolFileInstances::iterator pos, end = g_plugin_instances.end();
1351 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1352 {
1353 if (pos->create_callback == instance.create_callback)
1354 {
1355 g_plugin_instances.erase(pos);
1356 return true;
1357 }
1358 }
1359 }
1360 break;
1361
1362 case ePluginGetInstanceAtIndex:
1363 if (index < g_plugin_instances.size())
1364 {
1365 instance = g_plugin_instances[index];
1366 return true;
1367 }
1368 break;
1369
1370 default:
1371 break;
1372 }
1373 return false;
1374}
1375
1376
1377bool
1378PluginManager::RegisterPlugin
1379(
1380 const char *name,
1381 const char *description,
1382 SymbolFileCreateInstance create_callback
1383)
1384{
1385 if (create_callback)
1386 {
1387 SymbolFileInstance instance;
1388 assert (name && name[0]);
1389 instance.name = name;
1390 if (description && description[0])
1391 instance.description = description;
1392 instance.create_callback = create_callback;
1393 return AccessSymbolFileInstances (ePluginRegisterInstance, instance, 0);
1394 }
1395 return false;
1396}
1397
1398bool
1399PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1400{
1401 if (create_callback)
1402 {
1403 SymbolFileInstance instance;
1404 instance.create_callback = create_callback;
1405 return AccessSymbolFileInstances (ePluginUnregisterInstance, instance, 0);
1406 }
1407 return false;
1408}
1409
1410SymbolFileCreateInstance
1411PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1412{
1413 SymbolFileInstance instance;
1414 if (AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx))
1415 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001416 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001417}
1418SymbolFileCreateInstance
1419PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name)
1420{
1421 if (name && name[0])
1422 {
1423 SymbolFileInstance instance;
1424 std::string ss_name(name);
1425 for (uint32_t idx = 0; AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1426 {
1427 if (instance.name == ss_name)
1428 return instance.create_callback;
1429 }
1430 }
1431 return NULL;
1432}
1433
1434
1435
1436#pragma mark SymbolVendor
1437
Jason Molenda743e86a2010-06-11 23:44:18 +00001438struct SymbolVendorInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001439{
1440 SymbolVendorInstance() :
1441 name(),
1442 description(),
1443 create_callback(NULL)
1444 {
1445 }
1446
1447 std::string name;
1448 std::string description;
1449 SymbolVendorCreateInstance create_callback;
1450};
1451
1452typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1453
1454static bool
1455AccessSymbolVendorInstances (PluginAction action, SymbolVendorInstance &instance, uint32_t index)
1456{
1457 static SymbolVendorInstances g_plugin_instances;
1458
1459 switch (action)
1460 {
1461 case ePluginRegisterInstance:
1462 if (instance.create_callback)
1463 {
1464 g_plugin_instances.push_back (instance);
1465 return true;
1466 }
1467 break;
1468
1469 case ePluginUnregisterInstance:
1470 if (instance.create_callback)
1471 {
1472 SymbolVendorInstances::iterator pos, end = g_plugin_instances.end();
1473 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1474 {
1475 if (pos->create_callback == instance.create_callback)
1476 {
1477 g_plugin_instances.erase(pos);
1478 return true;
1479 }
1480 }
1481 }
1482 break;
1483
1484 case ePluginGetInstanceAtIndex:
1485 if (index < g_plugin_instances.size())
1486 {
1487 instance = g_plugin_instances[index];
1488 return true;
1489 }
1490 break;
1491
1492 default:
1493 break;
1494 }
1495 return false;
1496}
1497
1498bool
1499PluginManager::RegisterPlugin
1500(
1501 const char *name,
1502 const char *description,
1503 SymbolVendorCreateInstance create_callback
1504)
1505{
1506 if (create_callback)
1507 {
1508 SymbolVendorInstance instance;
1509 assert (name && name[0]);
1510 instance.name = name;
1511 if (description && description[0])
1512 instance.description = description;
1513 instance.create_callback = create_callback;
1514 return AccessSymbolVendorInstances (ePluginRegisterInstance, instance, 0);
1515 }
1516 return false;
1517}
1518
1519bool
1520PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1521{
1522 if (create_callback)
1523 {
1524 SymbolVendorInstance instance;
1525 instance.create_callback = create_callback;
1526 return AccessSymbolVendorInstances (ePluginUnregisterInstance, instance, 0);
1527 }
1528 return false;
1529}
1530
1531SymbolVendorCreateInstance
1532PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1533{
1534 SymbolVendorInstance instance;
1535 if (AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx))
1536 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001537 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001538}
1539
1540SymbolVendorCreateInstance
1541PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name)
1542{
1543 if (name && name[0])
1544 {
1545 SymbolVendorInstance instance;
1546 std::string ss_name(name);
1547 for (uint32_t idx = 0; AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1548 {
1549 if (instance.name == ss_name)
1550 return instance.create_callback;
1551 }
1552 }
1553 return NULL;
1554}
1555
1556
Jason Molendafbcb7f22010-09-10 07:49:16 +00001557#pragma mark UnwindAssemblyProfiler
1558
1559struct UnwindAssemblyProfilerInstance
1560{
1561 UnwindAssemblyProfilerInstance() :
1562 name(),
1563 description(),
1564 create_callback(NULL)
1565 {
1566 }
1567
1568 std::string name;
1569 std::string description;
1570 UnwindAssemblyProfilerCreateInstance create_callback;
1571};
1572
1573typedef std::vector<UnwindAssemblyProfilerInstance> UnwindAssemblyProfilerInstances;
1574
1575static bool
1576AccessUnwindAssemblyProfilerInstances (PluginAction action, UnwindAssemblyProfilerInstance &instance, uint32_t index)
1577{
1578 static UnwindAssemblyProfilerInstances g_plugin_instances;
1579
1580 switch (action)
1581 {
1582 case ePluginRegisterInstance:
1583 if (instance.create_callback)
1584 {
1585 g_plugin_instances.push_back (instance);
1586 return true;
1587 }
1588 break;
1589
1590 case ePluginUnregisterInstance:
1591 if (instance.create_callback)
1592 {
1593 UnwindAssemblyProfilerInstances::iterator pos, end = g_plugin_instances.end();
1594 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1595 {
1596 if (pos->create_callback == instance.create_callback)
1597 {
1598 g_plugin_instances.erase(pos);
1599 return true;
1600 }
1601 }
1602 }
1603 break;
1604
1605 case ePluginGetInstanceAtIndex:
1606 if (index < g_plugin_instances.size())
1607 {
1608 instance = g_plugin_instances[index];
1609 return true;
1610 }
1611 break;
1612
1613 default:
1614 break;
1615 }
1616 return false;
1617}
1618
1619bool
1620PluginManager::RegisterPlugin
1621(
1622 const char *name,
1623 const char *description,
1624 UnwindAssemblyProfilerCreateInstance create_callback
1625)
1626{
1627 if (create_callback)
1628 {
1629 UnwindAssemblyProfilerInstance instance;
1630 assert (name && name[0]);
1631 instance.name = name;
1632 if (description && description[0])
1633 instance.description = description;
1634 instance.create_callback = create_callback;
1635 return AccessUnwindAssemblyProfilerInstances (ePluginRegisterInstance, instance, 0);
1636 }
1637 return false;
1638}
1639
1640bool
1641PluginManager::UnregisterPlugin (UnwindAssemblyProfilerCreateInstance create_callback)
1642{
1643 if (create_callback)
1644 {
1645 UnwindAssemblyProfilerInstance instance;
1646 instance.create_callback = create_callback;
1647 return AccessUnwindAssemblyProfilerInstances (ePluginUnregisterInstance, instance, 0);
1648 }
1649 return false;
1650}
1651
1652UnwindAssemblyProfilerCreateInstance
1653PluginManager::GetUnwindAssemblyProfilerCreateCallbackAtIndex (uint32_t idx)
1654{
1655 UnwindAssemblyProfilerInstance instance;
1656 if (AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx))
1657 return instance.create_callback;
1658 return NULL;
1659}
1660
1661UnwindAssemblyProfilerCreateInstance
1662PluginManager::GetUnwindAssemblyProfilerCreateCallbackForPluginName (const char *name)
1663{
1664 if (name && name[0])
1665 {
1666 UnwindAssemblyProfilerInstance instance;
1667 std::string ss_name(name);
1668 for (uint32_t idx = 0; AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1669 {
1670 if (instance.name == ss_name)
1671 return instance.create_callback;
1672 }
1673 }
1674 return NULL;
1675}
1676
1677#pragma mark ArchDefaultUnwindPlan
1678
1679struct ArchDefaultUnwindPlanInstance
1680{
1681 ArchDefaultUnwindPlanInstance() :
1682 name(),
1683 description(),
1684 create_callback(NULL)
1685 {
1686 }
1687
1688 std::string name;
1689 std::string description;
1690 ArchDefaultUnwindPlanCreateInstance create_callback;
1691};
1692
1693typedef std::vector<ArchDefaultUnwindPlanInstance> ArchDefaultUnwindPlanInstances;
1694
1695static bool
1696AccessArchDefaultUnwindPlanInstances (PluginAction action, ArchDefaultUnwindPlanInstance &instance, uint32_t index)
1697{
1698 static ArchDefaultUnwindPlanInstances g_plugin_instances;
1699
1700 switch (action)
1701 {
1702 case ePluginRegisterInstance:
1703 if (instance.create_callback)
1704 {
1705 g_plugin_instances.push_back (instance);
1706 return true;
1707 }
1708 break;
1709
1710 case ePluginUnregisterInstance:
1711 if (instance.create_callback)
1712 {
1713 ArchDefaultUnwindPlanInstances::iterator pos, end = g_plugin_instances.end();
1714 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1715 {
1716 if (pos->create_callback == instance.create_callback)
1717 {
1718 g_plugin_instances.erase(pos);
1719 return true;
1720 }
1721 }
1722 }
1723 break;
1724
1725 case ePluginGetInstanceAtIndex:
1726 if (index < g_plugin_instances.size())
1727 {
1728 instance = g_plugin_instances[index];
1729 return true;
1730 }
1731 break;
1732
1733 default:
1734 break;
1735 }
1736 return false;
1737}
1738
1739bool
1740PluginManager::RegisterPlugin
1741(
1742 const char *name,
1743 const char *description,
1744 ArchDefaultUnwindPlanCreateInstance create_callback
1745)
1746{
1747 if (create_callback)
1748 {
1749 ArchDefaultUnwindPlanInstance instance;
1750 assert (name && name[0]);
1751 instance.name = name;
1752 if (description && description[0])
1753 instance.description = description;
1754 instance.create_callback = create_callback;
1755 return AccessArchDefaultUnwindPlanInstances (ePluginRegisterInstance, instance, 0);
1756 }
1757 return false;
1758}
1759
1760bool
1761PluginManager::UnregisterPlugin (ArchDefaultUnwindPlanCreateInstance create_callback)
1762{
1763 if (create_callback)
1764 {
1765 ArchDefaultUnwindPlanInstance instance;
1766 instance.create_callback = create_callback;
1767 return AccessArchDefaultUnwindPlanInstances (ePluginUnregisterInstance, instance, 0);
1768 }
1769 return false;
1770}
1771
1772ArchDefaultUnwindPlanCreateInstance
1773PluginManager::GetArchDefaultUnwindPlanCreateCallbackAtIndex (uint32_t idx)
1774{
1775 ArchDefaultUnwindPlanInstance instance;
1776 if (AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx))
1777 return instance.create_callback;
1778 return NULL;
1779}
1780
1781ArchDefaultUnwindPlanCreateInstance
1782PluginManager::GetArchDefaultUnwindPlanCreateCallbackForPluginName (const char *name)
1783{
1784 if (name && name[0])
1785 {
1786 ArchDefaultUnwindPlanInstance instance;
1787 std::string ss_name(name);
1788 for (uint32_t idx = 0; AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1789 {
1790 if (instance.name == ss_name)
1791 return instance.create_callback;
1792 }
1793 }
1794 return NULL;
1795}
1796
Jason Molenda0c7cc852010-09-22 07:37:07 +00001797#pragma mark ArchVolatileRegs
1798
1799struct ArchVolatileRegsInstance
1800{
1801 ArchVolatileRegsInstance() :
1802 name(),
1803 description(),
1804 create_callback(NULL)
1805 {
1806 }
1807
1808 std::string name;
1809 std::string description;
1810 ArchVolatileRegsCreateInstance create_callback;
1811};
1812
1813typedef std::vector<ArchVolatileRegsInstance> ArchVolatileRegsInstances;
1814
1815static bool
1816AccessArchVolatileRegsInstances (PluginAction action, ArchVolatileRegsInstance &instance, uint32_t index)
1817{
1818 static ArchVolatileRegsInstances g_plugin_instances;
1819
1820 switch (action)
1821 {
1822 case ePluginRegisterInstance:
1823 if (instance.create_callback)
1824 {
1825 g_plugin_instances.push_back (instance);
1826 return true;
1827 }
1828 break;
1829
1830 case ePluginUnregisterInstance:
1831 if (instance.create_callback)
1832 {
1833 ArchVolatileRegsInstances::iterator pos, end = g_plugin_instances.end();
1834 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1835 {
1836 if (pos->create_callback == instance.create_callback)
1837 {
1838 g_plugin_instances.erase(pos);
1839 return true;
1840 }
1841 }
1842 }
1843 break;
1844
1845 case ePluginGetInstanceAtIndex:
1846 if (index < g_plugin_instances.size())
1847 {
1848 instance = g_plugin_instances[index];
1849 return true;
1850 }
1851 break;
1852
1853 default:
1854 break;
1855 }
1856 return false;
1857}
1858
1859bool
1860PluginManager::RegisterPlugin
1861(
1862 const char *name,
1863 const char *description,
1864 ArchVolatileRegsCreateInstance create_callback
1865)
1866{
1867 if (create_callback)
1868 {
1869 ArchVolatileRegsInstance instance;
1870 assert (name && name[0]);
1871 instance.name = name;
1872 if (description && description[0])
1873 instance.description = description;
1874 instance.create_callback = create_callback;
1875 return AccessArchVolatileRegsInstances (ePluginRegisterInstance, instance, 0);
1876 }
1877 return false;
1878}
1879
1880bool
1881PluginManager::UnregisterPlugin (ArchVolatileRegsCreateInstance create_callback)
1882{
1883 if (create_callback)
1884 {
1885 ArchVolatileRegsInstance instance;
1886 instance.create_callback = create_callback;
1887 return AccessArchVolatileRegsInstances (ePluginUnregisterInstance, instance, 0);
1888 }
1889 return false;
1890}
1891
1892ArchVolatileRegsCreateInstance
1893PluginManager::GetArchVolatileRegsCreateCallbackAtIndex (uint32_t idx)
1894{
1895 ArchVolatileRegsInstance instance;
1896 if (AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx))
1897 return instance.create_callback;
1898 return NULL;
1899}
1900
1901ArchVolatileRegsCreateInstance
1902PluginManager::GetArchVolatileRegsCreateCallbackForPluginName (const char *name)
1903{
1904 if (name && name[0])
1905 {
1906 ArchVolatileRegsInstance instance;
1907 std::string ss_name(name);
1908 for (uint32_t idx = 0; AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1909 {
1910 if (instance.name == ss_name)
1911 return instance.create_callback;
1912 }
1913 }
1914 return NULL;
1915}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001916