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 JITLoader
548 
549 
550 struct JITLoaderInstance
551 {
552     JITLoaderInstance() :
553         name(),
554         description(),
555         create_callback(NULL),
556         debugger_init_callback (NULL)
557     {
558     }
559 
560     ConstString name;
561     std::string description;
562     JITLoaderCreateInstance create_callback;
563     DebuggerInitializeCallback debugger_init_callback;
564 };
565 
566 typedef std::vector<JITLoaderInstance> JITLoaderInstances;
567 
568 
569 static Mutex &
570 GetJITLoaderMutex ()
571 {
572     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
573     return g_instances_mutex;
574 }
575 
576 static JITLoaderInstances &
577 GetJITLoaderInstances ()
578 {
579     static JITLoaderInstances g_instances;
580     return g_instances;
581 }
582 
583 
584 bool
585 PluginManager::RegisterPlugin
586 (
587     const ConstString &name,
588     const char *description,
589     JITLoaderCreateInstance create_callback,
590     DebuggerInitializeCallback debugger_init_callback
591 )
592 {
593     if (create_callback)
594     {
595         JITLoaderInstance instance;
596         assert ((bool)name);
597         instance.name = name;
598         if (description && description[0])
599             instance.description = description;
600         instance.create_callback = create_callback;
601         instance.debugger_init_callback = debugger_init_callback;
602         Mutex::Locker locker (GetJITLoaderMutex ());
603         GetJITLoaderInstances ().push_back (instance);
604     }
605     return false;
606 }
607 
608 bool
609 PluginManager::UnregisterPlugin (JITLoaderCreateInstance create_callback)
610 {
611     if (create_callback)
612     {
613         Mutex::Locker locker (GetJITLoaderMutex ());
614         JITLoaderInstances &instances = GetJITLoaderInstances ();
615 
616         JITLoaderInstances::iterator pos, end = instances.end();
617         for (pos = instances.begin(); pos != end; ++ pos)
618         {
619             if (pos->create_callback == create_callback)
620             {
621                 instances.erase(pos);
622                 return true;
623             }
624         }
625     }
626     return false;
627 }
628 
629 JITLoaderCreateInstance
630 PluginManager::GetJITLoaderCreateCallbackAtIndex (uint32_t idx)
631 {
632     Mutex::Locker locker (GetJITLoaderMutex ());
633     JITLoaderInstances &instances = GetJITLoaderInstances ();
634     if (idx < instances.size())
635         return instances[idx].create_callback;
636     return NULL;
637 }
638 
639 JITLoaderCreateInstance
640 PluginManager::GetJITLoaderCreateCallbackForPluginName (const ConstString &name)
641 {
642     if (name)
643     {
644         Mutex::Locker locker (GetJITLoaderMutex ());
645         JITLoaderInstances &instances = GetJITLoaderInstances ();
646 
647         JITLoaderInstances::iterator pos, end = instances.end();
648         for (pos = instances.begin(); pos != end; ++ pos)
649         {
650             if (name == pos->name)
651                 return pos->create_callback;
652         }
653     }
654     return NULL;
655 }
656 
657 #pragma mark EmulateInstruction
658 
659 
660 struct EmulateInstructionInstance
661 {
662     EmulateInstructionInstance() :
663     name(),
664     description(),
665     create_callback(NULL)
666     {
667     }
668 
669     ConstString name;
670     std::string description;
671     EmulateInstructionCreateInstance create_callback;
672 };
673 
674 typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
675 
676 static Mutex &
677 GetEmulateInstructionMutex ()
678 {
679     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
680     return g_instances_mutex;
681 }
682 
683 static EmulateInstructionInstances &
684 GetEmulateInstructionInstances ()
685 {
686     static EmulateInstructionInstances g_instances;
687     return g_instances;
688 }
689 
690 
691 bool
692 PluginManager::RegisterPlugin
693 (
694     const ConstString &name,
695     const char *description,
696     EmulateInstructionCreateInstance create_callback
697 )
698 {
699     if (create_callback)
700     {
701         EmulateInstructionInstance instance;
702         assert ((bool)name);
703         instance.name = name;
704         if (description && description[0])
705             instance.description = description;
706         instance.create_callback = create_callback;
707         Mutex::Locker locker (GetEmulateInstructionMutex ());
708         GetEmulateInstructionInstances ().push_back (instance);
709     }
710     return false;
711 }
712 
713 bool
714 PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
715 {
716     if (create_callback)
717     {
718         Mutex::Locker locker (GetEmulateInstructionMutex ());
719         EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
720 
721         EmulateInstructionInstances::iterator pos, end = instances.end();
722         for (pos = instances.begin(); pos != end; ++ pos)
723         {
724             if (pos->create_callback == create_callback)
725             {
726                 instances.erase(pos);
727                 return true;
728             }
729         }
730     }
731     return false;
732 }
733 
734 EmulateInstructionCreateInstance
735 PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
736 {
737     Mutex::Locker locker (GetEmulateInstructionMutex ());
738     EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
739     if (idx < instances.size())
740         return instances[idx].create_callback;
741     return NULL;
742 }
743 
744 EmulateInstructionCreateInstance
745 PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name)
746 {
747     if (name)
748     {
749         Mutex::Locker locker (GetEmulateInstructionMutex ());
750         EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
751 
752         EmulateInstructionInstances::iterator pos, end = instances.end();
753         for (pos = instances.begin(); pos != end; ++ pos)
754         {
755             if (name == pos->name)
756                 return pos->create_callback;
757         }
758     }
759     return NULL;
760 }
761 #pragma mark OperatingSystem
762 
763 
764 struct OperatingSystemInstance
765 {
766     OperatingSystemInstance() :
767         name(),
768         description(),
769         create_callback(NULL)
770     {
771     }
772 
773     ConstString name;
774     std::string description;
775     OperatingSystemCreateInstance create_callback;
776 };
777 
778 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
779 
780 static Mutex &
781 GetOperatingSystemMutex ()
782 {
783     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
784     return g_instances_mutex;
785 }
786 
787 static OperatingSystemInstances &
788 GetOperatingSystemInstances ()
789 {
790     static OperatingSystemInstances g_instances;
791     return g_instances;
792 }
793 
794 bool
795 PluginManager::RegisterPlugin (const ConstString &name,
796                                const char *description,
797                                OperatingSystemCreateInstance create_callback)
798 {
799     if (create_callback)
800     {
801         OperatingSystemInstance instance;
802         assert ((bool)name);
803         instance.name = name;
804         if (description && description[0])
805             instance.description = description;
806         instance.create_callback = create_callback;
807         Mutex::Locker locker (GetOperatingSystemMutex ());
808         GetOperatingSystemInstances ().push_back (instance);
809     }
810     return false;
811 }
812 
813 bool
814 PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
815 {
816     if (create_callback)
817     {
818         Mutex::Locker locker (GetOperatingSystemMutex ());
819         OperatingSystemInstances &instances = GetOperatingSystemInstances ();
820 
821         OperatingSystemInstances::iterator pos, end = instances.end();
822         for (pos = instances.begin(); pos != end; ++ pos)
823         {
824             if (pos->create_callback == create_callback)
825             {
826                 instances.erase(pos);
827                 return true;
828             }
829         }
830     }
831     return false;
832 }
833 
834 OperatingSystemCreateInstance
835 PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
836 {
837     Mutex::Locker locker (GetOperatingSystemMutex ());
838     OperatingSystemInstances &instances = GetOperatingSystemInstances ();
839     if (idx < instances.size())
840         return instances[idx].create_callback;
841     return NULL;
842 }
843 
844 OperatingSystemCreateInstance
845 PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
846 {
847     if (name)
848     {
849         Mutex::Locker locker (GetOperatingSystemMutex ());
850         OperatingSystemInstances &instances = GetOperatingSystemInstances ();
851 
852         OperatingSystemInstances::iterator pos, end = instances.end();
853         for (pos = instances.begin(); pos != end; ++ pos)
854         {
855             if (name == pos->name)
856                 return pos->create_callback;
857         }
858     }
859     return NULL;
860 }
861 
862 
863 #pragma mark LanguageRuntime
864 
865 
866 struct LanguageRuntimeInstance
867 {
868     LanguageRuntimeInstance() :
869         name(),
870         description(),
871         create_callback(NULL)
872     {
873     }
874 
875     ConstString name;
876     std::string description;
877     LanguageRuntimeCreateInstance create_callback;
878 };
879 
880 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
881 
882 static Mutex &
883 GetLanguageRuntimeMutex ()
884 {
885     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
886     return g_instances_mutex;
887 }
888 
889 static LanguageRuntimeInstances &
890 GetLanguageRuntimeInstances ()
891 {
892     static LanguageRuntimeInstances g_instances;
893     return g_instances;
894 }
895 
896 bool
897 PluginManager::RegisterPlugin
898 (
899     const ConstString &name,
900     const char *description,
901     LanguageRuntimeCreateInstance create_callback
902 )
903 {
904     if (create_callback)
905     {
906         LanguageRuntimeInstance instance;
907         assert ((bool)name);
908         instance.name = name;
909         if (description && description[0])
910             instance.description = description;
911         instance.create_callback = create_callback;
912         Mutex::Locker locker (GetLanguageRuntimeMutex ());
913         GetLanguageRuntimeInstances ().push_back (instance);
914     }
915     return false;
916 }
917 
918 bool
919 PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
920 {
921     if (create_callback)
922     {
923         Mutex::Locker locker (GetLanguageRuntimeMutex ());
924         LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
925 
926         LanguageRuntimeInstances::iterator pos, end = instances.end();
927         for (pos = instances.begin(); pos != end; ++ pos)
928         {
929             if (pos->create_callback == create_callback)
930             {
931                 instances.erase(pos);
932                 return true;
933             }
934         }
935     }
936     return false;
937 }
938 
939 LanguageRuntimeCreateInstance
940 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
941 {
942     Mutex::Locker locker (GetLanguageRuntimeMutex ());
943     LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
944     if (idx < instances.size())
945         return instances[idx].create_callback;
946     return NULL;
947 }
948 
949 LanguageRuntimeCreateInstance
950 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
951 {
952     if (name)
953     {
954         Mutex::Locker locker (GetLanguageRuntimeMutex ());
955         LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
956 
957         LanguageRuntimeInstances::iterator pos, end = instances.end();
958         for (pos = instances.begin(); pos != end; ++ pos)
959         {
960             if (name == pos->name)
961                 return pos->create_callback;
962         }
963     }
964     return NULL;
965 }
966 
967 #pragma mark SystemRuntime
968 
969 
970 struct SystemRuntimeInstance
971 {
972     SystemRuntimeInstance() :
973         name(),
974         description(),
975         create_callback(NULL)
976     {
977     }
978 
979     ConstString name;
980     std::string description;
981     SystemRuntimeCreateInstance create_callback;
982 };
983 
984 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
985 
986 static Mutex &
987 GetSystemRuntimeMutex ()
988 {
989     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
990     return g_instances_mutex;
991 }
992 
993 static SystemRuntimeInstances &
994 GetSystemRuntimeInstances ()
995 {
996     static SystemRuntimeInstances g_instances;
997     return g_instances;
998 }
999 
1000 bool
1001 PluginManager::RegisterPlugin
1002 (
1003     const ConstString &name,
1004     const char *description,
1005     SystemRuntimeCreateInstance create_callback
1006 )
1007 {
1008     if (create_callback)
1009     {
1010         SystemRuntimeInstance instance;
1011         assert ((bool)name);
1012         instance.name = name;
1013         if (description && description[0])
1014             instance.description = description;
1015         instance.create_callback = create_callback;
1016         Mutex::Locker locker (GetSystemRuntimeMutex ());
1017         GetSystemRuntimeInstances ().push_back (instance);
1018     }
1019     return false;
1020 }
1021 
1022 bool
1023 PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
1024 {
1025     if (create_callback)
1026     {
1027         Mutex::Locker locker (GetSystemRuntimeMutex ());
1028         SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1029 
1030         SystemRuntimeInstances::iterator pos, end = instances.end();
1031         for (pos = instances.begin(); pos != end; ++ pos)
1032         {
1033             if (pos->create_callback == create_callback)
1034             {
1035                 instances.erase(pos);
1036                 return true;
1037             }
1038         }
1039     }
1040     return false;
1041 }
1042 
1043 SystemRuntimeCreateInstance
1044 PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
1045 {
1046     Mutex::Locker locker (GetSystemRuntimeMutex ());
1047     SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1048     if (idx < instances.size())
1049         return instances[idx].create_callback;
1050     return NULL;
1051 }
1052 
1053 SystemRuntimeCreateInstance
1054 PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
1055 {
1056     if (name)
1057     {
1058         Mutex::Locker locker (GetSystemRuntimeMutex ());
1059         SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1060 
1061         SystemRuntimeInstances::iterator pos, end = instances.end();
1062         for (pos = instances.begin(); pos != end; ++ pos)
1063         {
1064             if (name == pos->name)
1065                 return pos->create_callback;
1066         }
1067     }
1068     return NULL;
1069 }
1070 
1071 
1072 #pragma mark ObjectFile
1073 
1074 struct ObjectFileInstance
1075 {
1076     ObjectFileInstance() :
1077         name(),
1078         description(),
1079         create_callback(NULL),
1080         create_memory_callback (NULL),
1081         get_module_specifications (NULL),
1082         save_core (NULL)
1083     {
1084     }
1085 
1086     ConstString name;
1087     std::string description;
1088     ObjectFileCreateInstance create_callback;
1089     ObjectFileCreateMemoryInstance create_memory_callback;
1090     ObjectFileGetModuleSpecifications get_module_specifications;
1091     ObjectFileSaveCore save_core;
1092 };
1093 
1094 typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1095 
1096 static Mutex &
1097 GetObjectFileMutex ()
1098 {
1099     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1100     return g_instances_mutex;
1101 }
1102 
1103 static ObjectFileInstances &
1104 GetObjectFileInstances ()
1105 {
1106     static ObjectFileInstances g_instances;
1107     return g_instances;
1108 }
1109 
1110 
1111 bool
1112 PluginManager::RegisterPlugin (const ConstString &name,
1113                                const char *description,
1114                                ObjectFileCreateInstance create_callback,
1115                                ObjectFileCreateMemoryInstance create_memory_callback,
1116                                ObjectFileGetModuleSpecifications get_module_specifications,
1117                                ObjectFileSaveCore save_core)
1118 {
1119     if (create_callback)
1120     {
1121         ObjectFileInstance instance;
1122         assert ((bool)name);
1123         instance.name = name;
1124         if (description && description[0])
1125             instance.description = description;
1126         instance.create_callback = create_callback;
1127         instance.create_memory_callback = create_memory_callback;
1128         instance.save_core = save_core;
1129         instance.get_module_specifications = get_module_specifications;
1130         Mutex::Locker locker (GetObjectFileMutex ());
1131         GetObjectFileInstances ().push_back (instance);
1132     }
1133     return false;
1134 }
1135 
1136 bool
1137 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
1138 {
1139     if (create_callback)
1140     {
1141         Mutex::Locker locker (GetObjectFileMutex ());
1142         ObjectFileInstances &instances = GetObjectFileInstances ();
1143 
1144         ObjectFileInstances::iterator pos, end = instances.end();
1145         for (pos = instances.begin(); pos != end; ++ pos)
1146         {
1147             if (pos->create_callback == create_callback)
1148             {
1149                 instances.erase(pos);
1150                 return true;
1151             }
1152         }
1153     }
1154     return false;
1155 }
1156 
1157 ObjectFileCreateInstance
1158 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
1159 {
1160     Mutex::Locker locker (GetObjectFileMutex ());
1161     ObjectFileInstances &instances = GetObjectFileInstances ();
1162     if (idx < instances.size())
1163         return instances[idx].create_callback;
1164     return NULL;
1165 }
1166 
1167 
1168 ObjectFileCreateMemoryInstance
1169 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
1170 {
1171     Mutex::Locker locker (GetObjectFileMutex ());
1172     ObjectFileInstances &instances = GetObjectFileInstances ();
1173     if (idx < instances.size())
1174         return instances[idx].create_memory_callback;
1175     return NULL;
1176 }
1177 
1178 ObjectFileGetModuleSpecifications
1179 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1180 {
1181     Mutex::Locker locker (GetObjectFileMutex ());
1182     ObjectFileInstances &instances = GetObjectFileInstances ();
1183     if (idx < instances.size())
1184         return instances[idx].get_module_specifications;
1185     return NULL;
1186 }
1187 
1188 ObjectFileCreateInstance
1189 PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
1190 {
1191     if (name)
1192     {
1193         Mutex::Locker locker (GetObjectFileMutex ());
1194         ObjectFileInstances &instances = GetObjectFileInstances ();
1195 
1196         ObjectFileInstances::iterator pos, end = instances.end();
1197         for (pos = instances.begin(); pos != end; ++ pos)
1198         {
1199             if (name == pos->name)
1200                 return pos->create_callback;
1201         }
1202     }
1203     return NULL;
1204 }
1205 
1206 
1207 ObjectFileCreateMemoryInstance
1208 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
1209 {
1210     if (name)
1211     {
1212         Mutex::Locker locker (GetObjectFileMutex ());
1213         ObjectFileInstances &instances = GetObjectFileInstances ();
1214 
1215         ObjectFileInstances::iterator pos, end = instances.end();
1216         for (pos = instances.begin(); pos != end; ++ pos)
1217         {
1218             if (name == pos->name)
1219                 return pos->create_memory_callback;
1220         }
1221     }
1222     return NULL;
1223 }
1224 
1225 Error
1226 PluginManager::SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile)
1227 {
1228     Error error;
1229     Mutex::Locker locker (GetObjectFileMutex ());
1230     ObjectFileInstances &instances = GetObjectFileInstances ();
1231 
1232     ObjectFileInstances::iterator pos, end = instances.end();
1233     for (pos = instances.begin(); pos != end; ++ pos)
1234     {
1235         if (pos->save_core && pos->save_core (process_sp, outfile, error))
1236             return error;
1237     }
1238     error.SetErrorString("no ObjectFile plugins were able to save a core for this process");
1239     return error;
1240 }
1241 
1242 #pragma mark ObjectContainer
1243 
1244 struct ObjectContainerInstance
1245 {
1246     ObjectContainerInstance() :
1247         name(),
1248         description(),
1249         create_callback (NULL),
1250         get_module_specifications (NULL)
1251     {
1252     }
1253 
1254     ConstString name;
1255     std::string description;
1256     ObjectContainerCreateInstance create_callback;
1257     ObjectFileGetModuleSpecifications get_module_specifications;
1258 
1259 };
1260 
1261 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1262 
1263 static Mutex &
1264 GetObjectContainerMutex ()
1265 {
1266     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1267     return g_instances_mutex;
1268 }
1269 
1270 static ObjectContainerInstances &
1271 GetObjectContainerInstances ()
1272 {
1273     static ObjectContainerInstances g_instances;
1274     return g_instances;
1275 }
1276 
1277 bool
1278 PluginManager::RegisterPlugin (const ConstString &name,
1279                                const char *description,
1280                                ObjectContainerCreateInstance create_callback,
1281                                ObjectFileGetModuleSpecifications get_module_specifications)
1282 {
1283     if (create_callback)
1284     {
1285         ObjectContainerInstance instance;
1286         assert ((bool)name);
1287         instance.name = name;
1288         if (description && description[0])
1289             instance.description = description;
1290         instance.create_callback = create_callback;
1291         instance.get_module_specifications = get_module_specifications;
1292         Mutex::Locker locker (GetObjectContainerMutex ());
1293         GetObjectContainerInstances ().push_back (instance);
1294     }
1295     return false;
1296 }
1297 
1298 bool
1299 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1300 {
1301     if (create_callback)
1302     {
1303         Mutex::Locker locker (GetObjectContainerMutex ());
1304         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1305 
1306         ObjectContainerInstances::iterator pos, end = instances.end();
1307         for (pos = instances.begin(); pos != end; ++ pos)
1308         {
1309             if (pos->create_callback == create_callback)
1310             {
1311                 instances.erase(pos);
1312                 return true;
1313             }
1314         }
1315     }
1316     return false;
1317 }
1318 
1319 ObjectContainerCreateInstance
1320 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1321 {
1322     Mutex::Locker locker (GetObjectContainerMutex ());
1323     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1324     if (idx < instances.size())
1325         return instances[idx].create_callback;
1326     return NULL;
1327 }
1328 
1329 ObjectContainerCreateInstance
1330 PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
1331 {
1332     if (name)
1333     {
1334         Mutex::Locker locker (GetObjectContainerMutex ());
1335         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1336 
1337         ObjectContainerInstances::iterator pos, end = instances.end();
1338         for (pos = instances.begin(); pos != end; ++ pos)
1339         {
1340             if (name == pos->name)
1341                 return pos->create_callback;
1342         }
1343     }
1344     return NULL;
1345 }
1346 
1347 ObjectFileGetModuleSpecifications
1348 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1349 {
1350     Mutex::Locker locker (GetObjectContainerMutex ());
1351     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1352     if (idx < instances.size())
1353         return instances[idx].get_module_specifications;
1354     return NULL;
1355 }
1356 
1357 #pragma mark LogChannel
1358 
1359 struct LogInstance
1360 {
1361     LogInstance() :
1362         name(),
1363         description(),
1364         create_callback(NULL)
1365     {
1366     }
1367 
1368     ConstString name;
1369     std::string description;
1370     LogChannelCreateInstance create_callback;
1371 };
1372 
1373 typedef std::vector<LogInstance> LogInstances;
1374 
1375 static Mutex &
1376 GetLogMutex ()
1377 {
1378     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1379     return g_instances_mutex;
1380 }
1381 
1382 static LogInstances &
1383 GetLogInstances ()
1384 {
1385     static LogInstances g_instances;
1386     return g_instances;
1387 }
1388 
1389 
1390 
1391 bool
1392 PluginManager::RegisterPlugin
1393 (
1394     const ConstString &name,
1395     const char *description,
1396     LogChannelCreateInstance create_callback
1397 )
1398 {
1399     if (create_callback)
1400     {
1401         LogInstance instance;
1402         assert ((bool)name);
1403         instance.name = name;
1404         if (description && description[0])
1405             instance.description = description;
1406         instance.create_callback = create_callback;
1407         Mutex::Locker locker (GetLogMutex ());
1408         GetLogInstances ().push_back (instance);
1409     }
1410     return false;
1411 }
1412 
1413 bool
1414 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1415 {
1416     if (create_callback)
1417     {
1418         Mutex::Locker locker (GetLogMutex ());
1419         LogInstances &instances = GetLogInstances ();
1420 
1421         LogInstances::iterator pos, end = instances.end();
1422         for (pos = instances.begin(); pos != end; ++ pos)
1423         {
1424             if (pos->create_callback == create_callback)
1425             {
1426                 instances.erase(pos);
1427                 return true;
1428             }
1429         }
1430     }
1431     return false;
1432 }
1433 
1434 const char *
1435 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1436 {
1437     Mutex::Locker locker (GetLogMutex ());
1438     LogInstances &instances = GetLogInstances ();
1439     if (idx < instances.size())
1440         return instances[idx].name.GetCString();
1441     return NULL;
1442 }
1443 
1444 
1445 LogChannelCreateInstance
1446 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1447 {
1448     Mutex::Locker locker (GetLogMutex ());
1449     LogInstances &instances = GetLogInstances ();
1450     if (idx < instances.size())
1451         return instances[idx].create_callback;
1452     return NULL;
1453 }
1454 
1455 LogChannelCreateInstance
1456 PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
1457 {
1458     if (name)
1459     {
1460         Mutex::Locker locker (GetLogMutex ());
1461         LogInstances &instances = GetLogInstances ();
1462 
1463         LogInstances::iterator pos, end = instances.end();
1464         for (pos = instances.begin(); pos != end; ++ pos)
1465         {
1466             if (name == pos->name)
1467                 return pos->create_callback;
1468         }
1469     }
1470     return NULL;
1471 }
1472 
1473 #pragma mark Platform
1474 
1475 struct PlatformInstance
1476 {
1477     PlatformInstance() :
1478         name(),
1479         description(),
1480         create_callback(NULL),
1481         debugger_init_callback (NULL)
1482     {
1483     }
1484 
1485     ConstString name;
1486     std::string description;
1487     PlatformCreateInstance create_callback;
1488     DebuggerInitializeCallback debugger_init_callback;
1489 };
1490 
1491 typedef std::vector<PlatformInstance> PlatformInstances;
1492 
1493 static Mutex &
1494 GetPlatformInstancesMutex ()
1495 {
1496     static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1497     return g_platform_instances_mutex;
1498 }
1499 
1500 static PlatformInstances &
1501 GetPlatformInstances ()
1502 {
1503     static PlatformInstances g_platform_instances;
1504     return g_platform_instances;
1505 }
1506 
1507 
1508 bool
1509 PluginManager::RegisterPlugin (const ConstString &name,
1510                                const char *description,
1511                                PlatformCreateInstance create_callback,
1512                                DebuggerInitializeCallback debugger_init_callback)
1513 {
1514     if (create_callback)
1515     {
1516         Mutex::Locker locker (GetPlatformInstancesMutex ());
1517 
1518         PlatformInstance instance;
1519         assert ((bool)name);
1520         instance.name = name;
1521         if (description && description[0])
1522             instance.description = description;
1523         instance.create_callback = create_callback;
1524         instance.debugger_init_callback = debugger_init_callback;
1525         GetPlatformInstances ().push_back (instance);
1526         return true;
1527     }
1528     return false;
1529 }
1530 
1531 
1532 const char *
1533 PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1534 {
1535     Mutex::Locker locker (GetPlatformInstancesMutex ());
1536     PlatformInstances &instances = GetPlatformInstances ();
1537     if (idx < instances.size())
1538         return instances[idx].name.GetCString();
1539     return NULL;
1540 }
1541 
1542 const char *
1543 PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1544 {
1545     Mutex::Locker locker (GetPlatformInstancesMutex ());
1546     PlatformInstances &instances = GetPlatformInstances ();
1547     if (idx < instances.size())
1548         return instances[idx].description.c_str();
1549     return NULL;
1550 }
1551 
1552 bool
1553 PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1554 {
1555     if (create_callback)
1556     {
1557         Mutex::Locker locker (GetPlatformInstancesMutex ());
1558         PlatformInstances &instances = GetPlatformInstances ();
1559 
1560         PlatformInstances::iterator pos, end = instances.end();
1561         for (pos = instances.begin(); pos != end; ++ pos)
1562         {
1563             if (pos->create_callback == create_callback)
1564             {
1565                 instances.erase(pos);
1566                 return true;
1567             }
1568         }
1569     }
1570     return false;
1571 }
1572 
1573 PlatformCreateInstance
1574 PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1575 {
1576     Mutex::Locker locker (GetPlatformInstancesMutex ());
1577     PlatformInstances &instances = GetPlatformInstances ();
1578     if (idx < instances.size())
1579         return instances[idx].create_callback;
1580     return NULL;
1581 }
1582 
1583 PlatformCreateInstance
1584 PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
1585 {
1586     if (name)
1587     {
1588         Mutex::Locker locker (GetPlatformInstancesMutex ());
1589         PlatformInstances &instances = GetPlatformInstances ();
1590 
1591         PlatformInstances::iterator pos, end = instances.end();
1592         for (pos = instances.begin(); pos != end; ++ pos)
1593         {
1594             if (name == pos->name)
1595                 return pos->create_callback;
1596         }
1597     }
1598     return NULL;
1599 }
1600 
1601 size_t
1602 PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1603 {
1604     if (name)
1605     {
1606         Mutex::Locker locker (GetPlatformInstancesMutex ());
1607         PlatformInstances &instances = GetPlatformInstances ();
1608         llvm::StringRef name_sref(name);
1609 
1610         PlatformInstances::iterator pos, end = instances.end();
1611         for (pos = instances.begin(); pos != end; ++ pos)
1612         {
1613             llvm::StringRef plugin_name (pos->name.GetCString());
1614             if (plugin_name.startswith(name_sref))
1615                 matches.AppendString (plugin_name.data());
1616         }
1617     }
1618     return matches.GetSize();
1619 }
1620 #pragma mark Process
1621 
1622 struct ProcessInstance
1623 {
1624     ProcessInstance() :
1625         name(),
1626         description(),
1627         create_callback(NULL),
1628         debugger_init_callback(NULL)
1629     {
1630     }
1631 
1632     ConstString name;
1633     std::string description;
1634     ProcessCreateInstance create_callback;
1635     DebuggerInitializeCallback debugger_init_callback;
1636 };
1637 
1638 typedef std::vector<ProcessInstance> ProcessInstances;
1639 
1640 static Mutex &
1641 GetProcessMutex ()
1642 {
1643     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1644     return g_instances_mutex;
1645 }
1646 
1647 static ProcessInstances &
1648 GetProcessInstances ()
1649 {
1650     static ProcessInstances g_instances;
1651     return g_instances;
1652 }
1653 
1654 
1655 bool
1656 PluginManager::RegisterPlugin (const ConstString &name,
1657                                const char *description,
1658                                ProcessCreateInstance create_callback,
1659                                DebuggerInitializeCallback debugger_init_callback)
1660 {
1661     if (create_callback)
1662     {
1663         ProcessInstance instance;
1664         assert ((bool)name);
1665         instance.name = name;
1666         if (description && description[0])
1667             instance.description = description;
1668         instance.create_callback = create_callback;
1669         instance.debugger_init_callback = debugger_init_callback;
1670         Mutex::Locker locker (GetProcessMutex ());
1671         GetProcessInstances ().push_back (instance);
1672     }
1673     return false;
1674 }
1675 
1676 const char *
1677 PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1678 {
1679     Mutex::Locker locker (GetProcessMutex ());
1680     ProcessInstances &instances = GetProcessInstances ();
1681     if (idx < instances.size())
1682         return instances[idx].name.GetCString();
1683     return NULL;
1684 }
1685 
1686 const char *
1687 PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1688 {
1689     Mutex::Locker locker (GetProcessMutex ());
1690     ProcessInstances &instances = GetProcessInstances ();
1691     if (idx < instances.size())
1692         return instances[idx].description.c_str();
1693     return NULL;
1694 }
1695 
1696 bool
1697 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1698 {
1699     if (create_callback)
1700     {
1701         Mutex::Locker locker (GetProcessMutex ());
1702         ProcessInstances &instances = GetProcessInstances ();
1703 
1704         ProcessInstances::iterator pos, end = instances.end();
1705         for (pos = instances.begin(); pos != end; ++ pos)
1706         {
1707             if (pos->create_callback == create_callback)
1708             {
1709                 instances.erase(pos);
1710                 return true;
1711             }
1712         }
1713     }
1714     return false;
1715 }
1716 
1717 ProcessCreateInstance
1718 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1719 {
1720     Mutex::Locker locker (GetProcessMutex ());
1721     ProcessInstances &instances = GetProcessInstances ();
1722     if (idx < instances.size())
1723         return instances[idx].create_callback;
1724     return NULL;
1725 }
1726 
1727 
1728 ProcessCreateInstance
1729 PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
1730 {
1731     if (name)
1732     {
1733         Mutex::Locker locker (GetProcessMutex ());
1734         ProcessInstances &instances = GetProcessInstances ();
1735 
1736         ProcessInstances::iterator pos, end = instances.end();
1737         for (pos = instances.begin(); pos != end; ++ pos)
1738         {
1739             if (name == pos->name)
1740                 return pos->create_callback;
1741         }
1742     }
1743     return NULL;
1744 }
1745 
1746 #pragma mark SymbolFile
1747 
1748 struct SymbolFileInstance
1749 {
1750     SymbolFileInstance() :
1751         name(),
1752         description(),
1753         create_callback(NULL)
1754     {
1755     }
1756 
1757     ConstString name;
1758     std::string description;
1759     SymbolFileCreateInstance create_callback;
1760 };
1761 
1762 typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1763 
1764 static Mutex &
1765 GetSymbolFileMutex ()
1766 {
1767     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1768     return g_instances_mutex;
1769 }
1770 
1771 static SymbolFileInstances &
1772 GetSymbolFileInstances ()
1773 {
1774     static SymbolFileInstances g_instances;
1775     return g_instances;
1776 }
1777 
1778 
1779 bool
1780 PluginManager::RegisterPlugin
1781 (
1782     const ConstString &name,
1783     const char *description,
1784     SymbolFileCreateInstance create_callback
1785 )
1786 {
1787     if (create_callback)
1788     {
1789         SymbolFileInstance instance;
1790         assert ((bool)name);
1791         instance.name = name;
1792         if (description && description[0])
1793             instance.description = description;
1794         instance.create_callback = create_callback;
1795         Mutex::Locker locker (GetSymbolFileMutex ());
1796         GetSymbolFileInstances ().push_back (instance);
1797     }
1798     return false;
1799 }
1800 
1801 bool
1802 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1803 {
1804     if (create_callback)
1805     {
1806         Mutex::Locker locker (GetSymbolFileMutex ());
1807         SymbolFileInstances &instances = GetSymbolFileInstances ();
1808 
1809         SymbolFileInstances::iterator pos, end = instances.end();
1810         for (pos = instances.begin(); pos != end; ++ pos)
1811         {
1812             if (pos->create_callback == create_callback)
1813             {
1814                 instances.erase(pos);
1815                 return true;
1816             }
1817         }
1818     }
1819     return false;
1820 }
1821 
1822 SymbolFileCreateInstance
1823 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1824 {
1825     Mutex::Locker locker (GetSymbolFileMutex ());
1826     SymbolFileInstances &instances = GetSymbolFileInstances ();
1827     if (idx < instances.size())
1828         return instances[idx].create_callback;
1829     return NULL;
1830 }
1831 
1832 SymbolFileCreateInstance
1833 PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
1834 {
1835     if (name)
1836     {
1837         Mutex::Locker locker (GetSymbolFileMutex ());
1838         SymbolFileInstances &instances = GetSymbolFileInstances ();
1839 
1840         SymbolFileInstances::iterator pos, end = instances.end();
1841         for (pos = instances.begin(); pos != end; ++ pos)
1842         {
1843             if (name == pos->name)
1844                 return pos->create_callback;
1845         }
1846     }
1847     return NULL;
1848 }
1849 
1850 
1851 
1852 #pragma mark SymbolVendor
1853 
1854 struct SymbolVendorInstance
1855 {
1856     SymbolVendorInstance() :
1857         name(),
1858         description(),
1859         create_callback(NULL)
1860     {
1861     }
1862 
1863     ConstString name;
1864     std::string description;
1865     SymbolVendorCreateInstance create_callback;
1866 };
1867 
1868 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1869 
1870 static Mutex &
1871 GetSymbolVendorMutex ()
1872 {
1873     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1874     return g_instances_mutex;
1875 }
1876 
1877 static SymbolVendorInstances &
1878 GetSymbolVendorInstances ()
1879 {
1880     static SymbolVendorInstances g_instances;
1881     return g_instances;
1882 }
1883 
1884 bool
1885 PluginManager::RegisterPlugin
1886 (
1887     const ConstString &name,
1888     const char *description,
1889     SymbolVendorCreateInstance create_callback
1890 )
1891 {
1892     if (create_callback)
1893     {
1894         SymbolVendorInstance instance;
1895         assert ((bool)name);
1896         instance.name = name;
1897         if (description && description[0])
1898             instance.description = description;
1899         instance.create_callback = create_callback;
1900         Mutex::Locker locker (GetSymbolVendorMutex ());
1901         GetSymbolVendorInstances ().push_back (instance);
1902     }
1903     return false;
1904 }
1905 
1906 bool
1907 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1908 {
1909     if (create_callback)
1910     {
1911         Mutex::Locker locker (GetSymbolVendorMutex ());
1912         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1913 
1914         SymbolVendorInstances::iterator pos, end = instances.end();
1915         for (pos = instances.begin(); pos != end; ++ pos)
1916         {
1917             if (pos->create_callback == create_callback)
1918             {
1919                 instances.erase(pos);
1920                 return true;
1921             }
1922         }
1923     }
1924     return false;
1925 }
1926 
1927 SymbolVendorCreateInstance
1928 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1929 {
1930     Mutex::Locker locker (GetSymbolVendorMutex ());
1931     SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1932     if (idx < instances.size())
1933         return instances[idx].create_callback;
1934     return NULL;
1935 }
1936 
1937 
1938 SymbolVendorCreateInstance
1939 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
1940 {
1941     if (name)
1942     {
1943         Mutex::Locker locker (GetSymbolVendorMutex ());
1944         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1945 
1946         SymbolVendorInstances::iterator pos, end = instances.end();
1947         for (pos = instances.begin(); pos != end; ++ pos)
1948         {
1949             if (name == pos->name)
1950                 return pos->create_callback;
1951         }
1952     }
1953     return NULL;
1954 }
1955 
1956 
1957 #pragma mark UnwindAssembly
1958 
1959 struct UnwindAssemblyInstance
1960 {
1961     UnwindAssemblyInstance() :
1962         name(),
1963         description(),
1964         create_callback(NULL)
1965     {
1966     }
1967 
1968     ConstString name;
1969     std::string description;
1970     UnwindAssemblyCreateInstance create_callback;
1971 };
1972 
1973 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
1974 
1975 static Mutex &
1976 GetUnwindAssemblyMutex ()
1977 {
1978     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1979     return g_instances_mutex;
1980 }
1981 
1982 static UnwindAssemblyInstances &
1983 GetUnwindAssemblyInstances ()
1984 {
1985     static UnwindAssemblyInstances g_instances;
1986     return g_instances;
1987 }
1988 
1989 bool
1990 PluginManager::RegisterPlugin
1991 (
1992     const ConstString &name,
1993     const char *description,
1994     UnwindAssemblyCreateInstance create_callback
1995 )
1996 {
1997     if (create_callback)
1998     {
1999         UnwindAssemblyInstance instance;
2000         assert ((bool)name);
2001         instance.name = name;
2002         if (description && description[0])
2003             instance.description = description;
2004         instance.create_callback = create_callback;
2005         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2006         GetUnwindAssemblyInstances ().push_back (instance);
2007     }
2008     return false;
2009 }
2010 
2011 bool
2012 PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
2013 {
2014     if (create_callback)
2015     {
2016         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2017         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2018 
2019         UnwindAssemblyInstances::iterator pos, end = instances.end();
2020         for (pos = instances.begin(); pos != end; ++ pos)
2021         {
2022             if (pos->create_callback == create_callback)
2023             {
2024                 instances.erase(pos);
2025                 return true;
2026             }
2027         }
2028     }
2029     return false;
2030 }
2031 
2032 UnwindAssemblyCreateInstance
2033 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
2034 {
2035     Mutex::Locker locker (GetUnwindAssemblyMutex ());
2036     UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2037     if (idx < instances.size())
2038         return instances[idx].create_callback;
2039     return NULL;
2040 }
2041 
2042 
2043 UnwindAssemblyCreateInstance
2044 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
2045 {
2046     if (name)
2047     {
2048         Mutex::Locker locker (GetUnwindAssemblyMutex ());
2049         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2050 
2051         UnwindAssemblyInstances::iterator pos, end = instances.end();
2052         for (pos = instances.begin(); pos != end; ++ pos)
2053         {
2054             if (name == pos->name)
2055                 return pos->create_callback;
2056         }
2057     }
2058     return NULL;
2059 }
2060 
2061 void
2062 PluginManager::DebuggerInitialize (Debugger &debugger)
2063 {
2064     // Initialize the DynamicLoader plugins
2065     {
2066         Mutex::Locker locker (GetDynamicLoaderMutex ());
2067         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
2068 
2069         DynamicLoaderInstances::iterator pos, end = instances.end();
2070         for (pos = instances.begin(); pos != end; ++ pos)
2071         {
2072             if (pos->debugger_init_callback)
2073                 pos->debugger_init_callback (debugger);
2074         }
2075     }
2076 
2077     // Initialize the JITLoader plugins
2078     {
2079         Mutex::Locker locker (GetJITLoaderMutex ());
2080         JITLoaderInstances &instances = GetJITLoaderInstances ();
2081 
2082         JITLoaderInstances::iterator pos, end = instances.end();
2083         for (pos = instances.begin(); pos != end; ++ pos)
2084         {
2085             if (pos->debugger_init_callback)
2086                 pos->debugger_init_callback (debugger);
2087         }
2088     }
2089 
2090     // Initialize the Platform plugins
2091     {
2092         Mutex::Locker locker (GetPlatformInstancesMutex ());
2093         PlatformInstances &instances = GetPlatformInstances ();
2094 
2095         PlatformInstances::iterator pos, end = instances.end();
2096         for (pos = instances.begin(); pos != end; ++ pos)
2097         {
2098             if (pos->debugger_init_callback)
2099                 pos->debugger_init_callback (debugger);
2100         }
2101     }
2102 
2103     // Initialize the Process plugins
2104     {
2105         Mutex::Locker locker (GetProcessMutex());
2106         ProcessInstances &instances = GetProcessInstances();
2107 
2108         ProcessInstances::iterator pos, end = instances.end();
2109         for (pos = instances.begin(); pos != end; ++ pos)
2110         {
2111             if (pos->debugger_init_callback)
2112                 pos->debugger_init_callback (debugger);
2113         }
2114     }
2115 
2116 }
2117 
2118 // This is the preferred new way to register plugin specific settings.  e.g.
2119 // This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2120 static lldb::OptionValuePropertiesSP
2121 GetDebuggerPropertyForPlugins (Debugger &debugger,
2122                                        const ConstString &plugin_type_name,
2123                                        const ConstString &plugin_type_desc,
2124                                        bool can_create)
2125 {
2126     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2127     if (parent_properties_sp)
2128     {
2129         static ConstString g_property_name("plugin");
2130 
2131         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
2132         if (!plugin_properties_sp && can_create)
2133         {
2134             plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
2135             parent_properties_sp->AppendProperty (g_property_name,
2136                                                   ConstString("Settings specify to plugins."),
2137                                                   true,
2138                                                   plugin_properties_sp);
2139         }
2140 
2141         if (plugin_properties_sp)
2142         {
2143             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
2144             if (!plugin_type_properties_sp && can_create)
2145             {
2146                 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2147                 plugin_properties_sp->AppendProperty (plugin_type_name,
2148                                                       plugin_type_desc,
2149                                                       true,
2150                                                       plugin_type_properties_sp);
2151             }
2152             return plugin_type_properties_sp;
2153         }
2154     }
2155     return lldb::OptionValuePropertiesSP();
2156 }
2157 
2158 // This is deprecated way to register plugin specific settings.  e.g.
2159 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
2160 // and Platform generic settings would be under "platform.SETTINGNAME".
2161 static lldb::OptionValuePropertiesSP
2162 GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
2163                                        const ConstString &plugin_type_name,
2164                                        const ConstString &plugin_type_desc,
2165                                        bool can_create)
2166 {
2167     static ConstString g_property_name("plugin");
2168     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2169     if (parent_properties_sp)
2170     {
2171         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
2172         if (!plugin_properties_sp && can_create)
2173         {
2174             plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2175             parent_properties_sp->AppendProperty (plugin_type_name,
2176                                                   plugin_type_desc,
2177                                                   true,
2178                                                   plugin_properties_sp);
2179         }
2180 
2181         if (plugin_properties_sp)
2182         {
2183             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
2184             if (!plugin_type_properties_sp && can_create)
2185             {
2186                 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
2187                 plugin_properties_sp->AppendProperty (g_property_name,
2188                                                       ConstString("Settings specific to plugins"),
2189                                                       true,
2190                                                       plugin_type_properties_sp);
2191             }
2192             return plugin_type_properties_sp;
2193         }
2194     }
2195     return lldb::OptionValuePropertiesSP();
2196 }
2197 
2198 
2199 lldb::OptionValuePropertiesSP
2200 PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name)
2201 {
2202     lldb::OptionValuePropertiesSP properties_sp;
2203     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2204                                                                                             ConstString("dynamic-loader"),
2205                                                                                             ConstString(), // not creating to so we don't need the description
2206                                                                                             false));
2207     if (plugin_type_properties_sp)
2208         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2209     return properties_sp;
2210 }
2211 
2212 bool
2213 PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
2214                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2215                                                     const ConstString &description,
2216                                                     bool is_global_property)
2217 {
2218     if (properties_sp)
2219     {
2220         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2221                                                                                                 ConstString("dynamic-loader"),
2222                                                                                                 ConstString("Settings for dynamic loader plug-ins"),
2223                                                                                                 true));
2224         if (plugin_type_properties_sp)
2225         {
2226             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2227                                                        description,
2228                                                        is_global_property,
2229                                                        properties_sp);
2230             return true;
2231         }
2232     }
2233     return false;
2234 }
2235 
2236 
2237 lldb::OptionValuePropertiesSP
2238 PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
2239 {
2240     lldb::OptionValuePropertiesSP properties_sp;
2241     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2242                                                                                                     ConstString("platform"),
2243                                                                                                     ConstString(), // not creating to so we don't need the description
2244                                                                                                     false));
2245     if (plugin_type_properties_sp)
2246         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2247     return properties_sp;
2248 }
2249 
2250 bool
2251 PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
2252                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2253                                                     const ConstString &description,
2254                                                     bool is_global_property)
2255 {
2256     if (properties_sp)
2257     {
2258         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2259                                                                                                         ConstString("platform"),
2260                                                                                                         ConstString("Settings for platform plug-ins"),
2261                                                                                                         true));
2262         if (plugin_type_properties_sp)
2263         {
2264             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2265                                                        description,
2266                                                        is_global_property,
2267                                                        properties_sp);
2268             return true;
2269         }
2270     }
2271     return false;
2272 }
2273 
2274 
2275 lldb::OptionValuePropertiesSP
2276 PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
2277 {
2278     lldb::OptionValuePropertiesSP properties_sp;
2279     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2280                                                                                             ConstString("process"),
2281                                                                                             ConstString(), // not creating to so we don't need the description
2282                                                                                             false));
2283     if (plugin_type_properties_sp)
2284         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2285     return properties_sp;
2286 }
2287 
2288 bool
2289 PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
2290                                               const lldb::OptionValuePropertiesSP &properties_sp,
2291                                               const ConstString &description,
2292                                               bool is_global_property)
2293 {
2294     if (properties_sp)
2295     {
2296         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2297                                                                                                 ConstString("process"),
2298                                                                                                 ConstString("Settings for process plug-ins"),
2299                                                                                                 true));
2300         if (plugin_type_properties_sp)
2301         {
2302             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2303                                                        description,
2304                                                        is_global_property,
2305                                                        properties_sp);
2306             return true;
2307         }
2308     }
2309     return false;
2310 }
2311 
2312