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(NULL)
778     {
779     }
780 
781     ConstString name;
782     std::string description;
783     OperatingSystemCreateInstance create_callback;
784 };
785 
786 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
787 
788 static Mutex &
789 GetOperatingSystemMutex ()
790 {
791     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
792     return g_instances_mutex;
793 }
794 
795 static OperatingSystemInstances &
796 GetOperatingSystemInstances ()
797 {
798     static OperatingSystemInstances g_instances;
799     return g_instances;
800 }
801 
802 bool
803 PluginManager::RegisterPlugin (const ConstString &name,
804                                const char *description,
805                                OperatingSystemCreateInstance create_callback)
806 {
807     if (create_callback)
808     {
809         OperatingSystemInstance instance;
810         assert ((bool)name);
811         instance.name = name;
812         if (description && description[0])
813             instance.description = description;
814         instance.create_callback = create_callback;
815         Mutex::Locker locker (GetOperatingSystemMutex ());
816         GetOperatingSystemInstances ().push_back (instance);
817     }
818     return false;
819 }
820 
821 bool
822 PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
823 {
824     if (create_callback)
825     {
826         Mutex::Locker locker (GetOperatingSystemMutex ());
827         OperatingSystemInstances &instances = GetOperatingSystemInstances ();
828 
829         OperatingSystemInstances::iterator pos, end = instances.end();
830         for (pos = instances.begin(); pos != end; ++ pos)
831         {
832             if (pos->create_callback == create_callback)
833             {
834                 instances.erase(pos);
835                 return true;
836             }
837         }
838     }
839     return false;
840 }
841 
842 OperatingSystemCreateInstance
843 PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
844 {
845     Mutex::Locker locker (GetOperatingSystemMutex ());
846     OperatingSystemInstances &instances = GetOperatingSystemInstances ();
847     if (idx < instances.size())
848         return instances[idx].create_callback;
849     return NULL;
850 }
851 
852 OperatingSystemCreateInstance
853 PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
854 {
855     if (name)
856     {
857         Mutex::Locker locker (GetOperatingSystemMutex ());
858         OperatingSystemInstances &instances = GetOperatingSystemInstances ();
859 
860         OperatingSystemInstances::iterator pos, end = instances.end();
861         for (pos = instances.begin(); pos != end; ++ pos)
862         {
863             if (name == pos->name)
864                 return pos->create_callback;
865         }
866     }
867     return NULL;
868 }
869 
870 
871 #pragma mark Language
872 
873 
874 struct LanguageInstance
875 {
876     LanguageInstance() :
877         name(),
878         description(),
879         create_callback(NULL)
880     {
881     }
882 
883     ConstString name;
884     std::string description;
885     LanguageCreateInstance create_callback;
886 };
887 
888 typedef std::vector<LanguageInstance> LanguageInstances;
889 
890 static Mutex &
891 GetLanguageMutex ()
892 {
893     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
894     return g_instances_mutex;
895 }
896 
897 static LanguageInstances &
898 GetLanguageInstances ()
899 {
900     static LanguageInstances g_instances;
901     return g_instances;
902 }
903 
904 bool
905 PluginManager::RegisterPlugin
906 (
907  const ConstString &name,
908  const char *description,
909  LanguageCreateInstance create_callback
910  )
911 {
912     if (create_callback)
913     {
914         LanguageInstance instance;
915         assert ((bool)name);
916         instance.name = name;
917         if (description && description[0])
918             instance.description = description;
919         instance.create_callback = create_callback;
920         Mutex::Locker locker (GetLanguageMutex ());
921         GetLanguageInstances ().push_back (instance);
922     }
923     return false;
924 }
925 
926 bool
927 PluginManager::UnregisterPlugin (LanguageCreateInstance create_callback)
928 {
929     if (create_callback)
930     {
931         Mutex::Locker locker (GetLanguageMutex ());
932         LanguageInstances &instances = GetLanguageInstances ();
933 
934         LanguageInstances::iterator pos, end = instances.end();
935         for (pos = instances.begin(); pos != end; ++ pos)
936         {
937             if (pos->create_callback == create_callback)
938             {
939                 instances.erase(pos);
940                 return true;
941             }
942         }
943     }
944     return false;
945 }
946 
947 LanguageCreateInstance
948 PluginManager::GetLanguageCreateCallbackAtIndex (uint32_t idx)
949 {
950     Mutex::Locker locker (GetLanguageMutex ());
951     LanguageInstances &instances = GetLanguageInstances ();
952     if (idx < instances.size())
953         return instances[idx].create_callback;
954     return NULL;
955 }
956 
957 LanguageCreateInstance
958 PluginManager::GetLanguageCreateCallbackForPluginName (const ConstString &name)
959 {
960     if (name)
961     {
962         Mutex::Locker locker (GetLanguageMutex ());
963         LanguageInstances &instances = GetLanguageInstances ();
964 
965         LanguageInstances::iterator pos, end = instances.end();
966         for (pos = instances.begin(); pos != end; ++ pos)
967         {
968             if (name == pos->name)
969                 return pos->create_callback;
970         }
971     }
972     return NULL;
973 }
974 
975 
976 #pragma mark LanguageRuntime
977 
978 
979 struct LanguageRuntimeInstance
980 {
981     LanguageRuntimeInstance() :
982         name(),
983         description(),
984         create_callback(NULL)
985     {
986     }
987 
988     ConstString name;
989     std::string description;
990     LanguageRuntimeCreateInstance create_callback;
991     LanguageRuntimeGetCommandObject command_callback;
992 };
993 
994 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
995 
996 static Mutex &
997 GetLanguageRuntimeMutex ()
998 {
999     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1000     return g_instances_mutex;
1001 }
1002 
1003 static LanguageRuntimeInstances &
1004 GetLanguageRuntimeInstances ()
1005 {
1006     static LanguageRuntimeInstances g_instances;
1007     return g_instances;
1008 }
1009 
1010 bool
1011 PluginManager::RegisterPlugin
1012 (
1013     const ConstString &name,
1014     const char *description,
1015     LanguageRuntimeCreateInstance create_callback,
1016     LanguageRuntimeGetCommandObject command_callback
1017 )
1018 {
1019     if (create_callback)
1020     {
1021         LanguageRuntimeInstance instance;
1022         assert ((bool)name);
1023         instance.name = name;
1024         if (description && description[0])
1025             instance.description = description;
1026         instance.create_callback = create_callback;
1027         instance.command_callback = command_callback;
1028         Mutex::Locker locker (GetLanguageRuntimeMutex ());
1029         GetLanguageRuntimeInstances ().push_back (instance);
1030     }
1031     return false;
1032 }
1033 
1034 bool
1035 PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
1036 {
1037     if (create_callback)
1038     {
1039         Mutex::Locker locker (GetLanguageRuntimeMutex ());
1040         LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1041 
1042         LanguageRuntimeInstances::iterator pos, end = instances.end();
1043         for (pos = instances.begin(); pos != end; ++ pos)
1044         {
1045             if (pos->create_callback == create_callback)
1046             {
1047                 instances.erase(pos);
1048                 return true;
1049             }
1050         }
1051     }
1052     return false;
1053 }
1054 
1055 LanguageRuntimeCreateInstance
1056 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
1057 {
1058     Mutex::Locker locker (GetLanguageRuntimeMutex ());
1059     LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1060     if (idx < instances.size())
1061         return instances[idx].create_callback;
1062     return NULL;
1063 }
1064 
1065 LanguageRuntimeGetCommandObject
1066 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex (uint32_t idx)
1067 {
1068     Mutex::Locker locker (GetLanguageRuntimeMutex ());
1069     LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1070     if (idx < instances.size())
1071         return instances[idx].command_callback;
1072     return NULL;
1073 }
1074 
1075 LanguageRuntimeCreateInstance
1076 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
1077 {
1078     if (name)
1079     {
1080         Mutex::Locker locker (GetLanguageRuntimeMutex ());
1081         LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1082 
1083         LanguageRuntimeInstances::iterator pos, end = instances.end();
1084         for (pos = instances.begin(); pos != end; ++ pos)
1085         {
1086             if (name == pos->name)
1087                 return pos->create_callback;
1088         }
1089     }
1090     return NULL;
1091 }
1092 
1093 #pragma mark SystemRuntime
1094 
1095 
1096 struct SystemRuntimeInstance
1097 {
1098     SystemRuntimeInstance() :
1099         name(),
1100         description(),
1101         create_callback(NULL)
1102     {
1103     }
1104 
1105     ConstString name;
1106     std::string description;
1107     SystemRuntimeCreateInstance create_callback;
1108 };
1109 
1110 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
1111 
1112 static Mutex &
1113 GetSystemRuntimeMutex ()
1114 {
1115     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1116     return g_instances_mutex;
1117 }
1118 
1119 static SystemRuntimeInstances &
1120 GetSystemRuntimeInstances ()
1121 {
1122     static SystemRuntimeInstances g_instances;
1123     return g_instances;
1124 }
1125 
1126 bool
1127 PluginManager::RegisterPlugin
1128 (
1129     const ConstString &name,
1130     const char *description,
1131     SystemRuntimeCreateInstance create_callback
1132 )
1133 {
1134     if (create_callback)
1135     {
1136         SystemRuntimeInstance instance;
1137         assert ((bool)name);
1138         instance.name = name;
1139         if (description && description[0])
1140             instance.description = description;
1141         instance.create_callback = create_callback;
1142         Mutex::Locker locker (GetSystemRuntimeMutex ());
1143         GetSystemRuntimeInstances ().push_back (instance);
1144     }
1145     return false;
1146 }
1147 
1148 bool
1149 PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
1150 {
1151     if (create_callback)
1152     {
1153         Mutex::Locker locker (GetSystemRuntimeMutex ());
1154         SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1155 
1156         SystemRuntimeInstances::iterator pos, end = instances.end();
1157         for (pos = instances.begin(); pos != end; ++ pos)
1158         {
1159             if (pos->create_callback == create_callback)
1160             {
1161                 instances.erase(pos);
1162                 return true;
1163             }
1164         }
1165     }
1166     return false;
1167 }
1168 
1169 SystemRuntimeCreateInstance
1170 PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
1171 {
1172     Mutex::Locker locker (GetSystemRuntimeMutex ());
1173     SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1174     if (idx < instances.size())
1175         return instances[idx].create_callback;
1176     return NULL;
1177 }
1178 
1179 SystemRuntimeCreateInstance
1180 PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
1181 {
1182     if (name)
1183     {
1184         Mutex::Locker locker (GetSystemRuntimeMutex ());
1185         SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1186 
1187         SystemRuntimeInstances::iterator pos, end = instances.end();
1188         for (pos = instances.begin(); pos != end; ++ pos)
1189         {
1190             if (name == pos->name)
1191                 return pos->create_callback;
1192         }
1193     }
1194     return NULL;
1195 }
1196 
1197 
1198 #pragma mark ObjectFile
1199 
1200 struct ObjectFileInstance
1201 {
1202     ObjectFileInstance() :
1203         name(),
1204         description(),
1205         create_callback(NULL),
1206         create_memory_callback (NULL),
1207         get_module_specifications (NULL),
1208         save_core (NULL)
1209     {
1210     }
1211 
1212     ConstString name;
1213     std::string description;
1214     ObjectFileCreateInstance create_callback;
1215     ObjectFileCreateMemoryInstance create_memory_callback;
1216     ObjectFileGetModuleSpecifications get_module_specifications;
1217     ObjectFileSaveCore save_core;
1218 };
1219 
1220 typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1221 
1222 static Mutex &
1223 GetObjectFileMutex ()
1224 {
1225     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1226     return g_instances_mutex;
1227 }
1228 
1229 static ObjectFileInstances &
1230 GetObjectFileInstances ()
1231 {
1232     static ObjectFileInstances g_instances;
1233     return g_instances;
1234 }
1235 
1236 
1237 bool
1238 PluginManager::RegisterPlugin (const ConstString &name,
1239                                const char *description,
1240                                ObjectFileCreateInstance create_callback,
1241                                ObjectFileCreateMemoryInstance create_memory_callback,
1242                                ObjectFileGetModuleSpecifications get_module_specifications,
1243                                ObjectFileSaveCore save_core)
1244 {
1245     if (create_callback)
1246     {
1247         ObjectFileInstance instance;
1248         assert ((bool)name);
1249         instance.name = name;
1250         if (description && description[0])
1251             instance.description = description;
1252         instance.create_callback = create_callback;
1253         instance.create_memory_callback = create_memory_callback;
1254         instance.save_core = save_core;
1255         instance.get_module_specifications = get_module_specifications;
1256         Mutex::Locker locker (GetObjectFileMutex ());
1257         GetObjectFileInstances ().push_back (instance);
1258     }
1259     return false;
1260 }
1261 
1262 bool
1263 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
1264 {
1265     if (create_callback)
1266     {
1267         Mutex::Locker locker (GetObjectFileMutex ());
1268         ObjectFileInstances &instances = GetObjectFileInstances ();
1269 
1270         ObjectFileInstances::iterator pos, end = instances.end();
1271         for (pos = instances.begin(); pos != end; ++ pos)
1272         {
1273             if (pos->create_callback == create_callback)
1274             {
1275                 instances.erase(pos);
1276                 return true;
1277             }
1278         }
1279     }
1280     return false;
1281 }
1282 
1283 ObjectFileCreateInstance
1284 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
1285 {
1286     Mutex::Locker locker (GetObjectFileMutex ());
1287     ObjectFileInstances &instances = GetObjectFileInstances ();
1288     if (idx < instances.size())
1289         return instances[idx].create_callback;
1290     return NULL;
1291 }
1292 
1293 
1294 ObjectFileCreateMemoryInstance
1295 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
1296 {
1297     Mutex::Locker locker (GetObjectFileMutex ());
1298     ObjectFileInstances &instances = GetObjectFileInstances ();
1299     if (idx < instances.size())
1300         return instances[idx].create_memory_callback;
1301     return NULL;
1302 }
1303 
1304 ObjectFileGetModuleSpecifications
1305 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1306 {
1307     Mutex::Locker locker (GetObjectFileMutex ());
1308     ObjectFileInstances &instances = GetObjectFileInstances ();
1309     if (idx < instances.size())
1310         return instances[idx].get_module_specifications;
1311     return NULL;
1312 }
1313 
1314 ObjectFileCreateInstance
1315 PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
1316 {
1317     if (name)
1318     {
1319         Mutex::Locker locker (GetObjectFileMutex ());
1320         ObjectFileInstances &instances = GetObjectFileInstances ();
1321 
1322         ObjectFileInstances::iterator pos, end = instances.end();
1323         for (pos = instances.begin(); pos != end; ++ pos)
1324         {
1325             if (name == pos->name)
1326                 return pos->create_callback;
1327         }
1328     }
1329     return NULL;
1330 }
1331 
1332 
1333 ObjectFileCreateMemoryInstance
1334 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
1335 {
1336     if (name)
1337     {
1338         Mutex::Locker locker (GetObjectFileMutex ());
1339         ObjectFileInstances &instances = GetObjectFileInstances ();
1340 
1341         ObjectFileInstances::iterator pos, end = instances.end();
1342         for (pos = instances.begin(); pos != end; ++ pos)
1343         {
1344             if (name == pos->name)
1345                 return pos->create_memory_callback;
1346         }
1347     }
1348     return NULL;
1349 }
1350 
1351 Error
1352 PluginManager::SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile)
1353 {
1354     Error error;
1355     Mutex::Locker locker (GetObjectFileMutex ());
1356     ObjectFileInstances &instances = GetObjectFileInstances ();
1357 
1358     ObjectFileInstances::iterator pos, end = instances.end();
1359     for (pos = instances.begin(); pos != end; ++ pos)
1360     {
1361         if (pos->save_core && pos->save_core (process_sp, outfile, error))
1362             return error;
1363     }
1364     error.SetErrorString("no ObjectFile plugins were able to save a core for this process");
1365     return error;
1366 }
1367 
1368 #pragma mark ObjectContainer
1369 
1370 struct ObjectContainerInstance
1371 {
1372     ObjectContainerInstance() :
1373         name(),
1374         description(),
1375         create_callback (NULL),
1376         get_module_specifications (NULL)
1377     {
1378     }
1379 
1380     ConstString name;
1381     std::string description;
1382     ObjectContainerCreateInstance create_callback;
1383     ObjectFileGetModuleSpecifications get_module_specifications;
1384 
1385 };
1386 
1387 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1388 
1389 static Mutex &
1390 GetObjectContainerMutex ()
1391 {
1392     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1393     return g_instances_mutex;
1394 }
1395 
1396 static ObjectContainerInstances &
1397 GetObjectContainerInstances ()
1398 {
1399     static ObjectContainerInstances g_instances;
1400     return g_instances;
1401 }
1402 
1403 bool
1404 PluginManager::RegisterPlugin (const ConstString &name,
1405                                const char *description,
1406                                ObjectContainerCreateInstance create_callback,
1407                                ObjectFileGetModuleSpecifications get_module_specifications)
1408 {
1409     if (create_callback)
1410     {
1411         ObjectContainerInstance instance;
1412         assert ((bool)name);
1413         instance.name = name;
1414         if (description && description[0])
1415             instance.description = description;
1416         instance.create_callback = create_callback;
1417         instance.get_module_specifications = get_module_specifications;
1418         Mutex::Locker locker (GetObjectContainerMutex ());
1419         GetObjectContainerInstances ().push_back (instance);
1420     }
1421     return false;
1422 }
1423 
1424 bool
1425 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1426 {
1427     if (create_callback)
1428     {
1429         Mutex::Locker locker (GetObjectContainerMutex ());
1430         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1431 
1432         ObjectContainerInstances::iterator pos, end = instances.end();
1433         for (pos = instances.begin(); pos != end; ++ pos)
1434         {
1435             if (pos->create_callback == create_callback)
1436             {
1437                 instances.erase(pos);
1438                 return true;
1439             }
1440         }
1441     }
1442     return false;
1443 }
1444 
1445 ObjectContainerCreateInstance
1446 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1447 {
1448     Mutex::Locker locker (GetObjectContainerMutex ());
1449     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1450     if (idx < instances.size())
1451         return instances[idx].create_callback;
1452     return NULL;
1453 }
1454 
1455 ObjectContainerCreateInstance
1456 PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
1457 {
1458     if (name)
1459     {
1460         Mutex::Locker locker (GetObjectContainerMutex ());
1461         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1462 
1463         ObjectContainerInstances::iterator pos, end = instances.end();
1464         for (pos = instances.begin(); pos != end; ++ pos)
1465         {
1466             if (name == pos->name)
1467                 return pos->create_callback;
1468         }
1469     }
1470     return NULL;
1471 }
1472 
1473 ObjectFileGetModuleSpecifications
1474 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1475 {
1476     Mutex::Locker locker (GetObjectContainerMutex ());
1477     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1478     if (idx < instances.size())
1479         return instances[idx].get_module_specifications;
1480     return NULL;
1481 }
1482 
1483 #pragma mark LogChannel
1484 
1485 struct LogInstance
1486 {
1487     LogInstance() :
1488         name(),
1489         description(),
1490         create_callback(NULL)
1491     {
1492     }
1493 
1494     ConstString name;
1495     std::string description;
1496     LogChannelCreateInstance create_callback;
1497 };
1498 
1499 typedef std::vector<LogInstance> LogInstances;
1500 
1501 static Mutex &
1502 GetLogMutex ()
1503 {
1504     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1505     return g_instances_mutex;
1506 }
1507 
1508 static LogInstances &
1509 GetLogInstances ()
1510 {
1511     static LogInstances g_instances;
1512     return g_instances;
1513 }
1514 
1515 
1516 
1517 bool
1518 PluginManager::RegisterPlugin
1519 (
1520     const ConstString &name,
1521     const char *description,
1522     LogChannelCreateInstance create_callback
1523 )
1524 {
1525     if (create_callback)
1526     {
1527         LogInstance instance;
1528         assert ((bool)name);
1529         instance.name = name;
1530         if (description && description[0])
1531             instance.description = description;
1532         instance.create_callback = create_callback;
1533         Mutex::Locker locker (GetLogMutex ());
1534         GetLogInstances ().push_back (instance);
1535     }
1536     return false;
1537 }
1538 
1539 bool
1540 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1541 {
1542     if (create_callback)
1543     {
1544         Mutex::Locker locker (GetLogMutex ());
1545         LogInstances &instances = GetLogInstances ();
1546 
1547         LogInstances::iterator pos, end = instances.end();
1548         for (pos = instances.begin(); pos != end; ++ pos)
1549         {
1550             if (pos->create_callback == create_callback)
1551             {
1552                 instances.erase(pos);
1553                 return true;
1554             }
1555         }
1556     }
1557     return false;
1558 }
1559 
1560 const char *
1561 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1562 {
1563     Mutex::Locker locker (GetLogMutex ());
1564     LogInstances &instances = GetLogInstances ();
1565     if (idx < instances.size())
1566         return instances[idx].name.GetCString();
1567     return NULL;
1568 }
1569 
1570 
1571 LogChannelCreateInstance
1572 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1573 {
1574     Mutex::Locker locker (GetLogMutex ());
1575     LogInstances &instances = GetLogInstances ();
1576     if (idx < instances.size())
1577         return instances[idx].create_callback;
1578     return NULL;
1579 }
1580 
1581 LogChannelCreateInstance
1582 PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
1583 {
1584     if (name)
1585     {
1586         Mutex::Locker locker (GetLogMutex ());
1587         LogInstances &instances = GetLogInstances ();
1588 
1589         LogInstances::iterator pos, end = instances.end();
1590         for (pos = instances.begin(); pos != end; ++ pos)
1591         {
1592             if (name == pos->name)
1593                 return pos->create_callback;
1594         }
1595     }
1596     return NULL;
1597 }
1598 
1599 #pragma mark Platform
1600 
1601 struct PlatformInstance
1602 {
1603     PlatformInstance() :
1604         name(),
1605         description(),
1606         create_callback(NULL),
1607         debugger_init_callback (NULL)
1608     {
1609     }
1610 
1611     ConstString name;
1612     std::string description;
1613     PlatformCreateInstance create_callback;
1614     DebuggerInitializeCallback debugger_init_callback;
1615 };
1616 
1617 typedef std::vector<PlatformInstance> PlatformInstances;
1618 
1619 static Mutex &
1620 GetPlatformInstancesMutex ()
1621 {
1622     static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1623     return g_platform_instances_mutex;
1624 }
1625 
1626 static PlatformInstances &
1627 GetPlatformInstances ()
1628 {
1629     static PlatformInstances g_platform_instances;
1630     return g_platform_instances;
1631 }
1632 
1633 
1634 bool
1635 PluginManager::RegisterPlugin (const ConstString &name,
1636                                const char *description,
1637                                PlatformCreateInstance create_callback,
1638                                DebuggerInitializeCallback debugger_init_callback)
1639 {
1640     if (create_callback)
1641     {
1642         Mutex::Locker locker (GetPlatformInstancesMutex ());
1643 
1644         PlatformInstance instance;
1645         assert ((bool)name);
1646         instance.name = name;
1647         if (description && description[0])
1648             instance.description = description;
1649         instance.create_callback = create_callback;
1650         instance.debugger_init_callback = debugger_init_callback;
1651         GetPlatformInstances ().push_back (instance);
1652         return true;
1653     }
1654     return false;
1655 }
1656 
1657 
1658 const char *
1659 PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1660 {
1661     Mutex::Locker locker (GetPlatformInstancesMutex ());
1662     PlatformInstances &instances = GetPlatformInstances ();
1663     if (idx < instances.size())
1664         return instances[idx].name.GetCString();
1665     return NULL;
1666 }
1667 
1668 const char *
1669 PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1670 {
1671     Mutex::Locker locker (GetPlatformInstancesMutex ());
1672     PlatformInstances &instances = GetPlatformInstances ();
1673     if (idx < instances.size())
1674         return instances[idx].description.c_str();
1675     return NULL;
1676 }
1677 
1678 bool
1679 PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1680 {
1681     if (create_callback)
1682     {
1683         Mutex::Locker locker (GetPlatformInstancesMutex ());
1684         PlatformInstances &instances = GetPlatformInstances ();
1685 
1686         PlatformInstances::iterator pos, end = instances.end();
1687         for (pos = instances.begin(); pos != end; ++ pos)
1688         {
1689             if (pos->create_callback == create_callback)
1690             {
1691                 instances.erase(pos);
1692                 return true;
1693             }
1694         }
1695     }
1696     return false;
1697 }
1698 
1699 PlatformCreateInstance
1700 PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1701 {
1702     Mutex::Locker locker (GetPlatformInstancesMutex ());
1703     PlatformInstances &instances = GetPlatformInstances ();
1704     if (idx < instances.size())
1705         return instances[idx].create_callback;
1706     return NULL;
1707 }
1708 
1709 PlatformCreateInstance
1710 PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
1711 {
1712     if (name)
1713     {
1714         Mutex::Locker locker (GetPlatformInstancesMutex ());
1715         PlatformInstances &instances = GetPlatformInstances ();
1716 
1717         PlatformInstances::iterator pos, end = instances.end();
1718         for (pos = instances.begin(); pos != end; ++ pos)
1719         {
1720             if (name == pos->name)
1721                 return pos->create_callback;
1722         }
1723     }
1724     return NULL;
1725 }
1726 
1727 size_t
1728 PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1729 {
1730     if (name)
1731     {
1732         Mutex::Locker locker (GetPlatformInstancesMutex ());
1733         PlatformInstances &instances = GetPlatformInstances ();
1734         llvm::StringRef name_sref(name);
1735 
1736         PlatformInstances::iterator pos, end = instances.end();
1737         for (pos = instances.begin(); pos != end; ++ pos)
1738         {
1739             llvm::StringRef plugin_name (pos->name.GetCString());
1740             if (plugin_name.startswith(name_sref))
1741                 matches.AppendString (plugin_name.data());
1742         }
1743     }
1744     return matches.GetSize();
1745 }
1746 #pragma mark Process
1747 
1748 struct ProcessInstance
1749 {
1750     ProcessInstance() :
1751         name(),
1752         description(),
1753         create_callback(NULL),
1754         debugger_init_callback(NULL)
1755     {
1756     }
1757 
1758     ConstString name;
1759     std::string description;
1760     ProcessCreateInstance create_callback;
1761     DebuggerInitializeCallback debugger_init_callback;
1762 };
1763 
1764 typedef std::vector<ProcessInstance> ProcessInstances;
1765 
1766 static Mutex &
1767 GetProcessMutex ()
1768 {
1769     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1770     return g_instances_mutex;
1771 }
1772 
1773 static ProcessInstances &
1774 GetProcessInstances ()
1775 {
1776     static ProcessInstances g_instances;
1777     return g_instances;
1778 }
1779 
1780 
1781 bool
1782 PluginManager::RegisterPlugin (const ConstString &name,
1783                                const char *description,
1784                                ProcessCreateInstance create_callback,
1785                                DebuggerInitializeCallback debugger_init_callback)
1786 {
1787     if (create_callback)
1788     {
1789         ProcessInstance instance;
1790         assert ((bool)name);
1791         instance.name = name;
1792         if (description && description[0])
1793             instance.description = description;
1794         instance.create_callback = create_callback;
1795         instance.debugger_init_callback = debugger_init_callback;
1796         Mutex::Locker locker (GetProcessMutex ());
1797         GetProcessInstances ().push_back (instance);
1798     }
1799     return false;
1800 }
1801 
1802 const char *
1803 PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1804 {
1805     Mutex::Locker locker (GetProcessMutex ());
1806     ProcessInstances &instances = GetProcessInstances ();
1807     if (idx < instances.size())
1808         return instances[idx].name.GetCString();
1809     return NULL;
1810 }
1811 
1812 const char *
1813 PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1814 {
1815     Mutex::Locker locker (GetProcessMutex ());
1816     ProcessInstances &instances = GetProcessInstances ();
1817     if (idx < instances.size())
1818         return instances[idx].description.c_str();
1819     return NULL;
1820 }
1821 
1822 bool
1823 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1824 {
1825     if (create_callback)
1826     {
1827         Mutex::Locker locker (GetProcessMutex ());
1828         ProcessInstances &instances = GetProcessInstances ();
1829 
1830         ProcessInstances::iterator pos, end = instances.end();
1831         for (pos = instances.begin(); pos != end; ++ pos)
1832         {
1833             if (pos->create_callback == create_callback)
1834             {
1835                 instances.erase(pos);
1836                 return true;
1837             }
1838         }
1839     }
1840     return false;
1841 }
1842 
1843 ProcessCreateInstance
1844 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1845 {
1846     Mutex::Locker locker (GetProcessMutex ());
1847     ProcessInstances &instances = GetProcessInstances ();
1848     if (idx < instances.size())
1849         return instances[idx].create_callback;
1850     return NULL;
1851 }
1852 
1853 
1854 ProcessCreateInstance
1855 PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
1856 {
1857     if (name)
1858     {
1859         Mutex::Locker locker (GetProcessMutex ());
1860         ProcessInstances &instances = GetProcessInstances ();
1861 
1862         ProcessInstances::iterator pos, end = instances.end();
1863         for (pos = instances.begin(); pos != end; ++ pos)
1864         {
1865             if (name == pos->name)
1866                 return pos->create_callback;
1867         }
1868     }
1869     return NULL;
1870 }
1871 
1872 #pragma mark ScriptInterpreter
1873 
1874 struct ScriptInterpreterInstance
1875 {
1876     ScriptInterpreterInstance()
1877         : name()
1878         , language(lldb::eScriptLanguageNone)
1879         , description()
1880         , create_callback(NULL)
1881     {
1882     }
1883 
1884     ConstString name;
1885     lldb::ScriptLanguage language;
1886     std::string description;
1887     ScriptInterpreterCreateInstance create_callback;
1888 };
1889 
1890 typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
1891 
1892 static Mutex &
1893 GetScriptInterpreterMutex()
1894 {
1895     static Mutex g_instances_mutex(Mutex::eMutexTypeRecursive);
1896     return g_instances_mutex;
1897 }
1898 
1899 static ScriptInterpreterInstances &
1900 GetScriptInterpreterInstances()
1901 {
1902     static ScriptInterpreterInstances g_instances;
1903     return g_instances;
1904 }
1905 
1906 bool
1907 PluginManager::RegisterPlugin(const ConstString &name, const char *description, lldb::ScriptLanguage script_language,
1908                               ScriptInterpreterCreateInstance create_callback)
1909 {
1910     if (!create_callback)
1911         return false;
1912     ScriptInterpreterInstance instance;
1913     assert((bool)name);
1914     instance.name = name;
1915     if (description && description[0])
1916         instance.description = description;
1917     instance.create_callback = create_callback;
1918     instance.language = script_language;
1919     Mutex::Locker locker(GetScriptInterpreterMutex());
1920     GetScriptInterpreterInstances().push_back(instance);
1921     return false;
1922 }
1923 
1924 bool
1925 PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)
1926 {
1927     if (!create_callback)
1928         return false;
1929     Mutex::Locker locker(GetScriptInterpreterMutex());
1930     ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1931 
1932     ScriptInterpreterInstances::iterator pos, end = instances.end();
1933     for (pos = instances.begin(); pos != end; ++pos)
1934     {
1935         if (pos->create_callback != create_callback)
1936             continue;
1937 
1938         instances.erase(pos);
1939         return true;
1940     }
1941     return false;
1942 }
1943 
1944 ScriptInterpreterCreateInstance
1945 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)
1946 {
1947     Mutex::Locker locker(GetScriptInterpreterMutex());
1948     ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1949     if (idx < instances.size())
1950         return instances[idx].create_callback;
1951     return nullptr;
1952 }
1953 
1954 lldb::ScriptInterpreterSP
1955 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter)
1956 {
1957     Mutex::Locker locker(GetScriptInterpreterMutex());
1958     ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1959 
1960     ScriptInterpreterInstances::iterator pos, end = instances.end();
1961     ScriptInterpreterCreateInstance none_instance = nullptr;
1962     for (pos = instances.begin(); pos != end; ++pos)
1963     {
1964         if (pos->language == lldb::eScriptLanguageNone)
1965             none_instance = pos->create_callback;
1966 
1967         if (script_lang == pos->language)
1968             return pos->create_callback(interpreter);
1969     }
1970 
1971     // If we didn't find one, return the ScriptInterpreter for the null language.
1972     assert(none_instance != nullptr);
1973     return none_instance(interpreter);
1974 }
1975 
1976 #pragma mark SymbolFile
1977 
1978 struct SymbolFileInstance
1979 {
1980     SymbolFileInstance() :
1981         name(),
1982         description(),
1983         create_callback(nullptr),
1984         debugger_init_callback(nullptr)
1985     {
1986     }
1987 
1988     ConstString name;
1989     std::string description;
1990     SymbolFileCreateInstance create_callback;
1991     DebuggerInitializeCallback debugger_init_callback;
1992 };
1993 
1994 typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1995 
1996 static Mutex &
1997 GetSymbolFileMutex ()
1998 {
1999     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2000     return g_instances_mutex;
2001 }
2002 
2003 static SymbolFileInstances &
2004 GetSymbolFileInstances ()
2005 {
2006     static SymbolFileInstances g_instances;
2007     return g_instances;
2008 }
2009 
2010 
2011 bool
2012 PluginManager::RegisterPlugin
2013 (
2014     const ConstString &name,
2015     const char *description,
2016     SymbolFileCreateInstance create_callback,
2017     DebuggerInitializeCallback debugger_init_callback
2018 )
2019 {
2020     if (create_callback)
2021     {
2022         SymbolFileInstance instance;
2023         assert ((bool)name);
2024         instance.name = name;
2025         if (description && description[0])
2026             instance.description = description;
2027         instance.create_callback = create_callback;
2028         instance.debugger_init_callback = debugger_init_callback;
2029         Mutex::Locker locker (GetSymbolFileMutex ());
2030         GetSymbolFileInstances ().push_back (instance);
2031     }
2032     return false;
2033 }
2034 
2035 bool
2036 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
2037 {
2038     if (create_callback)
2039     {
2040         Mutex::Locker locker (GetSymbolFileMutex ());
2041         SymbolFileInstances &instances = GetSymbolFileInstances ();
2042 
2043         SymbolFileInstances::iterator pos, end = instances.end();
2044         for (pos = instances.begin(); pos != end; ++ pos)
2045         {
2046             if (pos->create_callback == create_callback)
2047             {
2048                 instances.erase(pos);
2049                 return true;
2050             }
2051         }
2052     }
2053     return false;
2054 }
2055 
2056 SymbolFileCreateInstance
2057 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
2058 {
2059     Mutex::Locker locker (GetSymbolFileMutex ());
2060     SymbolFileInstances &instances = GetSymbolFileInstances ();
2061     if (idx < instances.size())
2062         return instances[idx].create_callback;
2063     return NULL;
2064 }
2065 
2066 SymbolFileCreateInstance
2067 PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
2068 {
2069     if (name)
2070     {
2071         Mutex::Locker locker (GetSymbolFileMutex ());
2072         SymbolFileInstances &instances = GetSymbolFileInstances ();
2073 
2074         SymbolFileInstances::iterator pos, end = instances.end();
2075         for (pos = instances.begin(); pos != end; ++ pos)
2076         {
2077             if (name == pos->name)
2078                 return pos->create_callback;
2079         }
2080     }
2081     return NULL;
2082 }
2083 
2084 
2085 
2086 #pragma mark SymbolVendor
2087 
2088 struct SymbolVendorInstance
2089 {
2090     SymbolVendorInstance() :
2091         name(),
2092         description(),
2093         create_callback(NULL)
2094     {
2095     }
2096 
2097     ConstString name;
2098     std::string description;
2099     SymbolVendorCreateInstance create_callback;
2100 };
2101 
2102 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
2103 
2104 static Mutex &
2105 GetSymbolVendorMutex ()
2106 {
2107     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2108     return g_instances_mutex;
2109 }
2110 
2111 static SymbolVendorInstances &
2112 GetSymbolVendorInstances ()
2113 {
2114     static SymbolVendorInstances g_instances;
2115     return g_instances;
2116 }
2117 
2118 bool
2119 PluginManager::RegisterPlugin
2120 (
2121     const ConstString &name,
2122     const char *description,
2123     SymbolVendorCreateInstance create_callback
2124 )
2125 {
2126     if (create_callback)
2127     {
2128         SymbolVendorInstance instance;
2129         assert ((bool)name);
2130         instance.name = name;
2131         if (description && description[0])
2132             instance.description = description;
2133         instance.create_callback = create_callback;
2134         Mutex::Locker locker (GetSymbolVendorMutex ());
2135         GetSymbolVendorInstances ().push_back (instance);
2136     }
2137     return false;
2138 }
2139 
2140 bool
2141 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
2142 {
2143     if (create_callback)
2144     {
2145         Mutex::Locker locker (GetSymbolVendorMutex ());
2146         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2147 
2148         SymbolVendorInstances::iterator pos, end = instances.end();
2149         for (pos = instances.begin(); pos != end; ++ pos)
2150         {
2151             if (pos->create_callback == create_callback)
2152             {
2153                 instances.erase(pos);
2154                 return true;
2155             }
2156         }
2157     }
2158     return false;
2159 }
2160 
2161 SymbolVendorCreateInstance
2162 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
2163 {
2164     Mutex::Locker locker (GetSymbolVendorMutex ());
2165     SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2166     if (idx < instances.size())
2167         return instances[idx].create_callback;
2168     return NULL;
2169 }
2170 
2171 
2172 SymbolVendorCreateInstance
2173 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
2174 {
2175     if (name)
2176     {
2177         Mutex::Locker locker (GetSymbolVendorMutex ());
2178         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2179 
2180         SymbolVendorInstances::iterator pos, end = instances.end();
2181         for (pos = instances.begin(); pos != end; ++ pos)
2182         {
2183             if (name == pos->name)
2184                 return pos->create_callback;
2185         }
2186     }
2187     return NULL;
2188 }
2189 
2190 
2191 #pragma mark UnwindAssembly
2192 
2193 struct UnwindAssemblyInstance
2194 {
2195     UnwindAssemblyInstance() :
2196         name(),
2197         description(),
2198         create_callback(NULL)
2199     {
2200     }
2201 
2202     ConstString name;
2203     std::string description;
2204     UnwindAssemblyCreateInstance create_callback;
2205 };
2206 
2207 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
2208 
2209 static Mutex &
2210 GetUnwindAssemblyMutex ()
2211 {
2212     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2213     return g_instances_mutex;
2214 }
2215 
2216 static UnwindAssemblyInstances &
2217 GetUnwindAssemblyInstances ()
2218 {
2219     static UnwindAssemblyInstances g_instances;
2220     return g_instances;
2221 }
2222 
2223 bool
2224 PluginManager::RegisterPlugin
2225 (
2226     const ConstString &name,
2227     const char *description,
2228     UnwindAssemblyCreateInstance create_callback
2229 )
2230 {
2231     if (create_callback)
2232     {
2233         UnwindAssemblyInstance instance;
2234         assert ((bool)name);
2235         instance.name = name;
2236         if (description && description[0])
2237             instance.description = description;
2238         instance.create_callback = create_callback;
2239         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2240         GetUnwindAssemblyInstances ().push_back (instance);
2241     }
2242     return false;
2243 }
2244 
2245 bool
2246 PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
2247 {
2248     if (create_callback)
2249     {
2250         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2251         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2252 
2253         UnwindAssemblyInstances::iterator pos, end = instances.end();
2254         for (pos = instances.begin(); pos != end; ++ pos)
2255         {
2256             if (pos->create_callback == create_callback)
2257             {
2258                 instances.erase(pos);
2259                 return true;
2260             }
2261         }
2262     }
2263     return false;
2264 }
2265 
2266 UnwindAssemblyCreateInstance
2267 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
2268 {
2269     Mutex::Locker locker (GetUnwindAssemblyMutex ());
2270     UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2271     if (idx < instances.size())
2272         return instances[idx].create_callback;
2273     return NULL;
2274 }
2275 
2276 
2277 UnwindAssemblyCreateInstance
2278 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
2279 {
2280     if (name)
2281     {
2282         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2283         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2284 
2285         UnwindAssemblyInstances::iterator pos, end = instances.end();
2286         for (pos = instances.begin(); pos != end; ++ pos)
2287         {
2288             if (name == pos->name)
2289                 return pos->create_callback;
2290         }
2291     }
2292     return NULL;
2293 }
2294 
2295 #pragma mark MemoryHistory
2296 
2297 struct MemoryHistoryInstance
2298 {
2299     MemoryHistoryInstance() :
2300     name(),
2301     description(),
2302     create_callback(NULL)
2303     {
2304     }
2305 
2306     ConstString name;
2307     std::string description;
2308     MemoryHistoryCreateInstance create_callback;
2309 };
2310 
2311 typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
2312 
2313 static Mutex &
2314 GetMemoryHistoryMutex ()
2315 {
2316     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2317     return g_instances_mutex;
2318 }
2319 
2320 static MemoryHistoryInstances &
2321 GetMemoryHistoryInstances ()
2322 {
2323     static MemoryHistoryInstances g_instances;
2324     return g_instances;
2325 }
2326 
2327 bool
2328 PluginManager::RegisterPlugin
2329 (
2330  const ConstString &name,
2331  const char *description,
2332  MemoryHistoryCreateInstance create_callback
2333  )
2334 {
2335     if (create_callback)
2336     {
2337         MemoryHistoryInstance instance;
2338         assert ((bool)name);
2339         instance.name = name;
2340         if (description && description[0])
2341             instance.description = description;
2342         instance.create_callback = create_callback;
2343         Mutex::Locker locker (GetMemoryHistoryMutex ());
2344         GetMemoryHistoryInstances ().push_back (instance);
2345     }
2346     return false;
2347 }
2348 
2349 bool
2350 PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
2351 {
2352     if (create_callback)
2353     {
2354         Mutex::Locker locker (GetMemoryHistoryMutex ());
2355         MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2356 
2357         MemoryHistoryInstances::iterator pos, end = instances.end();
2358         for (pos = instances.begin(); pos != end; ++ pos)
2359         {
2360             if (pos->create_callback == create_callback)
2361             {
2362                 instances.erase(pos);
2363                 return true;
2364             }
2365         }
2366     }
2367     return false;
2368 }
2369 
2370 MemoryHistoryCreateInstance
2371 PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
2372 {
2373     Mutex::Locker locker (GetMemoryHistoryMutex ());
2374     MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2375     if (idx < instances.size())
2376         return instances[idx].create_callback;
2377     return NULL;
2378 }
2379 
2380 
2381 MemoryHistoryCreateInstance
2382 PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name)
2383 {
2384     if (name)
2385     {
2386         Mutex::Locker locker (GetMemoryHistoryMutex ());
2387         MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2388 
2389         MemoryHistoryInstances::iterator pos, end = instances.end();
2390         for (pos = instances.begin(); pos != end; ++ pos)
2391         {
2392             if (name == pos->name)
2393                 return pos->create_callback;
2394         }
2395     }
2396     return NULL;
2397 }
2398 
2399 #pragma mark InstrumentationRuntime
2400 
2401 struct InstrumentationRuntimeInstance
2402 {
2403     InstrumentationRuntimeInstance() :
2404     name(),
2405     description(),
2406     create_callback(NULL)
2407     {
2408     }
2409 
2410     ConstString name;
2411     std::string description;
2412     InstrumentationRuntimeCreateInstance create_callback;
2413     InstrumentationRuntimeGetType get_type_callback;
2414 };
2415 
2416 typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances;
2417 
2418 static Mutex &
2419 GetInstrumentationRuntimeMutex ()
2420 {
2421     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2422     return g_instances_mutex;
2423 }
2424 
2425 static InstrumentationRuntimeInstances &
2426 GetInstrumentationRuntimeInstances ()
2427 {
2428     static InstrumentationRuntimeInstances g_instances;
2429     return g_instances;
2430 }
2431 
2432 bool
2433 PluginManager::RegisterPlugin
2434 (
2435  const ConstString &name,
2436  const char *description,
2437  InstrumentationRuntimeCreateInstance create_callback,
2438  InstrumentationRuntimeGetType get_type_callback
2439  )
2440 {
2441     if (create_callback)
2442     {
2443         InstrumentationRuntimeInstance instance;
2444         assert ((bool)name);
2445         instance.name = name;
2446         if (description && description[0])
2447             instance.description = description;
2448         instance.create_callback = create_callback;
2449         instance.get_type_callback = get_type_callback;
2450         Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2451         GetInstrumentationRuntimeInstances ().push_back (instance);
2452     }
2453     return false;
2454 }
2455 
2456 bool
2457 PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback)
2458 {
2459     if (create_callback)
2460     {
2461         Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2462         InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2463 
2464         InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2465         for (pos = instances.begin(); pos != end; ++ pos)
2466         {
2467             if (pos->create_callback == create_callback)
2468             {
2469                 instances.erase(pos);
2470                 return true;
2471             }
2472         }
2473     }
2474     return false;
2475 }
2476 
2477 InstrumentationRuntimeGetType
2478 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx)
2479 {
2480     Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2481     InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2482     if (idx < instances.size())
2483         return instances[idx].get_type_callback;
2484     return NULL;
2485 }
2486 
2487 InstrumentationRuntimeCreateInstance
2488 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx)
2489 {
2490     Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2491     InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2492     if (idx < instances.size())
2493         return instances[idx].create_callback;
2494     return NULL;
2495 }
2496 
2497 
2498 InstrumentationRuntimeCreateInstance
2499 PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name)
2500 {
2501     if (name)
2502     {
2503         Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2504         InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2505 
2506         InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2507         for (pos = instances.begin(); pos != end; ++ pos)
2508         {
2509             if (name == pos->name)
2510                 return pos->create_callback;
2511         }
2512     }
2513     return NULL;
2514 }
2515 
2516 #pragma mark PluginManager
2517 
2518 void
2519 PluginManager::DebuggerInitialize (Debugger &debugger)
2520 {
2521     // Initialize the DynamicLoader plugins
2522     {
2523         Mutex::Locker locker (GetDynamicLoaderMutex ());
2524         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
2525 
2526         DynamicLoaderInstances::iterator pos, end = instances.end();
2527         for (pos = instances.begin(); pos != end; ++ pos)
2528         {
2529             if (pos->debugger_init_callback)
2530                 pos->debugger_init_callback (debugger);
2531         }
2532     }
2533 
2534     // Initialize the JITLoader plugins
2535     {
2536         Mutex::Locker locker (GetJITLoaderMutex ());
2537         JITLoaderInstances &instances = GetJITLoaderInstances ();
2538 
2539         JITLoaderInstances::iterator pos, end = instances.end();
2540         for (pos = instances.begin(); pos != end; ++ pos)
2541         {
2542             if (pos->debugger_init_callback)
2543                 pos->debugger_init_callback (debugger);
2544         }
2545     }
2546 
2547     // Initialize the Platform plugins
2548     {
2549         Mutex::Locker locker (GetPlatformInstancesMutex ());
2550         PlatformInstances &instances = GetPlatformInstances ();
2551 
2552         PlatformInstances::iterator pos, end = instances.end();
2553         for (pos = instances.begin(); pos != end; ++ pos)
2554         {
2555             if (pos->debugger_init_callback)
2556                 pos->debugger_init_callback (debugger);
2557         }
2558     }
2559 
2560     // Initialize the Process plugins
2561     {
2562         Mutex::Locker locker (GetProcessMutex());
2563         ProcessInstances &instances = GetProcessInstances();
2564 
2565         ProcessInstances::iterator pos, end = instances.end();
2566         for (pos = instances.begin(); pos != end; ++ pos)
2567         {
2568             if (pos->debugger_init_callback)
2569                 pos->debugger_init_callback (debugger);
2570         }
2571     }
2572 
2573     // Initialize the SymbolFile plugins
2574     {
2575         Mutex::Locker locker (GetSymbolFileMutex());
2576         for (auto& sym_file: GetSymbolFileInstances())
2577         {
2578             if (sym_file.debugger_init_callback)
2579                 sym_file.debugger_init_callback (debugger);
2580         }
2581     }
2582 }
2583 
2584 // This is the preferred new way to register plugin specific settings.  e.g.
2585 // This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2586 static lldb::OptionValuePropertiesSP
2587 GetDebuggerPropertyForPlugins (Debugger &debugger,
2588                                        const ConstString &plugin_type_name,
2589                                        const ConstString &plugin_type_desc,
2590                                        bool can_create)
2591 {
2592     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2593     if (parent_properties_sp)
2594     {
2595         static ConstString g_property_name("plugin");
2596 
2597         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
2598         if (!plugin_properties_sp && can_create)
2599         {
2600             plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
2601             parent_properties_sp->AppendProperty (g_property_name,
2602                                                   ConstString("Settings specify to plugins."),
2603                                                   true,
2604                                                   plugin_properties_sp);
2605         }
2606 
2607         if (plugin_properties_sp)
2608         {
2609             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
2610             if (!plugin_type_properties_sp && can_create)
2611             {
2612                 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2613                 plugin_properties_sp->AppendProperty (plugin_type_name,
2614                                                       plugin_type_desc,
2615                                                       true,
2616                                                       plugin_type_properties_sp);
2617             }
2618             return plugin_type_properties_sp;
2619         }
2620     }
2621     return lldb::OptionValuePropertiesSP();
2622 }
2623 
2624 // This is deprecated way to register plugin specific settings.  e.g.
2625 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
2626 // and Platform generic settings would be under "platform.SETTINGNAME".
2627 static lldb::OptionValuePropertiesSP
2628 GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
2629                                        const ConstString &plugin_type_name,
2630                                        const ConstString &plugin_type_desc,
2631                                        bool can_create)
2632 {
2633     static ConstString g_property_name("plugin");
2634     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2635     if (parent_properties_sp)
2636     {
2637         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
2638         if (!plugin_properties_sp && can_create)
2639         {
2640             plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2641             parent_properties_sp->AppendProperty (plugin_type_name,
2642                                                   plugin_type_desc,
2643                                                   true,
2644                                                   plugin_properties_sp);
2645         }
2646 
2647         if (plugin_properties_sp)
2648         {
2649             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
2650             if (!plugin_type_properties_sp && can_create)
2651             {
2652                 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
2653                 plugin_properties_sp->AppendProperty (g_property_name,
2654                                                       ConstString("Settings specific to plugins"),
2655                                                       true,
2656                                                       plugin_type_properties_sp);
2657             }
2658             return plugin_type_properties_sp;
2659         }
2660     }
2661     return lldb::OptionValuePropertiesSP();
2662 }
2663 
2664 
2665 lldb::OptionValuePropertiesSP
2666 PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name)
2667 {
2668     lldb::OptionValuePropertiesSP properties_sp;
2669     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2670                                                                                             ConstString("dynamic-loader"),
2671                                                                                             ConstString(), // not creating to so we don't need the description
2672                                                                                             false));
2673     if (plugin_type_properties_sp)
2674         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2675     return properties_sp;
2676 }
2677 
2678 bool
2679 PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
2680                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2681                                                     const ConstString &description,
2682                                                     bool is_global_property)
2683 {
2684     if (properties_sp)
2685     {
2686         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2687                                                                                                 ConstString("dynamic-loader"),
2688                                                                                                 ConstString("Settings for dynamic loader plug-ins"),
2689                                                                                                 true));
2690         if (plugin_type_properties_sp)
2691         {
2692             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2693                                                        description,
2694                                                        is_global_property,
2695                                                        properties_sp);
2696             return true;
2697         }
2698     }
2699     return false;
2700 }
2701 
2702 
2703 lldb::OptionValuePropertiesSP
2704 PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
2705 {
2706     lldb::OptionValuePropertiesSP properties_sp;
2707     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2708                                                                                                     ConstString("platform"),
2709                                                                                                     ConstString(), // not creating to so we don't need the description
2710                                                                                                     false));
2711     if (plugin_type_properties_sp)
2712         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2713     return properties_sp;
2714 }
2715 
2716 bool
2717 PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
2718                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2719                                                     const ConstString &description,
2720                                                     bool is_global_property)
2721 {
2722     if (properties_sp)
2723     {
2724         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2725                                                                                                         ConstString("platform"),
2726                                                                                                         ConstString("Settings for platform plug-ins"),
2727                                                                                                         true));
2728         if (plugin_type_properties_sp)
2729         {
2730             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2731                                                        description,
2732                                                        is_global_property,
2733                                                        properties_sp);
2734             return true;
2735         }
2736     }
2737     return false;
2738 }
2739 
2740 
2741 lldb::OptionValuePropertiesSP
2742 PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
2743 {
2744     lldb::OptionValuePropertiesSP properties_sp;
2745     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2746                                                                                             ConstString("process"),
2747                                                                                             ConstString(), // not creating to so we don't need the description
2748                                                                                             false));
2749     if (plugin_type_properties_sp)
2750         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2751     return properties_sp;
2752 }
2753 
2754 bool
2755 PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
2756                                               const lldb::OptionValuePropertiesSP &properties_sp,
2757                                               const ConstString &description,
2758                                               bool is_global_property)
2759 {
2760     if (properties_sp)
2761     {
2762         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2763                                                                                                 ConstString("process"),
2764                                                                                                 ConstString("Settings for process plug-ins"),
2765                                                                                                 true));
2766         if (plugin_type_properties_sp)
2767         {
2768             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2769                                                        description,
2770                                                        is_global_property,
2771                                                        properties_sp);
2772             return true;
2773         }
2774     }
2775     return false;
2776 }
2777 
2778 
2779 static const char* kSymbolFilePluginName("symbol-file");
2780 
2781 lldb::OptionValuePropertiesSP
2782 PluginManager::GetSettingForSymbolFilePlugin (Debugger &debugger,
2783                                               const ConstString &setting_name)
2784 {
2785     lldb::OptionValuePropertiesSP properties_sp;
2786     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2787                                                                                             ConstString(kSymbolFilePluginName),
2788                                                                                             ConstString(), // not creating to so we don't need the description
2789                                                                                             false));
2790     if (plugin_type_properties_sp)
2791         properties_sp = plugin_type_properties_sp->GetSubProperty (nullptr, setting_name);
2792     return properties_sp;
2793 }
2794 
2795 bool
2796 PluginManager::CreateSettingForSymbolFilePlugin (Debugger &debugger,
2797                                                  const lldb::OptionValuePropertiesSP &properties_sp,
2798                                                  const ConstString &description,
2799                                                  bool is_global_property)
2800 {
2801     if (properties_sp)
2802     {
2803         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2804                                                                                                 ConstString(kSymbolFilePluginName),
2805                                                                                                 ConstString("Settings for symbol file plug-ins"),
2806                                                                                                 true));
2807         if (plugin_type_properties_sp)
2808         {
2809             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2810                                                        description,
2811                                                        is_global_property,
2812                                                        properties_sp);
2813             return true;
2814         }
2815     }
2816     return false;
2817 }
2818