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