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