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/Core/PluginManager.h"
11 
12 #include <limits.h>
13 
14 #include <string>
15 #include <vector>
16 
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/Error.h"
19 #include "lldb/Host/FileSpec.h"
20 #include "lldb/Host/Host.h"
21 #include "lldb/Host/HostInfo.h"
22 #include "lldb/Host/Mutex.h"
23 #include "lldb/Interpreter/OptionValueProperties.h"
24 
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/Support/DynamicLibrary.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     PluginInfo()
45         : plugin_init_callback(nullptr), plugin_term_callback(nullptr)
46     {
47     }
48 
49     llvm::sys::DynamicLibrary library;
50     PluginInitCallback plugin_init_callback;
51     PluginTermCallback plugin_term_callback;
52 };
53 
54 typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
55 
56 static Mutex &
57 GetPluginMapMutex ()
58 {
59     static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
60     return g_plugin_map_mutex;
61 }
62 
63 static PluginTerminateMap &
64 GetPluginMap ()
65 {
66     static PluginTerminateMap g_plugin_map;
67     return g_plugin_map;
68 }
69 
70 static bool
71 PluginIsLoaded (const FileSpec &plugin_file_spec)
72 {
73     Mutex::Locker locker (GetPluginMapMutex ());
74     PluginTerminateMap &plugin_map = GetPluginMap ();
75     return plugin_map.find (plugin_file_spec) != plugin_map.end();
76 }
77 
78 static void
79 SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
80 {
81     Mutex::Locker locker (GetPluginMapMutex ());
82     PluginTerminateMap &plugin_map = GetPluginMap ();
83     assert (plugin_map.find (plugin_file_spec) == plugin_map.end());
84     plugin_map[plugin_file_spec] = plugin_info;
85 }
86 
87 template <typename FPtrTy>
88 static FPtrTy
89 CastToFPtr (void *VPtr)
90 {
91     return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
92 }
93 
94 static FileSpec::EnumerateDirectoryResult
95 LoadPluginCallback
96 (
97     void *baton,
98     FileSpec::FileType file_type,
99     const FileSpec &file_spec
100 )
101 {
102 //    PluginManager *plugin_manager = (PluginManager *)baton;
103     Error error;
104 
105     // If we have a regular file, a symbolic link or unknown file type, try
106     // and process the file. We must handle unknown as sometimes the directory
107     // enumeration might be enumerating a file system that doesn't have correct
108     // file type information.
109     if (file_type == FileSpec::eFileTypeRegular         ||
110         file_type == FileSpec::eFileTypeSymbolicLink    ||
111         file_type == FileSpec::eFileTypeUnknown          )
112     {
113         FileSpec plugin_file_spec (file_spec);
114         plugin_file_spec.ResolvePath();
115 
116         if (PluginIsLoaded (plugin_file_spec))
117             return FileSpec::eEnumerateDirectoryResultNext;
118         else
119         {
120             PluginInfo plugin_info;
121 
122             std::string pluginLoadError;
123             plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary (plugin_file_spec.GetPath().c_str(), &pluginLoadError);
124             if (plugin_info.library.isValid())
125             {
126                 bool success = false;
127                 plugin_info.plugin_init_callback =
128                     CastToFPtr<PluginInitCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
129                 if (plugin_info.plugin_init_callback)
130                 {
131                     // Call the plug-in "bool LLDBPluginInitialize(void)" function
132                     success = plugin_info.plugin_init_callback();
133                 }
134 
135                 if (success)
136                 {
137                     // It is ok for the "LLDBPluginTerminate" symbol to be NULL
138                     plugin_info.plugin_term_callback =
139                         CastToFPtr<PluginTermCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
140                 }
141                 else
142                 {
143                     // The initialize function returned FALSE which means the plug-in might not be
144                     // compatible, or might be too new or too old, or might not want to run on this
145                     // machine.  Set it to a default-constructed instance to invalidate it.
146                     plugin_info = PluginInfo();
147                 }
148 
149                 // Regardless of success or failure, cache the plug-in load
150                 // in our plug-in info so we don't try to load it again and
151                 // again.
152                 SetPluginInfo (plugin_file_spec, plugin_info);
153 
154                 return FileSpec::eEnumerateDirectoryResultNext;
155             }
156         }
157     }
158 
159     if (file_type == FileSpec::eFileTypeUnknown     ||
160         file_type == FileSpec::eFileTypeDirectory   ||
161         file_type == FileSpec::eFileTypeSymbolicLink )
162     {
163         // Try and recurse into anything that a directory or symbolic link.
164         // We must also do this for unknown as sometimes the directory enumeration
165         // might be enumerating a file system that doesn't have correct file type
166         // information.
167         return FileSpec::eEnumerateDirectoryResultEnter;
168     }
169 
170     return FileSpec::eEnumerateDirectoryResultNext;
171 }
172 
173 
174 void
175 PluginManager::Initialize ()
176 {
177 #if 1
178     FileSpec dir_spec;
179     const bool find_directories = true;
180     const bool find_files = true;
181     const bool find_other = true;
182     char dir_path[PATH_MAX];
183     if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
184     {
185         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
186         {
187             FileSpec::EnumerateDirectory (dir_path,
188                                           find_directories,
189                                           find_files,
190                                           find_other,
191                                           LoadPluginCallback,
192                                           NULL);
193         }
194     }
195 
196     if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
197     {
198         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
199         {
200             FileSpec::EnumerateDirectory (dir_path,
201                                           find_directories,
202                                           find_files,
203                                           find_other,
204                                           LoadPluginCallback,
205                                           NULL);
206         }
207     }
208 #endif
209 }
210 
211 void
212 PluginManager::Terminate ()
213 {
214     Mutex::Locker locker (GetPluginMapMutex ());
215     PluginTerminateMap &plugin_map = GetPluginMap ();
216 
217     PluginTerminateMap::const_iterator pos, end = plugin_map.end();
218     for (pos = plugin_map.begin(); pos != end; ++pos)
219     {
220         // Call the plug-in "void LLDBPluginTerminate (void)" function if there
221         // is one (if the symbol was not NULL).
222         if (pos->second.library.isValid())
223         {
224             if (pos->second.plugin_term_callback)
225                 pos->second.plugin_term_callback();
226         }
227     }
228     plugin_map.clear();
229 }
230 
231 
232 #pragma mark ABI
233 
234 
235 struct ABIInstance
236 {
237     ABIInstance() :
238         name(),
239         description(),
240         create_callback(NULL)
241     {
242     }
243 
244     ConstString name;
245     std::string description;
246     ABICreateInstance create_callback;
247 };
248 
249 typedef std::vector<ABIInstance> ABIInstances;
250 
251 static Mutex &
252 GetABIInstancesMutex ()
253 {
254     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
255     return g_instances_mutex;
256 }
257 
258 static ABIInstances &
259 GetABIInstances ()
260 {
261     static ABIInstances g_instances;
262     return g_instances;
263 }
264 
265 bool
266 PluginManager::RegisterPlugin
267 (
268     const ConstString &name,
269     const char *description,
270     ABICreateInstance create_callback
271 )
272 {
273     if (create_callback)
274     {
275         ABIInstance instance;
276         assert ((bool)name);
277         instance.name = name;
278         if (description && description[0])
279             instance.description = description;
280         instance.create_callback = create_callback;
281         Mutex::Locker locker (GetABIInstancesMutex ());
282         GetABIInstances ().push_back (instance);
283         return true;
284     }
285     return false;
286 }
287 
288 bool
289 PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
290 {
291     if (create_callback)
292     {
293         Mutex::Locker locker (GetABIInstancesMutex ());
294         ABIInstances &instances = GetABIInstances ();
295 
296         ABIInstances::iterator pos, end = instances.end();
297         for (pos = instances.begin(); pos != end; ++ pos)
298         {
299             if (pos->create_callback == create_callback)
300             {
301                 instances.erase(pos);
302                 return true;
303             }
304         }
305     }
306     return false;
307 }
308 
309 ABICreateInstance
310 PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
311 {
312     Mutex::Locker locker (GetABIInstancesMutex ());
313     ABIInstances &instances = GetABIInstances ();
314     if (idx < instances.size())
315         return instances[idx].create_callback;
316     return NULL;
317 }
318 
319 ABICreateInstance
320 PluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
321 {
322     if (name)
323     {
324         Mutex::Locker locker (GetABIInstancesMutex ());
325         ABIInstances &instances = GetABIInstances ();
326 
327         ABIInstances::iterator pos, end = instances.end();
328         for (pos = instances.begin(); pos != end; ++ pos)
329         {
330             if (name == pos->name)
331                 return pos->create_callback;
332         }
333     }
334     return NULL;
335 }
336 
337 
338 #pragma mark Disassembler
339 
340 
341 struct DisassemblerInstance
342 {
343     DisassemblerInstance() :
344         name(),
345         description(),
346         create_callback(NULL)
347     {
348     }
349 
350     ConstString name;
351     std::string description;
352     DisassemblerCreateInstance create_callback;
353 };
354 
355 typedef std::vector<DisassemblerInstance> DisassemblerInstances;
356 
357 static Mutex &
358 GetDisassemblerMutex ()
359 {
360     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
361     return g_instances_mutex;
362 }
363 
364 static DisassemblerInstances &
365 GetDisassemblerInstances ()
366 {
367     static DisassemblerInstances g_instances;
368     return g_instances;
369 }
370 
371 bool
372 PluginManager::RegisterPlugin
373 (
374     const ConstString &name,
375     const char *description,
376     DisassemblerCreateInstance create_callback
377 )
378 {
379     if (create_callback)
380     {
381         DisassemblerInstance instance;
382         assert ((bool)name);
383         instance.name = name;
384         if (description && description[0])
385             instance.description = description;
386         instance.create_callback = create_callback;
387         Mutex::Locker locker (GetDisassemblerMutex ());
388         GetDisassemblerInstances ().push_back (instance);
389         return true;
390     }
391     return false;
392 }
393 
394 bool
395 PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
396 {
397     if (create_callback)
398     {
399         Mutex::Locker locker (GetDisassemblerMutex ());
400         DisassemblerInstances &instances = GetDisassemblerInstances ();
401 
402         DisassemblerInstances::iterator pos, end = instances.end();
403         for (pos = instances.begin(); pos != end; ++ pos)
404         {
405             if (pos->create_callback == create_callback)
406             {
407                 instances.erase(pos);
408                 return true;
409             }
410         }
411     }
412     return false;
413 }
414 
415 DisassemblerCreateInstance
416 PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
417 {
418     Mutex::Locker locker (GetDisassemblerMutex ());
419     DisassemblerInstances &instances = GetDisassemblerInstances ();
420     if (idx < instances.size())
421         return instances[idx].create_callback;
422     return NULL;
423 }
424 
425 DisassemblerCreateInstance
426 PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &name)
427 {
428     if (name)
429     {
430         Mutex::Locker locker (GetDisassemblerMutex ());
431         DisassemblerInstances &instances = GetDisassemblerInstances ();
432 
433         DisassemblerInstances::iterator pos, end = instances.end();
434         for (pos = instances.begin(); pos != end; ++ pos)
435         {
436             if (name == pos->name)
437                 return pos->create_callback;
438         }
439     }
440     return NULL;
441 }
442 
443 
444 
445 #pragma mark DynamicLoader
446 
447 
448 struct DynamicLoaderInstance
449 {
450     DynamicLoaderInstance() :
451         name(),
452         description(),
453         create_callback(NULL),
454         debugger_init_callback (NULL)
455     {
456     }
457 
458     ConstString name;
459     std::string description;
460     DynamicLoaderCreateInstance create_callback;
461     DebuggerInitializeCallback debugger_init_callback;
462 };
463 
464 typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
465 
466 
467 static Mutex &
468 GetDynamicLoaderMutex ()
469 {
470     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
471     return g_instances_mutex;
472 }
473 
474 static DynamicLoaderInstances &
475 GetDynamicLoaderInstances ()
476 {
477     static DynamicLoaderInstances g_instances;
478     return g_instances;
479 }
480 
481 
482 bool
483 PluginManager::RegisterPlugin
484 (
485     const ConstString &name,
486     const char *description,
487     DynamicLoaderCreateInstance create_callback,
488     DebuggerInitializeCallback debugger_init_callback
489 )
490 {
491     if (create_callback)
492     {
493         DynamicLoaderInstance instance;
494         assert ((bool)name);
495         instance.name = name;
496         if (description && description[0])
497             instance.description = description;
498         instance.create_callback = create_callback;
499         instance.debugger_init_callback = debugger_init_callback;
500         Mutex::Locker locker (GetDynamicLoaderMutex ());
501         GetDynamicLoaderInstances ().push_back (instance);
502     }
503     return false;
504 }
505 
506 bool
507 PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
508 {
509     if (create_callback)
510     {
511         Mutex::Locker locker (GetDynamicLoaderMutex ());
512         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
513 
514         DynamicLoaderInstances::iterator pos, end = instances.end();
515         for (pos = instances.begin(); pos != end; ++ pos)
516         {
517             if (pos->create_callback == create_callback)
518             {
519                 instances.erase(pos);
520                 return true;
521             }
522         }
523     }
524     return false;
525 }
526 
527 DynamicLoaderCreateInstance
528 PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
529 {
530     Mutex::Locker locker (GetDynamicLoaderMutex ());
531     DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
532     if (idx < instances.size())
533         return instances[idx].create_callback;
534     return NULL;
535 }
536 
537 DynamicLoaderCreateInstance
538 PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name)
539 {
540     if (name)
541     {
542         Mutex::Locker locker (GetDynamicLoaderMutex ());
543         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
544 
545         DynamicLoaderInstances::iterator pos, end = instances.end();
546         for (pos = instances.begin(); pos != end; ++ pos)
547         {
548             if (name == pos->name)
549                 return pos->create_callback;
550         }
551     }
552     return NULL;
553 }
554 
555 #pragma mark JITLoader
556 
557 
558 struct JITLoaderInstance
559 {
560     JITLoaderInstance() :
561         name(),
562         description(),
563         create_callback(NULL),
564         debugger_init_callback (NULL)
565     {
566     }
567 
568     ConstString name;
569     std::string description;
570     JITLoaderCreateInstance create_callback;
571     DebuggerInitializeCallback debugger_init_callback;
572 };
573 
574 typedef std::vector<JITLoaderInstance> JITLoaderInstances;
575 
576 
577 static Mutex &
578 GetJITLoaderMutex ()
579 {
580     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
581     return g_instances_mutex;
582 }
583 
584 static JITLoaderInstances &
585 GetJITLoaderInstances ()
586 {
587     static JITLoaderInstances g_instances;
588     return g_instances;
589 }
590 
591 
592 bool
593 PluginManager::RegisterPlugin
594 (
595     const ConstString &name,
596     const char *description,
597     JITLoaderCreateInstance create_callback,
598     DebuggerInitializeCallback debugger_init_callback
599 )
600 {
601     if (create_callback)
602     {
603         JITLoaderInstance instance;
604         assert ((bool)name);
605         instance.name = name;
606         if (description && description[0])
607             instance.description = description;
608         instance.create_callback = create_callback;
609         instance.debugger_init_callback = debugger_init_callback;
610         Mutex::Locker locker (GetJITLoaderMutex ());
611         GetJITLoaderInstances ().push_back (instance);
612     }
613     return false;
614 }
615 
616 bool
617 PluginManager::UnregisterPlugin (JITLoaderCreateInstance create_callback)
618 {
619     if (create_callback)
620     {
621         Mutex::Locker locker (GetJITLoaderMutex ());
622         JITLoaderInstances &instances = GetJITLoaderInstances ();
623 
624         JITLoaderInstances::iterator pos, end = instances.end();
625         for (pos = instances.begin(); pos != end; ++ pos)
626         {
627             if (pos->create_callback == create_callback)
628             {
629                 instances.erase(pos);
630                 return true;
631             }
632         }
633     }
634     return false;
635 }
636 
637 JITLoaderCreateInstance
638 PluginManager::GetJITLoaderCreateCallbackAtIndex (uint32_t idx)
639 {
640     Mutex::Locker locker (GetJITLoaderMutex ());
641     JITLoaderInstances &instances = GetJITLoaderInstances ();
642     if (idx < instances.size())
643         return instances[idx].create_callback;
644     return NULL;
645 }
646 
647 JITLoaderCreateInstance
648 PluginManager::GetJITLoaderCreateCallbackForPluginName (const ConstString &name)
649 {
650     if (name)
651     {
652         Mutex::Locker locker (GetJITLoaderMutex ());
653         JITLoaderInstances &instances = GetJITLoaderInstances ();
654 
655         JITLoaderInstances::iterator pos, end = instances.end();
656         for (pos = instances.begin(); pos != end; ++ pos)
657         {
658             if (name == pos->name)
659                 return pos->create_callback;
660         }
661     }
662     return NULL;
663 }
664 
665 #pragma mark EmulateInstruction
666 
667 
668 struct EmulateInstructionInstance
669 {
670     EmulateInstructionInstance() :
671     name(),
672     description(),
673     create_callback(NULL)
674     {
675     }
676 
677     ConstString name;
678     std::string description;
679     EmulateInstructionCreateInstance create_callback;
680 };
681 
682 typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
683 
684 static Mutex &
685 GetEmulateInstructionMutex ()
686 {
687     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
688     return g_instances_mutex;
689 }
690 
691 static EmulateInstructionInstances &
692 GetEmulateInstructionInstances ()
693 {
694     static EmulateInstructionInstances g_instances;
695     return g_instances;
696 }
697 
698 
699 bool
700 PluginManager::RegisterPlugin
701 (
702     const ConstString &name,
703     const char *description,
704     EmulateInstructionCreateInstance create_callback
705 )
706 {
707     if (create_callback)
708     {
709         EmulateInstructionInstance instance;
710         assert ((bool)name);
711         instance.name = name;
712         if (description && description[0])
713             instance.description = description;
714         instance.create_callback = create_callback;
715         Mutex::Locker locker (GetEmulateInstructionMutex ());
716         GetEmulateInstructionInstances ().push_back (instance);
717     }
718     return false;
719 }
720 
721 bool
722 PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
723 {
724     if (create_callback)
725     {
726         Mutex::Locker locker (GetEmulateInstructionMutex ());
727         EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
728 
729         EmulateInstructionInstances::iterator pos, end = instances.end();
730         for (pos = instances.begin(); pos != end; ++ pos)
731         {
732             if (pos->create_callback == create_callback)
733             {
734                 instances.erase(pos);
735                 return true;
736             }
737         }
738     }
739     return false;
740 }
741 
742 EmulateInstructionCreateInstance
743 PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
744 {
745     Mutex::Locker locker (GetEmulateInstructionMutex ());
746     EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
747     if (idx < instances.size())
748         return instances[idx].create_callback;
749     return NULL;
750 }
751 
752 EmulateInstructionCreateInstance
753 PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name)
754 {
755     if (name)
756     {
757         Mutex::Locker locker (GetEmulateInstructionMutex ());
758         EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
759 
760         EmulateInstructionInstances::iterator pos, end = instances.end();
761         for (pos = instances.begin(); pos != end; ++ pos)
762         {
763             if (name == pos->name)
764                 return pos->create_callback;
765         }
766     }
767     return NULL;
768 }
769 #pragma mark OperatingSystem
770 
771 
772 struct OperatingSystemInstance
773 {
774     OperatingSystemInstance () :
775         name (),
776         description (),
777         create_callback (nullptr),
778         debugger_init_callback (nullptr)
779     {
780     }
781 
782     ConstString name;
783     std::string description;
784     OperatingSystemCreateInstance create_callback;
785     DebuggerInitializeCallback debugger_init_callback;
786 };
787 
788 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
789 
790 static Mutex &
791 GetOperatingSystemMutex ()
792 {
793     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
794     return g_instances_mutex;
795 }
796 
797 static OperatingSystemInstances &
798 GetOperatingSystemInstances ()
799 {
800     static OperatingSystemInstances g_instances;
801     return g_instances;
802 }
803 
804 bool
805 PluginManager::RegisterPlugin(const ConstString &name, const char *description,
806                               OperatingSystemCreateInstance create_callback,
807                               DebuggerInitializeCallback debugger_init_callback)
808 {
809     if (create_callback)
810     {
811         OperatingSystemInstance instance;
812         assert ((bool)name);
813         instance.name = name;
814         if (description && description[0])
815             instance.description = description;
816         instance.create_callback = create_callback;
817         instance.debugger_init_callback = debugger_init_callback;
818         Mutex::Locker locker (GetOperatingSystemMutex ());
819         GetOperatingSystemInstances ().push_back (instance);
820     }
821     return false;
822 }
823 
824 bool
825 PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
826 {
827     if (create_callback)
828     {
829         Mutex::Locker locker (GetOperatingSystemMutex ());
830         OperatingSystemInstances &instances = GetOperatingSystemInstances ();
831 
832         OperatingSystemInstances::iterator pos, end = instances.end();
833         for (pos = instances.begin(); pos != end; ++ pos)
834         {
835             if (pos->create_callback == create_callback)
836             {
837                 instances.erase(pos);
838                 return true;
839             }
840         }
841     }
842     return false;
843 }
844 
845 OperatingSystemCreateInstance
846 PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
847 {
848     Mutex::Locker locker (GetOperatingSystemMutex ());
849     OperatingSystemInstances &instances = GetOperatingSystemInstances ();
850     if (idx < instances.size())
851         return instances[idx].create_callback;
852     return NULL;
853 }
854 
855 OperatingSystemCreateInstance
856 PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
857 {
858     if (name)
859     {
860         Mutex::Locker locker (GetOperatingSystemMutex ());
861         OperatingSystemInstances &instances = GetOperatingSystemInstances ();
862 
863         OperatingSystemInstances::iterator pos, end = instances.end();
864         for (pos = instances.begin(); pos != end; ++ pos)
865         {
866             if (name == pos->name)
867                 return pos->create_callback;
868         }
869     }
870     return NULL;
871 }
872 
873 
874 #pragma mark Language
875 
876 
877 struct LanguageInstance
878 {
879     LanguageInstance() :
880         name(),
881         description(),
882         create_callback(NULL)
883     {
884     }
885 
886     ConstString name;
887     std::string description;
888     LanguageCreateInstance create_callback;
889 };
890 
891 typedef std::vector<LanguageInstance> LanguageInstances;
892 
893 static Mutex &
894 GetLanguageMutex ()
895 {
896     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
897     return g_instances_mutex;
898 }
899 
900 static LanguageInstances &
901 GetLanguageInstances ()
902 {
903     static LanguageInstances g_instances;
904     return g_instances;
905 }
906 
907 bool
908 PluginManager::RegisterPlugin
909 (
910  const ConstString &name,
911  const char *description,
912  LanguageCreateInstance create_callback
913  )
914 {
915     if (create_callback)
916     {
917         LanguageInstance instance;
918         assert ((bool)name);
919         instance.name = name;
920         if (description && description[0])
921             instance.description = description;
922         instance.create_callback = create_callback;
923         Mutex::Locker locker (GetLanguageMutex ());
924         GetLanguageInstances ().push_back (instance);
925     }
926     return false;
927 }
928 
929 bool
930 PluginManager::UnregisterPlugin (LanguageCreateInstance create_callback)
931 {
932     if (create_callback)
933     {
934         Mutex::Locker locker (GetLanguageMutex ());
935         LanguageInstances &instances = GetLanguageInstances ();
936 
937         LanguageInstances::iterator pos, end = instances.end();
938         for (pos = instances.begin(); pos != end; ++ pos)
939         {
940             if (pos->create_callback == create_callback)
941             {
942                 instances.erase(pos);
943                 return true;
944             }
945         }
946     }
947     return false;
948 }
949 
950 LanguageCreateInstance
951 PluginManager::GetLanguageCreateCallbackAtIndex (uint32_t idx)
952 {
953     Mutex::Locker locker (GetLanguageMutex ());
954     LanguageInstances &instances = GetLanguageInstances ();
955     if (idx < instances.size())
956         return instances[idx].create_callback;
957     return NULL;
958 }
959 
960 LanguageCreateInstance
961 PluginManager::GetLanguageCreateCallbackForPluginName (const ConstString &name)
962 {
963     if (name)
964     {
965         Mutex::Locker locker (GetLanguageMutex ());
966         LanguageInstances &instances = GetLanguageInstances ();
967 
968         LanguageInstances::iterator pos, end = instances.end();
969         for (pos = instances.begin(); pos != end; ++ pos)
970         {
971             if (name == pos->name)
972                 return pos->create_callback;
973         }
974     }
975     return NULL;
976 }
977 
978 
979 #pragma mark LanguageRuntime
980 
981 
982 struct LanguageRuntimeInstance
983 {
984     LanguageRuntimeInstance() :
985         name(),
986         description(),
987         create_callback(NULL)
988     {
989     }
990 
991     ConstString name;
992     std::string description;
993     LanguageRuntimeCreateInstance create_callback;
994     LanguageRuntimeGetCommandObject command_callback;
995 };
996 
997 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
998 
999 static Mutex &
1000 GetLanguageRuntimeMutex ()
1001 {
1002     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1003     return g_instances_mutex;
1004 }
1005 
1006 static LanguageRuntimeInstances &
1007 GetLanguageRuntimeInstances ()
1008 {
1009     static LanguageRuntimeInstances g_instances;
1010     return g_instances;
1011 }
1012 
1013 bool
1014 PluginManager::RegisterPlugin
1015 (
1016     const ConstString &name,
1017     const char *description,
1018     LanguageRuntimeCreateInstance create_callback,
1019     LanguageRuntimeGetCommandObject command_callback
1020 )
1021 {
1022     if (create_callback)
1023     {
1024         LanguageRuntimeInstance instance;
1025         assert ((bool)name);
1026         instance.name = name;
1027         if (description && description[0])
1028             instance.description = description;
1029         instance.create_callback = create_callback;
1030         instance.command_callback = command_callback;
1031         Mutex::Locker locker (GetLanguageRuntimeMutex ());
1032         GetLanguageRuntimeInstances ().push_back (instance);
1033     }
1034     return false;
1035 }
1036 
1037 bool
1038 PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
1039 {
1040     if (create_callback)
1041     {
1042         Mutex::Locker locker (GetLanguageRuntimeMutex ());
1043         LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1044 
1045         LanguageRuntimeInstances::iterator pos, end = instances.end();
1046         for (pos = instances.begin(); pos != end; ++ pos)
1047         {
1048             if (pos->create_callback == create_callback)
1049             {
1050                 instances.erase(pos);
1051                 return true;
1052             }
1053         }
1054     }
1055     return false;
1056 }
1057 
1058 LanguageRuntimeCreateInstance
1059 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
1060 {
1061     Mutex::Locker locker (GetLanguageRuntimeMutex ());
1062     LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1063     if (idx < instances.size())
1064         return instances[idx].create_callback;
1065     return NULL;
1066 }
1067 
1068 LanguageRuntimeGetCommandObject
1069 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex (uint32_t idx)
1070 {
1071     Mutex::Locker locker (GetLanguageRuntimeMutex ());
1072     LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1073     if (idx < instances.size())
1074         return instances[idx].command_callback;
1075     return NULL;
1076 }
1077 
1078 LanguageRuntimeCreateInstance
1079 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
1080 {
1081     if (name)
1082     {
1083         Mutex::Locker locker (GetLanguageRuntimeMutex ());
1084         LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1085 
1086         LanguageRuntimeInstances::iterator pos, end = instances.end();
1087         for (pos = instances.begin(); pos != end; ++ pos)
1088         {
1089             if (name == pos->name)
1090                 return pos->create_callback;
1091         }
1092     }
1093     return NULL;
1094 }
1095 
1096 #pragma mark SystemRuntime
1097 
1098 
1099 struct SystemRuntimeInstance
1100 {
1101     SystemRuntimeInstance() :
1102         name(),
1103         description(),
1104         create_callback(NULL)
1105     {
1106     }
1107 
1108     ConstString name;
1109     std::string description;
1110     SystemRuntimeCreateInstance create_callback;
1111 };
1112 
1113 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
1114 
1115 static Mutex &
1116 GetSystemRuntimeMutex ()
1117 {
1118     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1119     return g_instances_mutex;
1120 }
1121 
1122 static SystemRuntimeInstances &
1123 GetSystemRuntimeInstances ()
1124 {
1125     static SystemRuntimeInstances g_instances;
1126     return g_instances;
1127 }
1128 
1129 bool
1130 PluginManager::RegisterPlugin
1131 (
1132     const ConstString &name,
1133     const char *description,
1134     SystemRuntimeCreateInstance create_callback
1135 )
1136 {
1137     if (create_callback)
1138     {
1139         SystemRuntimeInstance instance;
1140         assert ((bool)name);
1141         instance.name = name;
1142         if (description && description[0])
1143             instance.description = description;
1144         instance.create_callback = create_callback;
1145         Mutex::Locker locker (GetSystemRuntimeMutex ());
1146         GetSystemRuntimeInstances ().push_back (instance);
1147     }
1148     return false;
1149 }
1150 
1151 bool
1152 PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
1153 {
1154     if (create_callback)
1155     {
1156         Mutex::Locker locker (GetSystemRuntimeMutex ());
1157         SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1158 
1159         SystemRuntimeInstances::iterator pos, end = instances.end();
1160         for (pos = instances.begin(); pos != end; ++ pos)
1161         {
1162             if (pos->create_callback == create_callback)
1163             {
1164                 instances.erase(pos);
1165                 return true;
1166             }
1167         }
1168     }
1169     return false;
1170 }
1171 
1172 SystemRuntimeCreateInstance
1173 PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
1174 {
1175     Mutex::Locker locker (GetSystemRuntimeMutex ());
1176     SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1177     if (idx < instances.size())
1178         return instances[idx].create_callback;
1179     return NULL;
1180 }
1181 
1182 SystemRuntimeCreateInstance
1183 PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
1184 {
1185     if (name)
1186     {
1187         Mutex::Locker locker (GetSystemRuntimeMutex ());
1188         SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1189 
1190         SystemRuntimeInstances::iterator pos, end = instances.end();
1191         for (pos = instances.begin(); pos != end; ++ pos)
1192         {
1193             if (name == pos->name)
1194                 return pos->create_callback;
1195         }
1196     }
1197     return NULL;
1198 }
1199 
1200 
1201 #pragma mark ObjectFile
1202 
1203 struct ObjectFileInstance
1204 {
1205     ObjectFileInstance() :
1206         name(),
1207         description(),
1208         create_callback(NULL),
1209         create_memory_callback (NULL),
1210         get_module_specifications (NULL),
1211         save_core (NULL)
1212     {
1213     }
1214 
1215     ConstString name;
1216     std::string description;
1217     ObjectFileCreateInstance create_callback;
1218     ObjectFileCreateMemoryInstance create_memory_callback;
1219     ObjectFileGetModuleSpecifications get_module_specifications;
1220     ObjectFileSaveCore save_core;
1221 };
1222 
1223 typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1224 
1225 static Mutex &
1226 GetObjectFileMutex ()
1227 {
1228     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1229     return g_instances_mutex;
1230 }
1231 
1232 static ObjectFileInstances &
1233 GetObjectFileInstances ()
1234 {
1235     static ObjectFileInstances g_instances;
1236     return g_instances;
1237 }
1238 
1239 
1240 bool
1241 PluginManager::RegisterPlugin (const ConstString &name,
1242                                const char *description,
1243                                ObjectFileCreateInstance create_callback,
1244                                ObjectFileCreateMemoryInstance create_memory_callback,
1245                                ObjectFileGetModuleSpecifications get_module_specifications,
1246                                ObjectFileSaveCore save_core)
1247 {
1248     if (create_callback)
1249     {
1250         ObjectFileInstance instance;
1251         assert ((bool)name);
1252         instance.name = name;
1253         if (description && description[0])
1254             instance.description = description;
1255         instance.create_callback = create_callback;
1256         instance.create_memory_callback = create_memory_callback;
1257         instance.save_core = save_core;
1258         instance.get_module_specifications = get_module_specifications;
1259         Mutex::Locker locker (GetObjectFileMutex ());
1260         GetObjectFileInstances ().push_back (instance);
1261     }
1262     return false;
1263 }
1264 
1265 bool
1266 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
1267 {
1268     if (create_callback)
1269     {
1270         Mutex::Locker locker (GetObjectFileMutex ());
1271         ObjectFileInstances &instances = GetObjectFileInstances ();
1272 
1273         ObjectFileInstances::iterator pos, end = instances.end();
1274         for (pos = instances.begin(); pos != end; ++ pos)
1275         {
1276             if (pos->create_callback == create_callback)
1277             {
1278                 instances.erase(pos);
1279                 return true;
1280             }
1281         }
1282     }
1283     return false;
1284 }
1285 
1286 ObjectFileCreateInstance
1287 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
1288 {
1289     Mutex::Locker locker (GetObjectFileMutex ());
1290     ObjectFileInstances &instances = GetObjectFileInstances ();
1291     if (idx < instances.size())
1292         return instances[idx].create_callback;
1293     return NULL;
1294 }
1295 
1296 
1297 ObjectFileCreateMemoryInstance
1298 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
1299 {
1300     Mutex::Locker locker (GetObjectFileMutex ());
1301     ObjectFileInstances &instances = GetObjectFileInstances ();
1302     if (idx < instances.size())
1303         return instances[idx].create_memory_callback;
1304     return NULL;
1305 }
1306 
1307 ObjectFileGetModuleSpecifications
1308 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1309 {
1310     Mutex::Locker locker (GetObjectFileMutex ());
1311     ObjectFileInstances &instances = GetObjectFileInstances ();
1312     if (idx < instances.size())
1313         return instances[idx].get_module_specifications;
1314     return NULL;
1315 }
1316 
1317 ObjectFileCreateInstance
1318 PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
1319 {
1320     if (name)
1321     {
1322         Mutex::Locker locker (GetObjectFileMutex ());
1323         ObjectFileInstances &instances = GetObjectFileInstances ();
1324 
1325         ObjectFileInstances::iterator pos, end = instances.end();
1326         for (pos = instances.begin(); pos != end; ++ pos)
1327         {
1328             if (name == pos->name)
1329                 return pos->create_callback;
1330         }
1331     }
1332     return NULL;
1333 }
1334 
1335 
1336 ObjectFileCreateMemoryInstance
1337 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
1338 {
1339     if (name)
1340     {
1341         Mutex::Locker locker (GetObjectFileMutex ());
1342         ObjectFileInstances &instances = GetObjectFileInstances ();
1343 
1344         ObjectFileInstances::iterator pos, end = instances.end();
1345         for (pos = instances.begin(); pos != end; ++ pos)
1346         {
1347             if (name == pos->name)
1348                 return pos->create_memory_callback;
1349         }
1350     }
1351     return NULL;
1352 }
1353 
1354 Error
1355 PluginManager::SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile)
1356 {
1357     Error error;
1358     Mutex::Locker locker (GetObjectFileMutex ());
1359     ObjectFileInstances &instances = GetObjectFileInstances ();
1360 
1361     ObjectFileInstances::iterator pos, end = instances.end();
1362     for (pos = instances.begin(); pos != end; ++ pos)
1363     {
1364         if (pos->save_core && pos->save_core (process_sp, outfile, error))
1365             return error;
1366     }
1367     error.SetErrorString("no ObjectFile plugins were able to save a core for this process");
1368     return error;
1369 }
1370 
1371 #pragma mark ObjectContainer
1372 
1373 struct ObjectContainerInstance
1374 {
1375     ObjectContainerInstance() :
1376         name(),
1377         description(),
1378         create_callback (NULL),
1379         get_module_specifications (NULL)
1380     {
1381     }
1382 
1383     ConstString name;
1384     std::string description;
1385     ObjectContainerCreateInstance create_callback;
1386     ObjectFileGetModuleSpecifications get_module_specifications;
1387 
1388 };
1389 
1390 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1391 
1392 static Mutex &
1393 GetObjectContainerMutex ()
1394 {
1395     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1396     return g_instances_mutex;
1397 }
1398 
1399 static ObjectContainerInstances &
1400 GetObjectContainerInstances ()
1401 {
1402     static ObjectContainerInstances g_instances;
1403     return g_instances;
1404 }
1405 
1406 bool
1407 PluginManager::RegisterPlugin (const ConstString &name,
1408                                const char *description,
1409                                ObjectContainerCreateInstance create_callback,
1410                                ObjectFileGetModuleSpecifications get_module_specifications)
1411 {
1412     if (create_callback)
1413     {
1414         ObjectContainerInstance instance;
1415         assert ((bool)name);
1416         instance.name = name;
1417         if (description && description[0])
1418             instance.description = description;
1419         instance.create_callback = create_callback;
1420         instance.get_module_specifications = get_module_specifications;
1421         Mutex::Locker locker (GetObjectContainerMutex ());
1422         GetObjectContainerInstances ().push_back (instance);
1423     }
1424     return false;
1425 }
1426 
1427 bool
1428 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1429 {
1430     if (create_callback)
1431     {
1432         Mutex::Locker locker (GetObjectContainerMutex ());
1433         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1434 
1435         ObjectContainerInstances::iterator pos, end = instances.end();
1436         for (pos = instances.begin(); pos != end; ++ pos)
1437         {
1438             if (pos->create_callback == create_callback)
1439             {
1440                 instances.erase(pos);
1441                 return true;
1442             }
1443         }
1444     }
1445     return false;
1446 }
1447 
1448 ObjectContainerCreateInstance
1449 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1450 {
1451     Mutex::Locker locker (GetObjectContainerMutex ());
1452     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1453     if (idx < instances.size())
1454         return instances[idx].create_callback;
1455     return NULL;
1456 }
1457 
1458 ObjectContainerCreateInstance
1459 PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
1460 {
1461     if (name)
1462     {
1463         Mutex::Locker locker (GetObjectContainerMutex ());
1464         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1465 
1466         ObjectContainerInstances::iterator pos, end = instances.end();
1467         for (pos = instances.begin(); pos != end; ++ pos)
1468         {
1469             if (name == pos->name)
1470                 return pos->create_callback;
1471         }
1472     }
1473     return NULL;
1474 }
1475 
1476 ObjectFileGetModuleSpecifications
1477 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1478 {
1479     Mutex::Locker locker (GetObjectContainerMutex ());
1480     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1481     if (idx < instances.size())
1482         return instances[idx].get_module_specifications;
1483     return NULL;
1484 }
1485 
1486 #pragma mark LogChannel
1487 
1488 struct LogInstance
1489 {
1490     LogInstance() :
1491         name(),
1492         description(),
1493         create_callback(NULL)
1494     {
1495     }
1496 
1497     ConstString name;
1498     std::string description;
1499     LogChannelCreateInstance create_callback;
1500 };
1501 
1502 typedef std::vector<LogInstance> LogInstances;
1503 
1504 static Mutex &
1505 GetLogMutex ()
1506 {
1507     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1508     return g_instances_mutex;
1509 }
1510 
1511 static LogInstances &
1512 GetLogInstances ()
1513 {
1514     static LogInstances g_instances;
1515     return g_instances;
1516 }
1517 
1518 
1519 
1520 bool
1521 PluginManager::RegisterPlugin
1522 (
1523     const ConstString &name,
1524     const char *description,
1525     LogChannelCreateInstance create_callback
1526 )
1527 {
1528     if (create_callback)
1529     {
1530         LogInstance instance;
1531         assert ((bool)name);
1532         instance.name = name;
1533         if (description && description[0])
1534             instance.description = description;
1535         instance.create_callback = create_callback;
1536         Mutex::Locker locker (GetLogMutex ());
1537         GetLogInstances ().push_back (instance);
1538     }
1539     return false;
1540 }
1541 
1542 bool
1543 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1544 {
1545     if (create_callback)
1546     {
1547         Mutex::Locker locker (GetLogMutex ());
1548         LogInstances &instances = GetLogInstances ();
1549 
1550         LogInstances::iterator pos, end = instances.end();
1551         for (pos = instances.begin(); pos != end; ++ pos)
1552         {
1553             if (pos->create_callback == create_callback)
1554             {
1555                 instances.erase(pos);
1556                 return true;
1557             }
1558         }
1559     }
1560     return false;
1561 }
1562 
1563 const char *
1564 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1565 {
1566     Mutex::Locker locker (GetLogMutex ());
1567     LogInstances &instances = GetLogInstances ();
1568     if (idx < instances.size())
1569         return instances[idx].name.GetCString();
1570     return NULL;
1571 }
1572 
1573 
1574 LogChannelCreateInstance
1575 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1576 {
1577     Mutex::Locker locker (GetLogMutex ());
1578     LogInstances &instances = GetLogInstances ();
1579     if (idx < instances.size())
1580         return instances[idx].create_callback;
1581     return NULL;
1582 }
1583 
1584 LogChannelCreateInstance
1585 PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
1586 {
1587     if (name)
1588     {
1589         Mutex::Locker locker (GetLogMutex ());
1590         LogInstances &instances = GetLogInstances ();
1591 
1592         LogInstances::iterator pos, end = instances.end();
1593         for (pos = instances.begin(); pos != end; ++ pos)
1594         {
1595             if (name == pos->name)
1596                 return pos->create_callback;
1597         }
1598     }
1599     return NULL;
1600 }
1601 
1602 #pragma mark Platform
1603 
1604 struct PlatformInstance
1605 {
1606     PlatformInstance() :
1607         name(),
1608         description(),
1609         create_callback(NULL),
1610         debugger_init_callback (NULL)
1611     {
1612     }
1613 
1614     ConstString name;
1615     std::string description;
1616     PlatformCreateInstance create_callback;
1617     DebuggerInitializeCallback debugger_init_callback;
1618 };
1619 
1620 typedef std::vector<PlatformInstance> PlatformInstances;
1621 
1622 static Mutex &
1623 GetPlatformInstancesMutex ()
1624 {
1625     static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1626     return g_platform_instances_mutex;
1627 }
1628 
1629 static PlatformInstances &
1630 GetPlatformInstances ()
1631 {
1632     static PlatformInstances g_platform_instances;
1633     return g_platform_instances;
1634 }
1635 
1636 
1637 bool
1638 PluginManager::RegisterPlugin (const ConstString &name,
1639                                const char *description,
1640                                PlatformCreateInstance create_callback,
1641                                DebuggerInitializeCallback debugger_init_callback)
1642 {
1643     if (create_callback)
1644     {
1645         Mutex::Locker locker (GetPlatformInstancesMutex ());
1646 
1647         PlatformInstance instance;
1648         assert ((bool)name);
1649         instance.name = name;
1650         if (description && description[0])
1651             instance.description = description;
1652         instance.create_callback = create_callback;
1653         instance.debugger_init_callback = debugger_init_callback;
1654         GetPlatformInstances ().push_back (instance);
1655         return true;
1656     }
1657     return false;
1658 }
1659 
1660 
1661 const char *
1662 PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1663 {
1664     Mutex::Locker locker (GetPlatformInstancesMutex ());
1665     PlatformInstances &instances = GetPlatformInstances ();
1666     if (idx < instances.size())
1667         return instances[idx].name.GetCString();
1668     return NULL;
1669 }
1670 
1671 const char *
1672 PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1673 {
1674     Mutex::Locker locker (GetPlatformInstancesMutex ());
1675     PlatformInstances &instances = GetPlatformInstances ();
1676     if (idx < instances.size())
1677         return instances[idx].description.c_str();
1678     return NULL;
1679 }
1680 
1681 bool
1682 PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1683 {
1684     if (create_callback)
1685     {
1686         Mutex::Locker locker (GetPlatformInstancesMutex ());
1687         PlatformInstances &instances = GetPlatformInstances ();
1688 
1689         PlatformInstances::iterator pos, end = instances.end();
1690         for (pos = instances.begin(); pos != end; ++ pos)
1691         {
1692             if (pos->create_callback == create_callback)
1693             {
1694                 instances.erase(pos);
1695                 return true;
1696             }
1697         }
1698     }
1699     return false;
1700 }
1701 
1702 PlatformCreateInstance
1703 PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1704 {
1705     Mutex::Locker locker (GetPlatformInstancesMutex ());
1706     PlatformInstances &instances = GetPlatformInstances ();
1707     if (idx < instances.size())
1708         return instances[idx].create_callback;
1709     return NULL;
1710 }
1711 
1712 PlatformCreateInstance
1713 PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
1714 {
1715     if (name)
1716     {
1717         Mutex::Locker locker (GetPlatformInstancesMutex ());
1718         PlatformInstances &instances = GetPlatformInstances ();
1719 
1720         PlatformInstances::iterator pos, end = instances.end();
1721         for (pos = instances.begin(); pos != end; ++ pos)
1722         {
1723             if (name == pos->name)
1724                 return pos->create_callback;
1725         }
1726     }
1727     return NULL;
1728 }
1729 
1730 size_t
1731 PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1732 {
1733     if (name)
1734     {
1735         Mutex::Locker locker (GetPlatformInstancesMutex ());
1736         PlatformInstances &instances = GetPlatformInstances ();
1737         llvm::StringRef name_sref(name);
1738 
1739         PlatformInstances::iterator pos, end = instances.end();
1740         for (pos = instances.begin(); pos != end; ++ pos)
1741         {
1742             llvm::StringRef plugin_name (pos->name.GetCString());
1743             if (plugin_name.startswith(name_sref))
1744                 matches.AppendString (plugin_name.data());
1745         }
1746     }
1747     return matches.GetSize();
1748 }
1749 #pragma mark Process
1750 
1751 struct ProcessInstance
1752 {
1753     ProcessInstance() :
1754         name(),
1755         description(),
1756         create_callback(NULL),
1757         debugger_init_callback(NULL)
1758     {
1759     }
1760 
1761     ConstString name;
1762     std::string description;
1763     ProcessCreateInstance create_callback;
1764     DebuggerInitializeCallback debugger_init_callback;
1765 };
1766 
1767 typedef std::vector<ProcessInstance> ProcessInstances;
1768 
1769 static Mutex &
1770 GetProcessMutex ()
1771 {
1772     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1773     return g_instances_mutex;
1774 }
1775 
1776 static ProcessInstances &
1777 GetProcessInstances ()
1778 {
1779     static ProcessInstances g_instances;
1780     return g_instances;
1781 }
1782 
1783 
1784 bool
1785 PluginManager::RegisterPlugin (const ConstString &name,
1786                                const char *description,
1787                                ProcessCreateInstance create_callback,
1788                                DebuggerInitializeCallback debugger_init_callback)
1789 {
1790     if (create_callback)
1791     {
1792         ProcessInstance instance;
1793         assert ((bool)name);
1794         instance.name = name;
1795         if (description && description[0])
1796             instance.description = description;
1797         instance.create_callback = create_callback;
1798         instance.debugger_init_callback = debugger_init_callback;
1799         Mutex::Locker locker (GetProcessMutex ());
1800         GetProcessInstances ().push_back (instance);
1801     }
1802     return false;
1803 }
1804 
1805 const char *
1806 PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1807 {
1808     Mutex::Locker locker (GetProcessMutex ());
1809     ProcessInstances &instances = GetProcessInstances ();
1810     if (idx < instances.size())
1811         return instances[idx].name.GetCString();
1812     return NULL;
1813 }
1814 
1815 const char *
1816 PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1817 {
1818     Mutex::Locker locker (GetProcessMutex ());
1819     ProcessInstances &instances = GetProcessInstances ();
1820     if (idx < instances.size())
1821         return instances[idx].description.c_str();
1822     return NULL;
1823 }
1824 
1825 bool
1826 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1827 {
1828     if (create_callback)
1829     {
1830         Mutex::Locker locker (GetProcessMutex ());
1831         ProcessInstances &instances = GetProcessInstances ();
1832 
1833         ProcessInstances::iterator pos, end = instances.end();
1834         for (pos = instances.begin(); pos != end; ++ pos)
1835         {
1836             if (pos->create_callback == create_callback)
1837             {
1838                 instances.erase(pos);
1839                 return true;
1840             }
1841         }
1842     }
1843     return false;
1844 }
1845 
1846 ProcessCreateInstance
1847 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1848 {
1849     Mutex::Locker locker (GetProcessMutex ());
1850     ProcessInstances &instances = GetProcessInstances ();
1851     if (idx < instances.size())
1852         return instances[idx].create_callback;
1853     return NULL;
1854 }
1855 
1856 
1857 ProcessCreateInstance
1858 PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
1859 {
1860     if (name)
1861     {
1862         Mutex::Locker locker (GetProcessMutex ());
1863         ProcessInstances &instances = GetProcessInstances ();
1864 
1865         ProcessInstances::iterator pos, end = instances.end();
1866         for (pos = instances.begin(); pos != end; ++ pos)
1867         {
1868             if (name == pos->name)
1869                 return pos->create_callback;
1870         }
1871     }
1872     return NULL;
1873 }
1874 
1875 #pragma mark ScriptInterpreter
1876 
1877 struct ScriptInterpreterInstance
1878 {
1879     ScriptInterpreterInstance()
1880         : name()
1881         , language(lldb::eScriptLanguageNone)
1882         , description()
1883         , create_callback(NULL)
1884     {
1885     }
1886 
1887     ConstString name;
1888     lldb::ScriptLanguage language;
1889     std::string description;
1890     ScriptInterpreterCreateInstance create_callback;
1891 };
1892 
1893 typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
1894 
1895 static Mutex &
1896 GetScriptInterpreterMutex()
1897 {
1898     static Mutex g_instances_mutex(Mutex::eMutexTypeRecursive);
1899     return g_instances_mutex;
1900 }
1901 
1902 static ScriptInterpreterInstances &
1903 GetScriptInterpreterInstances()
1904 {
1905     static ScriptInterpreterInstances g_instances;
1906     return g_instances;
1907 }
1908 
1909 bool
1910 PluginManager::RegisterPlugin(const ConstString &name, const char *description, lldb::ScriptLanguage script_language,
1911                               ScriptInterpreterCreateInstance create_callback)
1912 {
1913     if (!create_callback)
1914         return false;
1915     ScriptInterpreterInstance instance;
1916     assert((bool)name);
1917     instance.name = name;
1918     if (description && description[0])
1919         instance.description = description;
1920     instance.create_callback = create_callback;
1921     instance.language = script_language;
1922     Mutex::Locker locker(GetScriptInterpreterMutex());
1923     GetScriptInterpreterInstances().push_back(instance);
1924     return false;
1925 }
1926 
1927 bool
1928 PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)
1929 {
1930     if (!create_callback)
1931         return false;
1932     Mutex::Locker locker(GetScriptInterpreterMutex());
1933     ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1934 
1935     ScriptInterpreterInstances::iterator pos, end = instances.end();
1936     for (pos = instances.begin(); pos != end; ++pos)
1937     {
1938         if (pos->create_callback != create_callback)
1939             continue;
1940 
1941         instances.erase(pos);
1942         return true;
1943     }
1944     return false;
1945 }
1946 
1947 ScriptInterpreterCreateInstance
1948 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)
1949 {
1950     Mutex::Locker locker(GetScriptInterpreterMutex());
1951     ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1952     if (idx < instances.size())
1953         return instances[idx].create_callback;
1954     return nullptr;
1955 }
1956 
1957 lldb::ScriptInterpreterSP
1958 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter)
1959 {
1960     Mutex::Locker locker(GetScriptInterpreterMutex());
1961     ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1962 
1963     ScriptInterpreterInstances::iterator pos, end = instances.end();
1964     ScriptInterpreterCreateInstance none_instance = nullptr;
1965     for (pos = instances.begin(); pos != end; ++pos)
1966     {
1967         if (pos->language == lldb::eScriptLanguageNone)
1968             none_instance = pos->create_callback;
1969 
1970         if (script_lang == pos->language)
1971             return pos->create_callback(interpreter);
1972     }
1973 
1974     // If we didn't find one, return the ScriptInterpreter for the null language.
1975     assert(none_instance != nullptr);
1976     return none_instance(interpreter);
1977 }
1978 
1979 #pragma mark SymbolFile
1980 
1981 struct SymbolFileInstance
1982 {
1983     SymbolFileInstance() :
1984         name(),
1985         description(),
1986         create_callback(nullptr),
1987         debugger_init_callback(nullptr)
1988     {
1989     }
1990 
1991     ConstString name;
1992     std::string description;
1993     SymbolFileCreateInstance create_callback;
1994     DebuggerInitializeCallback debugger_init_callback;
1995 };
1996 
1997 typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1998 
1999 static Mutex &
2000 GetSymbolFileMutex ()
2001 {
2002     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2003     return g_instances_mutex;
2004 }
2005 
2006 static SymbolFileInstances &
2007 GetSymbolFileInstances ()
2008 {
2009     static SymbolFileInstances g_instances;
2010     return g_instances;
2011 }
2012 
2013 
2014 bool
2015 PluginManager::RegisterPlugin
2016 (
2017     const ConstString &name,
2018     const char *description,
2019     SymbolFileCreateInstance create_callback,
2020     DebuggerInitializeCallback debugger_init_callback
2021 )
2022 {
2023     if (create_callback)
2024     {
2025         SymbolFileInstance instance;
2026         assert ((bool)name);
2027         instance.name = name;
2028         if (description && description[0])
2029             instance.description = description;
2030         instance.create_callback = create_callback;
2031         instance.debugger_init_callback = debugger_init_callback;
2032         Mutex::Locker locker (GetSymbolFileMutex ());
2033         GetSymbolFileInstances ().push_back (instance);
2034     }
2035     return false;
2036 }
2037 
2038 bool
2039 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
2040 {
2041     if (create_callback)
2042     {
2043         Mutex::Locker locker (GetSymbolFileMutex ());
2044         SymbolFileInstances &instances = GetSymbolFileInstances ();
2045 
2046         SymbolFileInstances::iterator pos, end = instances.end();
2047         for (pos = instances.begin(); pos != end; ++ pos)
2048         {
2049             if (pos->create_callback == create_callback)
2050             {
2051                 instances.erase(pos);
2052                 return true;
2053             }
2054         }
2055     }
2056     return false;
2057 }
2058 
2059 SymbolFileCreateInstance
2060 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
2061 {
2062     Mutex::Locker locker (GetSymbolFileMutex ());
2063     SymbolFileInstances &instances = GetSymbolFileInstances ();
2064     if (idx < instances.size())
2065         return instances[idx].create_callback;
2066     return NULL;
2067 }
2068 
2069 SymbolFileCreateInstance
2070 PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
2071 {
2072     if (name)
2073     {
2074         Mutex::Locker locker (GetSymbolFileMutex ());
2075         SymbolFileInstances &instances = GetSymbolFileInstances ();
2076 
2077         SymbolFileInstances::iterator pos, end = instances.end();
2078         for (pos = instances.begin(); pos != end; ++ pos)
2079         {
2080             if (name == pos->name)
2081                 return pos->create_callback;
2082         }
2083     }
2084     return NULL;
2085 }
2086 
2087 
2088 
2089 #pragma mark SymbolVendor
2090 
2091 struct SymbolVendorInstance
2092 {
2093     SymbolVendorInstance() :
2094         name(),
2095         description(),
2096         create_callback(NULL)
2097     {
2098     }
2099 
2100     ConstString name;
2101     std::string description;
2102     SymbolVendorCreateInstance create_callback;
2103 };
2104 
2105 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
2106 
2107 static Mutex &
2108 GetSymbolVendorMutex ()
2109 {
2110     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2111     return g_instances_mutex;
2112 }
2113 
2114 static SymbolVendorInstances &
2115 GetSymbolVendorInstances ()
2116 {
2117     static SymbolVendorInstances g_instances;
2118     return g_instances;
2119 }
2120 
2121 bool
2122 PluginManager::RegisterPlugin
2123 (
2124     const ConstString &name,
2125     const char *description,
2126     SymbolVendorCreateInstance create_callback
2127 )
2128 {
2129     if (create_callback)
2130     {
2131         SymbolVendorInstance instance;
2132         assert ((bool)name);
2133         instance.name = name;
2134         if (description && description[0])
2135             instance.description = description;
2136         instance.create_callback = create_callback;
2137         Mutex::Locker locker (GetSymbolVendorMutex ());
2138         GetSymbolVendorInstances ().push_back (instance);
2139     }
2140     return false;
2141 }
2142 
2143 bool
2144 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
2145 {
2146     if (create_callback)
2147     {
2148         Mutex::Locker locker (GetSymbolVendorMutex ());
2149         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2150 
2151         SymbolVendorInstances::iterator pos, end = instances.end();
2152         for (pos = instances.begin(); pos != end; ++ pos)
2153         {
2154             if (pos->create_callback == create_callback)
2155             {
2156                 instances.erase(pos);
2157                 return true;
2158             }
2159         }
2160     }
2161     return false;
2162 }
2163 
2164 SymbolVendorCreateInstance
2165 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
2166 {
2167     Mutex::Locker locker (GetSymbolVendorMutex ());
2168     SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2169     if (idx < instances.size())
2170         return instances[idx].create_callback;
2171     return NULL;
2172 }
2173 
2174 
2175 SymbolVendorCreateInstance
2176 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
2177 {
2178     if (name)
2179     {
2180         Mutex::Locker locker (GetSymbolVendorMutex ());
2181         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2182 
2183         SymbolVendorInstances::iterator pos, end = instances.end();
2184         for (pos = instances.begin(); pos != end; ++ pos)
2185         {
2186             if (name == pos->name)
2187                 return pos->create_callback;
2188         }
2189     }
2190     return NULL;
2191 }
2192 
2193 
2194 #pragma mark UnwindAssembly
2195 
2196 struct UnwindAssemblyInstance
2197 {
2198     UnwindAssemblyInstance() :
2199         name(),
2200         description(),
2201         create_callback(NULL)
2202     {
2203     }
2204 
2205     ConstString name;
2206     std::string description;
2207     UnwindAssemblyCreateInstance create_callback;
2208 };
2209 
2210 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
2211 
2212 static Mutex &
2213 GetUnwindAssemblyMutex ()
2214 {
2215     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2216     return g_instances_mutex;
2217 }
2218 
2219 static UnwindAssemblyInstances &
2220 GetUnwindAssemblyInstances ()
2221 {
2222     static UnwindAssemblyInstances g_instances;
2223     return g_instances;
2224 }
2225 
2226 bool
2227 PluginManager::RegisterPlugin
2228 (
2229     const ConstString &name,
2230     const char *description,
2231     UnwindAssemblyCreateInstance create_callback
2232 )
2233 {
2234     if (create_callback)
2235     {
2236         UnwindAssemblyInstance instance;
2237         assert ((bool)name);
2238         instance.name = name;
2239         if (description && description[0])
2240             instance.description = description;
2241         instance.create_callback = create_callback;
2242         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2243         GetUnwindAssemblyInstances ().push_back (instance);
2244     }
2245     return false;
2246 }
2247 
2248 bool
2249 PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
2250 {
2251     if (create_callback)
2252     {
2253         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2254         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2255 
2256         UnwindAssemblyInstances::iterator pos, end = instances.end();
2257         for (pos = instances.begin(); pos != end; ++ pos)
2258         {
2259             if (pos->create_callback == create_callback)
2260             {
2261                 instances.erase(pos);
2262                 return true;
2263             }
2264         }
2265     }
2266     return false;
2267 }
2268 
2269 UnwindAssemblyCreateInstance
2270 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
2271 {
2272     Mutex::Locker locker (GetUnwindAssemblyMutex ());
2273     UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2274     if (idx < instances.size())
2275         return instances[idx].create_callback;
2276     return NULL;
2277 }
2278 
2279 
2280 UnwindAssemblyCreateInstance
2281 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
2282 {
2283     if (name)
2284     {
2285         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2286         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2287 
2288         UnwindAssemblyInstances::iterator pos, end = instances.end();
2289         for (pos = instances.begin(); pos != end; ++ pos)
2290         {
2291             if (name == pos->name)
2292                 return pos->create_callback;
2293         }
2294     }
2295     return NULL;
2296 }
2297 
2298 #pragma mark MemoryHistory
2299 
2300 struct MemoryHistoryInstance
2301 {
2302     MemoryHistoryInstance() :
2303     name(),
2304     description(),
2305     create_callback(NULL)
2306     {
2307     }
2308 
2309     ConstString name;
2310     std::string description;
2311     MemoryHistoryCreateInstance create_callback;
2312 };
2313 
2314 typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
2315 
2316 static Mutex &
2317 GetMemoryHistoryMutex ()
2318 {
2319     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2320     return g_instances_mutex;
2321 }
2322 
2323 static MemoryHistoryInstances &
2324 GetMemoryHistoryInstances ()
2325 {
2326     static MemoryHistoryInstances g_instances;
2327     return g_instances;
2328 }
2329 
2330 bool
2331 PluginManager::RegisterPlugin
2332 (
2333  const ConstString &name,
2334  const char *description,
2335  MemoryHistoryCreateInstance create_callback
2336  )
2337 {
2338     if (create_callback)
2339     {
2340         MemoryHistoryInstance instance;
2341         assert ((bool)name);
2342         instance.name = name;
2343         if (description && description[0])
2344             instance.description = description;
2345         instance.create_callback = create_callback;
2346         Mutex::Locker locker (GetMemoryHistoryMutex ());
2347         GetMemoryHistoryInstances ().push_back (instance);
2348     }
2349     return false;
2350 }
2351 
2352 bool
2353 PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
2354 {
2355     if (create_callback)
2356     {
2357         Mutex::Locker locker (GetMemoryHistoryMutex ());
2358         MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2359 
2360         MemoryHistoryInstances::iterator pos, end = instances.end();
2361         for (pos = instances.begin(); pos != end; ++ pos)
2362         {
2363             if (pos->create_callback == create_callback)
2364             {
2365                 instances.erase(pos);
2366                 return true;
2367             }
2368         }
2369     }
2370     return false;
2371 }
2372 
2373 MemoryHistoryCreateInstance
2374 PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
2375 {
2376     Mutex::Locker locker (GetMemoryHistoryMutex ());
2377     MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2378     if (idx < instances.size())
2379         return instances[idx].create_callback;
2380     return NULL;
2381 }
2382 
2383 
2384 MemoryHistoryCreateInstance
2385 PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name)
2386 {
2387     if (name)
2388     {
2389         Mutex::Locker locker (GetMemoryHistoryMutex ());
2390         MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2391 
2392         MemoryHistoryInstances::iterator pos, end = instances.end();
2393         for (pos = instances.begin(); pos != end; ++ pos)
2394         {
2395             if (name == pos->name)
2396                 return pos->create_callback;
2397         }
2398     }
2399     return NULL;
2400 }
2401 
2402 #pragma mark InstrumentationRuntime
2403 
2404 struct InstrumentationRuntimeInstance
2405 {
2406     InstrumentationRuntimeInstance() :
2407     name(),
2408     description(),
2409     create_callback(NULL)
2410     {
2411     }
2412 
2413     ConstString name;
2414     std::string description;
2415     InstrumentationRuntimeCreateInstance create_callback;
2416     InstrumentationRuntimeGetType get_type_callback;
2417 };
2418 
2419 typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances;
2420 
2421 static Mutex &
2422 GetInstrumentationRuntimeMutex ()
2423 {
2424     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2425     return g_instances_mutex;
2426 }
2427 
2428 static InstrumentationRuntimeInstances &
2429 GetInstrumentationRuntimeInstances ()
2430 {
2431     static InstrumentationRuntimeInstances g_instances;
2432     return g_instances;
2433 }
2434 
2435 bool
2436 PluginManager::RegisterPlugin
2437 (
2438  const ConstString &name,
2439  const char *description,
2440  InstrumentationRuntimeCreateInstance create_callback,
2441  InstrumentationRuntimeGetType get_type_callback
2442  )
2443 {
2444     if (create_callback)
2445     {
2446         InstrumentationRuntimeInstance instance;
2447         assert ((bool)name);
2448         instance.name = name;
2449         if (description && description[0])
2450             instance.description = description;
2451         instance.create_callback = create_callback;
2452         instance.get_type_callback = get_type_callback;
2453         Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2454         GetInstrumentationRuntimeInstances ().push_back (instance);
2455     }
2456     return false;
2457 }
2458 
2459 bool
2460 PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback)
2461 {
2462     if (create_callback)
2463     {
2464         Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2465         InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2466 
2467         InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2468         for (pos = instances.begin(); pos != end; ++ pos)
2469         {
2470             if (pos->create_callback == create_callback)
2471             {
2472                 instances.erase(pos);
2473                 return true;
2474             }
2475         }
2476     }
2477     return false;
2478 }
2479 
2480 InstrumentationRuntimeGetType
2481 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx)
2482 {
2483     Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2484     InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2485     if (idx < instances.size())
2486         return instances[idx].get_type_callback;
2487     return NULL;
2488 }
2489 
2490 InstrumentationRuntimeCreateInstance
2491 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx)
2492 {
2493     Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2494     InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2495     if (idx < instances.size())
2496         return instances[idx].create_callback;
2497     return NULL;
2498 }
2499 
2500 
2501 InstrumentationRuntimeCreateInstance
2502 PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name)
2503 {
2504     if (name)
2505     {
2506         Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2507         InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2508 
2509         InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2510         for (pos = instances.begin(); pos != end; ++ pos)
2511         {
2512             if (name == pos->name)
2513                 return pos->create_callback;
2514         }
2515     }
2516     return NULL;
2517 }
2518 
2519 #pragma mark TypeSystem
2520 
2521 
2522 struct TypeSystemInstance
2523 {
2524     TypeSystemInstance() :
2525     name(),
2526     description(),
2527     create_callback(NULL)
2528     {
2529     }
2530 
2531     ConstString name;
2532     std::string description;
2533     TypeSystemCreateInstance create_callback;
2534 };
2535 
2536 typedef std::vector<TypeSystemInstance> TypeSystemInstances;
2537 
2538 static Mutex &
2539 GetTypeSystemMutex ()
2540 {
2541     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2542     return g_instances_mutex;
2543 }
2544 
2545 static TypeSystemInstances &
2546 GetTypeSystemInstances ()
2547 {
2548     static TypeSystemInstances g_instances;
2549     return g_instances;
2550 }
2551 
2552 bool
2553 PluginManager::RegisterPlugin (const ConstString &name,
2554                                const char *description,
2555                                TypeSystemCreateInstance create_callback)
2556 {
2557     if (create_callback)
2558     {
2559         TypeSystemInstance instance;
2560         assert ((bool)name);
2561         instance.name = name;
2562         if (description && description[0])
2563             instance.description = description;
2564         instance.create_callback = create_callback;
2565         Mutex::Locker locker (GetTypeSystemMutex ());
2566         GetTypeSystemInstances ().push_back (instance);
2567     }
2568     return false;
2569 }
2570 
2571 bool
2572 PluginManager::UnregisterPlugin (TypeSystemCreateInstance create_callback)
2573 {
2574     if (create_callback)
2575     {
2576         Mutex::Locker locker (GetTypeSystemMutex ());
2577         TypeSystemInstances &instances = GetTypeSystemInstances ();
2578 
2579         TypeSystemInstances::iterator pos, end = instances.end();
2580         for (pos = instances.begin(); pos != end; ++ pos)
2581         {
2582             if (pos->create_callback == create_callback)
2583             {
2584                 instances.erase(pos);
2585                 return true;
2586             }
2587         }
2588     }
2589     return false;
2590 }
2591 
2592 TypeSystemCreateInstance
2593 PluginManager::GetTypeSystemCreateCallbackAtIndex (uint32_t idx)
2594 {
2595     Mutex::Locker locker (GetTypeSystemMutex ());
2596     TypeSystemInstances &instances = GetTypeSystemInstances ();
2597     if (idx < instances.size())
2598         return instances[idx].create_callback;
2599     return NULL;
2600 }
2601 
2602 TypeSystemCreateInstance
2603 PluginManager::GetTypeSystemCreateCallbackForPluginName (const ConstString &name)
2604 {
2605     if (name)
2606     {
2607         Mutex::Locker locker (GetTypeSystemMutex ());
2608         TypeSystemInstances &instances = GetTypeSystemInstances ();
2609 
2610         TypeSystemInstances::iterator pos, end = instances.end();
2611         for (pos = instances.begin(); pos != end; ++ pos)
2612         {
2613             if (name == pos->name)
2614                 return pos->create_callback;
2615         }
2616     }
2617     return NULL;
2618 }
2619 
2620 
2621 #pragma mark PluginManager
2622 
2623 void
2624 PluginManager::DebuggerInitialize (Debugger &debugger)
2625 {
2626     // Initialize the DynamicLoader plugins
2627     {
2628         Mutex::Locker locker (GetDynamicLoaderMutex ());
2629         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
2630 
2631         DynamicLoaderInstances::iterator pos, end = instances.end();
2632         for (pos = instances.begin(); pos != end; ++ pos)
2633         {
2634             if (pos->debugger_init_callback)
2635                 pos->debugger_init_callback (debugger);
2636         }
2637     }
2638 
2639     // Initialize the JITLoader plugins
2640     {
2641         Mutex::Locker locker (GetJITLoaderMutex ());
2642         JITLoaderInstances &instances = GetJITLoaderInstances ();
2643 
2644         JITLoaderInstances::iterator pos, end = instances.end();
2645         for (pos = instances.begin(); pos != end; ++ pos)
2646         {
2647             if (pos->debugger_init_callback)
2648                 pos->debugger_init_callback (debugger);
2649         }
2650     }
2651 
2652     // Initialize the Platform plugins
2653     {
2654         Mutex::Locker locker (GetPlatformInstancesMutex ());
2655         PlatformInstances &instances = GetPlatformInstances ();
2656 
2657         PlatformInstances::iterator pos, end = instances.end();
2658         for (pos = instances.begin(); pos != end; ++ pos)
2659         {
2660             if (pos->debugger_init_callback)
2661                 pos->debugger_init_callback (debugger);
2662         }
2663     }
2664 
2665     // Initialize the Process plugins
2666     {
2667         Mutex::Locker locker (GetProcessMutex());
2668         ProcessInstances &instances = GetProcessInstances();
2669 
2670         ProcessInstances::iterator pos, end = instances.end();
2671         for (pos = instances.begin(); pos != end; ++ pos)
2672         {
2673             if (pos->debugger_init_callback)
2674                 pos->debugger_init_callback (debugger);
2675         }
2676     }
2677 
2678     // Initialize the SymbolFile plugins
2679     {
2680         Mutex::Locker locker (GetSymbolFileMutex());
2681         for (auto& sym_file: GetSymbolFileInstances())
2682         {
2683             if (sym_file.debugger_init_callback)
2684                 sym_file.debugger_init_callback (debugger);
2685         }
2686     }
2687 
2688     // Initialize the OperatingSystem plugins
2689     {
2690         Mutex::Locker locker(GetOperatingSystemMutex());
2691         for (auto &os : GetOperatingSystemInstances())
2692         {
2693             if (os.debugger_init_callback)
2694                 os.debugger_init_callback(debugger);
2695         }
2696     }
2697 }
2698 
2699 // This is the preferred new way to register plugin specific settings.  e.g.
2700 // This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2701 static lldb::OptionValuePropertiesSP
2702 GetDebuggerPropertyForPlugins (Debugger &debugger,
2703                                        const ConstString &plugin_type_name,
2704                                        const ConstString &plugin_type_desc,
2705                                        bool can_create)
2706 {
2707     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2708     if (parent_properties_sp)
2709     {
2710         static ConstString g_property_name("plugin");
2711 
2712         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
2713         if (!plugin_properties_sp && can_create)
2714         {
2715             plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
2716             parent_properties_sp->AppendProperty (g_property_name,
2717                                                   ConstString("Settings specify to plugins."),
2718                                                   true,
2719                                                   plugin_properties_sp);
2720         }
2721 
2722         if (plugin_properties_sp)
2723         {
2724             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
2725             if (!plugin_type_properties_sp && can_create)
2726             {
2727                 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2728                 plugin_properties_sp->AppendProperty (plugin_type_name,
2729                                                       plugin_type_desc,
2730                                                       true,
2731                                                       plugin_type_properties_sp);
2732             }
2733             return plugin_type_properties_sp;
2734         }
2735     }
2736     return lldb::OptionValuePropertiesSP();
2737 }
2738 
2739 // This is deprecated way to register plugin specific settings.  e.g.
2740 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
2741 // and Platform generic settings would be under "platform.SETTINGNAME".
2742 static lldb::OptionValuePropertiesSP
2743 GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
2744                                        const ConstString &plugin_type_name,
2745                                        const ConstString &plugin_type_desc,
2746                                        bool can_create)
2747 {
2748     static ConstString g_property_name("plugin");
2749     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2750     if (parent_properties_sp)
2751     {
2752         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
2753         if (!plugin_properties_sp && can_create)
2754         {
2755             plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2756             parent_properties_sp->AppendProperty (plugin_type_name,
2757                                                   plugin_type_desc,
2758                                                   true,
2759                                                   plugin_properties_sp);
2760         }
2761 
2762         if (plugin_properties_sp)
2763         {
2764             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
2765             if (!plugin_type_properties_sp && can_create)
2766             {
2767                 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
2768                 plugin_properties_sp->AppendProperty (g_property_name,
2769                                                       ConstString("Settings specific to plugins"),
2770                                                       true,
2771                                                       plugin_type_properties_sp);
2772             }
2773             return plugin_type_properties_sp;
2774         }
2775     }
2776     return lldb::OptionValuePropertiesSP();
2777 }
2778 
2779 namespace {
2780 
2781 typedef lldb::OptionValuePropertiesSP
2782 GetDebuggerPropertyForPluginsPtr (Debugger&, const ConstString&, const ConstString&, bool can_create);
2783 
2784 lldb::OptionValuePropertiesSP
2785 GetSettingForPlugin (Debugger &debugger,
2786                      const ConstString &setting_name,
2787                      const ConstString &plugin_type_name,
2788                      GetDebuggerPropertyForPluginsPtr get_debugger_property= GetDebuggerPropertyForPlugins)
2789 {
2790     lldb::OptionValuePropertiesSP properties_sp;
2791     lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (debugger,
2792                                                                                     plugin_type_name,
2793                                                                                     ConstString(), // not creating to so we don't need the description
2794                                                                                     false));
2795     if (plugin_type_properties_sp)
2796         properties_sp = plugin_type_properties_sp->GetSubProperty (nullptr, setting_name);
2797     return properties_sp;
2798 }
2799 
2800 bool
2801 CreateSettingForPlugin (Debugger &debugger,
2802                         const ConstString &plugin_type_name,
2803                         const ConstString &plugin_type_desc,
2804                         const lldb::OptionValuePropertiesSP &properties_sp,
2805                         const ConstString &description,
2806                         bool is_global_property,
2807                         GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins)
2808 {
2809     if (properties_sp)
2810     {
2811         lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (
2812             debugger, plugin_type_name, plugin_type_desc, true));
2813         if (plugin_type_properties_sp)
2814         {
2815             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2816                                                        description,
2817                                                        is_global_property,
2818                                                        properties_sp);
2819             return true;
2820         }
2821     }
2822     return false;
2823 }
2824 
2825 const char* kDynamicLoaderPluginName("dynamic-loader");
2826 const char* kPlatformPluginName("platform");
2827 const char* kProcessPluginName("process");
2828 const char* kSymbolFilePluginName("symbol-file");
2829 const char* kJITLoaderPluginName("jit-loader");
2830 
2831 }
2832 
2833 lldb::OptionValuePropertiesSP
2834 PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger,
2835                                                  const ConstString &setting_name)
2836 {
2837     return GetSettingForPlugin(debugger, setting_name, ConstString(kDynamicLoaderPluginName));
2838 }
2839 
2840 bool
2841 PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
2842                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2843                                                     const ConstString &description,
2844                                                     bool is_global_property)
2845 {
2846     return CreateSettingForPlugin(debugger,
2847                                   ConstString(kDynamicLoaderPluginName),
2848                                   ConstString("Settings for dynamic loader plug-ins"),
2849                                   properties_sp,
2850                                   description,
2851                                   is_global_property);
2852 }
2853 
2854 
2855 lldb::OptionValuePropertiesSP
2856 PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
2857 {
2858     return GetSettingForPlugin(debugger,
2859                                setting_name,
2860                                ConstString(kPlatformPluginName),
2861                                GetDebuggerPropertyForPluginsOldStyle);
2862 }
2863 
2864 bool
2865 PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
2866                                                const lldb::OptionValuePropertiesSP &properties_sp,
2867                                                const ConstString &description,
2868                                                bool is_global_property)
2869 {
2870     return CreateSettingForPlugin(debugger,
2871                                   ConstString(kPlatformPluginName),
2872                                   ConstString("Settings for platform plug-ins"),
2873                                   properties_sp,
2874                                   description,
2875                                   is_global_property,
2876                                   GetDebuggerPropertyForPluginsOldStyle);
2877 }
2878 
2879 
2880 lldb::OptionValuePropertiesSP
2881 PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
2882 {
2883     return GetSettingForPlugin(debugger, setting_name, ConstString(kProcessPluginName));
2884 }
2885 
2886 bool
2887 PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
2888                                               const lldb::OptionValuePropertiesSP &properties_sp,
2889                                               const ConstString &description,
2890                                               bool is_global_property)
2891 {
2892     return CreateSettingForPlugin(debugger,
2893                                   ConstString(kProcessPluginName),
2894                                   ConstString("Settings for process plug-ins"),
2895                                   properties_sp,
2896                                   description,
2897                                   is_global_property);
2898 }
2899 
2900 lldb::OptionValuePropertiesSP
2901 PluginManager::GetSettingForSymbolFilePlugin (Debugger &debugger,
2902                                               const ConstString &setting_name)
2903 {
2904     return GetSettingForPlugin(debugger, setting_name, ConstString(kSymbolFilePluginName));
2905 }
2906 
2907 bool
2908 PluginManager::CreateSettingForSymbolFilePlugin (Debugger &debugger,
2909                                                  const lldb::OptionValuePropertiesSP &properties_sp,
2910                                                  const ConstString &description,
2911                                                  bool is_global_property)
2912 {
2913     return CreateSettingForPlugin(debugger,
2914                                   ConstString(kSymbolFilePluginName),
2915                                   ConstString("Settings for symbol file plug-ins"),
2916                                   properties_sp,
2917                                   description,
2918                                   is_global_property);
2919 }
2920 
2921 lldb::OptionValuePropertiesSP
2922 PluginManager::GetSettingForJITLoaderPlugin (Debugger &debugger,
2923                                              const ConstString &setting_name)
2924 {
2925     return GetSettingForPlugin(debugger, setting_name, ConstString(kJITLoaderPluginName));
2926 }
2927 
2928 bool
2929 PluginManager::CreateSettingForJITLoaderPlugin (Debugger &debugger,
2930                                                 const lldb::OptionValuePropertiesSP &properties_sp,
2931                                                 const ConstString &description,
2932                                                 bool is_global_property)
2933 {
2934     return CreateSettingForPlugin(debugger,
2935                                   ConstString(kJITLoaderPluginName),
2936                                   ConstString("Settings for JIT loader plug-ins"),
2937                                   properties_sp,
2938                                   description,
2939                                   is_global_property);
2940 }
2941 
2942 static const char *kOperatingSystemPluginName("os");
2943 
2944 lldb::OptionValuePropertiesSP
2945 PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, const ConstString &setting_name)
2946 {
2947     lldb::OptionValuePropertiesSP properties_sp;
2948     lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2949         GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName),
2950                                       ConstString(), // not creating to so we don't need the description
2951                                       false));
2952     if (plugin_type_properties_sp)
2953         properties_sp = plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2954     return properties_sp;
2955 }
2956 
2957 bool
2958 PluginManager::CreateSettingForOperatingSystemPlugin(Debugger &debugger,
2959                                                      const lldb::OptionValuePropertiesSP &properties_sp,
2960                                                      const ConstString &description, bool is_global_property)
2961 {
2962     if (properties_sp)
2963     {
2964         lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2965             GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName),
2966                                           ConstString("Settings for operating system plug-ins"), true));
2967         if (plugin_type_properties_sp)
2968         {
2969             plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), description, is_global_property,
2970                                                       properties_sp);
2971             return true;
2972         }
2973     }
2974     return false;
2975 }
2976