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