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