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