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