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