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