1 //===-- 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/lldb-python.h"
11 
12 #include "lldb/Core/PluginManager.h"
13 
14 #include <limits.h>
15 
16 #include <string>
17 #include <vector>
18 
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/Error.h"
21 #include "lldb/Host/FileSpec.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Host/Mutex.h"
24 #include "lldb/Interpreter/OptionValueProperties.h"
25 
26 #include "llvm/ADT/StringRef.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 enum PluginAction
32 {
33     ePluginRegisterInstance,
34     ePluginUnregisterInstance,
35     ePluginGetInstanceAtIndex
36 };
37 
38 
39 typedef bool (*PluginInitCallback) (void);
40 typedef void (*PluginTermCallback) (void);
41 
42 struct PluginInfo
43 {
44     void *plugin_handle;
45     PluginInitCallback plugin_init_callback;
46     PluginTermCallback plugin_term_callback;
47 };
48 
49 typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
50 
51 static Mutex &
52 GetPluginMapMutex ()
53 {
54     static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
55     return g_plugin_map_mutex;
56 }
57 
58 static PluginTerminateMap &
59 GetPluginMap ()
60 {
61     static PluginTerminateMap g_plugin_map;
62     return g_plugin_map;
63 }
64 
65 static bool
66 PluginIsLoaded (const FileSpec &plugin_file_spec)
67 {
68     Mutex::Locker locker (GetPluginMapMutex ());
69     PluginTerminateMap &plugin_map = GetPluginMap ();
70     return plugin_map.find (plugin_file_spec) != plugin_map.end();
71 }
72 
73 static void
74 SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
75 {
76     Mutex::Locker locker (GetPluginMapMutex ());
77     PluginTerminateMap &plugin_map = GetPluginMap ();
78     assert (plugin_map.find (plugin_file_spec) == plugin_map.end());
79     plugin_map[plugin_file_spec] = plugin_info;
80 }
81 
82 
83 static FileSpec::EnumerateDirectoryResult
84 LoadPluginCallback
85 (
86     void *baton,
87     FileSpec::FileType file_type,
88     const FileSpec &file_spec
89 )
90 {
91 //    PluginManager *plugin_manager = (PluginManager *)baton;
92     Error error;
93 
94     // If we have a regular file, a symbolic link or unknown file type, try
95     // and process the file. We must handle unknown as sometimes the directory
96     // enumeration might be enumerating a file system that doesn't have correct
97     // file type information.
98     if (file_type == FileSpec::eFileTypeRegular         ||
99         file_type == FileSpec::eFileTypeSymbolicLink    ||
100         file_type == FileSpec::eFileTypeUnknown          )
101     {
102         FileSpec plugin_file_spec (file_spec);
103         plugin_file_spec.ResolvePath();
104 
105         if (PluginIsLoaded (plugin_file_spec))
106             return FileSpec::eEnumerateDirectoryResultNext;
107         else
108         {
109             PluginInfo plugin_info = { NULL, NULL, NULL };
110             uint32_t flags = Host::eDynamicLibraryOpenOptionLazy |
111                              Host::eDynamicLibraryOpenOptionLocal |
112                              Host::eDynamicLibraryOpenOptionLimitGetSymbol;
113 
114             plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, flags, error);
115             if (plugin_info.plugin_handle)
116             {
117                 bool success = false;
118                 plugin_info.plugin_init_callback = (PluginInitCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error);
119                 if (plugin_info.plugin_init_callback)
120                 {
121                     // Call the plug-in "bool LLDBPluginInitialize(void)" function
122                     success = plugin_info.plugin_init_callback();
123                 }
124 
125                 if (success)
126                 {
127                     // It is ok for the "LLDBPluginTerminate" symbol to be NULL
128                     plugin_info.plugin_term_callback = (PluginTermCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error);
129                 }
130                 else
131                 {
132                     // The initialize function returned FALSE which means the
133                     // plug-in might not be compatible, or might be too new or
134                     // too old, or might not want to run on this machine.
135                     Host::DynamicLibraryClose (plugin_info.plugin_handle);
136                     plugin_info.plugin_handle = NULL;
137                     plugin_info.plugin_init_callback = NULL;
138                 }
139 
140                 // Regardless of success or failure, cache the plug-in load
141                 // in our plug-in info so we don't try to load it again and
142                 // again.
143                 SetPluginInfo (plugin_file_spec, plugin_info);
144 
145                 return FileSpec::eEnumerateDirectoryResultNext;
146             }
147         }
148     }
149 
150     if (file_type == FileSpec::eFileTypeUnknown     ||
151         file_type == FileSpec::eFileTypeDirectory   ||
152         file_type == FileSpec::eFileTypeSymbolicLink )
153     {
154         // Try and recurse into anything that a directory or symbolic link.
155         // We must also do this for unknown as sometimes the directory enumeration
156         // might be enurating a file system that doesn't have correct file type
157         // information.
158         return FileSpec::eEnumerateDirectoryResultEnter;
159     }
160 
161     return FileSpec::eEnumerateDirectoryResultNext;
162 }
163 
164 
165 void
166 PluginManager::Initialize ()
167 {
168 #if 1
169     FileSpec dir_spec;
170     const bool find_directories = true;
171     const bool find_files = true;
172     const bool find_other = true;
173     char dir_path[PATH_MAX];
174     if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, 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     if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
188     {
189         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
190         {
191             FileSpec::EnumerateDirectory (dir_path,
192                                           find_directories,
193                                           find_files,
194                                           find_other,
195                                           LoadPluginCallback,
196                                           NULL);
197         }
198     }
199 #endif
200 }
201 
202 void
203 PluginManager::Terminate ()
204 {
205     Mutex::Locker locker (GetPluginMapMutex ());
206     PluginTerminateMap &plugin_map = GetPluginMap ();
207 
208     PluginTerminateMap::const_iterator pos, end = plugin_map.end();
209     for (pos = plugin_map.begin(); pos != end; ++pos)
210     {
211         // Call the plug-in "void LLDBPluginTerminate (void)" function if there
212         // is one (if the symbol was not NULL).
213         if (pos->second.plugin_handle)
214         {
215             if (pos->second.plugin_term_callback)
216                 pos->second.plugin_term_callback();
217             Host::DynamicLibraryClose (pos->second.plugin_handle);
218         }
219     }
220     plugin_map.clear();
221 }
222 
223 
224 #pragma mark ABI
225 
226 
227 struct ABIInstance
228 {
229     ABIInstance() :
230         name(),
231         description(),
232         create_callback(NULL)
233     {
234     }
235 
236     ConstString name;
237     std::string description;
238     ABICreateInstance create_callback;
239 };
240 
241 typedef std::vector<ABIInstance> ABIInstances;
242 
243 static Mutex &
244 GetABIInstancesMutex ()
245 {
246     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
247     return g_instances_mutex;
248 }
249 
250 static ABIInstances &
251 GetABIInstances ()
252 {
253     static ABIInstances g_instances;
254     return g_instances;
255 }
256 
257 bool
258 PluginManager::RegisterPlugin
259 (
260     const ConstString &name,
261     const char *description,
262     ABICreateInstance create_callback
263 )
264 {
265     if (create_callback)
266     {
267         ABIInstance instance;
268         assert ((bool)name);
269         instance.name = name;
270         if (description && description[0])
271             instance.description = description;
272         instance.create_callback = create_callback;
273         Mutex::Locker locker (GetABIInstancesMutex ());
274         GetABIInstances ().push_back (instance);
275         return true;
276     }
277     return false;
278 }
279 
280 bool
281 PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
282 {
283     if (create_callback)
284     {
285         Mutex::Locker locker (GetABIInstancesMutex ());
286         ABIInstances &instances = GetABIInstances ();
287 
288         ABIInstances::iterator pos, end = instances.end();
289         for (pos = instances.begin(); pos != end; ++ pos)
290         {
291             if (pos->create_callback == create_callback)
292             {
293                 instances.erase(pos);
294                 return true;
295             }
296         }
297     }
298     return false;
299 }
300 
301 ABICreateInstance
302 PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
303 {
304     Mutex::Locker locker (GetABIInstancesMutex ());
305     ABIInstances &instances = GetABIInstances ();
306     if (idx < instances.size())
307         return instances[idx].create_callback;
308     return NULL;
309 }
310 
311 ABICreateInstance
312 PluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
313 {
314     if (name)
315     {
316         Mutex::Locker locker (GetABIInstancesMutex ());
317         ABIInstances &instances = GetABIInstances ();
318 
319         ABIInstances::iterator pos, end = instances.end();
320         for (pos = instances.begin(); pos != end; ++ pos)
321         {
322             if (name == pos->name)
323                 return pos->create_callback;
324         }
325     }
326     return NULL;
327 }
328 
329 
330 #pragma mark Disassembler
331 
332 
333 struct DisassemblerInstance
334 {
335     DisassemblerInstance() :
336         name(),
337         description(),
338         create_callback(NULL)
339     {
340     }
341 
342     ConstString name;
343     std::string description;
344     DisassemblerCreateInstance create_callback;
345 };
346 
347 typedef std::vector<DisassemblerInstance> DisassemblerInstances;
348 
349 static Mutex &
350 GetDisassemblerMutex ()
351 {
352     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
353     return g_instances_mutex;
354 }
355 
356 static DisassemblerInstances &
357 GetDisassemblerInstances ()
358 {
359     static DisassemblerInstances g_instances;
360     return g_instances;
361 }
362 
363 bool
364 PluginManager::RegisterPlugin
365 (
366     const ConstString &name,
367     const char *description,
368     DisassemblerCreateInstance create_callback
369 )
370 {
371     if (create_callback)
372     {
373         DisassemblerInstance instance;
374         assert ((bool)name);
375         instance.name = name;
376         if (description && description[0])
377             instance.description = description;
378         instance.create_callback = create_callback;
379         Mutex::Locker locker (GetDisassemblerMutex ());
380         GetDisassemblerInstances ().push_back (instance);
381         return true;
382     }
383     return false;
384 }
385 
386 bool
387 PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
388 {
389     if (create_callback)
390     {
391         Mutex::Locker locker (GetDisassemblerMutex ());
392         DisassemblerInstances &instances = GetDisassemblerInstances ();
393 
394         DisassemblerInstances::iterator pos, end = instances.end();
395         for (pos = instances.begin(); pos != end; ++ pos)
396         {
397             if (pos->create_callback == create_callback)
398             {
399                 instances.erase(pos);
400                 return true;
401             }
402         }
403     }
404     return false;
405 }
406 
407 DisassemblerCreateInstance
408 PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
409 {
410     Mutex::Locker locker (GetDisassemblerMutex ());
411     DisassemblerInstances &instances = GetDisassemblerInstances ();
412     if (idx < instances.size())
413         return instances[idx].create_callback;
414     return NULL;
415 }
416 
417 DisassemblerCreateInstance
418 PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &name)
419 {
420     if (name)
421     {
422         Mutex::Locker locker (GetDisassemblerMutex ());
423         DisassemblerInstances &instances = GetDisassemblerInstances ();
424 
425         DisassemblerInstances::iterator pos, end = instances.end();
426         for (pos = instances.begin(); pos != end; ++ pos)
427         {
428             if (name == pos->name)
429                 return pos->create_callback;
430         }
431     }
432     return NULL;
433 }
434 
435 
436 
437 #pragma mark DynamicLoader
438 
439 
440 struct DynamicLoaderInstance
441 {
442     DynamicLoaderInstance() :
443         name(),
444         description(),
445         create_callback(NULL),
446         debugger_init_callback (NULL)
447     {
448     }
449 
450     ConstString name;
451     std::string description;
452     DynamicLoaderCreateInstance create_callback;
453     DebuggerInitializeCallback debugger_init_callback;
454 };
455 
456 typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
457 
458 
459 static Mutex &
460 GetDynamicLoaderMutex ()
461 {
462     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
463     return g_instances_mutex;
464 }
465 
466 static DynamicLoaderInstances &
467 GetDynamicLoaderInstances ()
468 {
469     static DynamicLoaderInstances g_instances;
470     return g_instances;
471 }
472 
473 
474 bool
475 PluginManager::RegisterPlugin
476 (
477     const ConstString &name,
478     const char *description,
479     DynamicLoaderCreateInstance create_callback,
480     DebuggerInitializeCallback debugger_init_callback
481 )
482 {
483     if (create_callback)
484     {
485         DynamicLoaderInstance instance;
486         assert ((bool)name);
487         instance.name = name;
488         if (description && description[0])
489             instance.description = description;
490         instance.create_callback = create_callback;
491         instance.debugger_init_callback = debugger_init_callback;
492         Mutex::Locker locker (GetDynamicLoaderMutex ());
493         GetDynamicLoaderInstances ().push_back (instance);
494     }
495     return false;
496 }
497 
498 bool
499 PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
500 {
501     if (create_callback)
502     {
503         Mutex::Locker locker (GetDynamicLoaderMutex ());
504         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
505 
506         DynamicLoaderInstances::iterator pos, end = instances.end();
507         for (pos = instances.begin(); pos != end; ++ pos)
508         {
509             if (pos->create_callback == create_callback)
510             {
511                 instances.erase(pos);
512                 return true;
513             }
514         }
515     }
516     return false;
517 }
518 
519 DynamicLoaderCreateInstance
520 PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
521 {
522     Mutex::Locker locker (GetDynamicLoaderMutex ());
523     DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
524     if (idx < instances.size())
525         return instances[idx].create_callback;
526     return NULL;
527 }
528 
529 DynamicLoaderCreateInstance
530 PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name)
531 {
532     if (name)
533     {
534         Mutex::Locker locker (GetDynamicLoaderMutex ());
535         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
536 
537         DynamicLoaderInstances::iterator pos, end = instances.end();
538         for (pos = instances.begin(); pos != end; ++ pos)
539         {
540             if (name == pos->name)
541                 return pos->create_callback;
542         }
543     }
544     return NULL;
545 }
546 
547 #pragma mark JITLoader
548 
549 
550 struct JITLoaderInstance
551 {
552     JITLoaderInstance() :
553         name(),
554         description(),
555         create_callback(NULL),
556         debugger_init_callback (NULL)
557     {
558     }
559 
560     ConstString name;
561     std::string description;
562     JITLoaderCreateInstance create_callback;
563     DebuggerInitializeCallback debugger_init_callback;
564 };
565 
566 typedef std::vector<JITLoaderInstance> JITLoaderInstances;
567 
568 
569 static Mutex &
570 GetJITLoaderMutex ()
571 {
572     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
573     return g_instances_mutex;
574 }
575 
576 static JITLoaderInstances &
577 GetJITLoaderInstances ()
578 {
579     static JITLoaderInstances g_instances;
580     return g_instances;
581 }
582 
583 
584 bool
585 PluginManager::RegisterPlugin
586 (
587     const ConstString &name,
588     const char *description,
589     JITLoaderCreateInstance create_callback,
590     DebuggerInitializeCallback debugger_init_callback
591 )
592 {
593     if (create_callback)
594     {
595         JITLoaderInstance instance;
596         assert ((bool)name);
597         instance.name = name;
598         if (description && description[0])
599             instance.description = description;
600         instance.create_callback = create_callback;
601         instance.debugger_init_callback = debugger_init_callback;
602         Mutex::Locker locker (GetJITLoaderMutex ());
603         GetJITLoaderInstances ().push_back (instance);
604     }
605     return false;
606 }
607 
608 bool
609 PluginManager::UnregisterPlugin (JITLoaderCreateInstance create_callback)
610 {
611     if (create_callback)
612     {
613         Mutex::Locker locker (GetJITLoaderMutex ());
614         JITLoaderInstances &instances = GetJITLoaderInstances ();
615 
616         JITLoaderInstances::iterator pos, end = instances.end();
617         for (pos = instances.begin(); pos != end; ++ pos)
618         {
619             if (pos->create_callback == create_callback)
620             {
621                 instances.erase(pos);
622                 return true;
623             }
624         }
625     }
626     return false;
627 }
628 
629 JITLoaderCreateInstance
630 PluginManager::GetJITLoaderCreateCallbackAtIndex (uint32_t idx)
631 {
632     Mutex::Locker locker (GetJITLoaderMutex ());
633     JITLoaderInstances &instances = GetJITLoaderInstances ();
634     if (idx < instances.size())
635         return instances[idx].create_callback;
636     return NULL;
637 }
638 
639 JITLoaderCreateInstance
640 PluginManager::GetJITLoaderCreateCallbackForPluginName (const ConstString &name)
641 {
642     if (name)
643     {
644         Mutex::Locker locker (GetJITLoaderMutex ());
645         JITLoaderInstances &instances = GetJITLoaderInstances ();
646 
647         JITLoaderInstances::iterator pos, end = instances.end();
648         for (pos = instances.begin(); pos != end; ++ pos)
649         {
650             if (name == pos->name)
651                 return pos->create_callback;
652         }
653     }
654     return NULL;
655 }
656 
657 #pragma mark EmulateInstruction
658 
659 
660 struct EmulateInstructionInstance
661 {
662     EmulateInstructionInstance() :
663     name(),
664     description(),
665     create_callback(NULL)
666     {
667     }
668 
669     ConstString name;
670     std::string description;
671     EmulateInstructionCreateInstance create_callback;
672 };
673 
674 typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
675 
676 static Mutex &
677 GetEmulateInstructionMutex ()
678 {
679     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
680     return g_instances_mutex;
681 }
682 
683 static EmulateInstructionInstances &
684 GetEmulateInstructionInstances ()
685 {
686     static EmulateInstructionInstances g_instances;
687     return g_instances;
688 }
689 
690 
691 bool
692 PluginManager::RegisterPlugin
693 (
694     const ConstString &name,
695     const char *description,
696     EmulateInstructionCreateInstance create_callback
697 )
698 {
699     if (create_callback)
700     {
701         EmulateInstructionInstance instance;
702         assert ((bool)name);
703         instance.name = name;
704         if (description && description[0])
705             instance.description = description;
706         instance.create_callback = create_callback;
707         Mutex::Locker locker (GetEmulateInstructionMutex ());
708         GetEmulateInstructionInstances ().push_back (instance);
709     }
710     return false;
711 }
712 
713 bool
714 PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
715 {
716     if (create_callback)
717     {
718         Mutex::Locker locker (GetEmulateInstructionMutex ());
719         EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
720 
721         EmulateInstructionInstances::iterator pos, end = instances.end();
722         for (pos = instances.begin(); pos != end; ++ pos)
723         {
724             if (pos->create_callback == create_callback)
725             {
726                 instances.erase(pos);
727                 return true;
728             }
729         }
730     }
731     return false;
732 }
733 
734 EmulateInstructionCreateInstance
735 PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
736 {
737     Mutex::Locker locker (GetEmulateInstructionMutex ());
738     EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
739     if (idx < instances.size())
740         return instances[idx].create_callback;
741     return NULL;
742 }
743 
744 EmulateInstructionCreateInstance
745 PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name)
746 {
747     if (name)
748     {
749         Mutex::Locker locker (GetEmulateInstructionMutex ());
750         EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
751 
752         EmulateInstructionInstances::iterator pos, end = instances.end();
753         for (pos = instances.begin(); pos != end; ++ pos)
754         {
755             if (name == pos->name)
756                 return pos->create_callback;
757         }
758     }
759     return NULL;
760 }
761 #pragma mark OperatingSystem
762 
763 
764 struct OperatingSystemInstance
765 {
766     OperatingSystemInstance() :
767         name(),
768         description(),
769         create_callback(NULL)
770     {
771     }
772 
773     ConstString name;
774     std::string description;
775     OperatingSystemCreateInstance create_callback;
776 };
777 
778 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
779 
780 static Mutex &
781 GetOperatingSystemMutex ()
782 {
783     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
784     return g_instances_mutex;
785 }
786 
787 static OperatingSystemInstances &
788 GetOperatingSystemInstances ()
789 {
790     static OperatingSystemInstances g_instances;
791     return g_instances;
792 }
793 
794 bool
795 PluginManager::RegisterPlugin (const ConstString &name,
796                                const char *description,
797                                OperatingSystemCreateInstance create_callback)
798 {
799     if (create_callback)
800     {
801         OperatingSystemInstance instance;
802         assert ((bool)name);
803         instance.name = name;
804         if (description && description[0])
805             instance.description = description;
806         instance.create_callback = create_callback;
807         Mutex::Locker locker (GetOperatingSystemMutex ());
808         GetOperatingSystemInstances ().push_back (instance);
809     }
810     return false;
811 }
812 
813 bool
814 PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
815 {
816     if (create_callback)
817     {
818         Mutex::Locker locker (GetOperatingSystemMutex ());
819         OperatingSystemInstances &instances = GetOperatingSystemInstances ();
820 
821         OperatingSystemInstances::iterator pos, end = instances.end();
822         for (pos = instances.begin(); pos != end; ++ pos)
823         {
824             if (pos->create_callback == create_callback)
825             {
826                 instances.erase(pos);
827                 return true;
828             }
829         }
830     }
831     return false;
832 }
833 
834 OperatingSystemCreateInstance
835 PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
836 {
837     Mutex::Locker locker (GetOperatingSystemMutex ());
838     OperatingSystemInstances &instances = GetOperatingSystemInstances ();
839     if (idx < instances.size())
840         return instances[idx].create_callback;
841     return NULL;
842 }
843 
844 OperatingSystemCreateInstance
845 PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
846 {
847     if (name)
848     {
849         Mutex::Locker locker (GetOperatingSystemMutex ());
850         OperatingSystemInstances &instances = GetOperatingSystemInstances ();
851 
852         OperatingSystemInstances::iterator pos, end = instances.end();
853         for (pos = instances.begin(); pos != end; ++ pos)
854         {
855             if (name == pos->name)
856                 return pos->create_callback;
857         }
858     }
859     return NULL;
860 }
861 
862 
863 #pragma mark LanguageRuntime
864 
865 
866 struct LanguageRuntimeInstance
867 {
868     LanguageRuntimeInstance() :
869         name(),
870         description(),
871         create_callback(NULL)
872     {
873     }
874 
875     ConstString name;
876     std::string description;
877     LanguageRuntimeCreateInstance create_callback;
878 };
879 
880 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
881 
882 static Mutex &
883 GetLanguageRuntimeMutex ()
884 {
885     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
886     return g_instances_mutex;
887 }
888 
889 static LanguageRuntimeInstances &
890 GetLanguageRuntimeInstances ()
891 {
892     static LanguageRuntimeInstances g_instances;
893     return g_instances;
894 }
895 
896 bool
897 PluginManager::RegisterPlugin
898 (
899     const ConstString &name,
900     const char *description,
901     LanguageRuntimeCreateInstance create_callback
902 )
903 {
904     if (create_callback)
905     {
906         LanguageRuntimeInstance instance;
907         assert ((bool)name);
908         instance.name = name;
909         if (description && description[0])
910             instance.description = description;
911         instance.create_callback = create_callback;
912         Mutex::Locker locker (GetLanguageRuntimeMutex ());
913         GetLanguageRuntimeInstances ().push_back (instance);
914     }
915     return false;
916 }
917 
918 bool
919 PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
920 {
921     if (create_callback)
922     {
923         Mutex::Locker locker (GetLanguageRuntimeMutex ());
924         LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
925 
926         LanguageRuntimeInstances::iterator pos, end = instances.end();
927         for (pos = instances.begin(); pos != end; ++ pos)
928         {
929             if (pos->create_callback == create_callback)
930             {
931                 instances.erase(pos);
932                 return true;
933             }
934         }
935     }
936     return false;
937 }
938 
939 LanguageRuntimeCreateInstance
940 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
941 {
942     Mutex::Locker locker (GetLanguageRuntimeMutex ());
943     LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
944     if (idx < instances.size())
945         return instances[idx].create_callback;
946     return NULL;
947 }
948 
949 LanguageRuntimeCreateInstance
950 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
951 {
952     if (name)
953     {
954         Mutex::Locker locker (GetLanguageRuntimeMutex ());
955         LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
956 
957         LanguageRuntimeInstances::iterator pos, end = instances.end();
958         for (pos = instances.begin(); pos != end; ++ pos)
959         {
960             if (name == pos->name)
961                 return pos->create_callback;
962         }
963     }
964     return NULL;
965 }
966 
967 #pragma mark SystemRuntime
968 
969 
970 struct SystemRuntimeInstance
971 {
972     SystemRuntimeInstance() :
973         name(),
974         description(),
975         create_callback(NULL)
976     {
977     }
978 
979     ConstString name;
980     std::string description;
981     SystemRuntimeCreateInstance create_callback;
982 };
983 
984 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
985 
986 static Mutex &
987 GetSystemRuntimeMutex ()
988 {
989     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
990     return g_instances_mutex;
991 }
992 
993 static SystemRuntimeInstances &
994 GetSystemRuntimeInstances ()
995 {
996     static SystemRuntimeInstances g_instances;
997     return g_instances;
998 }
999 
1000 bool
1001 PluginManager::RegisterPlugin
1002 (
1003     const ConstString &name,
1004     const char *description,
1005     SystemRuntimeCreateInstance create_callback
1006 )
1007 {
1008     if (create_callback)
1009     {
1010         SystemRuntimeInstance instance;
1011         assert ((bool)name);
1012         instance.name = name;
1013         if (description && description[0])
1014             instance.description = description;
1015         instance.create_callback = create_callback;
1016         Mutex::Locker locker (GetSystemRuntimeMutex ());
1017         GetSystemRuntimeInstances ().push_back (instance);
1018     }
1019     return false;
1020 }
1021 
1022 bool
1023 PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
1024 {
1025     if (create_callback)
1026     {
1027         Mutex::Locker locker (GetSystemRuntimeMutex ());
1028         SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1029 
1030         SystemRuntimeInstances::iterator pos, end = instances.end();
1031         for (pos = instances.begin(); pos != end; ++ pos)
1032         {
1033             if (pos->create_callback == create_callback)
1034             {
1035                 instances.erase(pos);
1036                 return true;
1037             }
1038         }
1039     }
1040     return false;
1041 }
1042 
1043 SystemRuntimeCreateInstance
1044 PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
1045 {
1046     Mutex::Locker locker (GetSystemRuntimeMutex ());
1047     SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1048     if (idx < instances.size())
1049         return instances[idx].create_callback;
1050     return NULL;
1051 }
1052 
1053 SystemRuntimeCreateInstance
1054 PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
1055 {
1056     if (name)
1057     {
1058         Mutex::Locker locker (GetSystemRuntimeMutex ());
1059         SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1060 
1061         SystemRuntimeInstances::iterator pos, end = instances.end();
1062         for (pos = instances.begin(); pos != end; ++ pos)
1063         {
1064             if (name == pos->name)
1065                 return pos->create_callback;
1066         }
1067     }
1068     return NULL;
1069 }
1070 
1071 
1072 #pragma mark ObjectFile
1073 
1074 struct ObjectFileInstance
1075 {
1076     ObjectFileInstance() :
1077         name(),
1078         description(),
1079         create_callback(NULL),
1080         create_memory_callback (NULL),
1081         get_module_specifications (NULL)
1082     {
1083     }
1084 
1085     ConstString name;
1086     std::string description;
1087     ObjectFileCreateInstance create_callback;
1088     ObjectFileCreateMemoryInstance create_memory_callback;
1089     ObjectFileGetModuleSpecifications get_module_specifications;
1090 };
1091 
1092 typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1093 
1094 static Mutex &
1095 GetObjectFileMutex ()
1096 {
1097     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1098     return g_instances_mutex;
1099 }
1100 
1101 static ObjectFileInstances &
1102 GetObjectFileInstances ()
1103 {
1104     static ObjectFileInstances g_instances;
1105     return g_instances;
1106 }
1107 
1108 
1109 bool
1110 PluginManager::RegisterPlugin (const ConstString &name,
1111                                const char *description,
1112                                ObjectFileCreateInstance create_callback,
1113                                ObjectFileCreateMemoryInstance create_memory_callback,
1114                                ObjectFileGetModuleSpecifications get_module_specifications)
1115 {
1116     if (create_callback)
1117     {
1118         ObjectFileInstance instance;
1119         assert ((bool)name);
1120         instance.name = name;
1121         if (description && description[0])
1122             instance.description = description;
1123         instance.create_callback = create_callback;
1124         instance.create_memory_callback = create_memory_callback;
1125         instance.get_module_specifications = get_module_specifications;
1126         Mutex::Locker locker (GetObjectFileMutex ());
1127         GetObjectFileInstances ().push_back (instance);
1128     }
1129     return false;
1130 }
1131 
1132 bool
1133 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
1134 {
1135     if (create_callback)
1136     {
1137         Mutex::Locker locker (GetObjectFileMutex ());
1138         ObjectFileInstances &instances = GetObjectFileInstances ();
1139 
1140         ObjectFileInstances::iterator pos, end = instances.end();
1141         for (pos = instances.begin(); pos != end; ++ pos)
1142         {
1143             if (pos->create_callback == create_callback)
1144             {
1145                 instances.erase(pos);
1146                 return true;
1147             }
1148         }
1149     }
1150     return false;
1151 }
1152 
1153 ObjectFileCreateInstance
1154 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
1155 {
1156     Mutex::Locker locker (GetObjectFileMutex ());
1157     ObjectFileInstances &instances = GetObjectFileInstances ();
1158     if (idx < instances.size())
1159         return instances[idx].create_callback;
1160     return NULL;
1161 }
1162 
1163 
1164 ObjectFileCreateMemoryInstance
1165 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
1166 {
1167     Mutex::Locker locker (GetObjectFileMutex ());
1168     ObjectFileInstances &instances = GetObjectFileInstances ();
1169     if (idx < instances.size())
1170         return instances[idx].create_memory_callback;
1171     return NULL;
1172 }
1173 
1174 ObjectFileGetModuleSpecifications
1175 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1176 {
1177     Mutex::Locker locker (GetObjectFileMutex ());
1178     ObjectFileInstances &instances = GetObjectFileInstances ();
1179     if (idx < instances.size())
1180         return instances[idx].get_module_specifications;
1181     return NULL;
1182 }
1183 
1184 ObjectFileCreateInstance
1185 PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
1186 {
1187     if (name)
1188     {
1189         Mutex::Locker locker (GetObjectFileMutex ());
1190         ObjectFileInstances &instances = GetObjectFileInstances ();
1191 
1192         ObjectFileInstances::iterator pos, end = instances.end();
1193         for (pos = instances.begin(); pos != end; ++ pos)
1194         {
1195             if (name == pos->name)
1196                 return pos->create_callback;
1197         }
1198     }
1199     return NULL;
1200 }
1201 
1202 
1203 ObjectFileCreateMemoryInstance
1204 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
1205 {
1206     if (name)
1207     {
1208         Mutex::Locker locker (GetObjectFileMutex ());
1209         ObjectFileInstances &instances = GetObjectFileInstances ();
1210 
1211         ObjectFileInstances::iterator pos, end = instances.end();
1212         for (pos = instances.begin(); pos != end; ++ pos)
1213         {
1214             if (name == pos->name)
1215                 return pos->create_memory_callback;
1216         }
1217     }
1218     return NULL;
1219 }
1220 
1221 
1222 
1223 #pragma mark ObjectContainer
1224 
1225 struct ObjectContainerInstance
1226 {
1227     ObjectContainerInstance() :
1228         name(),
1229         description(),
1230         create_callback (NULL),
1231         get_module_specifications (NULL)
1232     {
1233     }
1234 
1235     ConstString name;
1236     std::string description;
1237     ObjectContainerCreateInstance create_callback;
1238     ObjectFileGetModuleSpecifications get_module_specifications;
1239 
1240 };
1241 
1242 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1243 
1244 static Mutex &
1245 GetObjectContainerMutex ()
1246 {
1247     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1248     return g_instances_mutex;
1249 }
1250 
1251 static ObjectContainerInstances &
1252 GetObjectContainerInstances ()
1253 {
1254     static ObjectContainerInstances g_instances;
1255     return g_instances;
1256 }
1257 
1258 bool
1259 PluginManager::RegisterPlugin (const ConstString &name,
1260                                const char *description,
1261                                ObjectContainerCreateInstance create_callback,
1262                                ObjectFileGetModuleSpecifications get_module_specifications)
1263 {
1264     if (create_callback)
1265     {
1266         ObjectContainerInstance instance;
1267         assert ((bool)name);
1268         instance.name = name;
1269         if (description && description[0])
1270             instance.description = description;
1271         instance.create_callback = create_callback;
1272         instance.get_module_specifications = get_module_specifications;
1273         Mutex::Locker locker (GetObjectContainerMutex ());
1274         GetObjectContainerInstances ().push_back (instance);
1275     }
1276     return false;
1277 }
1278 
1279 bool
1280 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1281 {
1282     if (create_callback)
1283     {
1284         Mutex::Locker locker (GetObjectContainerMutex ());
1285         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1286 
1287         ObjectContainerInstances::iterator pos, end = instances.end();
1288         for (pos = instances.begin(); pos != end; ++ pos)
1289         {
1290             if (pos->create_callback == create_callback)
1291             {
1292                 instances.erase(pos);
1293                 return true;
1294             }
1295         }
1296     }
1297     return false;
1298 }
1299 
1300 ObjectContainerCreateInstance
1301 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1302 {
1303     Mutex::Locker locker (GetObjectContainerMutex ());
1304     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1305     if (idx < instances.size())
1306         return instances[idx].create_callback;
1307     return NULL;
1308 }
1309 
1310 ObjectContainerCreateInstance
1311 PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
1312 {
1313     if (name)
1314     {
1315         Mutex::Locker locker (GetObjectContainerMutex ());
1316         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1317 
1318         ObjectContainerInstances::iterator pos, end = instances.end();
1319         for (pos = instances.begin(); pos != end; ++ pos)
1320         {
1321             if (name == pos->name)
1322                 return pos->create_callback;
1323         }
1324     }
1325     return NULL;
1326 }
1327 
1328 ObjectFileGetModuleSpecifications
1329 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1330 {
1331     Mutex::Locker locker (GetObjectContainerMutex ());
1332     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1333     if (idx < instances.size())
1334         return instances[idx].get_module_specifications;
1335     return NULL;
1336 }
1337 
1338 #pragma mark LogChannel
1339 
1340 struct LogInstance
1341 {
1342     LogInstance() :
1343         name(),
1344         description(),
1345         create_callback(NULL)
1346     {
1347     }
1348 
1349     ConstString name;
1350     std::string description;
1351     LogChannelCreateInstance create_callback;
1352 };
1353 
1354 typedef std::vector<LogInstance> LogInstances;
1355 
1356 static Mutex &
1357 GetLogMutex ()
1358 {
1359     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1360     return g_instances_mutex;
1361 }
1362 
1363 static LogInstances &
1364 GetLogInstances ()
1365 {
1366     static LogInstances g_instances;
1367     return g_instances;
1368 }
1369 
1370 
1371 
1372 bool
1373 PluginManager::RegisterPlugin
1374 (
1375     const ConstString &name,
1376     const char *description,
1377     LogChannelCreateInstance create_callback
1378 )
1379 {
1380     if (create_callback)
1381     {
1382         LogInstance instance;
1383         assert ((bool)name);
1384         instance.name = name;
1385         if (description && description[0])
1386             instance.description = description;
1387         instance.create_callback = create_callback;
1388         Mutex::Locker locker (GetLogMutex ());
1389         GetLogInstances ().push_back (instance);
1390     }
1391     return false;
1392 }
1393 
1394 bool
1395 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1396 {
1397     if (create_callback)
1398     {
1399         Mutex::Locker locker (GetLogMutex ());
1400         LogInstances &instances = GetLogInstances ();
1401 
1402         LogInstances::iterator pos, end = instances.end();
1403         for (pos = instances.begin(); pos != end; ++ pos)
1404         {
1405             if (pos->create_callback == create_callback)
1406             {
1407                 instances.erase(pos);
1408                 return true;
1409             }
1410         }
1411     }
1412     return false;
1413 }
1414 
1415 const char *
1416 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1417 {
1418     Mutex::Locker locker (GetLogMutex ());
1419     LogInstances &instances = GetLogInstances ();
1420     if (idx < instances.size())
1421         return instances[idx].name.GetCString();
1422     return NULL;
1423 }
1424 
1425 
1426 LogChannelCreateInstance
1427 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1428 {
1429     Mutex::Locker locker (GetLogMutex ());
1430     LogInstances &instances = GetLogInstances ();
1431     if (idx < instances.size())
1432         return instances[idx].create_callback;
1433     return NULL;
1434 }
1435 
1436 LogChannelCreateInstance
1437 PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
1438 {
1439     if (name)
1440     {
1441         Mutex::Locker locker (GetLogMutex ());
1442         LogInstances &instances = GetLogInstances ();
1443 
1444         LogInstances::iterator pos, end = instances.end();
1445         for (pos = instances.begin(); pos != end; ++ pos)
1446         {
1447             if (name == pos->name)
1448                 return pos->create_callback;
1449         }
1450     }
1451     return NULL;
1452 }
1453 
1454 #pragma mark Platform
1455 
1456 struct PlatformInstance
1457 {
1458     PlatformInstance() :
1459         name(),
1460         description(),
1461         create_callback(NULL),
1462         debugger_init_callback (NULL)
1463     {
1464     }
1465 
1466     ConstString name;
1467     std::string description;
1468     PlatformCreateInstance create_callback;
1469     DebuggerInitializeCallback debugger_init_callback;
1470 };
1471 
1472 typedef std::vector<PlatformInstance> PlatformInstances;
1473 
1474 static Mutex &
1475 GetPlatformInstancesMutex ()
1476 {
1477     static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1478     return g_platform_instances_mutex;
1479 }
1480 
1481 static PlatformInstances &
1482 GetPlatformInstances ()
1483 {
1484     static PlatformInstances g_platform_instances;
1485     return g_platform_instances;
1486 }
1487 
1488 
1489 bool
1490 PluginManager::RegisterPlugin (const ConstString &name,
1491                                const char *description,
1492                                PlatformCreateInstance create_callback,
1493                                DebuggerInitializeCallback debugger_init_callback)
1494 {
1495     if (create_callback)
1496     {
1497         Mutex::Locker locker (GetPlatformInstancesMutex ());
1498 
1499         PlatformInstance instance;
1500         assert ((bool)name);
1501         instance.name = name;
1502         if (description && description[0])
1503             instance.description = description;
1504         instance.create_callback = create_callback;
1505         instance.debugger_init_callback = debugger_init_callback;
1506         GetPlatformInstances ().push_back (instance);
1507         return true;
1508     }
1509     return false;
1510 }
1511 
1512 
1513 const char *
1514 PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1515 {
1516     Mutex::Locker locker (GetPlatformInstancesMutex ());
1517     PlatformInstances &instances = GetPlatformInstances ();
1518     if (idx < instances.size())
1519         return instances[idx].name.GetCString();
1520     return NULL;
1521 }
1522 
1523 const char *
1524 PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1525 {
1526     Mutex::Locker locker (GetPlatformInstancesMutex ());
1527     PlatformInstances &instances = GetPlatformInstances ();
1528     if (idx < instances.size())
1529         return instances[idx].description.c_str();
1530     return NULL;
1531 }
1532 
1533 bool
1534 PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1535 {
1536     if (create_callback)
1537     {
1538         Mutex::Locker locker (GetPlatformInstancesMutex ());
1539         PlatformInstances &instances = GetPlatformInstances ();
1540 
1541         PlatformInstances::iterator pos, end = instances.end();
1542         for (pos = instances.begin(); pos != end; ++ pos)
1543         {
1544             if (pos->create_callback == create_callback)
1545             {
1546                 instances.erase(pos);
1547                 return true;
1548             }
1549         }
1550     }
1551     return false;
1552 }
1553 
1554 PlatformCreateInstance
1555 PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1556 {
1557     Mutex::Locker locker (GetPlatformInstancesMutex ());
1558     PlatformInstances &instances = GetPlatformInstances ();
1559     if (idx < instances.size())
1560         return instances[idx].create_callback;
1561     return NULL;
1562 }
1563 
1564 PlatformCreateInstance
1565 PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
1566 {
1567     if (name)
1568     {
1569         Mutex::Locker locker (GetPlatformInstancesMutex ());
1570         PlatformInstances &instances = GetPlatformInstances ();
1571 
1572         PlatformInstances::iterator pos, end = instances.end();
1573         for (pos = instances.begin(); pos != end; ++ pos)
1574         {
1575             if (name == pos->name)
1576                 return pos->create_callback;
1577         }
1578     }
1579     return NULL;
1580 }
1581 
1582 size_t
1583 PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1584 {
1585     if (name)
1586     {
1587         Mutex::Locker locker (GetPlatformInstancesMutex ());
1588         PlatformInstances &instances = GetPlatformInstances ();
1589         llvm::StringRef name_sref(name);
1590 
1591         PlatformInstances::iterator pos, end = instances.end();
1592         for (pos = instances.begin(); pos != end; ++ pos)
1593         {
1594             llvm::StringRef plugin_name (pos->name.GetCString());
1595             if (plugin_name.startswith(name_sref))
1596                 matches.AppendString (plugin_name.data());
1597         }
1598     }
1599     return matches.GetSize();
1600 }
1601 #pragma mark Process
1602 
1603 struct ProcessInstance
1604 {
1605     ProcessInstance() :
1606         name(),
1607         description(),
1608         create_callback(NULL),
1609         debugger_init_callback(NULL)
1610     {
1611     }
1612 
1613     ConstString name;
1614     std::string description;
1615     ProcessCreateInstance create_callback;
1616     DebuggerInitializeCallback debugger_init_callback;
1617 };
1618 
1619 typedef std::vector<ProcessInstance> ProcessInstances;
1620 
1621 static Mutex &
1622 GetProcessMutex ()
1623 {
1624     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1625     return g_instances_mutex;
1626 }
1627 
1628 static ProcessInstances &
1629 GetProcessInstances ()
1630 {
1631     static ProcessInstances g_instances;
1632     return g_instances;
1633 }
1634 
1635 
1636 bool
1637 PluginManager::RegisterPlugin (const ConstString &name,
1638                                const char *description,
1639                                ProcessCreateInstance create_callback,
1640                                DebuggerInitializeCallback debugger_init_callback)
1641 {
1642     if (create_callback)
1643     {
1644         ProcessInstance instance;
1645         assert ((bool)name);
1646         instance.name = name;
1647         if (description && description[0])
1648             instance.description = description;
1649         instance.create_callback = create_callback;
1650         instance.debugger_init_callback = debugger_init_callback;
1651         Mutex::Locker locker (GetProcessMutex ());
1652         GetProcessInstances ().push_back (instance);
1653     }
1654     return false;
1655 }
1656 
1657 const char *
1658 PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1659 {
1660     Mutex::Locker locker (GetProcessMutex ());
1661     ProcessInstances &instances = GetProcessInstances ();
1662     if (idx < instances.size())
1663         return instances[idx].name.GetCString();
1664     return NULL;
1665 }
1666 
1667 const char *
1668 PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1669 {
1670     Mutex::Locker locker (GetProcessMutex ());
1671     ProcessInstances &instances = GetProcessInstances ();
1672     if (idx < instances.size())
1673         return instances[idx].description.c_str();
1674     return NULL;
1675 }
1676 
1677 bool
1678 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1679 {
1680     if (create_callback)
1681     {
1682         Mutex::Locker locker (GetProcessMutex ());
1683         ProcessInstances &instances = GetProcessInstances ();
1684 
1685         ProcessInstances::iterator pos, end = instances.end();
1686         for (pos = instances.begin(); pos != end; ++ pos)
1687         {
1688             if (pos->create_callback == create_callback)
1689             {
1690                 instances.erase(pos);
1691                 return true;
1692             }
1693         }
1694     }
1695     return false;
1696 }
1697 
1698 ProcessCreateInstance
1699 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1700 {
1701     Mutex::Locker locker (GetProcessMutex ());
1702     ProcessInstances &instances = GetProcessInstances ();
1703     if (idx < instances.size())
1704         return instances[idx].create_callback;
1705     return NULL;
1706 }
1707 
1708 
1709 ProcessCreateInstance
1710 PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
1711 {
1712     if (name)
1713     {
1714         Mutex::Locker locker (GetProcessMutex ());
1715         ProcessInstances &instances = GetProcessInstances ();
1716 
1717         ProcessInstances::iterator pos, end = instances.end();
1718         for (pos = instances.begin(); pos != end; ++ pos)
1719         {
1720             if (name == pos->name)
1721                 return pos->create_callback;
1722         }
1723     }
1724     return NULL;
1725 }
1726 
1727 #pragma mark SymbolFile
1728 
1729 struct SymbolFileInstance
1730 {
1731     SymbolFileInstance() :
1732         name(),
1733         description(),
1734         create_callback(NULL)
1735     {
1736     }
1737 
1738     ConstString name;
1739     std::string description;
1740     SymbolFileCreateInstance create_callback;
1741 };
1742 
1743 typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1744 
1745 static Mutex &
1746 GetSymbolFileMutex ()
1747 {
1748     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1749     return g_instances_mutex;
1750 }
1751 
1752 static SymbolFileInstances &
1753 GetSymbolFileInstances ()
1754 {
1755     static SymbolFileInstances g_instances;
1756     return g_instances;
1757 }
1758 
1759 
1760 bool
1761 PluginManager::RegisterPlugin
1762 (
1763     const ConstString &name,
1764     const char *description,
1765     SymbolFileCreateInstance create_callback
1766 )
1767 {
1768     if (create_callback)
1769     {
1770         SymbolFileInstance instance;
1771         assert ((bool)name);
1772         instance.name = name;
1773         if (description && description[0])
1774             instance.description = description;
1775         instance.create_callback = create_callback;
1776         Mutex::Locker locker (GetSymbolFileMutex ());
1777         GetSymbolFileInstances ().push_back (instance);
1778     }
1779     return false;
1780 }
1781 
1782 bool
1783 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1784 {
1785     if (create_callback)
1786     {
1787         Mutex::Locker locker (GetSymbolFileMutex ());
1788         SymbolFileInstances &instances = GetSymbolFileInstances ();
1789 
1790         SymbolFileInstances::iterator pos, end = instances.end();
1791         for (pos = instances.begin(); pos != end; ++ pos)
1792         {
1793             if (pos->create_callback == create_callback)
1794             {
1795                 instances.erase(pos);
1796                 return true;
1797             }
1798         }
1799     }
1800     return false;
1801 }
1802 
1803 SymbolFileCreateInstance
1804 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1805 {
1806     Mutex::Locker locker (GetSymbolFileMutex ());
1807     SymbolFileInstances &instances = GetSymbolFileInstances ();
1808     if (idx < instances.size())
1809         return instances[idx].create_callback;
1810     return NULL;
1811 }
1812 
1813 SymbolFileCreateInstance
1814 PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
1815 {
1816     if (name)
1817     {
1818         Mutex::Locker locker (GetSymbolFileMutex ());
1819         SymbolFileInstances &instances = GetSymbolFileInstances ();
1820 
1821         SymbolFileInstances::iterator pos, end = instances.end();
1822         for (pos = instances.begin(); pos != end; ++ pos)
1823         {
1824             if (name == pos->name)
1825                 return pos->create_callback;
1826         }
1827     }
1828     return NULL;
1829 }
1830 
1831 
1832 
1833 #pragma mark SymbolVendor
1834 
1835 struct SymbolVendorInstance
1836 {
1837     SymbolVendorInstance() :
1838         name(),
1839         description(),
1840         create_callback(NULL)
1841     {
1842     }
1843 
1844     ConstString name;
1845     std::string description;
1846     SymbolVendorCreateInstance create_callback;
1847 };
1848 
1849 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1850 
1851 static Mutex &
1852 GetSymbolVendorMutex ()
1853 {
1854     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1855     return g_instances_mutex;
1856 }
1857 
1858 static SymbolVendorInstances &
1859 GetSymbolVendorInstances ()
1860 {
1861     static SymbolVendorInstances g_instances;
1862     return g_instances;
1863 }
1864 
1865 bool
1866 PluginManager::RegisterPlugin
1867 (
1868     const ConstString &name,
1869     const char *description,
1870     SymbolVendorCreateInstance create_callback
1871 )
1872 {
1873     if (create_callback)
1874     {
1875         SymbolVendorInstance instance;
1876         assert ((bool)name);
1877         instance.name = name;
1878         if (description && description[0])
1879             instance.description = description;
1880         instance.create_callback = create_callback;
1881         Mutex::Locker locker (GetSymbolVendorMutex ());
1882         GetSymbolVendorInstances ().push_back (instance);
1883     }
1884     return false;
1885 }
1886 
1887 bool
1888 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1889 {
1890     if (create_callback)
1891     {
1892         Mutex::Locker locker (GetSymbolVendorMutex ());
1893         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1894 
1895         SymbolVendorInstances::iterator pos, end = instances.end();
1896         for (pos = instances.begin(); pos != end; ++ pos)
1897         {
1898             if (pos->create_callback == create_callback)
1899             {
1900                 instances.erase(pos);
1901                 return true;
1902             }
1903         }
1904     }
1905     return false;
1906 }
1907 
1908 SymbolVendorCreateInstance
1909 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1910 {
1911     Mutex::Locker locker (GetSymbolVendorMutex ());
1912     SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1913     if (idx < instances.size())
1914         return instances[idx].create_callback;
1915     return NULL;
1916 }
1917 
1918 
1919 SymbolVendorCreateInstance
1920 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
1921 {
1922     if (name)
1923     {
1924         Mutex::Locker locker (GetSymbolVendorMutex ());
1925         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1926 
1927         SymbolVendorInstances::iterator pos, end = instances.end();
1928         for (pos = instances.begin(); pos != end; ++ pos)
1929         {
1930             if (name == pos->name)
1931                 return pos->create_callback;
1932         }
1933     }
1934     return NULL;
1935 }
1936 
1937 
1938 #pragma mark UnwindAssembly
1939 
1940 struct UnwindAssemblyInstance
1941 {
1942     UnwindAssemblyInstance() :
1943         name(),
1944         description(),
1945         create_callback(NULL)
1946     {
1947     }
1948 
1949     ConstString name;
1950     std::string description;
1951     UnwindAssemblyCreateInstance create_callback;
1952 };
1953 
1954 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
1955 
1956 static Mutex &
1957 GetUnwindAssemblyMutex ()
1958 {
1959     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1960     return g_instances_mutex;
1961 }
1962 
1963 static UnwindAssemblyInstances &
1964 GetUnwindAssemblyInstances ()
1965 {
1966     static UnwindAssemblyInstances g_instances;
1967     return g_instances;
1968 }
1969 
1970 bool
1971 PluginManager::RegisterPlugin
1972 (
1973     const ConstString &name,
1974     const char *description,
1975     UnwindAssemblyCreateInstance create_callback
1976 )
1977 {
1978     if (create_callback)
1979     {
1980         UnwindAssemblyInstance instance;
1981         assert ((bool)name);
1982         instance.name = name;
1983         if (description && description[0])
1984             instance.description = description;
1985         instance.create_callback = create_callback;
1986         Mutex::Locker locker (GetUnwindAssemblyMutex ());
1987         GetUnwindAssemblyInstances ().push_back (instance);
1988     }
1989     return false;
1990 }
1991 
1992 bool
1993 PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
1994 {
1995     if (create_callback)
1996     {
1997         Mutex::Locker locker (GetUnwindAssemblyMutex ());
1998         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
1999 
2000         UnwindAssemblyInstances::iterator pos, end = instances.end();
2001         for (pos = instances.begin(); pos != end; ++ pos)
2002         {
2003             if (pos->create_callback == create_callback)
2004             {
2005                 instances.erase(pos);
2006                 return true;
2007             }
2008         }
2009     }
2010     return false;
2011 }
2012 
2013 UnwindAssemblyCreateInstance
2014 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
2015 {
2016     Mutex::Locker locker (GetUnwindAssemblyMutex ());
2017     UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2018     if (idx < instances.size())
2019         return instances[idx].create_callback;
2020     return NULL;
2021 }
2022 
2023 
2024 UnwindAssemblyCreateInstance
2025 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
2026 {
2027     if (name)
2028     {
2029         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2030         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2031 
2032         UnwindAssemblyInstances::iterator pos, end = instances.end();
2033         for (pos = instances.begin(); pos != end; ++ pos)
2034         {
2035             if (name == pos->name)
2036                 return pos->create_callback;
2037         }
2038     }
2039     return NULL;
2040 }
2041 
2042 void
2043 PluginManager::DebuggerInitialize (Debugger &debugger)
2044 {
2045     // Initialize the DynamicLoader plugins
2046     {
2047         Mutex::Locker locker (GetDynamicLoaderMutex ());
2048         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
2049 
2050         DynamicLoaderInstances::iterator pos, end = instances.end();
2051         for (pos = instances.begin(); pos != end; ++ pos)
2052         {
2053             if (pos->debugger_init_callback)
2054                 pos->debugger_init_callback (debugger);
2055         }
2056     }
2057 
2058     // Initialize the JITLoader plugins
2059     {
2060         Mutex::Locker locker (GetJITLoaderMutex ());
2061         JITLoaderInstances &instances = GetJITLoaderInstances ();
2062 
2063         JITLoaderInstances::iterator pos, end = instances.end();
2064         for (pos = instances.begin(); pos != end; ++ pos)
2065         {
2066             if (pos->debugger_init_callback)
2067                 pos->debugger_init_callback (debugger);
2068         }
2069     }
2070 
2071     // Initialize the Platform plugins
2072     {
2073         Mutex::Locker locker (GetPlatformInstancesMutex ());
2074         PlatformInstances &instances = GetPlatformInstances ();
2075 
2076         PlatformInstances::iterator pos, end = instances.end();
2077         for (pos = instances.begin(); pos != end; ++ pos)
2078         {
2079             if (pos->debugger_init_callback)
2080                 pos->debugger_init_callback (debugger);
2081         }
2082     }
2083 
2084     // Initialize the Process plugins
2085     {
2086         Mutex::Locker locker (GetProcessMutex());
2087         ProcessInstances &instances = GetProcessInstances();
2088 
2089         ProcessInstances::iterator pos, end = instances.end();
2090         for (pos = instances.begin(); pos != end; ++ pos)
2091         {
2092             if (pos->debugger_init_callback)
2093                 pos->debugger_init_callback (debugger);
2094         }
2095     }
2096 
2097 }
2098 
2099 // This is the preferred new way to register plugin specific settings.  e.g.
2100 // This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2101 static lldb::OptionValuePropertiesSP
2102 GetDebuggerPropertyForPlugins (Debugger &debugger,
2103                                        const ConstString &plugin_type_name,
2104                                        const ConstString &plugin_type_desc,
2105                                        bool can_create)
2106 {
2107     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2108     if (parent_properties_sp)
2109     {
2110         static ConstString g_property_name("plugin");
2111 
2112         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
2113         if (!plugin_properties_sp && can_create)
2114         {
2115             plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
2116             parent_properties_sp->AppendProperty (g_property_name,
2117                                                   ConstString("Settings specify to plugins."),
2118                                                   true,
2119                                                   plugin_properties_sp);
2120         }
2121 
2122         if (plugin_properties_sp)
2123         {
2124             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
2125             if (!plugin_type_properties_sp && can_create)
2126             {
2127                 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2128                 plugin_properties_sp->AppendProperty (plugin_type_name,
2129                                                       plugin_type_desc,
2130                                                       true,
2131                                                       plugin_type_properties_sp);
2132             }
2133             return plugin_type_properties_sp;
2134         }
2135     }
2136     return lldb::OptionValuePropertiesSP();
2137 }
2138 
2139 // This is deprecated way to register plugin specific settings.  e.g.
2140 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
2141 // and Platform generic settings would be under "platform.SETTINGNAME".
2142 static lldb::OptionValuePropertiesSP
2143 GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
2144                                        const ConstString &plugin_type_name,
2145                                        const ConstString &plugin_type_desc,
2146                                        bool can_create)
2147 {
2148     static ConstString g_property_name("plugin");
2149     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2150     if (parent_properties_sp)
2151     {
2152         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
2153         if (!plugin_properties_sp && can_create)
2154         {
2155             plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2156             parent_properties_sp->AppendProperty (plugin_type_name,
2157                                                   plugin_type_desc,
2158                                                   true,
2159                                                   plugin_properties_sp);
2160         }
2161 
2162         if (plugin_properties_sp)
2163         {
2164             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
2165             if (!plugin_type_properties_sp && can_create)
2166             {
2167                 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
2168                 plugin_properties_sp->AppendProperty (g_property_name,
2169                                                       ConstString("Settings specific to plugins"),
2170                                                       true,
2171                                                       plugin_type_properties_sp);
2172             }
2173             return plugin_type_properties_sp;
2174         }
2175     }
2176     return lldb::OptionValuePropertiesSP();
2177 }
2178 
2179 
2180 lldb::OptionValuePropertiesSP
2181 PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name)
2182 {
2183     lldb::OptionValuePropertiesSP properties_sp;
2184     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2185                                                                                             ConstString("dynamic-loader"),
2186                                                                                             ConstString(), // not creating to so we don't need the description
2187                                                                                             false));
2188     if (plugin_type_properties_sp)
2189         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2190     return properties_sp;
2191 }
2192 
2193 bool
2194 PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
2195                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2196                                                     const ConstString &description,
2197                                                     bool is_global_property)
2198 {
2199     if (properties_sp)
2200     {
2201         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2202                                                                                                 ConstString("dynamic-loader"),
2203                                                                                                 ConstString("Settings for dynamic loader plug-ins"),
2204                                                                                                 true));
2205         if (plugin_type_properties_sp)
2206         {
2207             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2208                                                        description,
2209                                                        is_global_property,
2210                                                        properties_sp);
2211             return true;
2212         }
2213     }
2214     return false;
2215 }
2216 
2217 
2218 lldb::OptionValuePropertiesSP
2219 PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
2220 {
2221     lldb::OptionValuePropertiesSP properties_sp;
2222     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2223                                                                                                     ConstString("platform"),
2224                                                                                                     ConstString(), // not creating to so we don't need the description
2225                                                                                                     false));
2226     if (plugin_type_properties_sp)
2227         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2228     return properties_sp;
2229 }
2230 
2231 bool
2232 PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
2233                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2234                                                     const ConstString &description,
2235                                                     bool is_global_property)
2236 {
2237     if (properties_sp)
2238     {
2239         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2240                                                                                                         ConstString("platform"),
2241                                                                                                         ConstString("Settings for platform plug-ins"),
2242                                                                                                         true));
2243         if (plugin_type_properties_sp)
2244         {
2245             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2246                                                        description,
2247                                                        is_global_property,
2248                                                        properties_sp);
2249             return true;
2250         }
2251     }
2252     return false;
2253 }
2254 
2255 
2256 lldb::OptionValuePropertiesSP
2257 PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
2258 {
2259     lldb::OptionValuePropertiesSP properties_sp;
2260     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2261                                                                                             ConstString("process"),
2262                                                                                             ConstString(), // not creating to so we don't need the description
2263                                                                                             false));
2264     if (plugin_type_properties_sp)
2265         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2266     return properties_sp;
2267 }
2268 
2269 bool
2270 PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
2271                                               const lldb::OptionValuePropertiesSP &properties_sp,
2272                                               const ConstString &description,
2273                                               bool is_global_property)
2274 {
2275     if (properties_sp)
2276     {
2277         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2278                                                                                                 ConstString("process"),
2279                                                                                                 ConstString("Settings for process plug-ins"),
2280                                                                                                 true));
2281         if (plugin_type_properties_sp)
2282         {
2283             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2284                                                        description,
2285                                                        is_global_property,
2286                                                        properties_sp);
2287             return true;
2288         }
2289     }
2290     return false;
2291 }
2292 
2293