PluginManager.cpp revision 296417
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/Core/PluginManager.h"
11
12#include <limits.h>
13
14#include <string>
15#include <vector>
16
17#include "lldb/Core/Debugger.h"
18#include "lldb/Core/Error.h"
19#include "lldb/Host/FileSpec.h"
20#include "lldb/Host/Host.h"
21#include "lldb/Host/HostInfo.h"
22#include "lldb/Host/Mutex.h"
23#include "lldb/Interpreter/OptionValueProperties.h"
24
25#include "llvm/ADT/StringRef.h"
26#include "llvm/Support/DynamicLibrary.h"
27
28using namespace lldb;
29using namespace lldb_private;
30
31enum PluginAction
32{
33    ePluginRegisterInstance,
34    ePluginUnregisterInstance,
35    ePluginGetInstanceAtIndex
36};
37
38
39typedef bool (*PluginInitCallback) (void);
40typedef void (*PluginTermCallback) (void);
41
42struct PluginInfo
43{
44    PluginInfo()
45        : plugin_init_callback(nullptr), plugin_term_callback(nullptr)
46    {
47    }
48
49    llvm::sys::DynamicLibrary library;
50    PluginInitCallback plugin_init_callback;
51    PluginTermCallback plugin_term_callback;
52};
53
54typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
55
56static Mutex &
57GetPluginMapMutex ()
58{
59    static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
60    return g_plugin_map_mutex;
61}
62
63static PluginTerminateMap &
64GetPluginMap ()
65{
66    static PluginTerminateMap g_plugin_map;
67    return g_plugin_map;
68}
69
70static bool
71PluginIsLoaded (const FileSpec &plugin_file_spec)
72{
73    Mutex::Locker locker (GetPluginMapMutex ());
74    PluginTerminateMap &plugin_map = GetPluginMap ();
75    return plugin_map.find (plugin_file_spec) != plugin_map.end();
76}
77
78static void
79SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
80{
81    Mutex::Locker locker (GetPluginMapMutex ());
82    PluginTerminateMap &plugin_map = GetPluginMap ();
83    assert (plugin_map.find (plugin_file_spec) == plugin_map.end());
84    plugin_map[plugin_file_spec] = plugin_info;
85}
86
87template <typename FPtrTy>
88static FPtrTy
89CastToFPtr (void *VPtr)
90{
91    return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
92}
93
94static FileSpec::EnumerateDirectoryResult
95LoadPluginCallback
96(
97    void *baton,
98    FileSpec::FileType file_type,
99    const FileSpec &file_spec
100)
101{
102//    PluginManager *plugin_manager = (PluginManager *)baton;
103    Error error;
104
105    // If we have a regular file, a symbolic link or unknown file type, try
106    // and process the file. We must handle unknown as sometimes the directory
107    // enumeration might be enumerating a file system that doesn't have correct
108    // file type information.
109    if (file_type == FileSpec::eFileTypeRegular         ||
110        file_type == FileSpec::eFileTypeSymbolicLink    ||
111        file_type == FileSpec::eFileTypeUnknown          )
112    {
113        FileSpec plugin_file_spec (file_spec);
114        plugin_file_spec.ResolvePath();
115
116        if (PluginIsLoaded (plugin_file_spec))
117            return FileSpec::eEnumerateDirectoryResultNext;
118        else
119        {
120            PluginInfo plugin_info;
121
122            std::string pluginLoadError;
123            plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary (plugin_file_spec.GetPath().c_str(), &pluginLoadError);
124            if (plugin_info.library.isValid())
125            {
126                bool success = false;
127                plugin_info.plugin_init_callback =
128                    CastToFPtr<PluginInitCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
129                if (plugin_info.plugin_init_callback)
130                {
131                    // Call the plug-in "bool LLDBPluginInitialize(void)" function
132                    success = plugin_info.plugin_init_callback();
133                }
134
135                if (success)
136                {
137                    // It is ok for the "LLDBPluginTerminate" symbol to be NULL
138                    plugin_info.plugin_term_callback =
139                        CastToFPtr<PluginTermCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
140                }
141                else
142                {
143                    // The initialize function returned FALSE which means the plug-in might not be
144                    // compatible, or might be too new or too old, or might not want to run on this
145                    // machine.  Set it to a default-constructed instance to invalidate it.
146                    plugin_info = PluginInfo();
147                }
148
149                // Regardless of success or failure, cache the plug-in load
150                // in our plug-in info so we don't try to load it again and
151                // again.
152                SetPluginInfo (plugin_file_spec, plugin_info);
153
154                return FileSpec::eEnumerateDirectoryResultNext;
155            }
156        }
157    }
158
159    if (file_type == FileSpec::eFileTypeUnknown     ||
160        file_type == FileSpec::eFileTypeDirectory   ||
161        file_type == FileSpec::eFileTypeSymbolicLink )
162    {
163        // Try and recurse into anything that a directory or symbolic link.
164        // We must also do this for unknown as sometimes the directory enumeration
165        // might be enumerating a file system that doesn't have correct file type
166        // information.
167        return FileSpec::eEnumerateDirectoryResultEnter;
168    }
169
170    return FileSpec::eEnumerateDirectoryResultNext;
171}
172
173
174void
175PluginManager::Initialize ()
176{
177#if 1
178    FileSpec dir_spec;
179    const bool find_directories = true;
180    const bool find_files = true;
181    const bool find_other = true;
182    char dir_path[PATH_MAX];
183    if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
184    {
185        if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
186        {
187            FileSpec::EnumerateDirectory (dir_path,
188                                          find_directories,
189                                          find_files,
190                                          find_other,
191                                          LoadPluginCallback,
192                                          NULL);
193        }
194    }
195
196    if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
197    {
198        if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
199        {
200            FileSpec::EnumerateDirectory (dir_path,
201                                          find_directories,
202                                          find_files,
203                                          find_other,
204                                          LoadPluginCallback,
205                                          NULL);
206        }
207    }
208#endif
209}
210
211void
212PluginManager::Terminate ()
213{
214    Mutex::Locker locker (GetPluginMapMutex ());
215    PluginTerminateMap &plugin_map = GetPluginMap ();
216
217    PluginTerminateMap::const_iterator pos, end = plugin_map.end();
218    for (pos = plugin_map.begin(); pos != end; ++pos)
219    {
220        // Call the plug-in "void LLDBPluginTerminate (void)" function if there
221        // is one (if the symbol was not NULL).
222        if (pos->second.library.isValid())
223        {
224            if (pos->second.plugin_term_callback)
225                pos->second.plugin_term_callback();
226        }
227    }
228    plugin_map.clear();
229}
230
231
232#pragma mark ABI
233
234
235struct ABIInstance
236{
237    ABIInstance() :
238        name(),
239        description(),
240        create_callback(NULL)
241    {
242    }
243
244    ConstString name;
245    std::string description;
246    ABICreateInstance create_callback;
247};
248
249typedef std::vector<ABIInstance> ABIInstances;
250
251static Mutex &
252GetABIInstancesMutex ()
253{
254    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
255    return g_instances_mutex;
256}
257
258static ABIInstances &
259GetABIInstances ()
260{
261    static ABIInstances g_instances;
262    return g_instances;
263}
264
265bool
266PluginManager::RegisterPlugin
267(
268    const ConstString &name,
269    const char *description,
270    ABICreateInstance create_callback
271)
272{
273    if (create_callback)
274    {
275        ABIInstance instance;
276        assert ((bool)name);
277        instance.name = name;
278        if (description && description[0])
279            instance.description = description;
280        instance.create_callback = create_callback;
281        Mutex::Locker locker (GetABIInstancesMutex ());
282        GetABIInstances ().push_back (instance);
283        return true;
284    }
285    return false;
286}
287
288bool
289PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
290{
291    if (create_callback)
292    {
293        Mutex::Locker locker (GetABIInstancesMutex ());
294        ABIInstances &instances = GetABIInstances ();
295
296        ABIInstances::iterator pos, end = instances.end();
297        for (pos = instances.begin(); pos != end; ++ pos)
298        {
299            if (pos->create_callback == create_callback)
300            {
301                instances.erase(pos);
302                return true;
303            }
304        }
305    }
306    return false;
307}
308
309ABICreateInstance
310PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
311{
312    Mutex::Locker locker (GetABIInstancesMutex ());
313    ABIInstances &instances = GetABIInstances ();
314    if (idx < instances.size())
315        return instances[idx].create_callback;
316    return NULL;
317}
318
319ABICreateInstance
320PluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
321{
322    if (name)
323    {
324        Mutex::Locker locker (GetABIInstancesMutex ());
325        ABIInstances &instances = GetABIInstances ();
326
327        ABIInstances::iterator pos, end = instances.end();
328        for (pos = instances.begin(); pos != end; ++ pos)
329        {
330            if (name == pos->name)
331                return pos->create_callback;
332        }
333    }
334    return NULL;
335}
336
337
338#pragma mark Disassembler
339
340
341struct DisassemblerInstance
342{
343    DisassemblerInstance() :
344        name(),
345        description(),
346        create_callback(NULL)
347    {
348    }
349
350    ConstString name;
351    std::string description;
352    DisassemblerCreateInstance create_callback;
353};
354
355typedef std::vector<DisassemblerInstance> DisassemblerInstances;
356
357static Mutex &
358GetDisassemblerMutex ()
359{
360    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
361    return g_instances_mutex;
362}
363
364static DisassemblerInstances &
365GetDisassemblerInstances ()
366{
367    static DisassemblerInstances g_instances;
368    return g_instances;
369}
370
371bool
372PluginManager::RegisterPlugin
373(
374    const ConstString &name,
375    const char *description,
376    DisassemblerCreateInstance create_callback
377)
378{
379    if (create_callback)
380    {
381        DisassemblerInstance instance;
382        assert ((bool)name);
383        instance.name = name;
384        if (description && description[0])
385            instance.description = description;
386        instance.create_callback = create_callback;
387        Mutex::Locker locker (GetDisassemblerMutex ());
388        GetDisassemblerInstances ().push_back (instance);
389        return true;
390    }
391    return false;
392}
393
394bool
395PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
396{
397    if (create_callback)
398    {
399        Mutex::Locker locker (GetDisassemblerMutex ());
400        DisassemblerInstances &instances = GetDisassemblerInstances ();
401
402        DisassemblerInstances::iterator pos, end = instances.end();
403        for (pos = instances.begin(); pos != end; ++ pos)
404        {
405            if (pos->create_callback == create_callback)
406            {
407                instances.erase(pos);
408                return true;
409            }
410        }
411    }
412    return false;
413}
414
415DisassemblerCreateInstance
416PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
417{
418    Mutex::Locker locker (GetDisassemblerMutex ());
419    DisassemblerInstances &instances = GetDisassemblerInstances ();
420    if (idx < instances.size())
421        return instances[idx].create_callback;
422    return NULL;
423}
424
425DisassemblerCreateInstance
426PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &name)
427{
428    if (name)
429    {
430        Mutex::Locker locker (GetDisassemblerMutex ());
431        DisassemblerInstances &instances = GetDisassemblerInstances ();
432
433        DisassemblerInstances::iterator pos, end = instances.end();
434        for (pos = instances.begin(); pos != end; ++ pos)
435        {
436            if (name == pos->name)
437                return pos->create_callback;
438        }
439    }
440    return NULL;
441}
442
443
444
445#pragma mark DynamicLoader
446
447
448struct DynamicLoaderInstance
449{
450    DynamicLoaderInstance() :
451        name(),
452        description(),
453        create_callback(NULL),
454        debugger_init_callback (NULL)
455    {
456    }
457
458    ConstString name;
459    std::string description;
460    DynamicLoaderCreateInstance create_callback;
461    DebuggerInitializeCallback debugger_init_callback;
462};
463
464typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
465
466
467static Mutex &
468GetDynamicLoaderMutex ()
469{
470    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
471    return g_instances_mutex;
472}
473
474static DynamicLoaderInstances &
475GetDynamicLoaderInstances ()
476{
477    static DynamicLoaderInstances g_instances;
478    return g_instances;
479}
480
481
482bool
483PluginManager::RegisterPlugin
484(
485    const ConstString &name,
486    const char *description,
487    DynamicLoaderCreateInstance create_callback,
488    DebuggerInitializeCallback debugger_init_callback
489)
490{
491    if (create_callback)
492    {
493        DynamicLoaderInstance instance;
494        assert ((bool)name);
495        instance.name = name;
496        if (description && description[0])
497            instance.description = description;
498        instance.create_callback = create_callback;
499        instance.debugger_init_callback = debugger_init_callback;
500        Mutex::Locker locker (GetDynamicLoaderMutex ());
501        GetDynamicLoaderInstances ().push_back (instance);
502    }
503    return false;
504}
505
506bool
507PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
508{
509    if (create_callback)
510    {
511        Mutex::Locker locker (GetDynamicLoaderMutex ());
512        DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
513
514        DynamicLoaderInstances::iterator pos, end = instances.end();
515        for (pos = instances.begin(); pos != end; ++ pos)
516        {
517            if (pos->create_callback == create_callback)
518            {
519                instances.erase(pos);
520                return true;
521            }
522        }
523    }
524    return false;
525}
526
527DynamicLoaderCreateInstance
528PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
529{
530    Mutex::Locker locker (GetDynamicLoaderMutex ());
531    DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
532    if (idx < instances.size())
533        return instances[idx].create_callback;
534    return NULL;
535}
536
537DynamicLoaderCreateInstance
538PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name)
539{
540    if (name)
541    {
542        Mutex::Locker locker (GetDynamicLoaderMutex ());
543        DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
544
545        DynamicLoaderInstances::iterator pos, end = instances.end();
546        for (pos = instances.begin(); pos != end; ++ pos)
547        {
548            if (name == pos->name)
549                return pos->create_callback;
550        }
551    }
552    return NULL;
553}
554
555#pragma mark JITLoader
556
557
558struct JITLoaderInstance
559{
560    JITLoaderInstance() :
561        name(),
562        description(),
563        create_callback(NULL),
564        debugger_init_callback (NULL)
565    {
566    }
567
568    ConstString name;
569    std::string description;
570    JITLoaderCreateInstance create_callback;
571    DebuggerInitializeCallback debugger_init_callback;
572};
573
574typedef std::vector<JITLoaderInstance> JITLoaderInstances;
575
576
577static Mutex &
578GetJITLoaderMutex ()
579{
580    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
581    return g_instances_mutex;
582}
583
584static JITLoaderInstances &
585GetJITLoaderInstances ()
586{
587    static JITLoaderInstances g_instances;
588    return g_instances;
589}
590
591
592bool
593PluginManager::RegisterPlugin
594(
595    const ConstString &name,
596    const char *description,
597    JITLoaderCreateInstance create_callback,
598    DebuggerInitializeCallback debugger_init_callback
599)
600{
601    if (create_callback)
602    {
603        JITLoaderInstance instance;
604        assert ((bool)name);
605        instance.name = name;
606        if (description && description[0])
607            instance.description = description;
608        instance.create_callback = create_callback;
609        instance.debugger_init_callback = debugger_init_callback;
610        Mutex::Locker locker (GetJITLoaderMutex ());
611        GetJITLoaderInstances ().push_back (instance);
612    }
613    return false;
614}
615
616bool
617PluginManager::UnregisterPlugin (JITLoaderCreateInstance create_callback)
618{
619    if (create_callback)
620    {
621        Mutex::Locker locker (GetJITLoaderMutex ());
622        JITLoaderInstances &instances = GetJITLoaderInstances ();
623
624        JITLoaderInstances::iterator pos, end = instances.end();
625        for (pos = instances.begin(); pos != end; ++ pos)
626        {
627            if (pos->create_callback == create_callback)
628            {
629                instances.erase(pos);
630                return true;
631            }
632        }
633    }
634    return false;
635}
636
637JITLoaderCreateInstance
638PluginManager::GetJITLoaderCreateCallbackAtIndex (uint32_t idx)
639{
640    Mutex::Locker locker (GetJITLoaderMutex ());
641    JITLoaderInstances &instances = GetJITLoaderInstances ();
642    if (idx < instances.size())
643        return instances[idx].create_callback;
644    return NULL;
645}
646
647JITLoaderCreateInstance
648PluginManager::GetJITLoaderCreateCallbackForPluginName (const ConstString &name)
649{
650    if (name)
651    {
652        Mutex::Locker locker (GetJITLoaderMutex ());
653        JITLoaderInstances &instances = GetJITLoaderInstances ();
654
655        JITLoaderInstances::iterator pos, end = instances.end();
656        for (pos = instances.begin(); pos != end; ++ pos)
657        {
658            if (name == pos->name)
659                return pos->create_callback;
660        }
661    }
662    return NULL;
663}
664
665#pragma mark EmulateInstruction
666
667
668struct EmulateInstructionInstance
669{
670    EmulateInstructionInstance() :
671    name(),
672    description(),
673    create_callback(NULL)
674    {
675    }
676
677    ConstString name;
678    std::string description;
679    EmulateInstructionCreateInstance create_callback;
680};
681
682typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
683
684static Mutex &
685GetEmulateInstructionMutex ()
686{
687    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
688    return g_instances_mutex;
689}
690
691static EmulateInstructionInstances &
692GetEmulateInstructionInstances ()
693{
694    static EmulateInstructionInstances g_instances;
695    return g_instances;
696}
697
698
699bool
700PluginManager::RegisterPlugin
701(
702    const ConstString &name,
703    const char *description,
704    EmulateInstructionCreateInstance create_callback
705)
706{
707    if (create_callback)
708    {
709        EmulateInstructionInstance instance;
710        assert ((bool)name);
711        instance.name = name;
712        if (description && description[0])
713            instance.description = description;
714        instance.create_callback = create_callback;
715        Mutex::Locker locker (GetEmulateInstructionMutex ());
716        GetEmulateInstructionInstances ().push_back (instance);
717    }
718    return false;
719}
720
721bool
722PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
723{
724    if (create_callback)
725    {
726        Mutex::Locker locker (GetEmulateInstructionMutex ());
727        EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
728
729        EmulateInstructionInstances::iterator pos, end = instances.end();
730        for (pos = instances.begin(); pos != end; ++ pos)
731        {
732            if (pos->create_callback == create_callback)
733            {
734                instances.erase(pos);
735                return true;
736            }
737        }
738    }
739    return false;
740}
741
742EmulateInstructionCreateInstance
743PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
744{
745    Mutex::Locker locker (GetEmulateInstructionMutex ());
746    EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
747    if (idx < instances.size())
748        return instances[idx].create_callback;
749    return NULL;
750}
751
752EmulateInstructionCreateInstance
753PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name)
754{
755    if (name)
756    {
757        Mutex::Locker locker (GetEmulateInstructionMutex ());
758        EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
759
760        EmulateInstructionInstances::iterator pos, end = instances.end();
761        for (pos = instances.begin(); pos != end; ++ pos)
762        {
763            if (name == pos->name)
764                return pos->create_callback;
765        }
766    }
767    return NULL;
768}
769#pragma mark OperatingSystem
770
771
772struct OperatingSystemInstance
773{
774    OperatingSystemInstance () :
775        name (),
776        description (),
777        create_callback (nullptr),
778        debugger_init_callback (nullptr)
779    {
780    }
781
782    ConstString name;
783    std::string description;
784    OperatingSystemCreateInstance create_callback;
785    DebuggerInitializeCallback debugger_init_callback;
786};
787
788typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
789
790static Mutex &
791GetOperatingSystemMutex ()
792{
793    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
794    return g_instances_mutex;
795}
796
797static OperatingSystemInstances &
798GetOperatingSystemInstances ()
799{
800    static OperatingSystemInstances g_instances;
801    return g_instances;
802}
803
804bool
805PluginManager::RegisterPlugin(const ConstString &name, const char *description,
806                              OperatingSystemCreateInstance create_callback,
807                              DebuggerInitializeCallback debugger_init_callback)
808{
809    if (create_callback)
810    {
811        OperatingSystemInstance instance;
812        assert ((bool)name);
813        instance.name = name;
814        if (description && description[0])
815            instance.description = description;
816        instance.create_callback = create_callback;
817        instance.debugger_init_callback = debugger_init_callback;
818        Mutex::Locker locker (GetOperatingSystemMutex ());
819        GetOperatingSystemInstances ().push_back (instance);
820    }
821    return false;
822}
823
824bool
825PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
826{
827    if (create_callback)
828    {
829        Mutex::Locker locker (GetOperatingSystemMutex ());
830        OperatingSystemInstances &instances = GetOperatingSystemInstances ();
831
832        OperatingSystemInstances::iterator pos, end = instances.end();
833        for (pos = instances.begin(); pos != end; ++ pos)
834        {
835            if (pos->create_callback == create_callback)
836            {
837                instances.erase(pos);
838                return true;
839            }
840        }
841    }
842    return false;
843}
844
845OperatingSystemCreateInstance
846PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
847{
848    Mutex::Locker locker (GetOperatingSystemMutex ());
849    OperatingSystemInstances &instances = GetOperatingSystemInstances ();
850    if (idx < instances.size())
851        return instances[idx].create_callback;
852    return NULL;
853}
854
855OperatingSystemCreateInstance
856PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
857{
858    if (name)
859    {
860        Mutex::Locker locker (GetOperatingSystemMutex ());
861        OperatingSystemInstances &instances = GetOperatingSystemInstances ();
862
863        OperatingSystemInstances::iterator pos, end = instances.end();
864        for (pos = instances.begin(); pos != end; ++ pos)
865        {
866            if (name == pos->name)
867                return pos->create_callback;
868        }
869    }
870    return NULL;
871}
872
873
874#pragma mark Language
875
876
877struct LanguageInstance
878{
879    LanguageInstance() :
880        name(),
881        description(),
882        create_callback(NULL)
883    {
884    }
885
886    ConstString name;
887    std::string description;
888    LanguageCreateInstance create_callback;
889};
890
891typedef std::vector<LanguageInstance> LanguageInstances;
892
893static Mutex &
894GetLanguageMutex ()
895{
896    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
897    return g_instances_mutex;
898}
899
900static LanguageInstances &
901GetLanguageInstances ()
902{
903    static LanguageInstances g_instances;
904    return g_instances;
905}
906
907bool
908PluginManager::RegisterPlugin
909(
910 const ConstString &name,
911 const char *description,
912 LanguageCreateInstance create_callback
913 )
914{
915    if (create_callback)
916    {
917        LanguageInstance instance;
918        assert ((bool)name);
919        instance.name = name;
920        if (description && description[0])
921            instance.description = description;
922        instance.create_callback = create_callback;
923        Mutex::Locker locker (GetLanguageMutex ());
924        GetLanguageInstances ().push_back (instance);
925    }
926    return false;
927}
928
929bool
930PluginManager::UnregisterPlugin (LanguageCreateInstance create_callback)
931{
932    if (create_callback)
933    {
934        Mutex::Locker locker (GetLanguageMutex ());
935        LanguageInstances &instances = GetLanguageInstances ();
936
937        LanguageInstances::iterator pos, end = instances.end();
938        for (pos = instances.begin(); pos != end; ++ pos)
939        {
940            if (pos->create_callback == create_callback)
941            {
942                instances.erase(pos);
943                return true;
944            }
945        }
946    }
947    return false;
948}
949
950LanguageCreateInstance
951PluginManager::GetLanguageCreateCallbackAtIndex (uint32_t idx)
952{
953    Mutex::Locker locker (GetLanguageMutex ());
954    LanguageInstances &instances = GetLanguageInstances ();
955    if (idx < instances.size())
956        return instances[idx].create_callback;
957    return NULL;
958}
959
960LanguageCreateInstance
961PluginManager::GetLanguageCreateCallbackForPluginName (const ConstString &name)
962{
963    if (name)
964    {
965        Mutex::Locker locker (GetLanguageMutex ());
966        LanguageInstances &instances = GetLanguageInstances ();
967
968        LanguageInstances::iterator pos, end = instances.end();
969        for (pos = instances.begin(); pos != end; ++ pos)
970        {
971            if (name == pos->name)
972                return pos->create_callback;
973        }
974    }
975    return NULL;
976}
977
978
979#pragma mark LanguageRuntime
980
981
982struct LanguageRuntimeInstance
983{
984    LanguageRuntimeInstance() :
985        name(),
986        description(),
987        create_callback(NULL)
988    {
989    }
990
991    ConstString name;
992    std::string description;
993    LanguageRuntimeCreateInstance create_callback;
994    LanguageRuntimeGetCommandObject command_callback;
995};
996
997typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
998
999static Mutex &
1000GetLanguageRuntimeMutex ()
1001{
1002    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1003    return g_instances_mutex;
1004}
1005
1006static LanguageRuntimeInstances &
1007GetLanguageRuntimeInstances ()
1008{
1009    static LanguageRuntimeInstances g_instances;
1010    return g_instances;
1011}
1012
1013bool
1014PluginManager::RegisterPlugin
1015(
1016    const ConstString &name,
1017    const char *description,
1018    LanguageRuntimeCreateInstance create_callback,
1019    LanguageRuntimeGetCommandObject command_callback
1020)
1021{
1022    if (create_callback)
1023    {
1024        LanguageRuntimeInstance instance;
1025        assert ((bool)name);
1026        instance.name = name;
1027        if (description && description[0])
1028            instance.description = description;
1029        instance.create_callback = create_callback;
1030        instance.command_callback = command_callback;
1031        Mutex::Locker locker (GetLanguageRuntimeMutex ());
1032        GetLanguageRuntimeInstances ().push_back (instance);
1033    }
1034    return false;
1035}
1036
1037bool
1038PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
1039{
1040    if (create_callback)
1041    {
1042        Mutex::Locker locker (GetLanguageRuntimeMutex ());
1043        LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1044
1045        LanguageRuntimeInstances::iterator pos, end = instances.end();
1046        for (pos = instances.begin(); pos != end; ++ pos)
1047        {
1048            if (pos->create_callback == create_callback)
1049            {
1050                instances.erase(pos);
1051                return true;
1052            }
1053        }
1054    }
1055    return false;
1056}
1057
1058LanguageRuntimeCreateInstance
1059PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
1060{
1061    Mutex::Locker locker (GetLanguageRuntimeMutex ());
1062    LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1063    if (idx < instances.size())
1064        return instances[idx].create_callback;
1065    return NULL;
1066}
1067
1068LanguageRuntimeGetCommandObject
1069PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex (uint32_t idx)
1070{
1071    Mutex::Locker locker (GetLanguageRuntimeMutex ());
1072    LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1073    if (idx < instances.size())
1074        return instances[idx].command_callback;
1075    return NULL;
1076}
1077
1078LanguageRuntimeCreateInstance
1079PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
1080{
1081    if (name)
1082    {
1083        Mutex::Locker locker (GetLanguageRuntimeMutex ());
1084        LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
1085
1086        LanguageRuntimeInstances::iterator pos, end = instances.end();
1087        for (pos = instances.begin(); pos != end; ++ pos)
1088        {
1089            if (name == pos->name)
1090                return pos->create_callback;
1091        }
1092    }
1093    return NULL;
1094}
1095
1096#pragma mark SystemRuntime
1097
1098
1099struct SystemRuntimeInstance
1100{
1101    SystemRuntimeInstance() :
1102        name(),
1103        description(),
1104        create_callback(NULL)
1105    {
1106    }
1107
1108    ConstString name;
1109    std::string description;
1110    SystemRuntimeCreateInstance create_callback;
1111};
1112
1113typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
1114
1115static Mutex &
1116GetSystemRuntimeMutex ()
1117{
1118    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1119    return g_instances_mutex;
1120}
1121
1122static SystemRuntimeInstances &
1123GetSystemRuntimeInstances ()
1124{
1125    static SystemRuntimeInstances g_instances;
1126    return g_instances;
1127}
1128
1129bool
1130PluginManager::RegisterPlugin
1131(
1132    const ConstString &name,
1133    const char *description,
1134    SystemRuntimeCreateInstance create_callback
1135)
1136{
1137    if (create_callback)
1138    {
1139        SystemRuntimeInstance instance;
1140        assert ((bool)name);
1141        instance.name = name;
1142        if (description && description[0])
1143            instance.description = description;
1144        instance.create_callback = create_callback;
1145        Mutex::Locker locker (GetSystemRuntimeMutex ());
1146        GetSystemRuntimeInstances ().push_back (instance);
1147    }
1148    return false;
1149}
1150
1151bool
1152PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
1153{
1154    if (create_callback)
1155    {
1156        Mutex::Locker locker (GetSystemRuntimeMutex ());
1157        SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1158
1159        SystemRuntimeInstances::iterator pos, end = instances.end();
1160        for (pos = instances.begin(); pos != end; ++ pos)
1161        {
1162            if (pos->create_callback == create_callback)
1163            {
1164                instances.erase(pos);
1165                return true;
1166            }
1167        }
1168    }
1169    return false;
1170}
1171
1172SystemRuntimeCreateInstance
1173PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
1174{
1175    Mutex::Locker locker (GetSystemRuntimeMutex ());
1176    SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1177    if (idx < instances.size())
1178        return instances[idx].create_callback;
1179    return NULL;
1180}
1181
1182SystemRuntimeCreateInstance
1183PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
1184{
1185    if (name)
1186    {
1187        Mutex::Locker locker (GetSystemRuntimeMutex ());
1188        SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1189
1190        SystemRuntimeInstances::iterator pos, end = instances.end();
1191        for (pos = instances.begin(); pos != end; ++ pos)
1192        {
1193            if (name == pos->name)
1194                return pos->create_callback;
1195        }
1196    }
1197    return NULL;
1198}
1199
1200
1201#pragma mark ObjectFile
1202
1203struct ObjectFileInstance
1204{
1205    ObjectFileInstance() :
1206        name(),
1207        description(),
1208        create_callback(NULL),
1209        create_memory_callback (NULL),
1210        get_module_specifications (NULL),
1211        save_core (NULL)
1212    {
1213    }
1214
1215    ConstString name;
1216    std::string description;
1217    ObjectFileCreateInstance create_callback;
1218    ObjectFileCreateMemoryInstance create_memory_callback;
1219    ObjectFileGetModuleSpecifications get_module_specifications;
1220    ObjectFileSaveCore save_core;
1221};
1222
1223typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1224
1225static Mutex &
1226GetObjectFileMutex ()
1227{
1228    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1229    return g_instances_mutex;
1230}
1231
1232static ObjectFileInstances &
1233GetObjectFileInstances ()
1234{
1235    static ObjectFileInstances g_instances;
1236    return g_instances;
1237}
1238
1239
1240bool
1241PluginManager::RegisterPlugin (const ConstString &name,
1242                               const char *description,
1243                               ObjectFileCreateInstance create_callback,
1244                               ObjectFileCreateMemoryInstance create_memory_callback,
1245                               ObjectFileGetModuleSpecifications get_module_specifications,
1246                               ObjectFileSaveCore save_core)
1247{
1248    if (create_callback)
1249    {
1250        ObjectFileInstance instance;
1251        assert ((bool)name);
1252        instance.name = name;
1253        if (description && description[0])
1254            instance.description = description;
1255        instance.create_callback = create_callback;
1256        instance.create_memory_callback = create_memory_callback;
1257        instance.save_core = save_core;
1258        instance.get_module_specifications = get_module_specifications;
1259        Mutex::Locker locker (GetObjectFileMutex ());
1260        GetObjectFileInstances ().push_back (instance);
1261    }
1262    return false;
1263}
1264
1265bool
1266PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
1267{
1268    if (create_callback)
1269    {
1270        Mutex::Locker locker (GetObjectFileMutex ());
1271        ObjectFileInstances &instances = GetObjectFileInstances ();
1272
1273        ObjectFileInstances::iterator pos, end = instances.end();
1274        for (pos = instances.begin(); pos != end; ++ pos)
1275        {
1276            if (pos->create_callback == create_callback)
1277            {
1278                instances.erase(pos);
1279                return true;
1280            }
1281        }
1282    }
1283    return false;
1284}
1285
1286ObjectFileCreateInstance
1287PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
1288{
1289    Mutex::Locker locker (GetObjectFileMutex ());
1290    ObjectFileInstances &instances = GetObjectFileInstances ();
1291    if (idx < instances.size())
1292        return instances[idx].create_callback;
1293    return NULL;
1294}
1295
1296
1297ObjectFileCreateMemoryInstance
1298PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
1299{
1300    Mutex::Locker locker (GetObjectFileMutex ());
1301    ObjectFileInstances &instances = GetObjectFileInstances ();
1302    if (idx < instances.size())
1303        return instances[idx].create_memory_callback;
1304    return NULL;
1305}
1306
1307ObjectFileGetModuleSpecifications
1308PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1309{
1310    Mutex::Locker locker (GetObjectFileMutex ());
1311    ObjectFileInstances &instances = GetObjectFileInstances ();
1312    if (idx < instances.size())
1313        return instances[idx].get_module_specifications;
1314    return NULL;
1315}
1316
1317ObjectFileCreateInstance
1318PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
1319{
1320    if (name)
1321    {
1322        Mutex::Locker locker (GetObjectFileMutex ());
1323        ObjectFileInstances &instances = GetObjectFileInstances ();
1324
1325        ObjectFileInstances::iterator pos, end = instances.end();
1326        for (pos = instances.begin(); pos != end; ++ pos)
1327        {
1328            if (name == pos->name)
1329                return pos->create_callback;
1330        }
1331    }
1332    return NULL;
1333}
1334
1335
1336ObjectFileCreateMemoryInstance
1337PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
1338{
1339    if (name)
1340    {
1341        Mutex::Locker locker (GetObjectFileMutex ());
1342        ObjectFileInstances &instances = GetObjectFileInstances ();
1343
1344        ObjectFileInstances::iterator pos, end = instances.end();
1345        for (pos = instances.begin(); pos != end; ++ pos)
1346        {
1347            if (name == pos->name)
1348                return pos->create_memory_callback;
1349        }
1350    }
1351    return NULL;
1352}
1353
1354Error
1355PluginManager::SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile)
1356{
1357    Error error;
1358    Mutex::Locker locker (GetObjectFileMutex ());
1359    ObjectFileInstances &instances = GetObjectFileInstances ();
1360
1361    ObjectFileInstances::iterator pos, end = instances.end();
1362    for (pos = instances.begin(); pos != end; ++ pos)
1363    {
1364        if (pos->save_core && pos->save_core (process_sp, outfile, error))
1365            return error;
1366    }
1367    error.SetErrorString("no ObjectFile plugins were able to save a core for this process");
1368    return error;
1369}
1370
1371#pragma mark ObjectContainer
1372
1373struct ObjectContainerInstance
1374{
1375    ObjectContainerInstance() :
1376        name(),
1377        description(),
1378        create_callback (NULL),
1379        get_module_specifications (NULL)
1380    {
1381    }
1382
1383    ConstString name;
1384    std::string description;
1385    ObjectContainerCreateInstance create_callback;
1386    ObjectFileGetModuleSpecifications get_module_specifications;
1387
1388};
1389
1390typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1391
1392static Mutex &
1393GetObjectContainerMutex ()
1394{
1395    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1396    return g_instances_mutex;
1397}
1398
1399static ObjectContainerInstances &
1400GetObjectContainerInstances ()
1401{
1402    static ObjectContainerInstances g_instances;
1403    return g_instances;
1404}
1405
1406bool
1407PluginManager::RegisterPlugin (const ConstString &name,
1408                               const char *description,
1409                               ObjectContainerCreateInstance create_callback,
1410                               ObjectFileGetModuleSpecifications get_module_specifications)
1411{
1412    if (create_callback)
1413    {
1414        ObjectContainerInstance instance;
1415        assert ((bool)name);
1416        instance.name = name;
1417        if (description && description[0])
1418            instance.description = description;
1419        instance.create_callback = create_callback;
1420        instance.get_module_specifications = get_module_specifications;
1421        Mutex::Locker locker (GetObjectContainerMutex ());
1422        GetObjectContainerInstances ().push_back (instance);
1423    }
1424    return false;
1425}
1426
1427bool
1428PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1429{
1430    if (create_callback)
1431    {
1432        Mutex::Locker locker (GetObjectContainerMutex ());
1433        ObjectContainerInstances &instances = GetObjectContainerInstances ();
1434
1435        ObjectContainerInstances::iterator pos, end = instances.end();
1436        for (pos = instances.begin(); pos != end; ++ pos)
1437        {
1438            if (pos->create_callback == create_callback)
1439            {
1440                instances.erase(pos);
1441                return true;
1442            }
1443        }
1444    }
1445    return false;
1446}
1447
1448ObjectContainerCreateInstance
1449PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1450{
1451    Mutex::Locker locker (GetObjectContainerMutex ());
1452    ObjectContainerInstances &instances = GetObjectContainerInstances ();
1453    if (idx < instances.size())
1454        return instances[idx].create_callback;
1455    return NULL;
1456}
1457
1458ObjectContainerCreateInstance
1459PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
1460{
1461    if (name)
1462    {
1463        Mutex::Locker locker (GetObjectContainerMutex ());
1464        ObjectContainerInstances &instances = GetObjectContainerInstances ();
1465
1466        ObjectContainerInstances::iterator pos, end = instances.end();
1467        for (pos = instances.begin(); pos != end; ++ pos)
1468        {
1469            if (name == pos->name)
1470                return pos->create_callback;
1471        }
1472    }
1473    return NULL;
1474}
1475
1476ObjectFileGetModuleSpecifications
1477PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1478{
1479    Mutex::Locker locker (GetObjectContainerMutex ());
1480    ObjectContainerInstances &instances = GetObjectContainerInstances ();
1481    if (idx < instances.size())
1482        return instances[idx].get_module_specifications;
1483    return NULL;
1484}
1485
1486#pragma mark LogChannel
1487
1488struct LogInstance
1489{
1490    LogInstance() :
1491        name(),
1492        description(),
1493        create_callback(NULL)
1494    {
1495    }
1496
1497    ConstString name;
1498    std::string description;
1499    LogChannelCreateInstance create_callback;
1500};
1501
1502typedef std::vector<LogInstance> LogInstances;
1503
1504static Mutex &
1505GetLogMutex ()
1506{
1507    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1508    return g_instances_mutex;
1509}
1510
1511static LogInstances &
1512GetLogInstances ()
1513{
1514    static LogInstances g_instances;
1515    return g_instances;
1516}
1517
1518
1519
1520bool
1521PluginManager::RegisterPlugin
1522(
1523    const ConstString &name,
1524    const char *description,
1525    LogChannelCreateInstance create_callback
1526)
1527{
1528    if (create_callback)
1529    {
1530        LogInstance instance;
1531        assert ((bool)name);
1532        instance.name = name;
1533        if (description && description[0])
1534            instance.description = description;
1535        instance.create_callback = create_callback;
1536        Mutex::Locker locker (GetLogMutex ());
1537        GetLogInstances ().push_back (instance);
1538    }
1539    return false;
1540}
1541
1542bool
1543PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1544{
1545    if (create_callback)
1546    {
1547        Mutex::Locker locker (GetLogMutex ());
1548        LogInstances &instances = GetLogInstances ();
1549
1550        LogInstances::iterator pos, end = instances.end();
1551        for (pos = instances.begin(); pos != end; ++ pos)
1552        {
1553            if (pos->create_callback == create_callback)
1554            {
1555                instances.erase(pos);
1556                return true;
1557            }
1558        }
1559    }
1560    return false;
1561}
1562
1563const char *
1564PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1565{
1566    Mutex::Locker locker (GetLogMutex ());
1567    LogInstances &instances = GetLogInstances ();
1568    if (idx < instances.size())
1569        return instances[idx].name.GetCString();
1570    return NULL;
1571}
1572
1573
1574LogChannelCreateInstance
1575PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1576{
1577    Mutex::Locker locker (GetLogMutex ());
1578    LogInstances &instances = GetLogInstances ();
1579    if (idx < instances.size())
1580        return instances[idx].create_callback;
1581    return NULL;
1582}
1583
1584LogChannelCreateInstance
1585PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
1586{
1587    if (name)
1588    {
1589        Mutex::Locker locker (GetLogMutex ());
1590        LogInstances &instances = GetLogInstances ();
1591
1592        LogInstances::iterator pos, end = instances.end();
1593        for (pos = instances.begin(); pos != end; ++ pos)
1594        {
1595            if (name == pos->name)
1596                return pos->create_callback;
1597        }
1598    }
1599    return NULL;
1600}
1601
1602#pragma mark Platform
1603
1604struct PlatformInstance
1605{
1606    PlatformInstance() :
1607        name(),
1608        description(),
1609        create_callback(NULL),
1610        debugger_init_callback (NULL)
1611    {
1612    }
1613
1614    ConstString name;
1615    std::string description;
1616    PlatformCreateInstance create_callback;
1617    DebuggerInitializeCallback debugger_init_callback;
1618};
1619
1620typedef std::vector<PlatformInstance> PlatformInstances;
1621
1622static Mutex &
1623GetPlatformInstancesMutex ()
1624{
1625    static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1626    return g_platform_instances_mutex;
1627}
1628
1629static PlatformInstances &
1630GetPlatformInstances ()
1631{
1632    static PlatformInstances g_platform_instances;
1633    return g_platform_instances;
1634}
1635
1636
1637bool
1638PluginManager::RegisterPlugin (const ConstString &name,
1639                               const char *description,
1640                               PlatformCreateInstance create_callback,
1641                               DebuggerInitializeCallback debugger_init_callback)
1642{
1643    if (create_callback)
1644    {
1645        Mutex::Locker locker (GetPlatformInstancesMutex ());
1646
1647        PlatformInstance instance;
1648        assert ((bool)name);
1649        instance.name = name;
1650        if (description && description[0])
1651            instance.description = description;
1652        instance.create_callback = create_callback;
1653        instance.debugger_init_callback = debugger_init_callback;
1654        GetPlatformInstances ().push_back (instance);
1655        return true;
1656    }
1657    return false;
1658}
1659
1660
1661const char *
1662PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1663{
1664    Mutex::Locker locker (GetPlatformInstancesMutex ());
1665    PlatformInstances &instances = GetPlatformInstances ();
1666    if (idx < instances.size())
1667        return instances[idx].name.GetCString();
1668    return NULL;
1669}
1670
1671const char *
1672PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1673{
1674    Mutex::Locker locker (GetPlatformInstancesMutex ());
1675    PlatformInstances &instances = GetPlatformInstances ();
1676    if (idx < instances.size())
1677        return instances[idx].description.c_str();
1678    return NULL;
1679}
1680
1681bool
1682PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1683{
1684    if (create_callback)
1685    {
1686        Mutex::Locker locker (GetPlatformInstancesMutex ());
1687        PlatformInstances &instances = GetPlatformInstances ();
1688
1689        PlatformInstances::iterator pos, end = instances.end();
1690        for (pos = instances.begin(); pos != end; ++ pos)
1691        {
1692            if (pos->create_callback == create_callback)
1693            {
1694                instances.erase(pos);
1695                return true;
1696            }
1697        }
1698    }
1699    return false;
1700}
1701
1702PlatformCreateInstance
1703PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1704{
1705    Mutex::Locker locker (GetPlatformInstancesMutex ());
1706    PlatformInstances &instances = GetPlatformInstances ();
1707    if (idx < instances.size())
1708        return instances[idx].create_callback;
1709    return NULL;
1710}
1711
1712PlatformCreateInstance
1713PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
1714{
1715    if (name)
1716    {
1717        Mutex::Locker locker (GetPlatformInstancesMutex ());
1718        PlatformInstances &instances = GetPlatformInstances ();
1719
1720        PlatformInstances::iterator pos, end = instances.end();
1721        for (pos = instances.begin(); pos != end; ++ pos)
1722        {
1723            if (name == pos->name)
1724                return pos->create_callback;
1725        }
1726    }
1727    return NULL;
1728}
1729
1730size_t
1731PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1732{
1733    if (name)
1734    {
1735        Mutex::Locker locker (GetPlatformInstancesMutex ());
1736        PlatformInstances &instances = GetPlatformInstances ();
1737        llvm::StringRef name_sref(name);
1738
1739        PlatformInstances::iterator pos, end = instances.end();
1740        for (pos = instances.begin(); pos != end; ++ pos)
1741        {
1742            llvm::StringRef plugin_name (pos->name.GetCString());
1743            if (plugin_name.startswith(name_sref))
1744                matches.AppendString (plugin_name.data());
1745        }
1746    }
1747    return matches.GetSize();
1748}
1749#pragma mark Process
1750
1751struct ProcessInstance
1752{
1753    ProcessInstance() :
1754        name(),
1755        description(),
1756        create_callback(NULL),
1757        debugger_init_callback(NULL)
1758    {
1759    }
1760
1761    ConstString name;
1762    std::string description;
1763    ProcessCreateInstance create_callback;
1764    DebuggerInitializeCallback debugger_init_callback;
1765};
1766
1767typedef std::vector<ProcessInstance> ProcessInstances;
1768
1769static Mutex &
1770GetProcessMutex ()
1771{
1772    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1773    return g_instances_mutex;
1774}
1775
1776static ProcessInstances &
1777GetProcessInstances ()
1778{
1779    static ProcessInstances g_instances;
1780    return g_instances;
1781}
1782
1783
1784bool
1785PluginManager::RegisterPlugin (const ConstString &name,
1786                               const char *description,
1787                               ProcessCreateInstance create_callback,
1788                               DebuggerInitializeCallback debugger_init_callback)
1789{
1790    if (create_callback)
1791    {
1792        ProcessInstance instance;
1793        assert ((bool)name);
1794        instance.name = name;
1795        if (description && description[0])
1796            instance.description = description;
1797        instance.create_callback = create_callback;
1798        instance.debugger_init_callback = debugger_init_callback;
1799        Mutex::Locker locker (GetProcessMutex ());
1800        GetProcessInstances ().push_back (instance);
1801    }
1802    return false;
1803}
1804
1805const char *
1806PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1807{
1808    Mutex::Locker locker (GetProcessMutex ());
1809    ProcessInstances &instances = GetProcessInstances ();
1810    if (idx < instances.size())
1811        return instances[idx].name.GetCString();
1812    return NULL;
1813}
1814
1815const char *
1816PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1817{
1818    Mutex::Locker locker (GetProcessMutex ());
1819    ProcessInstances &instances = GetProcessInstances ();
1820    if (idx < instances.size())
1821        return instances[idx].description.c_str();
1822    return NULL;
1823}
1824
1825bool
1826PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1827{
1828    if (create_callback)
1829    {
1830        Mutex::Locker locker (GetProcessMutex ());
1831        ProcessInstances &instances = GetProcessInstances ();
1832
1833        ProcessInstances::iterator pos, end = instances.end();
1834        for (pos = instances.begin(); pos != end; ++ pos)
1835        {
1836            if (pos->create_callback == create_callback)
1837            {
1838                instances.erase(pos);
1839                return true;
1840            }
1841        }
1842    }
1843    return false;
1844}
1845
1846ProcessCreateInstance
1847PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1848{
1849    Mutex::Locker locker (GetProcessMutex ());
1850    ProcessInstances &instances = GetProcessInstances ();
1851    if (idx < instances.size())
1852        return instances[idx].create_callback;
1853    return NULL;
1854}
1855
1856
1857ProcessCreateInstance
1858PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
1859{
1860    if (name)
1861    {
1862        Mutex::Locker locker (GetProcessMutex ());
1863        ProcessInstances &instances = GetProcessInstances ();
1864
1865        ProcessInstances::iterator pos, end = instances.end();
1866        for (pos = instances.begin(); pos != end; ++ pos)
1867        {
1868            if (name == pos->name)
1869                return pos->create_callback;
1870        }
1871    }
1872    return NULL;
1873}
1874
1875#pragma mark ScriptInterpreter
1876
1877struct ScriptInterpreterInstance
1878{
1879    ScriptInterpreterInstance()
1880        : name()
1881        , language(lldb::eScriptLanguageNone)
1882        , description()
1883        , create_callback(NULL)
1884    {
1885    }
1886
1887    ConstString name;
1888    lldb::ScriptLanguage language;
1889    std::string description;
1890    ScriptInterpreterCreateInstance create_callback;
1891};
1892
1893typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
1894
1895static Mutex &
1896GetScriptInterpreterMutex()
1897{
1898    static Mutex g_instances_mutex(Mutex::eMutexTypeRecursive);
1899    return g_instances_mutex;
1900}
1901
1902static ScriptInterpreterInstances &
1903GetScriptInterpreterInstances()
1904{
1905    static ScriptInterpreterInstances g_instances;
1906    return g_instances;
1907}
1908
1909bool
1910PluginManager::RegisterPlugin(const ConstString &name, const char *description, lldb::ScriptLanguage script_language,
1911                              ScriptInterpreterCreateInstance create_callback)
1912{
1913    if (!create_callback)
1914        return false;
1915    ScriptInterpreterInstance instance;
1916    assert((bool)name);
1917    instance.name = name;
1918    if (description && description[0])
1919        instance.description = description;
1920    instance.create_callback = create_callback;
1921    instance.language = script_language;
1922    Mutex::Locker locker(GetScriptInterpreterMutex());
1923    GetScriptInterpreterInstances().push_back(instance);
1924    return false;
1925}
1926
1927bool
1928PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)
1929{
1930    if (!create_callback)
1931        return false;
1932    Mutex::Locker locker(GetScriptInterpreterMutex());
1933    ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1934
1935    ScriptInterpreterInstances::iterator pos, end = instances.end();
1936    for (pos = instances.begin(); pos != end; ++pos)
1937    {
1938        if (pos->create_callback != create_callback)
1939            continue;
1940
1941        instances.erase(pos);
1942        return true;
1943    }
1944    return false;
1945}
1946
1947ScriptInterpreterCreateInstance
1948PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)
1949{
1950    Mutex::Locker locker(GetScriptInterpreterMutex());
1951    ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1952    if (idx < instances.size())
1953        return instances[idx].create_callback;
1954    return nullptr;
1955}
1956
1957lldb::ScriptInterpreterSP
1958PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter)
1959{
1960    Mutex::Locker locker(GetScriptInterpreterMutex());
1961    ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1962
1963    ScriptInterpreterInstances::iterator pos, end = instances.end();
1964    ScriptInterpreterCreateInstance none_instance = nullptr;
1965    for (pos = instances.begin(); pos != end; ++pos)
1966    {
1967        if (pos->language == lldb::eScriptLanguageNone)
1968            none_instance = pos->create_callback;
1969
1970        if (script_lang == pos->language)
1971            return pos->create_callback(interpreter);
1972    }
1973
1974    // If we didn't find one, return the ScriptInterpreter for the null language.
1975    assert(none_instance != nullptr);
1976    return none_instance(interpreter);
1977}
1978
1979#pragma mark SymbolFile
1980
1981struct SymbolFileInstance
1982{
1983    SymbolFileInstance() :
1984        name(),
1985        description(),
1986        create_callback(nullptr),
1987        debugger_init_callback(nullptr)
1988    {
1989    }
1990
1991    ConstString name;
1992    std::string description;
1993    SymbolFileCreateInstance create_callback;
1994    DebuggerInitializeCallback debugger_init_callback;
1995};
1996
1997typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1998
1999static Mutex &
2000GetSymbolFileMutex ()
2001{
2002    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2003    return g_instances_mutex;
2004}
2005
2006static SymbolFileInstances &
2007GetSymbolFileInstances ()
2008{
2009    static SymbolFileInstances g_instances;
2010    return g_instances;
2011}
2012
2013
2014bool
2015PluginManager::RegisterPlugin
2016(
2017    const ConstString &name,
2018    const char *description,
2019    SymbolFileCreateInstance create_callback,
2020    DebuggerInitializeCallback debugger_init_callback
2021)
2022{
2023    if (create_callback)
2024    {
2025        SymbolFileInstance instance;
2026        assert ((bool)name);
2027        instance.name = name;
2028        if (description && description[0])
2029            instance.description = description;
2030        instance.create_callback = create_callback;
2031        instance.debugger_init_callback = debugger_init_callback;
2032        Mutex::Locker locker (GetSymbolFileMutex ());
2033        GetSymbolFileInstances ().push_back (instance);
2034    }
2035    return false;
2036}
2037
2038bool
2039PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
2040{
2041    if (create_callback)
2042    {
2043        Mutex::Locker locker (GetSymbolFileMutex ());
2044        SymbolFileInstances &instances = GetSymbolFileInstances ();
2045
2046        SymbolFileInstances::iterator pos, end = instances.end();
2047        for (pos = instances.begin(); pos != end; ++ pos)
2048        {
2049            if (pos->create_callback == create_callback)
2050            {
2051                instances.erase(pos);
2052                return true;
2053            }
2054        }
2055    }
2056    return false;
2057}
2058
2059SymbolFileCreateInstance
2060PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
2061{
2062    Mutex::Locker locker (GetSymbolFileMutex ());
2063    SymbolFileInstances &instances = GetSymbolFileInstances ();
2064    if (idx < instances.size())
2065        return instances[idx].create_callback;
2066    return NULL;
2067}
2068
2069SymbolFileCreateInstance
2070PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
2071{
2072    if (name)
2073    {
2074        Mutex::Locker locker (GetSymbolFileMutex ());
2075        SymbolFileInstances &instances = GetSymbolFileInstances ();
2076
2077        SymbolFileInstances::iterator pos, end = instances.end();
2078        for (pos = instances.begin(); pos != end; ++ pos)
2079        {
2080            if (name == pos->name)
2081                return pos->create_callback;
2082        }
2083    }
2084    return NULL;
2085}
2086
2087
2088
2089#pragma mark SymbolVendor
2090
2091struct SymbolVendorInstance
2092{
2093    SymbolVendorInstance() :
2094        name(),
2095        description(),
2096        create_callback(NULL)
2097    {
2098    }
2099
2100    ConstString name;
2101    std::string description;
2102    SymbolVendorCreateInstance create_callback;
2103};
2104
2105typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
2106
2107static Mutex &
2108GetSymbolVendorMutex ()
2109{
2110    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2111    return g_instances_mutex;
2112}
2113
2114static SymbolVendorInstances &
2115GetSymbolVendorInstances ()
2116{
2117    static SymbolVendorInstances g_instances;
2118    return g_instances;
2119}
2120
2121bool
2122PluginManager::RegisterPlugin
2123(
2124    const ConstString &name,
2125    const char *description,
2126    SymbolVendorCreateInstance create_callback
2127)
2128{
2129    if (create_callback)
2130    {
2131        SymbolVendorInstance instance;
2132        assert ((bool)name);
2133        instance.name = name;
2134        if (description && description[0])
2135            instance.description = description;
2136        instance.create_callback = create_callback;
2137        Mutex::Locker locker (GetSymbolVendorMutex ());
2138        GetSymbolVendorInstances ().push_back (instance);
2139    }
2140    return false;
2141}
2142
2143bool
2144PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
2145{
2146    if (create_callback)
2147    {
2148        Mutex::Locker locker (GetSymbolVendorMutex ());
2149        SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2150
2151        SymbolVendorInstances::iterator pos, end = instances.end();
2152        for (pos = instances.begin(); pos != end; ++ pos)
2153        {
2154            if (pos->create_callback == create_callback)
2155            {
2156                instances.erase(pos);
2157                return true;
2158            }
2159        }
2160    }
2161    return false;
2162}
2163
2164SymbolVendorCreateInstance
2165PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
2166{
2167    Mutex::Locker locker (GetSymbolVendorMutex ());
2168    SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2169    if (idx < instances.size())
2170        return instances[idx].create_callback;
2171    return NULL;
2172}
2173
2174
2175SymbolVendorCreateInstance
2176PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
2177{
2178    if (name)
2179    {
2180        Mutex::Locker locker (GetSymbolVendorMutex ());
2181        SymbolVendorInstances &instances = GetSymbolVendorInstances ();
2182
2183        SymbolVendorInstances::iterator pos, end = instances.end();
2184        for (pos = instances.begin(); pos != end; ++ pos)
2185        {
2186            if (name == pos->name)
2187                return pos->create_callback;
2188        }
2189    }
2190    return NULL;
2191}
2192
2193
2194#pragma mark UnwindAssembly
2195
2196struct UnwindAssemblyInstance
2197{
2198    UnwindAssemblyInstance() :
2199        name(),
2200        description(),
2201        create_callback(NULL)
2202    {
2203    }
2204
2205    ConstString name;
2206    std::string description;
2207    UnwindAssemblyCreateInstance create_callback;
2208};
2209
2210typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
2211
2212static Mutex &
2213GetUnwindAssemblyMutex ()
2214{
2215    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2216    return g_instances_mutex;
2217}
2218
2219static UnwindAssemblyInstances &
2220GetUnwindAssemblyInstances ()
2221{
2222    static UnwindAssemblyInstances g_instances;
2223    return g_instances;
2224}
2225
2226bool
2227PluginManager::RegisterPlugin
2228(
2229    const ConstString &name,
2230    const char *description,
2231    UnwindAssemblyCreateInstance create_callback
2232)
2233{
2234    if (create_callback)
2235    {
2236        UnwindAssemblyInstance instance;
2237        assert ((bool)name);
2238        instance.name = name;
2239        if (description && description[0])
2240            instance.description = description;
2241        instance.create_callback = create_callback;
2242        Mutex::Locker locker (GetUnwindAssemblyMutex ());
2243        GetUnwindAssemblyInstances ().push_back (instance);
2244    }
2245    return false;
2246}
2247
2248bool
2249PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
2250{
2251    if (create_callback)
2252    {
2253        Mutex::Locker locker (GetUnwindAssemblyMutex ());
2254        UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2255
2256        UnwindAssemblyInstances::iterator pos, end = instances.end();
2257        for (pos = instances.begin(); pos != end; ++ pos)
2258        {
2259            if (pos->create_callback == create_callback)
2260            {
2261                instances.erase(pos);
2262                return true;
2263            }
2264        }
2265    }
2266    return false;
2267}
2268
2269UnwindAssemblyCreateInstance
2270PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
2271{
2272    Mutex::Locker locker (GetUnwindAssemblyMutex ());
2273    UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2274    if (idx < instances.size())
2275        return instances[idx].create_callback;
2276    return NULL;
2277}
2278
2279
2280UnwindAssemblyCreateInstance
2281PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
2282{
2283    if (name)
2284    {
2285        Mutex::Locker locker (GetUnwindAssemblyMutex ());
2286        UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2287
2288        UnwindAssemblyInstances::iterator pos, end = instances.end();
2289        for (pos = instances.begin(); pos != end; ++ pos)
2290        {
2291            if (name == pos->name)
2292                return pos->create_callback;
2293        }
2294    }
2295    return NULL;
2296}
2297
2298#pragma mark MemoryHistory
2299
2300struct MemoryHistoryInstance
2301{
2302    MemoryHistoryInstance() :
2303    name(),
2304    description(),
2305    create_callback(NULL)
2306    {
2307    }
2308
2309    ConstString name;
2310    std::string description;
2311    MemoryHistoryCreateInstance create_callback;
2312};
2313
2314typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
2315
2316static Mutex &
2317GetMemoryHistoryMutex ()
2318{
2319    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2320    return g_instances_mutex;
2321}
2322
2323static MemoryHistoryInstances &
2324GetMemoryHistoryInstances ()
2325{
2326    static MemoryHistoryInstances g_instances;
2327    return g_instances;
2328}
2329
2330bool
2331PluginManager::RegisterPlugin
2332(
2333 const ConstString &name,
2334 const char *description,
2335 MemoryHistoryCreateInstance create_callback
2336 )
2337{
2338    if (create_callback)
2339    {
2340        MemoryHistoryInstance instance;
2341        assert ((bool)name);
2342        instance.name = name;
2343        if (description && description[0])
2344            instance.description = description;
2345        instance.create_callback = create_callback;
2346        Mutex::Locker locker (GetMemoryHistoryMutex ());
2347        GetMemoryHistoryInstances ().push_back (instance);
2348    }
2349    return false;
2350}
2351
2352bool
2353PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
2354{
2355    if (create_callback)
2356    {
2357        Mutex::Locker locker (GetMemoryHistoryMutex ());
2358        MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2359
2360        MemoryHistoryInstances::iterator pos, end = instances.end();
2361        for (pos = instances.begin(); pos != end; ++ pos)
2362        {
2363            if (pos->create_callback == create_callback)
2364            {
2365                instances.erase(pos);
2366                return true;
2367            }
2368        }
2369    }
2370    return false;
2371}
2372
2373MemoryHistoryCreateInstance
2374PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
2375{
2376    Mutex::Locker locker (GetMemoryHistoryMutex ());
2377    MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2378    if (idx < instances.size())
2379        return instances[idx].create_callback;
2380    return NULL;
2381}
2382
2383
2384MemoryHistoryCreateInstance
2385PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name)
2386{
2387    if (name)
2388    {
2389        Mutex::Locker locker (GetMemoryHistoryMutex ());
2390        MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2391
2392        MemoryHistoryInstances::iterator pos, end = instances.end();
2393        for (pos = instances.begin(); pos != end; ++ pos)
2394        {
2395            if (name == pos->name)
2396                return pos->create_callback;
2397        }
2398    }
2399    return NULL;
2400}
2401
2402#pragma mark InstrumentationRuntime
2403
2404struct InstrumentationRuntimeInstance
2405{
2406    InstrumentationRuntimeInstance() :
2407    name(),
2408    description(),
2409    create_callback(NULL)
2410    {
2411    }
2412
2413    ConstString name;
2414    std::string description;
2415    InstrumentationRuntimeCreateInstance create_callback;
2416    InstrumentationRuntimeGetType get_type_callback;
2417};
2418
2419typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances;
2420
2421static Mutex &
2422GetInstrumentationRuntimeMutex ()
2423{
2424    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2425    return g_instances_mutex;
2426}
2427
2428static InstrumentationRuntimeInstances &
2429GetInstrumentationRuntimeInstances ()
2430{
2431    static InstrumentationRuntimeInstances g_instances;
2432    return g_instances;
2433}
2434
2435bool
2436PluginManager::RegisterPlugin
2437(
2438 const ConstString &name,
2439 const char *description,
2440 InstrumentationRuntimeCreateInstance create_callback,
2441 InstrumentationRuntimeGetType get_type_callback
2442 )
2443{
2444    if (create_callback)
2445    {
2446        InstrumentationRuntimeInstance instance;
2447        assert ((bool)name);
2448        instance.name = name;
2449        if (description && description[0])
2450            instance.description = description;
2451        instance.create_callback = create_callback;
2452        instance.get_type_callback = get_type_callback;
2453        Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2454        GetInstrumentationRuntimeInstances ().push_back (instance);
2455    }
2456    return false;
2457}
2458
2459bool
2460PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback)
2461{
2462    if (create_callback)
2463    {
2464        Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2465        InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2466
2467        InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2468        for (pos = instances.begin(); pos != end; ++ pos)
2469        {
2470            if (pos->create_callback == create_callback)
2471            {
2472                instances.erase(pos);
2473                return true;
2474            }
2475        }
2476    }
2477    return false;
2478}
2479
2480InstrumentationRuntimeGetType
2481PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx)
2482{
2483    Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2484    InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2485    if (idx < instances.size())
2486        return instances[idx].get_type_callback;
2487    return NULL;
2488}
2489
2490InstrumentationRuntimeCreateInstance
2491PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx)
2492{
2493    Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2494    InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2495    if (idx < instances.size())
2496        return instances[idx].create_callback;
2497    return NULL;
2498}
2499
2500
2501InstrumentationRuntimeCreateInstance
2502PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name)
2503{
2504    if (name)
2505    {
2506        Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2507        InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2508
2509        InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2510        for (pos = instances.begin(); pos != end; ++ pos)
2511        {
2512            if (name == pos->name)
2513                return pos->create_callback;
2514        }
2515    }
2516    return NULL;
2517}
2518
2519#pragma mark TypeSystem
2520
2521
2522struct TypeSystemInstance
2523{
2524    TypeSystemInstance() :
2525    name(),
2526    description(),
2527    create_callback(NULL)
2528    {
2529    }
2530
2531    ConstString name;
2532    std::string description;
2533    TypeSystemCreateInstance create_callback;
2534    TypeSystemEnumerateSupportedLanguages enumerate_callback;
2535};
2536
2537typedef std::vector<TypeSystemInstance> TypeSystemInstances;
2538
2539static Mutex &
2540GetTypeSystemMutex ()
2541{
2542    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2543    return g_instances_mutex;
2544}
2545
2546static TypeSystemInstances &
2547GetTypeSystemInstances ()
2548{
2549    static TypeSystemInstances g_instances;
2550    return g_instances;
2551}
2552
2553bool
2554PluginManager::RegisterPlugin (const ConstString &name,
2555                               const char *description,
2556                               TypeSystemCreateInstance create_callback,
2557                               TypeSystemEnumerateSupportedLanguages enumerate_supported_languages_callback)
2558{
2559    if (create_callback)
2560    {
2561        TypeSystemInstance instance;
2562        assert ((bool)name);
2563        instance.name = name;
2564        if (description && description[0])
2565            instance.description = description;
2566        instance.create_callback = create_callback;
2567        instance.enumerate_callback = enumerate_supported_languages_callback;
2568        Mutex::Locker locker (GetTypeSystemMutex ());
2569        GetTypeSystemInstances ().push_back (instance);
2570    }
2571    return false;
2572}
2573
2574bool
2575PluginManager::UnregisterPlugin (TypeSystemCreateInstance create_callback)
2576{
2577    if (create_callback)
2578    {
2579        Mutex::Locker locker (GetTypeSystemMutex ());
2580        TypeSystemInstances &instances = GetTypeSystemInstances ();
2581
2582        TypeSystemInstances::iterator pos, end = instances.end();
2583        for (pos = instances.begin(); pos != end; ++ pos)
2584        {
2585            if (pos->create_callback == create_callback)
2586            {
2587                instances.erase(pos);
2588                return true;
2589            }
2590        }
2591    }
2592    return false;
2593}
2594
2595TypeSystemCreateInstance
2596PluginManager::GetTypeSystemCreateCallbackAtIndex (uint32_t idx)
2597{
2598    Mutex::Locker locker (GetTypeSystemMutex ());
2599    TypeSystemInstances &instances = GetTypeSystemInstances ();
2600    if (idx < instances.size())
2601        return instances[idx].create_callback;
2602    return NULL;
2603}
2604
2605TypeSystemCreateInstance
2606PluginManager::GetTypeSystemCreateCallbackForPluginName (const ConstString &name)
2607{
2608    if (name)
2609    {
2610        Mutex::Locker locker (GetTypeSystemMutex ());
2611        TypeSystemInstances &instances = GetTypeSystemInstances ();
2612
2613        TypeSystemInstances::iterator pos, end = instances.end();
2614        for (pos = instances.begin(); pos != end; ++ pos)
2615        {
2616            if (name == pos->name)
2617                return pos->create_callback;
2618        }
2619    }
2620    return NULL;
2621}
2622
2623TypeSystemEnumerateSupportedLanguages
2624PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
2625{
2626    Mutex::Locker locker (GetTypeSystemMutex ());
2627    TypeSystemInstances &instances = GetTypeSystemInstances ();
2628    if (idx < instances.size())
2629        return instances[idx].enumerate_callback;
2630    return NULL;
2631}
2632
2633TypeSystemEnumerateSupportedLanguages
2634PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name)
2635{
2636    if (name)
2637    {
2638        Mutex::Locker locker (GetTypeSystemMutex ());
2639        TypeSystemInstances &instances = GetTypeSystemInstances ();
2640
2641        TypeSystemInstances::iterator pos, end = instances.end();
2642        for (pos = instances.begin(); pos != end; ++ pos)
2643        {
2644            if (name == pos->name)
2645                return pos->enumerate_callback;
2646        }
2647    }
2648    return NULL;
2649}
2650
2651#pragma mark REPL
2652
2653struct REPLInstance
2654{
2655    REPLInstance() :
2656    name(),
2657    description(),
2658    create_callback(NULL)
2659    {
2660    }
2661
2662    ConstString name;
2663    std::string description;
2664    REPLCreateInstance create_callback;
2665    REPLEnumerateSupportedLanguages enumerate_languages_callback;
2666};
2667
2668typedef std::vector<REPLInstance> REPLInstances;
2669
2670static Mutex &
2671GetREPLMutex ()
2672{
2673    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2674    return g_instances_mutex;
2675}
2676
2677static REPLInstances &
2678GetREPLInstances ()
2679{
2680    static REPLInstances g_instances;
2681    return g_instances;
2682}
2683
2684bool
2685PluginManager::RegisterPlugin (const ConstString &name,
2686                               const char *description,
2687                               REPLCreateInstance create_callback,
2688                               REPLEnumerateSupportedLanguages enumerate_languages_callback)
2689{
2690    if (create_callback)
2691    {
2692        REPLInstance instance;
2693        assert ((bool)name);
2694        instance.name = name;
2695        if (description && description[0])
2696            instance.description = description;
2697        instance.create_callback = create_callback;
2698        instance.enumerate_languages_callback = enumerate_languages_callback;
2699        Mutex::Locker locker (GetREPLMutex ());
2700        GetREPLInstances ().push_back (instance);
2701    }
2702    return false;
2703}
2704
2705bool
2706PluginManager::UnregisterPlugin (REPLCreateInstance create_callback)
2707{
2708    if (create_callback)
2709    {
2710        Mutex::Locker locker (GetREPLMutex ());
2711        REPLInstances &instances = GetREPLInstances ();
2712
2713        REPLInstances::iterator pos, end = instances.end();
2714        for (pos = instances.begin(); pos != end; ++ pos)
2715        {
2716            if (pos->create_callback == create_callback)
2717            {
2718                instances.erase(pos);
2719                return true;
2720            }
2721        }
2722    }
2723    return false;
2724}
2725
2726REPLCreateInstance
2727PluginManager::GetREPLCreateCallbackAtIndex (uint32_t idx)
2728{
2729    Mutex::Locker locker (GetREPLMutex ());
2730    REPLInstances &instances = GetREPLInstances ();
2731    if (idx < instances.size())
2732        return instances[idx].create_callback;
2733    return NULL;
2734}
2735
2736REPLCreateInstance
2737PluginManager::GetREPLCreateCallbackForPluginName (const ConstString &name)
2738{
2739    if (name)
2740    {
2741        Mutex::Locker locker (GetREPLMutex ());
2742        REPLInstances &instances = GetREPLInstances ();
2743
2744        REPLInstances::iterator pos, end = instances.end();
2745        for (pos = instances.begin(); pos != end; ++ pos)
2746        {
2747            if (name == pos->name)
2748                return pos->create_callback;
2749        }
2750    }
2751    return NULL;
2752}
2753
2754REPLEnumerateSupportedLanguages
2755PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
2756{
2757    Mutex::Locker locker (GetREPLMutex ());
2758    REPLInstances &instances = GetREPLInstances ();
2759    if (idx < instances.size())
2760        return instances[idx].enumerate_languages_callback;
2761    return NULL;
2762}
2763
2764
2765REPLEnumerateSupportedLanguages
2766PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name)
2767{
2768    if (name)
2769    {
2770        Mutex::Locker locker (GetREPLMutex ());
2771        REPLInstances &instances = GetREPLInstances ();
2772
2773        REPLInstances::iterator pos, end = instances.end();
2774        for (pos = instances.begin(); pos != end; ++ pos)
2775        {
2776            if (name == pos->name)
2777                return pos->enumerate_languages_callback;
2778        }
2779    }
2780    return NULL;
2781}
2782
2783#pragma mark PluginManager
2784
2785void
2786PluginManager::DebuggerInitialize (Debugger &debugger)
2787{
2788    // Initialize the DynamicLoader plugins
2789    {
2790        Mutex::Locker locker (GetDynamicLoaderMutex ());
2791        DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
2792
2793        DynamicLoaderInstances::iterator pos, end = instances.end();
2794        for (pos = instances.begin(); pos != end; ++ pos)
2795        {
2796            if (pos->debugger_init_callback)
2797                pos->debugger_init_callback (debugger);
2798        }
2799    }
2800
2801    // Initialize the JITLoader plugins
2802    {
2803        Mutex::Locker locker (GetJITLoaderMutex ());
2804        JITLoaderInstances &instances = GetJITLoaderInstances ();
2805
2806        JITLoaderInstances::iterator pos, end = instances.end();
2807        for (pos = instances.begin(); pos != end; ++ pos)
2808        {
2809            if (pos->debugger_init_callback)
2810                pos->debugger_init_callback (debugger);
2811        }
2812    }
2813
2814    // Initialize the Platform plugins
2815    {
2816        Mutex::Locker locker (GetPlatformInstancesMutex ());
2817        PlatformInstances &instances = GetPlatformInstances ();
2818
2819        PlatformInstances::iterator pos, end = instances.end();
2820        for (pos = instances.begin(); pos != end; ++ pos)
2821        {
2822            if (pos->debugger_init_callback)
2823                pos->debugger_init_callback (debugger);
2824        }
2825    }
2826
2827    // Initialize the Process plugins
2828    {
2829        Mutex::Locker locker (GetProcessMutex());
2830        ProcessInstances &instances = GetProcessInstances();
2831
2832        ProcessInstances::iterator pos, end = instances.end();
2833        for (pos = instances.begin(); pos != end; ++ pos)
2834        {
2835            if (pos->debugger_init_callback)
2836                pos->debugger_init_callback (debugger);
2837        }
2838    }
2839
2840    // Initialize the SymbolFile plugins
2841    {
2842        Mutex::Locker locker (GetSymbolFileMutex());
2843        for (auto& sym_file: GetSymbolFileInstances())
2844        {
2845            if (sym_file.debugger_init_callback)
2846                sym_file.debugger_init_callback (debugger);
2847        }
2848    }
2849
2850    // Initialize the OperatingSystem plugins
2851    {
2852        Mutex::Locker locker(GetOperatingSystemMutex());
2853        for (auto &os : GetOperatingSystemInstances())
2854        {
2855            if (os.debugger_init_callback)
2856                os.debugger_init_callback(debugger);
2857        }
2858    }
2859}
2860
2861// This is the preferred new way to register plugin specific settings.  e.g.
2862// This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2863static lldb::OptionValuePropertiesSP
2864GetDebuggerPropertyForPlugins (Debugger &debugger,
2865                                       const ConstString &plugin_type_name,
2866                                       const ConstString &plugin_type_desc,
2867                                       bool can_create)
2868{
2869    lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2870    if (parent_properties_sp)
2871    {
2872        static ConstString g_property_name("plugin");
2873
2874        OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
2875        if (!plugin_properties_sp && can_create)
2876        {
2877            plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
2878            parent_properties_sp->AppendProperty (g_property_name,
2879                                                  ConstString("Settings specify to plugins."),
2880                                                  true,
2881                                                  plugin_properties_sp);
2882        }
2883
2884        if (plugin_properties_sp)
2885        {
2886            lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
2887            if (!plugin_type_properties_sp && can_create)
2888            {
2889                plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2890                plugin_properties_sp->AppendProperty (plugin_type_name,
2891                                                      plugin_type_desc,
2892                                                      true,
2893                                                      plugin_type_properties_sp);
2894            }
2895            return plugin_type_properties_sp;
2896        }
2897    }
2898    return lldb::OptionValuePropertiesSP();
2899}
2900
2901// This is deprecated way to register plugin specific settings.  e.g.
2902// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
2903// and Platform generic settings would be under "platform.SETTINGNAME".
2904static lldb::OptionValuePropertiesSP
2905GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
2906                                       const ConstString &plugin_type_name,
2907                                       const ConstString &plugin_type_desc,
2908                                       bool can_create)
2909{
2910    static ConstString g_property_name("plugin");
2911    lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2912    if (parent_properties_sp)
2913    {
2914        OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
2915        if (!plugin_properties_sp && can_create)
2916        {
2917            plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2918            parent_properties_sp->AppendProperty (plugin_type_name,
2919                                                  plugin_type_desc,
2920                                                  true,
2921                                                  plugin_properties_sp);
2922        }
2923
2924        if (plugin_properties_sp)
2925        {
2926            lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
2927            if (!plugin_type_properties_sp && can_create)
2928            {
2929                plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
2930                plugin_properties_sp->AppendProperty (g_property_name,
2931                                                      ConstString("Settings specific to plugins"),
2932                                                      true,
2933                                                      plugin_type_properties_sp);
2934            }
2935            return plugin_type_properties_sp;
2936        }
2937    }
2938    return lldb::OptionValuePropertiesSP();
2939}
2940
2941namespace {
2942
2943typedef lldb::OptionValuePropertiesSP
2944GetDebuggerPropertyForPluginsPtr (Debugger&, const ConstString&, const ConstString&, bool can_create);
2945
2946lldb::OptionValuePropertiesSP
2947GetSettingForPlugin (Debugger &debugger,
2948                     const ConstString &setting_name,
2949                     const ConstString &plugin_type_name,
2950                     GetDebuggerPropertyForPluginsPtr get_debugger_property= GetDebuggerPropertyForPlugins)
2951{
2952    lldb::OptionValuePropertiesSP properties_sp;
2953    lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (debugger,
2954                                                                                    plugin_type_name,
2955                                                                                    ConstString(), // not creating to so we don't need the description
2956                                                                                    false));
2957    if (plugin_type_properties_sp)
2958        properties_sp = plugin_type_properties_sp->GetSubProperty (nullptr, setting_name);
2959    return properties_sp;
2960}
2961
2962bool
2963CreateSettingForPlugin (Debugger &debugger,
2964                        const ConstString &plugin_type_name,
2965                        const ConstString &plugin_type_desc,
2966                        const lldb::OptionValuePropertiesSP &properties_sp,
2967                        const ConstString &description,
2968                        bool is_global_property,
2969                        GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins)
2970{
2971    if (properties_sp)
2972    {
2973        lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (
2974            debugger, plugin_type_name, plugin_type_desc, true));
2975        if (plugin_type_properties_sp)
2976        {
2977            plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2978                                                       description,
2979                                                       is_global_property,
2980                                                       properties_sp);
2981            return true;
2982        }
2983    }
2984    return false;
2985}
2986
2987const char* kDynamicLoaderPluginName("dynamic-loader");
2988const char* kPlatformPluginName("platform");
2989const char* kProcessPluginName("process");
2990const char* kSymbolFilePluginName("symbol-file");
2991const char* kJITLoaderPluginName("jit-loader");
2992
2993}
2994
2995lldb::OptionValuePropertiesSP
2996PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger,
2997                                                 const ConstString &setting_name)
2998{
2999    return GetSettingForPlugin(debugger, setting_name, ConstString(kDynamicLoaderPluginName));
3000}
3001
3002bool
3003PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
3004                                                    const lldb::OptionValuePropertiesSP &properties_sp,
3005                                                    const ConstString &description,
3006                                                    bool is_global_property)
3007{
3008    return CreateSettingForPlugin(debugger,
3009                                  ConstString(kDynamicLoaderPluginName),
3010                                  ConstString("Settings for dynamic loader plug-ins"),
3011                                  properties_sp,
3012                                  description,
3013                                  is_global_property);
3014}
3015
3016
3017lldb::OptionValuePropertiesSP
3018PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
3019{
3020    return GetSettingForPlugin(debugger,
3021                               setting_name,
3022                               ConstString(kPlatformPluginName),
3023                               GetDebuggerPropertyForPluginsOldStyle);
3024}
3025
3026bool
3027PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
3028                                               const lldb::OptionValuePropertiesSP &properties_sp,
3029                                               const ConstString &description,
3030                                               bool is_global_property)
3031{
3032    return CreateSettingForPlugin(debugger,
3033                                  ConstString(kPlatformPluginName),
3034                                  ConstString("Settings for platform plug-ins"),
3035                                  properties_sp,
3036                                  description,
3037                                  is_global_property,
3038                                  GetDebuggerPropertyForPluginsOldStyle);
3039}
3040
3041
3042lldb::OptionValuePropertiesSP
3043PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
3044{
3045    return GetSettingForPlugin(debugger, setting_name, ConstString(kProcessPluginName));
3046}
3047
3048bool
3049PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
3050                                              const lldb::OptionValuePropertiesSP &properties_sp,
3051                                              const ConstString &description,
3052                                              bool is_global_property)
3053{
3054    return CreateSettingForPlugin(debugger,
3055                                  ConstString(kProcessPluginName),
3056                                  ConstString("Settings for process plug-ins"),
3057                                  properties_sp,
3058                                  description,
3059                                  is_global_property);
3060}
3061
3062lldb::OptionValuePropertiesSP
3063PluginManager::GetSettingForSymbolFilePlugin (Debugger &debugger,
3064                                              const ConstString &setting_name)
3065{
3066    return GetSettingForPlugin(debugger, setting_name, ConstString(kSymbolFilePluginName));
3067}
3068
3069bool
3070PluginManager::CreateSettingForSymbolFilePlugin (Debugger &debugger,
3071                                                 const lldb::OptionValuePropertiesSP &properties_sp,
3072                                                 const ConstString &description,
3073                                                 bool is_global_property)
3074{
3075    return CreateSettingForPlugin(debugger,
3076                                  ConstString(kSymbolFilePluginName),
3077                                  ConstString("Settings for symbol file plug-ins"),
3078                                  properties_sp,
3079                                  description,
3080                                  is_global_property);
3081}
3082
3083lldb::OptionValuePropertiesSP
3084PluginManager::GetSettingForJITLoaderPlugin (Debugger &debugger,
3085                                             const ConstString &setting_name)
3086{
3087    return GetSettingForPlugin(debugger, setting_name, ConstString(kJITLoaderPluginName));
3088}
3089
3090bool
3091PluginManager::CreateSettingForJITLoaderPlugin (Debugger &debugger,
3092                                                const lldb::OptionValuePropertiesSP &properties_sp,
3093                                                const ConstString &description,
3094                                                bool is_global_property)
3095{
3096    return CreateSettingForPlugin(debugger,
3097                                  ConstString(kJITLoaderPluginName),
3098                                  ConstString("Settings for JIT loader plug-ins"),
3099                                  properties_sp,
3100                                  description,
3101                                  is_global_property);
3102}
3103
3104static const char *kOperatingSystemPluginName("os");
3105
3106lldb::OptionValuePropertiesSP
3107PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, const ConstString &setting_name)
3108{
3109    lldb::OptionValuePropertiesSP properties_sp;
3110    lldb::OptionValuePropertiesSP plugin_type_properties_sp(
3111        GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName),
3112                                      ConstString(), // not creating to so we don't need the description
3113                                      false));
3114    if (plugin_type_properties_sp)
3115        properties_sp = plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
3116    return properties_sp;
3117}
3118
3119bool
3120PluginManager::CreateSettingForOperatingSystemPlugin(Debugger &debugger,
3121                                                     const lldb::OptionValuePropertiesSP &properties_sp,
3122                                                     const ConstString &description, bool is_global_property)
3123{
3124    if (properties_sp)
3125    {
3126        lldb::OptionValuePropertiesSP plugin_type_properties_sp(
3127            GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName),
3128                                          ConstString("Settings for operating system plug-ins"), true));
3129        if (plugin_type_properties_sp)
3130        {
3131            plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), description, is_global_property,
3132                                                      properties_sp);
3133            return true;
3134        }
3135    }
3136    return false;
3137}
3138