]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Core/PluginManager.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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 ObjectFile
858
859 struct ObjectFileInstance
860 {
861     ObjectFileInstance() :
862         name(),
863         description(),
864         create_callback(NULL),
865         create_memory_callback (NULL),
866         get_module_specifications (NULL)
867     {
868     }
869
870     ConstString name;
871     std::string description;
872     ObjectFileCreateInstance create_callback;
873     ObjectFileCreateMemoryInstance create_memory_callback;
874     ObjectFileGetModuleSpecifications get_module_specifications;
875 };
876
877 typedef std::vector<ObjectFileInstance> ObjectFileInstances;
878
879 static Mutex &
880 GetObjectFileMutex ()
881 {
882     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
883     return g_instances_mutex;
884 }
885
886 static ObjectFileInstances &
887 GetObjectFileInstances ()
888 {
889     static ObjectFileInstances g_instances;
890     return g_instances;
891 }
892
893
894 bool
895 PluginManager::RegisterPlugin (const ConstString &name,
896                                const char *description,
897                                ObjectFileCreateInstance create_callback,
898                                ObjectFileCreateMemoryInstance create_memory_callback,
899                                ObjectFileGetModuleSpecifications get_module_specifications)
900 {
901     if (create_callback)
902     {
903         ObjectFileInstance instance;
904         assert ((bool)name);
905         instance.name = name;
906         if (description && description[0])
907             instance.description = description;
908         instance.create_callback = create_callback;
909         instance.create_memory_callback = create_memory_callback;
910         instance.get_module_specifications = get_module_specifications;
911         Mutex::Locker locker (GetObjectFileMutex ());
912         GetObjectFileInstances ().push_back (instance);
913     }
914     return false;
915 }
916
917 bool
918 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
919 {
920     if (create_callback)
921     {
922         Mutex::Locker locker (GetObjectFileMutex ());
923         ObjectFileInstances &instances = GetObjectFileInstances ();
924         
925         ObjectFileInstances::iterator pos, end = instances.end();
926         for (pos = instances.begin(); pos != end; ++ pos)
927         {
928             if (pos->create_callback == create_callback)
929             {
930                 instances.erase(pos);
931                 return true;
932             }
933         }
934     }
935     return false;
936 }
937
938 ObjectFileCreateInstance
939 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
940 {
941     Mutex::Locker locker (GetObjectFileMutex ());
942     ObjectFileInstances &instances = GetObjectFileInstances ();
943     if (idx < instances.size())
944         return instances[idx].create_callback;
945     return NULL;
946 }
947
948
949 ObjectFileCreateMemoryInstance
950 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
951 {
952     Mutex::Locker locker (GetObjectFileMutex ());
953     ObjectFileInstances &instances = GetObjectFileInstances ();
954     if (idx < instances.size())
955         return instances[idx].create_memory_callback;
956     return NULL;
957 }
958
959 ObjectFileGetModuleSpecifications
960 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
961 {
962     Mutex::Locker locker (GetObjectFileMutex ());
963     ObjectFileInstances &instances = GetObjectFileInstances ();
964     if (idx < instances.size())
965         return instances[idx].get_module_specifications;
966     return NULL;
967 }
968
969 ObjectFileCreateInstance
970 PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
971 {
972     if (name)
973     {
974         Mutex::Locker locker (GetObjectFileMutex ());
975         ObjectFileInstances &instances = GetObjectFileInstances ();
976         
977         ObjectFileInstances::iterator pos, end = instances.end();
978         for (pos = instances.begin(); pos != end; ++ pos)
979         {
980             if (name == pos->name)
981                 return pos->create_callback;
982         }
983     }
984     return NULL;
985 }
986
987
988 ObjectFileCreateMemoryInstance
989 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
990 {
991     if (name)
992     {
993         Mutex::Locker locker (GetObjectFileMutex ());
994         ObjectFileInstances &instances = GetObjectFileInstances ();
995         
996         ObjectFileInstances::iterator pos, end = instances.end();
997         for (pos = instances.begin(); pos != end; ++ pos)
998         {
999             if (name == pos->name)
1000                 return pos->create_memory_callback;
1001         }
1002     }
1003     return NULL;
1004 }
1005
1006
1007
1008 #pragma mark ObjectContainer
1009
1010 struct ObjectContainerInstance
1011 {
1012     ObjectContainerInstance() :
1013         name(),
1014         description(),
1015         create_callback (NULL),
1016         get_module_specifications (NULL)
1017     {
1018     }
1019
1020     ConstString name;
1021     std::string description;
1022     ObjectContainerCreateInstance create_callback;
1023     ObjectFileGetModuleSpecifications get_module_specifications;
1024
1025 };
1026
1027 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1028
1029 static Mutex &
1030 GetObjectContainerMutex ()
1031 {
1032     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1033     return g_instances_mutex;
1034 }
1035
1036 static ObjectContainerInstances &
1037 GetObjectContainerInstances ()
1038 {
1039     static ObjectContainerInstances g_instances;
1040     return g_instances;
1041 }
1042
1043 bool
1044 PluginManager::RegisterPlugin (const ConstString &name,
1045                                const char *description,
1046                                ObjectContainerCreateInstance create_callback,
1047                                ObjectFileGetModuleSpecifications get_module_specifications)
1048 {
1049     if (create_callback)
1050     {
1051         ObjectContainerInstance instance;
1052         assert ((bool)name);
1053         instance.name = name;
1054         if (description && description[0])
1055             instance.description = description;
1056         instance.create_callback = create_callback;
1057         instance.get_module_specifications = get_module_specifications;
1058         Mutex::Locker locker (GetObjectContainerMutex ());
1059         GetObjectContainerInstances ().push_back (instance);
1060     }
1061     return false;
1062 }
1063
1064 bool
1065 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1066 {
1067     if (create_callback)
1068     {
1069         Mutex::Locker locker (GetObjectContainerMutex ());
1070         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1071         
1072         ObjectContainerInstances::iterator pos, end = instances.end();
1073         for (pos = instances.begin(); pos != end; ++ pos)
1074         {
1075             if (pos->create_callback == create_callback)
1076             {
1077                 instances.erase(pos);
1078                 return true;
1079             }
1080         }
1081     }
1082     return false;
1083 }
1084
1085 ObjectContainerCreateInstance
1086 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1087 {
1088     Mutex::Locker locker (GetObjectContainerMutex ());
1089     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1090     if (idx < instances.size())
1091         return instances[idx].create_callback;
1092     return NULL;
1093 }
1094
1095 ObjectContainerCreateInstance
1096 PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
1097 {
1098     if (name)
1099     {
1100         Mutex::Locker locker (GetObjectContainerMutex ());
1101         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1102         
1103         ObjectContainerInstances::iterator pos, end = instances.end();
1104         for (pos = instances.begin(); pos != end; ++ pos)
1105         {
1106             if (name == pos->name)
1107                 return pos->create_callback;
1108         }
1109     }
1110     return NULL;
1111 }
1112
1113 ObjectFileGetModuleSpecifications
1114 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1115 {
1116     Mutex::Locker locker (GetObjectContainerMutex ());
1117     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1118     if (idx < instances.size())
1119         return instances[idx].get_module_specifications;
1120     return NULL;
1121 }
1122
1123 #pragma mark LogChannel
1124
1125 struct LogInstance
1126 {
1127     LogInstance() :
1128         name(),
1129         description(),
1130         create_callback(NULL)
1131     {
1132     }
1133
1134     ConstString name;
1135     std::string description;
1136     LogChannelCreateInstance create_callback;
1137 };
1138
1139 typedef std::vector<LogInstance> LogInstances;
1140
1141 static Mutex &
1142 GetLogMutex ()
1143 {
1144     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1145     return g_instances_mutex;
1146 }
1147
1148 static LogInstances &
1149 GetLogInstances ()
1150 {
1151     static LogInstances g_instances;
1152     return g_instances;
1153 }
1154
1155
1156
1157 bool
1158 PluginManager::RegisterPlugin
1159 (
1160     const ConstString &name,
1161     const char *description,
1162     LogChannelCreateInstance create_callback
1163 )
1164 {
1165     if (create_callback)
1166     {
1167         LogInstance instance;
1168         assert ((bool)name);
1169         instance.name = name;
1170         if (description && description[0])
1171             instance.description = description;
1172         instance.create_callback = create_callback;
1173         Mutex::Locker locker (GetLogMutex ());
1174         GetLogInstances ().push_back (instance);
1175     }
1176     return false;
1177 }
1178
1179 bool
1180 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1181 {
1182     if (create_callback)
1183     {
1184         Mutex::Locker locker (GetLogMutex ());
1185         LogInstances &instances = GetLogInstances ();
1186         
1187         LogInstances::iterator pos, end = instances.end();
1188         for (pos = instances.begin(); pos != end; ++ pos)
1189         {
1190             if (pos->create_callback == create_callback)
1191             {
1192                 instances.erase(pos);
1193                 return true;
1194             }
1195         }
1196     }
1197     return false;
1198 }
1199
1200 const char *
1201 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1202 {
1203     Mutex::Locker locker (GetLogMutex ());
1204     LogInstances &instances = GetLogInstances ();
1205     if (idx < instances.size())
1206         return instances[idx].name.GetCString();
1207     return NULL;
1208 }
1209
1210
1211 LogChannelCreateInstance
1212 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1213 {
1214     Mutex::Locker locker (GetLogMutex ());
1215     LogInstances &instances = GetLogInstances ();
1216     if (idx < instances.size())
1217         return instances[idx].create_callback;
1218     return NULL;
1219 }
1220
1221 LogChannelCreateInstance
1222 PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
1223 {
1224     if (name)
1225     {
1226         Mutex::Locker locker (GetLogMutex ());
1227         LogInstances &instances = GetLogInstances ();
1228         
1229         LogInstances::iterator pos, end = instances.end();
1230         for (pos = instances.begin(); pos != end; ++ pos)
1231         {
1232             if (name == pos->name)
1233                 return pos->create_callback;
1234         }
1235     }
1236     return NULL;
1237 }
1238
1239 #pragma mark Platform
1240
1241 struct PlatformInstance
1242 {
1243     PlatformInstance() :
1244         name(),
1245         description(),
1246         create_callback(NULL),
1247         debugger_init_callback (NULL)
1248     {
1249     }
1250     
1251     ConstString name;
1252     std::string description;
1253     PlatformCreateInstance create_callback;
1254     DebuggerInitializeCallback debugger_init_callback;
1255 };
1256
1257 typedef std::vector<PlatformInstance> PlatformInstances;
1258
1259 static Mutex &
1260 GetPlatformInstancesMutex ()
1261 {
1262     static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1263     return g_platform_instances_mutex;
1264 }
1265
1266 static PlatformInstances &
1267 GetPlatformInstances ()
1268 {
1269     static PlatformInstances g_platform_instances;
1270     return g_platform_instances;
1271 }
1272
1273
1274 bool
1275 PluginManager::RegisterPlugin (const ConstString &name,
1276                                const char *description,
1277                                PlatformCreateInstance create_callback,
1278                                DebuggerInitializeCallback debugger_init_callback)
1279 {
1280     if (create_callback)
1281     {
1282         Mutex::Locker locker (GetPlatformInstancesMutex ());
1283         
1284         PlatformInstance instance;
1285         assert ((bool)name);
1286         instance.name = name;
1287         if (description && description[0])
1288             instance.description = description;
1289         instance.create_callback = create_callback;
1290         instance.debugger_init_callback = debugger_init_callback;
1291         GetPlatformInstances ().push_back (instance);
1292         return true;
1293     }
1294     return false;
1295 }
1296
1297
1298 const char *
1299 PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1300 {
1301     Mutex::Locker locker (GetPlatformInstancesMutex ());
1302     PlatformInstances &instances = GetPlatformInstances ();
1303     if (idx < instances.size())
1304         return instances[idx].name.GetCString();
1305     return NULL;
1306 }
1307
1308 const char *
1309 PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1310 {
1311     Mutex::Locker locker (GetPlatformInstancesMutex ());
1312     PlatformInstances &instances = GetPlatformInstances ();
1313     if (idx < instances.size())
1314         return instances[idx].description.c_str();
1315     return NULL;
1316 }
1317
1318 bool
1319 PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1320 {
1321     if (create_callback)
1322     {
1323         Mutex::Locker locker (GetPlatformInstancesMutex ());
1324         PlatformInstances &instances = GetPlatformInstances ();
1325
1326         PlatformInstances::iterator pos, end = instances.end();
1327         for (pos = instances.begin(); pos != end; ++ pos)
1328         {
1329             if (pos->create_callback == create_callback)
1330             {
1331                 instances.erase(pos);
1332                 return true;
1333             }
1334         }
1335     }
1336     return false;
1337 }
1338
1339 PlatformCreateInstance
1340 PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1341 {
1342     Mutex::Locker locker (GetPlatformInstancesMutex ());
1343     PlatformInstances &instances = GetPlatformInstances ();
1344     if (idx < instances.size())
1345         return instances[idx].create_callback;
1346     return NULL;
1347 }
1348
1349 PlatformCreateInstance
1350 PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
1351 {
1352     if (name)
1353     {
1354         Mutex::Locker locker (GetPlatformInstancesMutex ());
1355         PlatformInstances &instances = GetPlatformInstances ();
1356
1357         PlatformInstances::iterator pos, end = instances.end();
1358         for (pos = instances.begin(); pos != end; ++ pos)
1359         {
1360             if (name == pos->name)
1361                 return pos->create_callback;
1362         }
1363     }
1364     return NULL;
1365 }
1366
1367 size_t
1368 PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1369 {
1370     if (name)
1371     {
1372         Mutex::Locker locker (GetPlatformInstancesMutex ());
1373         PlatformInstances &instances = GetPlatformInstances ();
1374         llvm::StringRef name_sref(name);
1375
1376         PlatformInstances::iterator pos, end = instances.end();
1377         for (pos = instances.begin(); pos != end; ++ pos)
1378         {
1379             llvm::StringRef plugin_name (pos->name.GetCString());
1380             if (plugin_name.startswith(name_sref))
1381                 matches.AppendString (plugin_name.data());
1382         }
1383     }
1384     return matches.GetSize();
1385 }
1386 #pragma mark Process
1387
1388 struct ProcessInstance
1389 {
1390     ProcessInstance() :
1391         name(),
1392         description(),
1393         create_callback(NULL),
1394         debugger_init_callback(NULL)
1395     {
1396     }
1397     
1398     ConstString name;
1399     std::string description;
1400     ProcessCreateInstance create_callback;
1401     DebuggerInitializeCallback debugger_init_callback;
1402 };
1403
1404 typedef std::vector<ProcessInstance> ProcessInstances;
1405
1406 static Mutex &
1407 GetProcessMutex ()
1408 {
1409     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1410     return g_instances_mutex;
1411 }
1412
1413 static ProcessInstances &
1414 GetProcessInstances ()
1415 {
1416     static ProcessInstances g_instances;
1417     return g_instances;
1418 }
1419
1420
1421 bool
1422 PluginManager::RegisterPlugin (const ConstString &name,
1423                                const char *description,
1424                                ProcessCreateInstance create_callback,
1425                                DebuggerInitializeCallback debugger_init_callback)
1426 {
1427     if (create_callback)
1428     {
1429         ProcessInstance instance;
1430         assert ((bool)name);
1431         instance.name = name;
1432         if (description && description[0])
1433             instance.description = description;
1434         instance.create_callback = create_callback;
1435         instance.debugger_init_callback = debugger_init_callback;
1436         Mutex::Locker locker (GetProcessMutex ());
1437         GetProcessInstances ().push_back (instance);
1438     }
1439     return false;
1440 }
1441
1442 const char *
1443 PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1444 {
1445     Mutex::Locker locker (GetProcessMutex ());
1446     ProcessInstances &instances = GetProcessInstances ();
1447     if (idx < instances.size())
1448         return instances[idx].name.GetCString();
1449     return NULL;
1450 }
1451
1452 const char *
1453 PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1454 {
1455     Mutex::Locker locker (GetProcessMutex ());
1456     ProcessInstances &instances = GetProcessInstances ();
1457     if (idx < instances.size())
1458         return instances[idx].description.c_str();
1459     return NULL;
1460 }
1461
1462 bool
1463 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1464 {
1465     if (create_callback)
1466     {
1467         Mutex::Locker locker (GetProcessMutex ());
1468         ProcessInstances &instances = GetProcessInstances ();
1469         
1470         ProcessInstances::iterator pos, end = instances.end();
1471         for (pos = instances.begin(); pos != end; ++ pos)
1472         {
1473             if (pos->create_callback == create_callback)
1474             {
1475                 instances.erase(pos);
1476                 return true;
1477             }
1478         }
1479     }
1480     return false;
1481 }
1482
1483 ProcessCreateInstance
1484 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1485 {
1486     Mutex::Locker locker (GetProcessMutex ());
1487     ProcessInstances &instances = GetProcessInstances ();
1488     if (idx < instances.size())
1489         return instances[idx].create_callback;
1490     return NULL;
1491 }
1492
1493
1494 ProcessCreateInstance
1495 PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
1496 {
1497     if (name)
1498     {
1499         Mutex::Locker locker (GetProcessMutex ());
1500         ProcessInstances &instances = GetProcessInstances ();
1501         
1502         ProcessInstances::iterator pos, end = instances.end();
1503         for (pos = instances.begin(); pos != end; ++ pos)
1504         {
1505             if (name == pos->name)
1506                 return pos->create_callback;
1507         }
1508     }
1509     return NULL;
1510 }
1511
1512 #pragma mark SymbolFile
1513
1514 struct SymbolFileInstance
1515 {
1516     SymbolFileInstance() :
1517         name(),
1518         description(),
1519         create_callback(NULL)
1520     {
1521     }
1522
1523     ConstString name;
1524     std::string description;
1525     SymbolFileCreateInstance create_callback;
1526 };
1527
1528 typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1529
1530 static Mutex &
1531 GetSymbolFileMutex ()
1532 {
1533     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1534     return g_instances_mutex;
1535 }
1536
1537 static SymbolFileInstances &
1538 GetSymbolFileInstances ()
1539 {
1540     static SymbolFileInstances g_instances;
1541     return g_instances;
1542 }
1543
1544
1545 bool
1546 PluginManager::RegisterPlugin
1547 (
1548     const ConstString &name,
1549     const char *description,
1550     SymbolFileCreateInstance create_callback
1551 )
1552 {
1553     if (create_callback)
1554     {
1555         SymbolFileInstance instance;
1556         assert ((bool)name);
1557         instance.name = name;
1558         if (description && description[0])
1559             instance.description = description;
1560         instance.create_callback = create_callback;
1561         Mutex::Locker locker (GetSymbolFileMutex ());
1562         GetSymbolFileInstances ().push_back (instance);
1563     }
1564     return false;
1565 }
1566
1567 bool
1568 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1569 {
1570     if (create_callback)
1571     {
1572         Mutex::Locker locker (GetSymbolFileMutex ());
1573         SymbolFileInstances &instances = GetSymbolFileInstances ();
1574         
1575         SymbolFileInstances::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 SymbolFileCreateInstance
1589 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1590 {
1591     Mutex::Locker locker (GetSymbolFileMutex ());
1592     SymbolFileInstances &instances = GetSymbolFileInstances ();
1593     if (idx < instances.size())
1594         return instances[idx].create_callback;
1595     return NULL;
1596 }
1597
1598 SymbolFileCreateInstance
1599 PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
1600 {
1601     if (name)
1602     {
1603         Mutex::Locker locker (GetSymbolFileMutex ());
1604         SymbolFileInstances &instances = GetSymbolFileInstances ();
1605         
1606         SymbolFileInstances::iterator pos, end = instances.end();
1607         for (pos = instances.begin(); pos != end; ++ pos)
1608         {
1609             if (name == pos->name)
1610                 return pos->create_callback;
1611         }
1612     }
1613     return NULL;
1614 }
1615
1616
1617
1618 #pragma mark SymbolVendor
1619
1620 struct SymbolVendorInstance
1621 {
1622     SymbolVendorInstance() :
1623         name(),
1624         description(),
1625         create_callback(NULL)
1626     {
1627     }
1628
1629     ConstString name;
1630     std::string description;
1631     SymbolVendorCreateInstance create_callback;
1632 };
1633
1634 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1635
1636 static Mutex &
1637 GetSymbolVendorMutex ()
1638 {
1639     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1640     return g_instances_mutex;
1641 }
1642
1643 static SymbolVendorInstances &
1644 GetSymbolVendorInstances ()
1645 {
1646     static SymbolVendorInstances g_instances;
1647     return g_instances;
1648 }
1649
1650 bool
1651 PluginManager::RegisterPlugin
1652 (
1653     const ConstString &name,
1654     const char *description,
1655     SymbolVendorCreateInstance create_callback
1656 )
1657 {
1658     if (create_callback)
1659     {
1660         SymbolVendorInstance 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 (GetSymbolVendorMutex ());
1667         GetSymbolVendorInstances ().push_back (instance);
1668     }
1669     return false;
1670 }
1671
1672 bool
1673 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1674 {
1675     if (create_callback)
1676     {
1677         Mutex::Locker locker (GetSymbolVendorMutex ());
1678         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1679         
1680         SymbolVendorInstances::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 SymbolVendorCreateInstance
1694 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1695 {
1696     Mutex::Locker locker (GetSymbolVendorMutex ());
1697     SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1698     if (idx < instances.size())
1699         return instances[idx].create_callback;
1700     return NULL;
1701 }
1702
1703
1704 SymbolVendorCreateInstance
1705 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
1706 {
1707     if (name)
1708     {
1709         Mutex::Locker locker (GetSymbolVendorMutex ());
1710         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1711         
1712         SymbolVendorInstances::iterator pos, end = instances.end();
1713         for (pos = instances.begin(); pos != end; ++ pos)
1714         {
1715             if (name == pos->name)
1716                 return pos->create_callback;
1717         }
1718     }
1719     return NULL;
1720 }
1721
1722
1723 #pragma mark UnwindAssembly
1724
1725 struct UnwindAssemblyInstance
1726 {
1727     UnwindAssemblyInstance() :
1728         name(),
1729         description(),
1730         create_callback(NULL)
1731     {
1732     }
1733
1734     ConstString name;
1735     std::string description;
1736     UnwindAssemblyCreateInstance create_callback;
1737 };
1738
1739 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
1740
1741 static Mutex &
1742 GetUnwindAssemblyMutex ()
1743 {
1744     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1745     return g_instances_mutex;
1746 }
1747
1748 static UnwindAssemblyInstances &
1749 GetUnwindAssemblyInstances ()
1750 {
1751     static UnwindAssemblyInstances g_instances;
1752     return g_instances;
1753 }
1754
1755 bool
1756 PluginManager::RegisterPlugin
1757 (
1758     const ConstString &name,
1759     const char *description,
1760     UnwindAssemblyCreateInstance create_callback
1761 )
1762 {
1763     if (create_callback)
1764     {
1765         UnwindAssemblyInstance 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 (GetUnwindAssemblyMutex ());
1772         GetUnwindAssemblyInstances ().push_back (instance);
1773     }
1774     return false;
1775 }
1776
1777 bool
1778 PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
1779 {
1780     if (create_callback)
1781     {
1782         Mutex::Locker locker (GetUnwindAssemblyMutex ());
1783         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
1784         
1785         UnwindAssemblyInstances::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 UnwindAssemblyCreateInstance
1799 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
1800 {
1801     Mutex::Locker locker (GetUnwindAssemblyMutex ());
1802     UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
1803     if (idx < instances.size())
1804         return instances[idx].create_callback;
1805     return NULL;
1806 }
1807
1808
1809 UnwindAssemblyCreateInstance
1810 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
1811 {
1812     if (name)
1813     {
1814         Mutex::Locker locker (GetUnwindAssemblyMutex ());
1815         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
1816         
1817         UnwindAssemblyInstances::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 void
1828 PluginManager::DebuggerInitialize (Debugger &debugger)
1829 {
1830     // Initialize the DynamicLoader plugins
1831     {
1832         Mutex::Locker locker (GetDynamicLoaderMutex ());
1833         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
1834     
1835         DynamicLoaderInstances::iterator pos, end = instances.end();
1836         for (pos = instances.begin(); pos != end; ++ pos)
1837         {
1838             if (pos->debugger_init_callback)
1839                 pos->debugger_init_callback (debugger);
1840         }
1841     }
1842
1843     // Initialize the Platform plugins
1844     {
1845         Mutex::Locker locker (GetPlatformInstancesMutex ());
1846         PlatformInstances &instances = GetPlatformInstances ();
1847     
1848         PlatformInstances::iterator pos, end = instances.end();
1849         for (pos = instances.begin(); pos != end; ++ pos)
1850         {
1851             if (pos->debugger_init_callback)
1852                 pos->debugger_init_callback (debugger);
1853         }
1854     }
1855     
1856     // Initialize the Process plugins
1857     {
1858         Mutex::Locker locker (GetProcessMutex());
1859         ProcessInstances &instances = GetProcessInstances();
1860         
1861         ProcessInstances::iterator pos, end = instances.end();
1862         for (pos = instances.begin(); pos != end; ++ pos)
1863         {
1864             if (pos->debugger_init_callback)
1865                 pos->debugger_init_callback (debugger);
1866         }
1867     }
1868
1869 }
1870
1871 // This is the preferred new way to register plugin specific settings.  e.g.
1872 // This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1873 static lldb::OptionValuePropertiesSP
1874 GetDebuggerPropertyForPlugins (Debugger &debugger,
1875                                        const ConstString &plugin_type_name,
1876                                        const ConstString &plugin_type_desc,
1877                                        bool can_create)
1878 {
1879     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
1880     if (parent_properties_sp)
1881     {
1882         static ConstString g_property_name("plugin");
1883         
1884         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
1885         if (!plugin_properties_sp && can_create)
1886         {
1887             plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
1888             parent_properties_sp->AppendProperty (g_property_name,
1889                                                   ConstString("Settings specify to plugins."),
1890                                                   true,
1891                                                   plugin_properties_sp);
1892         }
1893         
1894         if (plugin_properties_sp)
1895         {
1896             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
1897             if (!plugin_type_properties_sp && can_create)
1898             {
1899                 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
1900                 plugin_properties_sp->AppendProperty (plugin_type_name,
1901                                                       plugin_type_desc,
1902                                                       true,
1903                                                       plugin_type_properties_sp);
1904             }
1905             return plugin_type_properties_sp;
1906         }
1907     }
1908     return lldb::OptionValuePropertiesSP();
1909 }
1910
1911 // This is deprecated way to register plugin specific settings.  e.g.
1912 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
1913 // and Platform generic settings would be under "platform.SETTINGNAME".
1914 static lldb::OptionValuePropertiesSP
1915 GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
1916                                        const ConstString &plugin_type_name,
1917                                        const ConstString &plugin_type_desc,
1918                                        bool can_create)
1919 {
1920     static ConstString g_property_name("plugin");
1921     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
1922     if (parent_properties_sp)
1923     {
1924         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
1925         if (!plugin_properties_sp && can_create)
1926         {
1927             plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
1928             parent_properties_sp->AppendProperty (plugin_type_name,
1929                                                   plugin_type_desc,
1930                                                   true,
1931                                                   plugin_properties_sp);
1932         }
1933         
1934         if (plugin_properties_sp)
1935         {
1936             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
1937             if (!plugin_type_properties_sp && can_create)
1938             {
1939                 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
1940                 plugin_properties_sp->AppendProperty (g_property_name,
1941                                                       ConstString("Settings specific to plugins"),
1942                                                       true,
1943                                                       plugin_type_properties_sp);
1944             }
1945             return plugin_type_properties_sp;
1946         }
1947     }
1948     return lldb::OptionValuePropertiesSP();
1949 }
1950
1951
1952 lldb::OptionValuePropertiesSP
1953 PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name)
1954 {
1955     lldb::OptionValuePropertiesSP properties_sp;
1956     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
1957                                                                                             ConstString("dynamic-loader"),
1958                                                                                             ConstString(), // not creating to so we don't need the description
1959                                                                                             false));
1960     if (plugin_type_properties_sp)
1961         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
1962     return properties_sp;
1963 }
1964
1965 bool
1966 PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
1967                                                     const lldb::OptionValuePropertiesSP &properties_sp,
1968                                                     const ConstString &description,
1969                                                     bool is_global_property)
1970 {
1971     if (properties_sp)
1972     {
1973         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
1974                                                                                                 ConstString("dynamic-loader"),
1975                                                                                                 ConstString("Settings for dynamic loader plug-ins"),
1976                                                                                                 true));
1977         if (plugin_type_properties_sp)
1978         {
1979             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
1980                                                        description,
1981                                                        is_global_property,
1982                                                        properties_sp);
1983             return true;
1984         }
1985     }
1986     return false;
1987 }
1988
1989
1990 lldb::OptionValuePropertiesSP
1991 PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
1992 {
1993     lldb::OptionValuePropertiesSP properties_sp;
1994     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
1995                                                                                                     ConstString("platform"),
1996                                                                                                     ConstString(), // not creating to so we don't need the description
1997                                                                                                     false));
1998     if (plugin_type_properties_sp)
1999         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2000     return properties_sp;
2001 }
2002
2003 bool
2004 PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
2005                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2006                                                     const ConstString &description,
2007                                                     bool is_global_property)
2008 {
2009     if (properties_sp)
2010     {
2011         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2012                                                                                                         ConstString("platform"),
2013                                                                                                         ConstString("Settings for platform plug-ins"),
2014                                                                                                         true));
2015         if (plugin_type_properties_sp)
2016         {
2017             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2018                                                        description,
2019                                                        is_global_property,
2020                                                        properties_sp);
2021             return true;
2022         }
2023     }
2024     return false;
2025 }
2026
2027
2028 lldb::OptionValuePropertiesSP
2029 PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
2030 {
2031     lldb::OptionValuePropertiesSP properties_sp;
2032     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2033                                                                                             ConstString("process"),
2034                                                                                             ConstString(), // not creating to so we don't need the description
2035                                                                                             false));
2036     if (plugin_type_properties_sp)
2037         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2038     return properties_sp;
2039 }
2040
2041 bool
2042 PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
2043                                               const lldb::OptionValuePropertiesSP &properties_sp,
2044                                               const ConstString &description,
2045                                               bool is_global_property)
2046 {
2047     if (properties_sp)
2048     {
2049         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2050                                                                                                 ConstString("process"),
2051                                                                                                 ConstString("Settings for process plug-ins"),
2052                                                                                                 true));
2053         if (plugin_type_properties_sp)
2054         {
2055             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2056                                                        description,
2057                                                        is_global_property,
2058                                                        properties_sp);
2059             return true;
2060         }
2061     }
2062     return false;
2063 }
2064