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