PluginManager.cpp revision 288943
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(NULL)
778    {
779    }
780
781    ConstString name;
782    std::string description;
783    OperatingSystemCreateInstance create_callback;
784};
785
786typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
787
788static Mutex &
789GetOperatingSystemMutex ()
790{
791    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
792    return g_instances_mutex;
793}
794
795static OperatingSystemInstances &
796GetOperatingSystemInstances ()
797{
798    static OperatingSystemInstances g_instances;
799    return g_instances;
800}
801
802bool
803PluginManager::RegisterPlugin (const ConstString &name,
804                               const char *description,
805                               OperatingSystemCreateInstance create_callback)
806{
807    if (create_callback)
808    {
809        OperatingSystemInstance instance;
810        assert ((bool)name);
811        instance.name = name;
812        if (description && description[0])
813            instance.description = description;
814        instance.create_callback = create_callback;
815        Mutex::Locker locker (GetOperatingSystemMutex ());
816        GetOperatingSystemInstances ().push_back (instance);
817    }
818    return false;
819}
820
821bool
822PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
823{
824    if (create_callback)
825    {
826        Mutex::Locker locker (GetOperatingSystemMutex ());
827        OperatingSystemInstances &instances = GetOperatingSystemInstances ();
828
829        OperatingSystemInstances::iterator pos, end = instances.end();
830        for (pos = instances.begin(); pos != end; ++ pos)
831        {
832            if (pos->create_callback == create_callback)
833            {
834                instances.erase(pos);
835                return true;
836            }
837        }
838    }
839    return false;
840}
841
842OperatingSystemCreateInstance
843PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
844{
845    Mutex::Locker locker (GetOperatingSystemMutex ());
846    OperatingSystemInstances &instances = GetOperatingSystemInstances ();
847    if (idx < instances.size())
848        return instances[idx].create_callback;
849    return NULL;
850}
851
852OperatingSystemCreateInstance
853PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
854{
855    if (name)
856    {
857        Mutex::Locker locker (GetOperatingSystemMutex ());
858        OperatingSystemInstances &instances = GetOperatingSystemInstances ();
859
860        OperatingSystemInstances::iterator pos, end = instances.end();
861        for (pos = instances.begin(); pos != end; ++ pos)
862        {
863            if (name == pos->name)
864                return pos->create_callback;
865        }
866    }
867    return NULL;
868}
869
870
871#pragma mark LanguageRuntime
872
873
874struct LanguageRuntimeInstance
875{
876    LanguageRuntimeInstance() :
877        name(),
878        description(),
879        create_callback(NULL)
880    {
881    }
882
883    ConstString name;
884    std::string description;
885    LanguageRuntimeCreateInstance create_callback;
886    LanguageRuntimeGetCommandObject command_callback;
887};
888
889typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
890
891static Mutex &
892GetLanguageRuntimeMutex ()
893{
894    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
895    return g_instances_mutex;
896}
897
898static LanguageRuntimeInstances &
899GetLanguageRuntimeInstances ()
900{
901    static LanguageRuntimeInstances g_instances;
902    return g_instances;
903}
904
905bool
906PluginManager::RegisterPlugin
907(
908    const ConstString &name,
909    const char *description,
910    LanguageRuntimeCreateInstance create_callback,
911    LanguageRuntimeGetCommandObject command_callback
912)
913{
914    if (create_callback)
915    {
916        LanguageRuntimeInstance instance;
917        assert ((bool)name);
918        instance.name = name;
919        if (description && description[0])
920            instance.description = description;
921        instance.create_callback = create_callback;
922        instance.command_callback = command_callback;
923        Mutex::Locker locker (GetLanguageRuntimeMutex ());
924        GetLanguageRuntimeInstances ().push_back (instance);
925    }
926    return false;
927}
928
929bool
930PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
931{
932    if (create_callback)
933    {
934        Mutex::Locker locker (GetLanguageRuntimeMutex ());
935        LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
936
937        LanguageRuntimeInstances::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
950LanguageRuntimeCreateInstance
951PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
952{
953    Mutex::Locker locker (GetLanguageRuntimeMutex ());
954    LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
955    if (idx < instances.size())
956        return instances[idx].create_callback;
957    return NULL;
958}
959
960LanguageRuntimeGetCommandObject
961PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex (uint32_t idx)
962{
963    Mutex::Locker locker (GetLanguageRuntimeMutex ());
964    LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
965    if (idx < instances.size())
966        return instances[idx].command_callback;
967    return NULL;
968}
969
970LanguageRuntimeCreateInstance
971PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
972{
973    if (name)
974    {
975        Mutex::Locker locker (GetLanguageRuntimeMutex ());
976        LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
977
978        LanguageRuntimeInstances::iterator pos, end = instances.end();
979        for (pos = instances.begin(); pos != end; ++ pos)
980        {
981            if (name == pos->name)
982                return pos->create_callback;
983        }
984    }
985    return NULL;
986}
987
988#pragma mark SystemRuntime
989
990
991struct SystemRuntimeInstance
992{
993    SystemRuntimeInstance() :
994        name(),
995        description(),
996        create_callback(NULL)
997    {
998    }
999
1000    ConstString name;
1001    std::string description;
1002    SystemRuntimeCreateInstance create_callback;
1003};
1004
1005typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
1006
1007static Mutex &
1008GetSystemRuntimeMutex ()
1009{
1010    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1011    return g_instances_mutex;
1012}
1013
1014static SystemRuntimeInstances &
1015GetSystemRuntimeInstances ()
1016{
1017    static SystemRuntimeInstances g_instances;
1018    return g_instances;
1019}
1020
1021bool
1022PluginManager::RegisterPlugin
1023(
1024    const ConstString &name,
1025    const char *description,
1026    SystemRuntimeCreateInstance create_callback
1027)
1028{
1029    if (create_callback)
1030    {
1031        SystemRuntimeInstance instance;
1032        assert ((bool)name);
1033        instance.name = name;
1034        if (description && description[0])
1035            instance.description = description;
1036        instance.create_callback = create_callback;
1037        Mutex::Locker locker (GetSystemRuntimeMutex ());
1038        GetSystemRuntimeInstances ().push_back (instance);
1039    }
1040    return false;
1041}
1042
1043bool
1044PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
1045{
1046    if (create_callback)
1047    {
1048        Mutex::Locker locker (GetSystemRuntimeMutex ());
1049        SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1050
1051        SystemRuntimeInstances::iterator pos, end = instances.end();
1052        for (pos = instances.begin(); pos != end; ++ pos)
1053        {
1054            if (pos->create_callback == create_callback)
1055            {
1056                instances.erase(pos);
1057                return true;
1058            }
1059        }
1060    }
1061    return false;
1062}
1063
1064SystemRuntimeCreateInstance
1065PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
1066{
1067    Mutex::Locker locker (GetSystemRuntimeMutex ());
1068    SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1069    if (idx < instances.size())
1070        return instances[idx].create_callback;
1071    return NULL;
1072}
1073
1074SystemRuntimeCreateInstance
1075PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
1076{
1077    if (name)
1078    {
1079        Mutex::Locker locker (GetSystemRuntimeMutex ());
1080        SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
1081
1082        SystemRuntimeInstances::iterator pos, end = instances.end();
1083        for (pos = instances.begin(); pos != end; ++ pos)
1084        {
1085            if (name == pos->name)
1086                return pos->create_callback;
1087        }
1088    }
1089    return NULL;
1090}
1091
1092
1093#pragma mark ObjectFile
1094
1095struct ObjectFileInstance
1096{
1097    ObjectFileInstance() :
1098        name(),
1099        description(),
1100        create_callback(NULL),
1101        create_memory_callback (NULL),
1102        get_module_specifications (NULL),
1103        save_core (NULL)
1104    {
1105    }
1106
1107    ConstString name;
1108    std::string description;
1109    ObjectFileCreateInstance create_callback;
1110    ObjectFileCreateMemoryInstance create_memory_callback;
1111    ObjectFileGetModuleSpecifications get_module_specifications;
1112    ObjectFileSaveCore save_core;
1113};
1114
1115typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1116
1117static Mutex &
1118GetObjectFileMutex ()
1119{
1120    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1121    return g_instances_mutex;
1122}
1123
1124static ObjectFileInstances &
1125GetObjectFileInstances ()
1126{
1127    static ObjectFileInstances g_instances;
1128    return g_instances;
1129}
1130
1131
1132bool
1133PluginManager::RegisterPlugin (const ConstString &name,
1134                               const char *description,
1135                               ObjectFileCreateInstance create_callback,
1136                               ObjectFileCreateMemoryInstance create_memory_callback,
1137                               ObjectFileGetModuleSpecifications get_module_specifications,
1138                               ObjectFileSaveCore save_core)
1139{
1140    if (create_callback)
1141    {
1142        ObjectFileInstance instance;
1143        assert ((bool)name);
1144        instance.name = name;
1145        if (description && description[0])
1146            instance.description = description;
1147        instance.create_callback = create_callback;
1148        instance.create_memory_callback = create_memory_callback;
1149        instance.save_core = save_core;
1150        instance.get_module_specifications = get_module_specifications;
1151        Mutex::Locker locker (GetObjectFileMutex ());
1152        GetObjectFileInstances ().push_back (instance);
1153    }
1154    return false;
1155}
1156
1157bool
1158PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
1159{
1160    if (create_callback)
1161    {
1162        Mutex::Locker locker (GetObjectFileMutex ());
1163        ObjectFileInstances &instances = GetObjectFileInstances ();
1164
1165        ObjectFileInstances::iterator pos, end = instances.end();
1166        for (pos = instances.begin(); pos != end; ++ pos)
1167        {
1168            if (pos->create_callback == create_callback)
1169            {
1170                instances.erase(pos);
1171                return true;
1172            }
1173        }
1174    }
1175    return false;
1176}
1177
1178ObjectFileCreateInstance
1179PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
1180{
1181    Mutex::Locker locker (GetObjectFileMutex ());
1182    ObjectFileInstances &instances = GetObjectFileInstances ();
1183    if (idx < instances.size())
1184        return instances[idx].create_callback;
1185    return NULL;
1186}
1187
1188
1189ObjectFileCreateMemoryInstance
1190PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
1191{
1192    Mutex::Locker locker (GetObjectFileMutex ());
1193    ObjectFileInstances &instances = GetObjectFileInstances ();
1194    if (idx < instances.size())
1195        return instances[idx].create_memory_callback;
1196    return NULL;
1197}
1198
1199ObjectFileGetModuleSpecifications
1200PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1201{
1202    Mutex::Locker locker (GetObjectFileMutex ());
1203    ObjectFileInstances &instances = GetObjectFileInstances ();
1204    if (idx < instances.size())
1205        return instances[idx].get_module_specifications;
1206    return NULL;
1207}
1208
1209ObjectFileCreateInstance
1210PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
1211{
1212    if (name)
1213    {
1214        Mutex::Locker locker (GetObjectFileMutex ());
1215        ObjectFileInstances &instances = GetObjectFileInstances ();
1216
1217        ObjectFileInstances::iterator pos, end = instances.end();
1218        for (pos = instances.begin(); pos != end; ++ pos)
1219        {
1220            if (name == pos->name)
1221                return pos->create_callback;
1222        }
1223    }
1224    return NULL;
1225}
1226
1227
1228ObjectFileCreateMemoryInstance
1229PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
1230{
1231    if (name)
1232    {
1233        Mutex::Locker locker (GetObjectFileMutex ());
1234        ObjectFileInstances &instances = GetObjectFileInstances ();
1235
1236        ObjectFileInstances::iterator pos, end = instances.end();
1237        for (pos = instances.begin(); pos != end; ++ pos)
1238        {
1239            if (name == pos->name)
1240                return pos->create_memory_callback;
1241        }
1242    }
1243    return NULL;
1244}
1245
1246Error
1247PluginManager::SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile)
1248{
1249    Error error;
1250    Mutex::Locker locker (GetObjectFileMutex ());
1251    ObjectFileInstances &instances = GetObjectFileInstances ();
1252
1253    ObjectFileInstances::iterator pos, end = instances.end();
1254    for (pos = instances.begin(); pos != end; ++ pos)
1255    {
1256        if (pos->save_core && pos->save_core (process_sp, outfile, error))
1257            return error;
1258    }
1259    error.SetErrorString("no ObjectFile plugins were able to save a core for this process");
1260    return error;
1261}
1262
1263#pragma mark ObjectContainer
1264
1265struct ObjectContainerInstance
1266{
1267    ObjectContainerInstance() :
1268        name(),
1269        description(),
1270        create_callback (NULL),
1271        get_module_specifications (NULL)
1272    {
1273    }
1274
1275    ConstString name;
1276    std::string description;
1277    ObjectContainerCreateInstance create_callback;
1278    ObjectFileGetModuleSpecifications get_module_specifications;
1279
1280};
1281
1282typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1283
1284static Mutex &
1285GetObjectContainerMutex ()
1286{
1287    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1288    return g_instances_mutex;
1289}
1290
1291static ObjectContainerInstances &
1292GetObjectContainerInstances ()
1293{
1294    static ObjectContainerInstances g_instances;
1295    return g_instances;
1296}
1297
1298bool
1299PluginManager::RegisterPlugin (const ConstString &name,
1300                               const char *description,
1301                               ObjectContainerCreateInstance create_callback,
1302                               ObjectFileGetModuleSpecifications get_module_specifications)
1303{
1304    if (create_callback)
1305    {
1306        ObjectContainerInstance instance;
1307        assert ((bool)name);
1308        instance.name = name;
1309        if (description && description[0])
1310            instance.description = description;
1311        instance.create_callback = create_callback;
1312        instance.get_module_specifications = get_module_specifications;
1313        Mutex::Locker locker (GetObjectContainerMutex ());
1314        GetObjectContainerInstances ().push_back (instance);
1315    }
1316    return false;
1317}
1318
1319bool
1320PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1321{
1322    if (create_callback)
1323    {
1324        Mutex::Locker locker (GetObjectContainerMutex ());
1325        ObjectContainerInstances &instances = GetObjectContainerInstances ();
1326
1327        ObjectContainerInstances::iterator pos, end = instances.end();
1328        for (pos = instances.begin(); pos != end; ++ pos)
1329        {
1330            if (pos->create_callback == create_callback)
1331            {
1332                instances.erase(pos);
1333                return true;
1334            }
1335        }
1336    }
1337    return false;
1338}
1339
1340ObjectContainerCreateInstance
1341PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1342{
1343    Mutex::Locker locker (GetObjectContainerMutex ());
1344    ObjectContainerInstances &instances = GetObjectContainerInstances ();
1345    if (idx < instances.size())
1346        return instances[idx].create_callback;
1347    return NULL;
1348}
1349
1350ObjectContainerCreateInstance
1351PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
1352{
1353    if (name)
1354    {
1355        Mutex::Locker locker (GetObjectContainerMutex ());
1356        ObjectContainerInstances &instances = GetObjectContainerInstances ();
1357
1358        ObjectContainerInstances::iterator pos, end = instances.end();
1359        for (pos = instances.begin(); pos != end; ++ pos)
1360        {
1361            if (name == pos->name)
1362                return pos->create_callback;
1363        }
1364    }
1365    return NULL;
1366}
1367
1368ObjectFileGetModuleSpecifications
1369PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1370{
1371    Mutex::Locker locker (GetObjectContainerMutex ());
1372    ObjectContainerInstances &instances = GetObjectContainerInstances ();
1373    if (idx < instances.size())
1374        return instances[idx].get_module_specifications;
1375    return NULL;
1376}
1377
1378#pragma mark LogChannel
1379
1380struct LogInstance
1381{
1382    LogInstance() :
1383        name(),
1384        description(),
1385        create_callback(NULL)
1386    {
1387    }
1388
1389    ConstString name;
1390    std::string description;
1391    LogChannelCreateInstance create_callback;
1392};
1393
1394typedef std::vector<LogInstance> LogInstances;
1395
1396static Mutex &
1397GetLogMutex ()
1398{
1399    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1400    return g_instances_mutex;
1401}
1402
1403static LogInstances &
1404GetLogInstances ()
1405{
1406    static LogInstances g_instances;
1407    return g_instances;
1408}
1409
1410
1411
1412bool
1413PluginManager::RegisterPlugin
1414(
1415    const ConstString &name,
1416    const char *description,
1417    LogChannelCreateInstance create_callback
1418)
1419{
1420    if (create_callback)
1421    {
1422        LogInstance instance;
1423        assert ((bool)name);
1424        instance.name = name;
1425        if (description && description[0])
1426            instance.description = description;
1427        instance.create_callback = create_callback;
1428        Mutex::Locker locker (GetLogMutex ());
1429        GetLogInstances ().push_back (instance);
1430    }
1431    return false;
1432}
1433
1434bool
1435PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1436{
1437    if (create_callback)
1438    {
1439        Mutex::Locker locker (GetLogMutex ());
1440        LogInstances &instances = GetLogInstances ();
1441
1442        LogInstances::iterator pos, end = instances.end();
1443        for (pos = instances.begin(); pos != end; ++ pos)
1444        {
1445            if (pos->create_callback == create_callback)
1446            {
1447                instances.erase(pos);
1448                return true;
1449            }
1450        }
1451    }
1452    return false;
1453}
1454
1455const char *
1456PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1457{
1458    Mutex::Locker locker (GetLogMutex ());
1459    LogInstances &instances = GetLogInstances ();
1460    if (idx < instances.size())
1461        return instances[idx].name.GetCString();
1462    return NULL;
1463}
1464
1465
1466LogChannelCreateInstance
1467PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1468{
1469    Mutex::Locker locker (GetLogMutex ());
1470    LogInstances &instances = GetLogInstances ();
1471    if (idx < instances.size())
1472        return instances[idx].create_callback;
1473    return NULL;
1474}
1475
1476LogChannelCreateInstance
1477PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
1478{
1479    if (name)
1480    {
1481        Mutex::Locker locker (GetLogMutex ());
1482        LogInstances &instances = GetLogInstances ();
1483
1484        LogInstances::iterator pos, end = instances.end();
1485        for (pos = instances.begin(); pos != end; ++ pos)
1486        {
1487            if (name == pos->name)
1488                return pos->create_callback;
1489        }
1490    }
1491    return NULL;
1492}
1493
1494#pragma mark Platform
1495
1496struct PlatformInstance
1497{
1498    PlatformInstance() :
1499        name(),
1500        description(),
1501        create_callback(NULL),
1502        debugger_init_callback (NULL)
1503    {
1504    }
1505
1506    ConstString name;
1507    std::string description;
1508    PlatformCreateInstance create_callback;
1509    DebuggerInitializeCallback debugger_init_callback;
1510};
1511
1512typedef std::vector<PlatformInstance> PlatformInstances;
1513
1514static Mutex &
1515GetPlatformInstancesMutex ()
1516{
1517    static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1518    return g_platform_instances_mutex;
1519}
1520
1521static PlatformInstances &
1522GetPlatformInstances ()
1523{
1524    static PlatformInstances g_platform_instances;
1525    return g_platform_instances;
1526}
1527
1528
1529bool
1530PluginManager::RegisterPlugin (const ConstString &name,
1531                               const char *description,
1532                               PlatformCreateInstance create_callback,
1533                               DebuggerInitializeCallback debugger_init_callback)
1534{
1535    if (create_callback)
1536    {
1537        Mutex::Locker locker (GetPlatformInstancesMutex ());
1538
1539        PlatformInstance instance;
1540        assert ((bool)name);
1541        instance.name = name;
1542        if (description && description[0])
1543            instance.description = description;
1544        instance.create_callback = create_callback;
1545        instance.debugger_init_callback = debugger_init_callback;
1546        GetPlatformInstances ().push_back (instance);
1547        return true;
1548    }
1549    return false;
1550}
1551
1552
1553const char *
1554PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1555{
1556    Mutex::Locker locker (GetPlatformInstancesMutex ());
1557    PlatformInstances &instances = GetPlatformInstances ();
1558    if (idx < instances.size())
1559        return instances[idx].name.GetCString();
1560    return NULL;
1561}
1562
1563const char *
1564PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1565{
1566    Mutex::Locker locker (GetPlatformInstancesMutex ());
1567    PlatformInstances &instances = GetPlatformInstances ();
1568    if (idx < instances.size())
1569        return instances[idx].description.c_str();
1570    return NULL;
1571}
1572
1573bool
1574PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1575{
1576    if (create_callback)
1577    {
1578        Mutex::Locker locker (GetPlatformInstancesMutex ());
1579        PlatformInstances &instances = GetPlatformInstances ();
1580
1581        PlatformInstances::iterator pos, end = instances.end();
1582        for (pos = instances.begin(); pos != end; ++ pos)
1583        {
1584            if (pos->create_callback == create_callback)
1585            {
1586                instances.erase(pos);
1587                return true;
1588            }
1589        }
1590    }
1591    return false;
1592}
1593
1594PlatformCreateInstance
1595PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1596{
1597    Mutex::Locker locker (GetPlatformInstancesMutex ());
1598    PlatformInstances &instances = GetPlatformInstances ();
1599    if (idx < instances.size())
1600        return instances[idx].create_callback;
1601    return NULL;
1602}
1603
1604PlatformCreateInstance
1605PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
1606{
1607    if (name)
1608    {
1609        Mutex::Locker locker (GetPlatformInstancesMutex ());
1610        PlatformInstances &instances = GetPlatformInstances ();
1611
1612        PlatformInstances::iterator pos, end = instances.end();
1613        for (pos = instances.begin(); pos != end; ++ pos)
1614        {
1615            if (name == pos->name)
1616                return pos->create_callback;
1617        }
1618    }
1619    return NULL;
1620}
1621
1622size_t
1623PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1624{
1625    if (name)
1626    {
1627        Mutex::Locker locker (GetPlatformInstancesMutex ());
1628        PlatformInstances &instances = GetPlatformInstances ();
1629        llvm::StringRef name_sref(name);
1630
1631        PlatformInstances::iterator pos, end = instances.end();
1632        for (pos = instances.begin(); pos != end; ++ pos)
1633        {
1634            llvm::StringRef plugin_name (pos->name.GetCString());
1635            if (plugin_name.startswith(name_sref))
1636                matches.AppendString (plugin_name.data());
1637        }
1638    }
1639    return matches.GetSize();
1640}
1641#pragma mark Process
1642
1643struct ProcessInstance
1644{
1645    ProcessInstance() :
1646        name(),
1647        description(),
1648        create_callback(NULL),
1649        debugger_init_callback(NULL)
1650    {
1651    }
1652
1653    ConstString name;
1654    std::string description;
1655    ProcessCreateInstance create_callback;
1656    DebuggerInitializeCallback debugger_init_callback;
1657};
1658
1659typedef std::vector<ProcessInstance> ProcessInstances;
1660
1661static Mutex &
1662GetProcessMutex ()
1663{
1664    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1665    return g_instances_mutex;
1666}
1667
1668static ProcessInstances &
1669GetProcessInstances ()
1670{
1671    static ProcessInstances g_instances;
1672    return g_instances;
1673}
1674
1675
1676bool
1677PluginManager::RegisterPlugin (const ConstString &name,
1678                               const char *description,
1679                               ProcessCreateInstance create_callback,
1680                               DebuggerInitializeCallback debugger_init_callback)
1681{
1682    if (create_callback)
1683    {
1684        ProcessInstance instance;
1685        assert ((bool)name);
1686        instance.name = name;
1687        if (description && description[0])
1688            instance.description = description;
1689        instance.create_callback = create_callback;
1690        instance.debugger_init_callback = debugger_init_callback;
1691        Mutex::Locker locker (GetProcessMutex ());
1692        GetProcessInstances ().push_back (instance);
1693    }
1694    return false;
1695}
1696
1697const char *
1698PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1699{
1700    Mutex::Locker locker (GetProcessMutex ());
1701    ProcessInstances &instances = GetProcessInstances ();
1702    if (idx < instances.size())
1703        return instances[idx].name.GetCString();
1704    return NULL;
1705}
1706
1707const char *
1708PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1709{
1710    Mutex::Locker locker (GetProcessMutex ());
1711    ProcessInstances &instances = GetProcessInstances ();
1712    if (idx < instances.size())
1713        return instances[idx].description.c_str();
1714    return NULL;
1715}
1716
1717bool
1718PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1719{
1720    if (create_callback)
1721    {
1722        Mutex::Locker locker (GetProcessMutex ());
1723        ProcessInstances &instances = GetProcessInstances ();
1724
1725        ProcessInstances::iterator pos, end = instances.end();
1726        for (pos = instances.begin(); pos != end; ++ pos)
1727        {
1728            if (pos->create_callback == create_callback)
1729            {
1730                instances.erase(pos);
1731                return true;
1732            }
1733        }
1734    }
1735    return false;
1736}
1737
1738ProcessCreateInstance
1739PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1740{
1741    Mutex::Locker locker (GetProcessMutex ());
1742    ProcessInstances &instances = GetProcessInstances ();
1743    if (idx < instances.size())
1744        return instances[idx].create_callback;
1745    return NULL;
1746}
1747
1748
1749ProcessCreateInstance
1750PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
1751{
1752    if (name)
1753    {
1754        Mutex::Locker locker (GetProcessMutex ());
1755        ProcessInstances &instances = GetProcessInstances ();
1756
1757        ProcessInstances::iterator pos, end = instances.end();
1758        for (pos = instances.begin(); pos != end; ++ pos)
1759        {
1760            if (name == pos->name)
1761                return pos->create_callback;
1762        }
1763    }
1764    return NULL;
1765}
1766
1767#pragma mark SymbolFile
1768
1769struct SymbolFileInstance
1770{
1771    SymbolFileInstance() :
1772        name(),
1773        description(),
1774        create_callback(NULL)
1775    {
1776    }
1777
1778    ConstString name;
1779    std::string description;
1780    SymbolFileCreateInstance create_callback;
1781};
1782
1783typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1784
1785static Mutex &
1786GetSymbolFileMutex ()
1787{
1788    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1789    return g_instances_mutex;
1790}
1791
1792static SymbolFileInstances &
1793GetSymbolFileInstances ()
1794{
1795    static SymbolFileInstances g_instances;
1796    return g_instances;
1797}
1798
1799
1800bool
1801PluginManager::RegisterPlugin
1802(
1803    const ConstString &name,
1804    const char *description,
1805    SymbolFileCreateInstance create_callback
1806)
1807{
1808    if (create_callback)
1809    {
1810        SymbolFileInstance instance;
1811        assert ((bool)name);
1812        instance.name = name;
1813        if (description && description[0])
1814            instance.description = description;
1815        instance.create_callback = create_callback;
1816        Mutex::Locker locker (GetSymbolFileMutex ());
1817        GetSymbolFileInstances ().push_back (instance);
1818    }
1819    return false;
1820}
1821
1822bool
1823PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1824{
1825    if (create_callback)
1826    {
1827        Mutex::Locker locker (GetSymbolFileMutex ());
1828        SymbolFileInstances &instances = GetSymbolFileInstances ();
1829
1830        SymbolFileInstances::iterator pos, end = instances.end();
1831        for (pos = instances.begin(); pos != end; ++ pos)
1832        {
1833            if (pos->create_callback == create_callback)
1834            {
1835                instances.erase(pos);
1836                return true;
1837            }
1838        }
1839    }
1840    return false;
1841}
1842
1843SymbolFileCreateInstance
1844PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1845{
1846    Mutex::Locker locker (GetSymbolFileMutex ());
1847    SymbolFileInstances &instances = GetSymbolFileInstances ();
1848    if (idx < instances.size())
1849        return instances[idx].create_callback;
1850    return NULL;
1851}
1852
1853SymbolFileCreateInstance
1854PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
1855{
1856    if (name)
1857    {
1858        Mutex::Locker locker (GetSymbolFileMutex ());
1859        SymbolFileInstances &instances = GetSymbolFileInstances ();
1860
1861        SymbolFileInstances::iterator pos, end = instances.end();
1862        for (pos = instances.begin(); pos != end; ++ pos)
1863        {
1864            if (name == pos->name)
1865                return pos->create_callback;
1866        }
1867    }
1868    return NULL;
1869}
1870
1871
1872
1873#pragma mark SymbolVendor
1874
1875struct SymbolVendorInstance
1876{
1877    SymbolVendorInstance() :
1878        name(),
1879        description(),
1880        create_callback(NULL)
1881    {
1882    }
1883
1884    ConstString name;
1885    std::string description;
1886    SymbolVendorCreateInstance create_callback;
1887};
1888
1889typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1890
1891static Mutex &
1892GetSymbolVendorMutex ()
1893{
1894    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1895    return g_instances_mutex;
1896}
1897
1898static SymbolVendorInstances &
1899GetSymbolVendorInstances ()
1900{
1901    static SymbolVendorInstances g_instances;
1902    return g_instances;
1903}
1904
1905bool
1906PluginManager::RegisterPlugin
1907(
1908    const ConstString &name,
1909    const char *description,
1910    SymbolVendorCreateInstance create_callback
1911)
1912{
1913    if (create_callback)
1914    {
1915        SymbolVendorInstance 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        Mutex::Locker locker (GetSymbolVendorMutex ());
1922        GetSymbolVendorInstances ().push_back (instance);
1923    }
1924    return false;
1925}
1926
1927bool
1928PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1929{
1930    if (create_callback)
1931    {
1932        Mutex::Locker locker (GetSymbolVendorMutex ());
1933        SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1934
1935        SymbolVendorInstances::iterator pos, end = instances.end();
1936        for (pos = instances.begin(); pos != end; ++ pos)
1937        {
1938            if (pos->create_callback == create_callback)
1939            {
1940                instances.erase(pos);
1941                return true;
1942            }
1943        }
1944    }
1945    return false;
1946}
1947
1948SymbolVendorCreateInstance
1949PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1950{
1951    Mutex::Locker locker (GetSymbolVendorMutex ());
1952    SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1953    if (idx < instances.size())
1954        return instances[idx].create_callback;
1955    return NULL;
1956}
1957
1958
1959SymbolVendorCreateInstance
1960PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
1961{
1962    if (name)
1963    {
1964        Mutex::Locker locker (GetSymbolVendorMutex ());
1965        SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1966
1967        SymbolVendorInstances::iterator pos, end = instances.end();
1968        for (pos = instances.begin(); pos != end; ++ pos)
1969        {
1970            if (name == pos->name)
1971                return pos->create_callback;
1972        }
1973    }
1974    return NULL;
1975}
1976
1977
1978#pragma mark UnwindAssembly
1979
1980struct UnwindAssemblyInstance
1981{
1982    UnwindAssemblyInstance() :
1983        name(),
1984        description(),
1985        create_callback(NULL)
1986    {
1987    }
1988
1989    ConstString name;
1990    std::string description;
1991    UnwindAssemblyCreateInstance create_callback;
1992};
1993
1994typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
1995
1996static Mutex &
1997GetUnwindAssemblyMutex ()
1998{
1999    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2000    return g_instances_mutex;
2001}
2002
2003static UnwindAssemblyInstances &
2004GetUnwindAssemblyInstances ()
2005{
2006    static UnwindAssemblyInstances g_instances;
2007    return g_instances;
2008}
2009
2010bool
2011PluginManager::RegisterPlugin
2012(
2013    const ConstString &name,
2014    const char *description,
2015    UnwindAssemblyCreateInstance create_callback
2016)
2017{
2018    if (create_callback)
2019    {
2020        UnwindAssemblyInstance instance;
2021        assert ((bool)name);
2022        instance.name = name;
2023        if (description && description[0])
2024            instance.description = description;
2025        instance.create_callback = create_callback;
2026        Mutex::Locker locker (GetUnwindAssemblyMutex ());
2027        GetUnwindAssemblyInstances ().push_back (instance);
2028    }
2029    return false;
2030}
2031
2032bool
2033PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
2034{
2035    if (create_callback)
2036    {
2037        Mutex::Locker locker (GetUnwindAssemblyMutex ());
2038        UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2039
2040        UnwindAssemblyInstances::iterator pos, end = instances.end();
2041        for (pos = instances.begin(); pos != end; ++ pos)
2042        {
2043            if (pos->create_callback == create_callback)
2044            {
2045                instances.erase(pos);
2046                return true;
2047            }
2048        }
2049    }
2050    return false;
2051}
2052
2053UnwindAssemblyCreateInstance
2054PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
2055{
2056    Mutex::Locker locker (GetUnwindAssemblyMutex ());
2057    UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2058    if (idx < instances.size())
2059        return instances[idx].create_callback;
2060    return NULL;
2061}
2062
2063
2064UnwindAssemblyCreateInstance
2065PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
2066{
2067    if (name)
2068    {
2069        Mutex::Locker locker (GetUnwindAssemblyMutex ());
2070        UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
2071
2072        UnwindAssemblyInstances::iterator pos, end = instances.end();
2073        for (pos = instances.begin(); pos != end; ++ pos)
2074        {
2075            if (name == pos->name)
2076                return pos->create_callback;
2077        }
2078    }
2079    return NULL;
2080}
2081
2082#pragma mark MemoryHistory
2083
2084struct MemoryHistoryInstance
2085{
2086    MemoryHistoryInstance() :
2087    name(),
2088    description(),
2089    create_callback(NULL)
2090    {
2091    }
2092
2093    ConstString name;
2094    std::string description;
2095    MemoryHistoryCreateInstance create_callback;
2096};
2097
2098typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
2099
2100static Mutex &
2101GetMemoryHistoryMutex ()
2102{
2103    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2104    return g_instances_mutex;
2105}
2106
2107static MemoryHistoryInstances &
2108GetMemoryHistoryInstances ()
2109{
2110    static MemoryHistoryInstances g_instances;
2111    return g_instances;
2112}
2113
2114bool
2115PluginManager::RegisterPlugin
2116(
2117 const ConstString &name,
2118 const char *description,
2119 MemoryHistoryCreateInstance create_callback
2120 )
2121{
2122    if (create_callback)
2123    {
2124        MemoryHistoryInstance instance;
2125        assert ((bool)name);
2126        instance.name = name;
2127        if (description && description[0])
2128            instance.description = description;
2129        instance.create_callback = create_callback;
2130        Mutex::Locker locker (GetMemoryHistoryMutex ());
2131        GetMemoryHistoryInstances ().push_back (instance);
2132    }
2133    return false;
2134}
2135
2136bool
2137PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
2138{
2139    if (create_callback)
2140    {
2141        Mutex::Locker locker (GetMemoryHistoryMutex ());
2142        MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2143
2144        MemoryHistoryInstances::iterator pos, end = instances.end();
2145        for (pos = instances.begin(); pos != end; ++ pos)
2146        {
2147            if (pos->create_callback == create_callback)
2148            {
2149                instances.erase(pos);
2150                return true;
2151            }
2152        }
2153    }
2154    return false;
2155}
2156
2157MemoryHistoryCreateInstance
2158PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
2159{
2160    Mutex::Locker locker (GetMemoryHistoryMutex ());
2161    MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2162    if (idx < instances.size())
2163        return instances[idx].create_callback;
2164    return NULL;
2165}
2166
2167
2168MemoryHistoryCreateInstance
2169PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name)
2170{
2171    if (name)
2172    {
2173        Mutex::Locker locker (GetMemoryHistoryMutex ());
2174        MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
2175
2176        MemoryHistoryInstances::iterator pos, end = instances.end();
2177        for (pos = instances.begin(); pos != end; ++ pos)
2178        {
2179            if (name == pos->name)
2180                return pos->create_callback;
2181        }
2182    }
2183    return NULL;
2184}
2185
2186#pragma mark InstrumentationRuntime
2187
2188struct InstrumentationRuntimeInstance
2189{
2190    InstrumentationRuntimeInstance() :
2191    name(),
2192    description(),
2193    create_callback(NULL)
2194    {
2195    }
2196
2197    ConstString name;
2198    std::string description;
2199    InstrumentationRuntimeCreateInstance create_callback;
2200    InstrumentationRuntimeGetType get_type_callback;
2201};
2202
2203typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances;
2204
2205static Mutex &
2206GetInstrumentationRuntimeMutex ()
2207{
2208    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
2209    return g_instances_mutex;
2210}
2211
2212static InstrumentationRuntimeInstances &
2213GetInstrumentationRuntimeInstances ()
2214{
2215    static InstrumentationRuntimeInstances g_instances;
2216    return g_instances;
2217}
2218
2219bool
2220PluginManager::RegisterPlugin
2221(
2222 const ConstString &name,
2223 const char *description,
2224 InstrumentationRuntimeCreateInstance create_callback,
2225 InstrumentationRuntimeGetType get_type_callback
2226 )
2227{
2228    if (create_callback)
2229    {
2230        InstrumentationRuntimeInstance instance;
2231        assert ((bool)name);
2232        instance.name = name;
2233        if (description && description[0])
2234            instance.description = description;
2235        instance.create_callback = create_callback;
2236        instance.get_type_callback = get_type_callback;
2237        Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2238        GetInstrumentationRuntimeInstances ().push_back (instance);
2239    }
2240    return false;
2241}
2242
2243bool
2244PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback)
2245{
2246    if (create_callback)
2247    {
2248        Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2249        InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2250
2251        InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2252        for (pos = instances.begin(); pos != end; ++ pos)
2253        {
2254            if (pos->create_callback == create_callback)
2255            {
2256                instances.erase(pos);
2257                return true;
2258            }
2259        }
2260    }
2261    return false;
2262}
2263
2264InstrumentationRuntimeGetType
2265PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx)
2266{
2267    Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2268    InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2269    if (idx < instances.size())
2270        return instances[idx].get_type_callback;
2271    return NULL;
2272}
2273
2274InstrumentationRuntimeCreateInstance
2275PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx)
2276{
2277    Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2278    InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2279    if (idx < instances.size())
2280        return instances[idx].create_callback;
2281    return NULL;
2282}
2283
2284
2285InstrumentationRuntimeCreateInstance
2286PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name)
2287{
2288    if (name)
2289    {
2290        Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
2291        InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
2292
2293        InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2294        for (pos = instances.begin(); pos != end; ++ pos)
2295        {
2296            if (name == pos->name)
2297                return pos->create_callback;
2298        }
2299    }
2300    return NULL;
2301}
2302
2303#pragma mark PluginManager
2304
2305void
2306PluginManager::DebuggerInitialize (Debugger &debugger)
2307{
2308    // Initialize the DynamicLoader plugins
2309    {
2310        Mutex::Locker locker (GetDynamicLoaderMutex ());
2311        DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
2312
2313        DynamicLoaderInstances::iterator pos, end = instances.end();
2314        for (pos = instances.begin(); pos != end; ++ pos)
2315        {
2316            if (pos->debugger_init_callback)
2317                pos->debugger_init_callback (debugger);
2318        }
2319    }
2320
2321    // Initialize the JITLoader plugins
2322    {
2323        Mutex::Locker locker (GetJITLoaderMutex ());
2324        JITLoaderInstances &instances = GetJITLoaderInstances ();
2325
2326        JITLoaderInstances::iterator pos, end = instances.end();
2327        for (pos = instances.begin(); pos != end; ++ pos)
2328        {
2329            if (pos->debugger_init_callback)
2330                pos->debugger_init_callback (debugger);
2331        }
2332    }
2333
2334    // Initialize the Platform plugins
2335    {
2336        Mutex::Locker locker (GetPlatformInstancesMutex ());
2337        PlatformInstances &instances = GetPlatformInstances ();
2338
2339        PlatformInstances::iterator pos, end = instances.end();
2340        for (pos = instances.begin(); pos != end; ++ pos)
2341        {
2342            if (pos->debugger_init_callback)
2343                pos->debugger_init_callback (debugger);
2344        }
2345    }
2346
2347    // Initialize the Process plugins
2348    {
2349        Mutex::Locker locker (GetProcessMutex());
2350        ProcessInstances &instances = GetProcessInstances();
2351
2352        ProcessInstances::iterator pos, end = instances.end();
2353        for (pos = instances.begin(); pos != end; ++ pos)
2354        {
2355            if (pos->debugger_init_callback)
2356                pos->debugger_init_callback (debugger);
2357        }
2358    }
2359
2360}
2361
2362// This is the preferred new way to register plugin specific settings.  e.g.
2363// This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2364static lldb::OptionValuePropertiesSP
2365GetDebuggerPropertyForPlugins (Debugger &debugger,
2366                                       const ConstString &plugin_type_name,
2367                                       const ConstString &plugin_type_desc,
2368                                       bool can_create)
2369{
2370    lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2371    if (parent_properties_sp)
2372    {
2373        static ConstString g_property_name("plugin");
2374
2375        OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
2376        if (!plugin_properties_sp && can_create)
2377        {
2378            plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
2379            parent_properties_sp->AppendProperty (g_property_name,
2380                                                  ConstString("Settings specify to plugins."),
2381                                                  true,
2382                                                  plugin_properties_sp);
2383        }
2384
2385        if (plugin_properties_sp)
2386        {
2387            lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
2388            if (!plugin_type_properties_sp && can_create)
2389            {
2390                plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2391                plugin_properties_sp->AppendProperty (plugin_type_name,
2392                                                      plugin_type_desc,
2393                                                      true,
2394                                                      plugin_type_properties_sp);
2395            }
2396            return plugin_type_properties_sp;
2397        }
2398    }
2399    return lldb::OptionValuePropertiesSP();
2400}
2401
2402// This is deprecated way to register plugin specific settings.  e.g.
2403// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
2404// and Platform generic settings would be under "platform.SETTINGNAME".
2405static lldb::OptionValuePropertiesSP
2406GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
2407                                       const ConstString &plugin_type_name,
2408                                       const ConstString &plugin_type_desc,
2409                                       bool can_create)
2410{
2411    static ConstString g_property_name("plugin");
2412    lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2413    if (parent_properties_sp)
2414    {
2415        OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
2416        if (!plugin_properties_sp && can_create)
2417        {
2418            plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2419            parent_properties_sp->AppendProperty (plugin_type_name,
2420                                                  plugin_type_desc,
2421                                                  true,
2422                                                  plugin_properties_sp);
2423        }
2424
2425        if (plugin_properties_sp)
2426        {
2427            lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
2428            if (!plugin_type_properties_sp && can_create)
2429            {
2430                plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
2431                plugin_properties_sp->AppendProperty (g_property_name,
2432                                                      ConstString("Settings specific to plugins"),
2433                                                      true,
2434                                                      plugin_type_properties_sp);
2435            }
2436            return plugin_type_properties_sp;
2437        }
2438    }
2439    return lldb::OptionValuePropertiesSP();
2440}
2441
2442
2443lldb::OptionValuePropertiesSP
2444PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name)
2445{
2446    lldb::OptionValuePropertiesSP properties_sp;
2447    lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2448                                                                                            ConstString("dynamic-loader"),
2449                                                                                            ConstString(), // not creating to so we don't need the description
2450                                                                                            false));
2451    if (plugin_type_properties_sp)
2452        properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2453    return properties_sp;
2454}
2455
2456bool
2457PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
2458                                                    const lldb::OptionValuePropertiesSP &properties_sp,
2459                                                    const ConstString &description,
2460                                                    bool is_global_property)
2461{
2462    if (properties_sp)
2463    {
2464        lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2465                                                                                                ConstString("dynamic-loader"),
2466                                                                                                ConstString("Settings for dynamic loader plug-ins"),
2467                                                                                                true));
2468        if (plugin_type_properties_sp)
2469        {
2470            plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2471                                                       description,
2472                                                       is_global_property,
2473                                                       properties_sp);
2474            return true;
2475        }
2476    }
2477    return false;
2478}
2479
2480
2481lldb::OptionValuePropertiesSP
2482PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
2483{
2484    lldb::OptionValuePropertiesSP properties_sp;
2485    lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2486                                                                                                    ConstString("platform"),
2487                                                                                                    ConstString(), // not creating to so we don't need the description
2488                                                                                                    false));
2489    if (plugin_type_properties_sp)
2490        properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2491    return properties_sp;
2492}
2493
2494bool
2495PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
2496                                                    const lldb::OptionValuePropertiesSP &properties_sp,
2497                                                    const ConstString &description,
2498                                                    bool is_global_property)
2499{
2500    if (properties_sp)
2501    {
2502        lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2503                                                                                                        ConstString("platform"),
2504                                                                                                        ConstString("Settings for platform plug-ins"),
2505                                                                                                        true));
2506        if (plugin_type_properties_sp)
2507        {
2508            plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2509                                                       description,
2510                                                       is_global_property,
2511                                                       properties_sp);
2512            return true;
2513        }
2514    }
2515    return false;
2516}
2517
2518
2519lldb::OptionValuePropertiesSP
2520PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
2521{
2522    lldb::OptionValuePropertiesSP properties_sp;
2523    lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2524                                                                                            ConstString("process"),
2525                                                                                            ConstString(), // not creating to so we don't need the description
2526                                                                                            false));
2527    if (plugin_type_properties_sp)
2528        properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2529    return properties_sp;
2530}
2531
2532bool
2533PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
2534                                              const lldb::OptionValuePropertiesSP &properties_sp,
2535                                              const ConstString &description,
2536                                              bool is_global_property)
2537{
2538    if (properties_sp)
2539    {
2540        lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2541                                                                                                ConstString("process"),
2542                                                                                                ConstString("Settings for process plug-ins"),
2543                                                                                                true));
2544        if (plugin_type_properties_sp)
2545        {
2546            plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2547                                                       description,
2548                                                       is_global_property,
2549                                                       properties_sp);
2550            return true;
2551        }
2552    }
2553    return false;
2554}
2555
2556