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