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 ScriptInterpreter
1768 
1769 struct ScriptInterpreterInstance
1770 {
1771     ScriptInterpreterInstance()
1772         : name()
1773         , language(lldb::eScriptLanguageNone)
1774         , description()
1775         , create_callback(NULL)
1776     {
1777     }
1778 
1779     ConstString name;
1780     lldb::ScriptLanguage language;
1781     std::string description;
1782     ScriptInterpreterCreateInstance create_callback;
1783 };
1784 
1785 typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
1786 
1787 static Mutex &
1788 GetScriptInterpreterMutex()
1789 {
1790     static Mutex g_instances_mutex(Mutex::eMutexTypeRecursive);
1791     return g_instances_mutex;
1792 }
1793 
1794 static ScriptInterpreterInstances &
1795 GetScriptInterpreterInstances()
1796 {
1797     static ScriptInterpreterInstances g_instances;
1798     return g_instances;
1799 }
1800 
1801 bool
1802 PluginManager::RegisterPlugin(const ConstString &name, const char *description, lldb::ScriptLanguage script_language,
1803                               ScriptInterpreterCreateInstance create_callback)
1804 {
1805     if (!create_callback)
1806         return false;
1807     ScriptInterpreterInstance instance;
1808     assert((bool)name);
1809     instance.name = name;
1810     if (description && description[0])
1811         instance.description = description;
1812     instance.create_callback = create_callback;
1813     instance.language = script_language;
1814     Mutex::Locker locker(GetScriptInterpreterMutex());
1815     GetScriptInterpreterInstances().push_back(instance);
1816     return false;
1817 }
1818 
1819 bool
1820 PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)
1821 {
1822     if (!create_callback)
1823         return false;
1824     Mutex::Locker locker(GetScriptInterpreterMutex());
1825     ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1826 
1827     ScriptInterpreterInstances::iterator pos, end = instances.end();
1828     for (pos = instances.begin(); pos != end; ++pos)
1829     {
1830         if (pos->create_callback != create_callback)
1831             continue;
1832 
1833         instances.erase(pos);
1834         return true;
1835     }
1836     return false;
1837 }
1838 
1839 ScriptInterpreterCreateInstance
1840 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)
1841 {
1842     Mutex::Locker locker(GetScriptInterpreterMutex());
1843     ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1844     if (idx < instances.size())
1845         return instances[idx].create_callback;
1846     return nullptr;
1847 }
1848 
1849 lldb::ScriptInterpreterSP
1850 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter)
1851 {
1852     Mutex::Locker locker(GetScriptInterpreterMutex());
1853     ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1854 
1855     ScriptInterpreterInstances::iterator pos, end = instances.end();
1856     ScriptInterpreterCreateInstance none_instance = nullptr;
1857     for (pos = instances.begin(); pos != end; ++pos)
1858     {
1859         if (pos->language == lldb::eScriptLanguageNone)
1860             none_instance = pos->create_callback;
1861 
1862         if (script_lang == pos->language)
1863             return pos->create_callback(interpreter);
1864     }
1865 
1866     // If we didn't find one, return the ScriptInterpreter for the null language.
1867     assert(none_instance != nullptr);
1868     return none_instance(interpreter);
1869 }
1870 
1871 #pragma mark SymbolFile
1872 
1873 struct SymbolFileInstance
1874 {
1875     SymbolFileInstance() :
1876         name(),
1877         description(),
1878         create_callback(nullptr),
1879         debugger_init_callback(nullptr)
1880     {
1881     }
1882 
1883     ConstString name;
1884     std::string description;
1885     SymbolFileCreateInstance create_callback;
1886     DebuggerInitializeCallback debugger_init_callback;
1887 };
1888 
1889 typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1890 
1891 static Mutex &
1892 GetSymbolFileMutex ()
1893 {
1894     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1895     return g_instances_mutex;
1896 }
1897 
1898 static SymbolFileInstances &
1899 GetSymbolFileInstances ()
1900 {
1901     static SymbolFileInstances g_instances;
1902     return g_instances;
1903 }
1904 
1905 
1906 bool
1907 PluginManager::RegisterPlugin
1908 (
1909     const ConstString &name,
1910     const char *description,
1911     SymbolFileCreateInstance create_callback,
1912     DebuggerInitializeCallback debugger_init_callback
1913 )
1914 {
1915     if (create_callback)
1916     {
1917         SymbolFileInstance 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         instance.debugger_init_callback = debugger_init_callback;
1924         Mutex::Locker locker (GetSymbolFileMutex ());
1925         GetSymbolFileInstances ().push_back (instance);
1926     }
1927     return false;
1928 }
1929 
1930 bool
1931 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1932 {
1933     if (create_callback)
1934     {
1935         Mutex::Locker locker (GetSymbolFileMutex ());
1936         SymbolFileInstances &instances = GetSymbolFileInstances ();
1937 
1938         SymbolFileInstances::iterator pos, end = instances.end();
1939         for (pos = instances.begin(); pos != end; ++ pos)
1940         {
1941             if (pos->create_callback == create_callback)
1942             {
1943                 instances.erase(pos);
1944                 return true;
1945             }
1946         }
1947     }
1948     return false;
1949 }
1950 
1951 SymbolFileCreateInstance
1952 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1953 {
1954     Mutex::Locker locker (GetSymbolFileMutex ());
1955     SymbolFileInstances &instances = GetSymbolFileInstances ();
1956     if (idx < instances.size())
1957         return instances[idx].create_callback;
1958     return NULL;
1959 }
1960 
1961 SymbolFileCreateInstance
1962 PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
1963 {
1964     if (name)
1965     {
1966         Mutex::Locker locker (GetSymbolFileMutex ());
1967         SymbolFileInstances &instances = GetSymbolFileInstances ();
1968 
1969         SymbolFileInstances::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 
1981 #pragma mark SymbolVendor
1982 
1983 struct SymbolVendorInstance
1984 {
1985     SymbolVendorInstance() :
1986         name(),
1987         description(),
1988         create_callback(NULL)
1989     {
1990     }
1991 
1992     ConstString name;
1993     std::string description;
1994     SymbolVendorCreateInstance create_callback;
1995 };
1996 
1997 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1998 
1999 static Mutex &
2000 GetSymbolVendorMutex ()
2001 {
2002     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2003     return g_instances_mutex;
2004 }
2005 
2006 static SymbolVendorInstances &
2007 GetSymbolVendorInstances ()
2008 {
2009     static SymbolVendorInstances g_instances;
2010     return g_instances;
2011 }
2012 
2013 bool
2014 PluginManager::RegisterPlugin
2015 (
2016     const ConstString &name,
2017     const char *description,
2018     SymbolVendorCreateInstance create_callback
2019 )
2020 {
2021     if (create_callback)
2022     {
2023         SymbolVendorInstance instance;
2024         assert ((bool)name);
2025         instance.name = name;
2026         if (description && description[0])
2027             instance.description = description;
2028         instance.create_callback = create_callback;
2029         Mutex::Locker locker (GetSymbolVendorMutex ());
2030         GetSymbolVendorInstances ().push_back (instance);
2031     }
2032     return false;
2033 }
2034 
2035 bool
2036 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
2037 {
2038     if (create_callback)
2039     {
2040         Mutex::Locker locker (GetSymbolVendorMutex ());
2041         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2042 
2043         SymbolVendorInstances::iterator pos, end = instances.end();
2044         for (pos = instances.begin(); pos != end; ++ pos)
2045         {
2046             if (pos->create_callback == create_callback)
2047             {
2048                 instances.erase(pos);
2049                 return true;
2050             }
2051         }
2052     }
2053     return false;
2054 }
2055 
2056 SymbolVendorCreateInstance
2057 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
2058 {
2059     Mutex::Locker locker (GetSymbolVendorMutex ());
2060     SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2061     if (idx < instances.size())
2062         return instances[idx].create_callback;
2063     return NULL;
2064 }
2065 
2066 
2067 SymbolVendorCreateInstance
2068 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
2069 {
2070     if (name)
2071     {
2072         Mutex::Locker locker (GetSymbolVendorMutex ());
2073         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2074 
2075         SymbolVendorInstances::iterator pos, end = instances.end();
2076         for (pos = instances.begin(); pos != end; ++ pos)
2077         {
2078             if (name == pos->name)
2079                 return pos->create_callback;
2080         }
2081     }
2082     return NULL;
2083 }
2084 
2085 
2086 #pragma mark UnwindAssembly
2087 
2088 struct UnwindAssemblyInstance
2089 {
2090     UnwindAssemblyInstance() :
2091         name(),
2092         description(),
2093         create_callback(NULL)
2094     {
2095     }
2096 
2097     ConstString name;
2098     std::string description;
2099     UnwindAssemblyCreateInstance create_callback;
2100 };
2101 
2102 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
2103 
2104 static Mutex &
2105 GetUnwindAssemblyMutex ()
2106 {
2107     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2108     return g_instances_mutex;
2109 }
2110 
2111 static UnwindAssemblyInstances &
2112 GetUnwindAssemblyInstances ()
2113 {
2114     static UnwindAssemblyInstances g_instances;
2115     return g_instances;
2116 }
2117 
2118 bool
2119 PluginManager::RegisterPlugin
2120 (
2121     const ConstString &name,
2122     const char *description,
2123     UnwindAssemblyCreateInstance create_callback
2124 )
2125 {
2126     if (create_callback)
2127     {
2128         UnwindAssemblyInstance instance;
2129         assert ((bool)name);
2130         instance.name = name;
2131         if (description && description[0])
2132             instance.description = description;
2133         instance.create_callback = create_callback;
2134         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2135         GetUnwindAssemblyInstances ().push_back (instance);
2136     }
2137     return false;
2138 }
2139 
2140 bool
2141 PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
2142 {
2143     if (create_callback)
2144     {
2145         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2146         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2147 
2148         UnwindAssemblyInstances::iterator pos, end = instances.end();
2149         for (pos = instances.begin(); pos != end; ++ pos)
2150         {
2151             if (pos->create_callback == create_callback)
2152             {
2153                 instances.erase(pos);
2154                 return true;
2155             }
2156         }
2157     }
2158     return false;
2159 }
2160 
2161 UnwindAssemblyCreateInstance
2162 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
2163 {
2164     Mutex::Locker locker (GetUnwindAssemblyMutex ());
2165     UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2166     if (idx < instances.size())
2167         return instances[idx].create_callback;
2168     return NULL;
2169 }
2170 
2171 
2172 UnwindAssemblyCreateInstance
2173 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
2174 {
2175     if (name)
2176     {
2177         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2178         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2179 
2180         UnwindAssemblyInstances::iterator pos, end = instances.end();
2181         for (pos = instances.begin(); pos != end; ++ pos)
2182         {
2183             if (name == pos->name)
2184                 return pos->create_callback;
2185         }
2186     }
2187     return NULL;
2188 }
2189 
2190 #pragma mark MemoryHistory
2191 
2192 struct MemoryHistoryInstance
2193 {
2194     MemoryHistoryInstance() :
2195     name(),
2196     description(),
2197     create_callback(NULL)
2198     {
2199     }
2200 
2201     ConstString name;
2202     std::string description;
2203     MemoryHistoryCreateInstance create_callback;
2204 };
2205 
2206 typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
2207 
2208 static Mutex &
2209 GetMemoryHistoryMutex ()
2210 {
2211     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2212     return g_instances_mutex;
2213 }
2214 
2215 static MemoryHistoryInstances &
2216 GetMemoryHistoryInstances ()
2217 {
2218     static MemoryHistoryInstances g_instances;
2219     return g_instances;
2220 }
2221 
2222 bool
2223 PluginManager::RegisterPlugin
2224 (
2225  const ConstString &name,
2226  const char *description,
2227  MemoryHistoryCreateInstance create_callback
2228  )
2229 {
2230     if (create_callback)
2231     {
2232         MemoryHistoryInstance 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         Mutex::Locker locker (GetMemoryHistoryMutex ());
2239         GetMemoryHistoryInstances ().push_back (instance);
2240     }
2241     return false;
2242 }
2243 
2244 bool
2245 PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
2246 {
2247     if (create_callback)
2248     {
2249         Mutex::Locker locker (GetMemoryHistoryMutex ());
2250         MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2251 
2252         MemoryHistoryInstances::iterator pos, end = instances.end();
2253         for (pos = instances.begin(); pos != end; ++ pos)
2254         {
2255             if (pos->create_callback == create_callback)
2256             {
2257                 instances.erase(pos);
2258                 return true;
2259             }
2260         }
2261     }
2262     return false;
2263 }
2264 
2265 MemoryHistoryCreateInstance
2266 PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
2267 {
2268     Mutex::Locker locker (GetMemoryHistoryMutex ());
2269     MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2270     if (idx < instances.size())
2271         return instances[idx].create_callback;
2272     return NULL;
2273 }
2274 
2275 
2276 MemoryHistoryCreateInstance
2277 PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name)
2278 {
2279     if (name)
2280     {
2281         Mutex::Locker locker (GetMemoryHistoryMutex ());
2282         MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2283 
2284         MemoryHistoryInstances::iterator pos, end = instances.end();
2285         for (pos = instances.begin(); pos != end; ++ pos)
2286         {
2287             if (name == pos->name)
2288                 return pos->create_callback;
2289         }
2290     }
2291     return NULL;
2292 }
2293 
2294 #pragma mark InstrumentationRuntime
2295 
2296 struct InstrumentationRuntimeInstance
2297 {
2298     InstrumentationRuntimeInstance() :
2299     name(),
2300     description(),
2301     create_callback(NULL)
2302     {
2303     }
2304 
2305     ConstString name;
2306     std::string description;
2307     InstrumentationRuntimeCreateInstance create_callback;
2308     InstrumentationRuntimeGetType get_type_callback;
2309 };
2310 
2311 typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances;
2312 
2313 static Mutex &
2314 GetInstrumentationRuntimeMutex ()
2315 {
2316     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2317     return g_instances_mutex;
2318 }
2319 
2320 static InstrumentationRuntimeInstances &
2321 GetInstrumentationRuntimeInstances ()
2322 {
2323     static InstrumentationRuntimeInstances g_instances;
2324     return g_instances;
2325 }
2326 
2327 bool
2328 PluginManager::RegisterPlugin
2329 (
2330  const ConstString &name,
2331  const char *description,
2332  InstrumentationRuntimeCreateInstance create_callback,
2333  InstrumentationRuntimeGetType get_type_callback
2334  )
2335 {
2336     if (create_callback)
2337     {
2338         InstrumentationRuntimeInstance instance;
2339         assert ((bool)name);
2340         instance.name = name;
2341         if (description && description[0])
2342             instance.description = description;
2343         instance.create_callback = create_callback;
2344         instance.get_type_callback = get_type_callback;
2345         Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2346         GetInstrumentationRuntimeInstances ().push_back (instance);
2347     }
2348     return false;
2349 }
2350 
2351 bool
2352 PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback)
2353 {
2354     if (create_callback)
2355     {
2356         Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2357         InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2358 
2359         InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2360         for (pos = instances.begin(); pos != end; ++ pos)
2361         {
2362             if (pos->create_callback == create_callback)
2363             {
2364                 instances.erase(pos);
2365                 return true;
2366             }
2367         }
2368     }
2369     return false;
2370 }
2371 
2372 InstrumentationRuntimeGetType
2373 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx)
2374 {
2375     Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2376     InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2377     if (idx < instances.size())
2378         return instances[idx].get_type_callback;
2379     return NULL;
2380 }
2381 
2382 InstrumentationRuntimeCreateInstance
2383 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx)
2384 {
2385     Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2386     InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2387     if (idx < instances.size())
2388         return instances[idx].create_callback;
2389     return NULL;
2390 }
2391 
2392 
2393 InstrumentationRuntimeCreateInstance
2394 PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name)
2395 {
2396     if (name)
2397     {
2398         Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2399         InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2400 
2401         InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2402         for (pos = instances.begin(); pos != end; ++ pos)
2403         {
2404             if (name == pos->name)
2405                 return pos->create_callback;
2406         }
2407     }
2408     return NULL;
2409 }
2410 
2411 #pragma mark PluginManager
2412 
2413 void
2414 PluginManager::DebuggerInitialize (Debugger &debugger)
2415 {
2416     // Initialize the DynamicLoader plugins
2417     {
2418         Mutex::Locker locker (GetDynamicLoaderMutex ());
2419         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
2420 
2421         DynamicLoaderInstances::iterator pos, end = instances.end();
2422         for (pos = instances.begin(); pos != end; ++ pos)
2423         {
2424             if (pos->debugger_init_callback)
2425                 pos->debugger_init_callback (debugger);
2426         }
2427     }
2428 
2429     // Initialize the JITLoader plugins
2430     {
2431         Mutex::Locker locker (GetJITLoaderMutex ());
2432         JITLoaderInstances &instances = GetJITLoaderInstances ();
2433 
2434         JITLoaderInstances::iterator pos, end = instances.end();
2435         for (pos = instances.begin(); pos != end; ++ pos)
2436         {
2437             if (pos->debugger_init_callback)
2438                 pos->debugger_init_callback (debugger);
2439         }
2440     }
2441 
2442     // Initialize the Platform plugins
2443     {
2444         Mutex::Locker locker (GetPlatformInstancesMutex ());
2445         PlatformInstances &instances = GetPlatformInstances ();
2446 
2447         PlatformInstances::iterator pos, end = instances.end();
2448         for (pos = instances.begin(); pos != end; ++ pos)
2449         {
2450             if (pos->debugger_init_callback)
2451                 pos->debugger_init_callback (debugger);
2452         }
2453     }
2454 
2455     // Initialize the Process plugins
2456     {
2457         Mutex::Locker locker (GetProcessMutex());
2458         ProcessInstances &instances = GetProcessInstances();
2459 
2460         ProcessInstances::iterator pos, end = instances.end();
2461         for (pos = instances.begin(); pos != end; ++ pos)
2462         {
2463             if (pos->debugger_init_callback)
2464                 pos->debugger_init_callback (debugger);
2465         }
2466     }
2467 
2468     // Initialize the SymbolFile plugins
2469     {
2470         Mutex::Locker locker (GetSymbolFileMutex());
2471         for (auto& sym_file: GetSymbolFileInstances())
2472         {
2473             if (sym_file.debugger_init_callback)
2474                 sym_file.debugger_init_callback (debugger);
2475         }
2476     }
2477 }
2478 
2479 // This is the preferred new way to register plugin specific settings.  e.g.
2480 // This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2481 static lldb::OptionValuePropertiesSP
2482 GetDebuggerPropertyForPlugins (Debugger &debugger,
2483                                        const ConstString &plugin_type_name,
2484                                        const ConstString &plugin_type_desc,
2485                                        bool can_create)
2486 {
2487     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2488     if (parent_properties_sp)
2489     {
2490         static ConstString g_property_name("plugin");
2491 
2492         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
2493         if (!plugin_properties_sp && can_create)
2494         {
2495             plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
2496             parent_properties_sp->AppendProperty (g_property_name,
2497                                                   ConstString("Settings specify to plugins."),
2498                                                   true,
2499                                                   plugin_properties_sp);
2500         }
2501 
2502         if (plugin_properties_sp)
2503         {
2504             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
2505             if (!plugin_type_properties_sp && can_create)
2506             {
2507                 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2508                 plugin_properties_sp->AppendProperty (plugin_type_name,
2509                                                       plugin_type_desc,
2510                                                       true,
2511                                                       plugin_type_properties_sp);
2512             }
2513             return plugin_type_properties_sp;
2514         }
2515     }
2516     return lldb::OptionValuePropertiesSP();
2517 }
2518 
2519 // This is deprecated way to register plugin specific settings.  e.g.
2520 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
2521 // and Platform generic settings would be under "platform.SETTINGNAME".
2522 static lldb::OptionValuePropertiesSP
2523 GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
2524                                        const ConstString &plugin_type_name,
2525                                        const ConstString &plugin_type_desc,
2526                                        bool can_create)
2527 {
2528     static ConstString g_property_name("plugin");
2529     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2530     if (parent_properties_sp)
2531     {
2532         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
2533         if (!plugin_properties_sp && can_create)
2534         {
2535             plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2536             parent_properties_sp->AppendProperty (plugin_type_name,
2537                                                   plugin_type_desc,
2538                                                   true,
2539                                                   plugin_properties_sp);
2540         }
2541 
2542         if (plugin_properties_sp)
2543         {
2544             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
2545             if (!plugin_type_properties_sp && can_create)
2546             {
2547                 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
2548                 plugin_properties_sp->AppendProperty (g_property_name,
2549                                                       ConstString("Settings specific to plugins"),
2550                                                       true,
2551                                                       plugin_type_properties_sp);
2552             }
2553             return plugin_type_properties_sp;
2554         }
2555     }
2556     return lldb::OptionValuePropertiesSP();
2557 }
2558 
2559 
2560 lldb::OptionValuePropertiesSP
2561 PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name)
2562 {
2563     lldb::OptionValuePropertiesSP properties_sp;
2564     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2565                                                                                             ConstString("dynamic-loader"),
2566                                                                                             ConstString(), // not creating to so we don't need the description
2567                                                                                             false));
2568     if (plugin_type_properties_sp)
2569         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2570     return properties_sp;
2571 }
2572 
2573 bool
2574 PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
2575                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2576                                                     const ConstString &description,
2577                                                     bool is_global_property)
2578 {
2579     if (properties_sp)
2580     {
2581         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2582                                                                                                 ConstString("dynamic-loader"),
2583                                                                                                 ConstString("Settings for dynamic loader plug-ins"),
2584                                                                                                 true));
2585         if (plugin_type_properties_sp)
2586         {
2587             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2588                                                        description,
2589                                                        is_global_property,
2590                                                        properties_sp);
2591             return true;
2592         }
2593     }
2594     return false;
2595 }
2596 
2597 
2598 lldb::OptionValuePropertiesSP
2599 PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
2600 {
2601     lldb::OptionValuePropertiesSP properties_sp;
2602     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2603                                                                                                     ConstString("platform"),
2604                                                                                                     ConstString(), // not creating to so we don't need the description
2605                                                                                                     false));
2606     if (plugin_type_properties_sp)
2607         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2608     return properties_sp;
2609 }
2610 
2611 bool
2612 PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
2613                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2614                                                     const ConstString &description,
2615                                                     bool is_global_property)
2616 {
2617     if (properties_sp)
2618     {
2619         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2620                                                                                                         ConstString("platform"),
2621                                                                                                         ConstString("Settings for platform plug-ins"),
2622                                                                                                         true));
2623         if (plugin_type_properties_sp)
2624         {
2625             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2626                                                        description,
2627                                                        is_global_property,
2628                                                        properties_sp);
2629             return true;
2630         }
2631     }
2632     return false;
2633 }
2634 
2635 
2636 lldb::OptionValuePropertiesSP
2637 PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
2638 {
2639     lldb::OptionValuePropertiesSP properties_sp;
2640     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2641                                                                                             ConstString("process"),
2642                                                                                             ConstString(), // not creating to so we don't need the description
2643                                                                                             false));
2644     if (plugin_type_properties_sp)
2645         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2646     return properties_sp;
2647 }
2648 
2649 bool
2650 PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
2651                                               const lldb::OptionValuePropertiesSP &properties_sp,
2652                                               const ConstString &description,
2653                                               bool is_global_property)
2654 {
2655     if (properties_sp)
2656     {
2657         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2658                                                                                                 ConstString("process"),
2659                                                                                                 ConstString("Settings for process plug-ins"),
2660                                                                                                 true));
2661         if (plugin_type_properties_sp)
2662         {
2663             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2664                                                        description,
2665                                                        is_global_property,
2666                                                        properties_sp);
2667             return true;
2668         }
2669     }
2670     return false;
2671 }
2672 
2673 
2674 static const char* kSymbolFilePluginName("symbol-file");
2675 
2676 lldb::OptionValuePropertiesSP
2677 PluginManager::GetSettingForSymbolFilePlugin (Debugger &debugger,
2678                                               const ConstString &setting_name)
2679 {
2680     lldb::OptionValuePropertiesSP properties_sp;
2681     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2682                                                                                             ConstString(kSymbolFilePluginName),
2683                                                                                             ConstString(), // not creating to so we don't need the description
2684                                                                                             false));
2685     if (plugin_type_properties_sp)
2686         properties_sp = plugin_type_properties_sp->GetSubProperty (nullptr, setting_name);
2687     return properties_sp;
2688 }
2689 
2690 bool
2691 PluginManager::CreateSettingForSymbolFilePlugin (Debugger &debugger,
2692                                                  const lldb::OptionValuePropertiesSP &properties_sp,
2693                                                  const ConstString &description,
2694                                                  bool is_global_property)
2695 {
2696     if (properties_sp)
2697     {
2698         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2699                                                                                                 ConstString(kSymbolFilePluginName),
2700                                                                                                 ConstString("Settings for symbol file plug-ins"),
2701                                                                                                 true));
2702         if (plugin_type_properties_sp)
2703         {
2704             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2705                                                        description,
2706                                                        is_global_property,
2707                                                        properties_sp);
2708             return true;
2709         }
2710     }
2711     return false;
2712 }
2713