1254721Semaste//===-- PluginManager.cpp ---------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "lldb/Core/PluginManager.h"
13254721Semaste
14254721Semaste#include <limits.h>
15254721Semaste
16254721Semaste#include <string>
17254721Semaste#include <vector>
18254721Semaste
19254721Semaste#include "lldb/Core/Debugger.h"
20254721Semaste#include "lldb/Core/Error.h"
21254721Semaste#include "lldb/Host/FileSpec.h"
22254721Semaste#include "lldb/Host/Host.h"
23254721Semaste#include "lldb/Host/Mutex.h"
24254721Semaste#include "lldb/Interpreter/OptionValueProperties.h"
25254721Semaste
26254721Semaste#include "llvm/ADT/StringRef.h"
27254721Semaste
28254721Semasteusing namespace lldb;
29254721Semasteusing namespace lldb_private;
30254721Semaste
31254721Semasteenum PluginAction
32254721Semaste{
33254721Semaste    ePluginRegisterInstance,
34254721Semaste    ePluginUnregisterInstance,
35254721Semaste    ePluginGetInstanceAtIndex
36254721Semaste};
37254721Semaste
38254721Semaste
39254721Semastetypedef bool (*PluginInitCallback) (void);
40254721Semastetypedef void (*PluginTermCallback) (void);
41254721Semaste
42254721Semastestruct PluginInfo
43254721Semaste{
44254721Semaste    void *plugin_handle;
45254721Semaste    PluginInitCallback plugin_init_callback;
46254721Semaste    PluginTermCallback plugin_term_callback;
47254721Semaste};
48254721Semaste
49254721Semastetypedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
50254721Semaste
51254721Semastestatic Mutex &
52254721SemasteGetPluginMapMutex ()
53254721Semaste{
54254721Semaste    static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
55254721Semaste    return g_plugin_map_mutex;
56254721Semaste}
57254721Semaste
58254721Semastestatic PluginTerminateMap &
59254721SemasteGetPluginMap ()
60254721Semaste{
61254721Semaste    static PluginTerminateMap g_plugin_map;
62254721Semaste    return g_plugin_map;
63254721Semaste}
64254721Semaste
65254721Semastestatic bool
66254721SemastePluginIsLoaded (const FileSpec &plugin_file_spec)
67254721Semaste{
68254721Semaste    Mutex::Locker locker (GetPluginMapMutex ());
69254721Semaste    PluginTerminateMap &plugin_map = GetPluginMap ();
70254721Semaste    return plugin_map.find (plugin_file_spec) != plugin_map.end();
71254721Semaste}
72254721Semaste
73254721Semastestatic void
74254721SemasteSetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
75254721Semaste{
76254721Semaste    Mutex::Locker locker (GetPluginMapMutex ());
77254721Semaste    PluginTerminateMap &plugin_map = GetPluginMap ();
78254721Semaste    assert (plugin_map.find (plugin_file_spec) == plugin_map.end());
79254721Semaste    plugin_map[plugin_file_spec] = plugin_info;
80254721Semaste}
81254721Semaste
82254721Semaste
83254721Semastestatic FileSpec::EnumerateDirectoryResult
84254721SemasteLoadPluginCallback
85254721Semaste(
86254721Semaste    void *baton,
87254721Semaste    FileSpec::FileType file_type,
88254721Semaste    const FileSpec &file_spec
89254721Semaste)
90254721Semaste{
91254721Semaste//    PluginManager *plugin_manager = (PluginManager *)baton;
92254721Semaste    Error error;
93254721Semaste
94254721Semaste    // If we have a regular file, a symbolic link or unknown file type, try
95254721Semaste    // and process the file. We must handle unknown as sometimes the directory
96254721Semaste    // enumeration might be enumerating a file system that doesn't have correct
97254721Semaste    // file type information.
98254721Semaste    if (file_type == FileSpec::eFileTypeRegular         ||
99254721Semaste        file_type == FileSpec::eFileTypeSymbolicLink    ||
100254721Semaste        file_type == FileSpec::eFileTypeUnknown          )
101254721Semaste    {
102254721Semaste        FileSpec plugin_file_spec (file_spec);
103254721Semaste        plugin_file_spec.ResolvePath();
104254721Semaste
105254721Semaste        if (PluginIsLoaded (plugin_file_spec))
106254721Semaste            return FileSpec::eEnumerateDirectoryResultNext;
107254721Semaste        else
108254721Semaste        {
109254721Semaste            PluginInfo plugin_info = { NULL, NULL, NULL };
110254721Semaste            uint32_t flags = Host::eDynamicLibraryOpenOptionLazy |
111254721Semaste                             Host::eDynamicLibraryOpenOptionLocal |
112254721Semaste                             Host::eDynamicLibraryOpenOptionLimitGetSymbol;
113254721Semaste
114254721Semaste            plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, flags, error);
115254721Semaste            if (plugin_info.plugin_handle)
116254721Semaste            {
117254721Semaste                bool success = false;
118254721Semaste                plugin_info.plugin_init_callback = (PluginInitCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error);
119254721Semaste                if (plugin_info.plugin_init_callback)
120254721Semaste                {
121254721Semaste                    // Call the plug-in "bool LLDBPluginInitialize(void)" function
122254721Semaste                    success = plugin_info.plugin_init_callback();
123254721Semaste                }
124254721Semaste
125254721Semaste                if (success)
126254721Semaste                {
127254721Semaste                    // It is ok for the "LLDBPluginTerminate" symbol to be NULL
128254721Semaste                    plugin_info.plugin_term_callback = (PluginTermCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error);
129254721Semaste                }
130254721Semaste                else
131254721Semaste                {
132254721Semaste                    // The initialize function returned FALSE which means the
133254721Semaste                    // plug-in might not be compatible, or might be too new or
134254721Semaste                    // too old, or might not want to run on this machine.
135254721Semaste                    Host::DynamicLibraryClose (plugin_info.plugin_handle);
136254721Semaste                    plugin_info.plugin_handle = NULL;
137254721Semaste                    plugin_info.plugin_init_callback = NULL;
138254721Semaste                }
139254721Semaste
140254721Semaste                // Regardless of success or failure, cache the plug-in load
141254721Semaste                // in our plug-in info so we don't try to load it again and
142254721Semaste                // again.
143254721Semaste                SetPluginInfo (plugin_file_spec, plugin_info);
144254721Semaste
145254721Semaste                return FileSpec::eEnumerateDirectoryResultNext;
146254721Semaste            }
147254721Semaste        }
148254721Semaste    }
149254721Semaste
150254721Semaste    if (file_type == FileSpec::eFileTypeUnknown     ||
151254721Semaste        file_type == FileSpec::eFileTypeDirectory   ||
152254721Semaste        file_type == FileSpec::eFileTypeSymbolicLink )
153254721Semaste    {
154254721Semaste        // Try and recurse into anything that a directory or symbolic link.
155254721Semaste        // We must also do this for unknown as sometimes the directory enumeration
156254721Semaste        // might be enurating a file system that doesn't have correct file type
157254721Semaste        // information.
158254721Semaste        return FileSpec::eEnumerateDirectoryResultEnter;
159254721Semaste    }
160254721Semaste
161254721Semaste    return FileSpec::eEnumerateDirectoryResultNext;
162254721Semaste}
163254721Semaste
164254721Semaste
165254721Semastevoid
166254721SemastePluginManager::Initialize ()
167254721Semaste{
168254721Semaste#if 1
169254721Semaste    FileSpec dir_spec;
170254721Semaste    const bool find_directories = true;
171254721Semaste    const bool find_files = true;
172254721Semaste    const bool find_other = true;
173254721Semaste    char dir_path[PATH_MAX];
174254721Semaste    if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
175254721Semaste    {
176254721Semaste        if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
177254721Semaste        {
178254721Semaste            FileSpec::EnumerateDirectory (dir_path,
179254721Semaste                                          find_directories,
180254721Semaste                                          find_files,
181254721Semaste                                          find_other,
182254721Semaste                                          LoadPluginCallback,
183254721Semaste                                          NULL);
184254721Semaste        }
185254721Semaste    }
186254721Semaste
187254721Semaste    if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
188254721Semaste    {
189254721Semaste        if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
190254721Semaste        {
191254721Semaste            FileSpec::EnumerateDirectory (dir_path,
192254721Semaste                                          find_directories,
193254721Semaste                                          find_files,
194254721Semaste                                          find_other,
195254721Semaste                                          LoadPluginCallback,
196254721Semaste                                          NULL);
197254721Semaste        }
198254721Semaste    }
199254721Semaste#endif
200254721Semaste}
201254721Semaste
202254721Semastevoid
203254721SemastePluginManager::Terminate ()
204254721Semaste{
205254721Semaste    Mutex::Locker locker (GetPluginMapMutex ());
206254721Semaste    PluginTerminateMap &plugin_map = GetPluginMap ();
207254721Semaste
208254721Semaste    PluginTerminateMap::const_iterator pos, end = plugin_map.end();
209254721Semaste    for (pos = plugin_map.begin(); pos != end; ++pos)
210254721Semaste    {
211254721Semaste        // Call the plug-in "void LLDBPluginTerminate (void)" function if there
212254721Semaste        // is one (if the symbol was not NULL).
213254721Semaste        if (pos->second.plugin_handle)
214254721Semaste        {
215254721Semaste            if (pos->second.plugin_term_callback)
216254721Semaste                pos->second.plugin_term_callback();
217254721Semaste            Host::DynamicLibraryClose (pos->second.plugin_handle);
218254721Semaste        }
219254721Semaste    }
220254721Semaste    plugin_map.clear();
221254721Semaste}
222254721Semaste
223254721Semaste
224254721Semaste#pragma mark ABI
225254721Semaste
226254721Semaste
227254721Semastestruct ABIInstance
228254721Semaste{
229254721Semaste    ABIInstance() :
230254721Semaste        name(),
231254721Semaste        description(),
232254721Semaste        create_callback(NULL)
233254721Semaste    {
234254721Semaste    }
235254721Semaste
236254721Semaste    ConstString name;
237254721Semaste    std::string description;
238254721Semaste    ABICreateInstance create_callback;
239254721Semaste};
240254721Semaste
241254721Semastetypedef std::vector<ABIInstance> ABIInstances;
242254721Semaste
243254721Semastestatic Mutex &
244254721SemasteGetABIInstancesMutex ()
245254721Semaste{
246254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
247254721Semaste    return g_instances_mutex;
248254721Semaste}
249254721Semaste
250254721Semastestatic ABIInstances &
251254721SemasteGetABIInstances ()
252254721Semaste{
253254721Semaste    static ABIInstances g_instances;
254254721Semaste    return g_instances;
255254721Semaste}
256254721Semaste
257254721Semastebool
258254721SemastePluginManager::RegisterPlugin
259254721Semaste(
260254721Semaste    const ConstString &name,
261254721Semaste    const char *description,
262254721Semaste    ABICreateInstance create_callback
263254721Semaste)
264254721Semaste{
265254721Semaste    if (create_callback)
266254721Semaste    {
267254721Semaste        ABIInstance instance;
268254721Semaste        assert ((bool)name);
269254721Semaste        instance.name = name;
270254721Semaste        if (description && description[0])
271254721Semaste            instance.description = description;
272254721Semaste        instance.create_callback = create_callback;
273254721Semaste        Mutex::Locker locker (GetABIInstancesMutex ());
274254721Semaste        GetABIInstances ().push_back (instance);
275254721Semaste        return true;
276254721Semaste    }
277254721Semaste    return false;
278254721Semaste}
279254721Semaste
280254721Semastebool
281254721SemastePluginManager::UnregisterPlugin (ABICreateInstance create_callback)
282254721Semaste{
283254721Semaste    if (create_callback)
284254721Semaste    {
285254721Semaste        Mutex::Locker locker (GetABIInstancesMutex ());
286254721Semaste        ABIInstances &instances = GetABIInstances ();
287254721Semaste
288254721Semaste        ABIInstances::iterator pos, end = instances.end();
289254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
290254721Semaste        {
291254721Semaste            if (pos->create_callback == create_callback)
292254721Semaste            {
293254721Semaste                instances.erase(pos);
294254721Semaste                return true;
295254721Semaste            }
296254721Semaste        }
297254721Semaste    }
298254721Semaste    return false;
299254721Semaste}
300254721Semaste
301254721SemasteABICreateInstance
302254721SemastePluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
303254721Semaste{
304254721Semaste    Mutex::Locker locker (GetABIInstancesMutex ());
305254721Semaste    ABIInstances &instances = GetABIInstances ();
306254721Semaste    if (idx < instances.size())
307254721Semaste        return instances[idx].create_callback;
308254721Semaste    return NULL;
309254721Semaste}
310254721Semaste
311254721SemasteABICreateInstance
312254721SemastePluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
313254721Semaste{
314254721Semaste    if (name)
315254721Semaste    {
316254721Semaste        Mutex::Locker locker (GetABIInstancesMutex ());
317254721Semaste        ABIInstances &instances = GetABIInstances ();
318254721Semaste
319254721Semaste        ABIInstances::iterator pos, end = instances.end();
320254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
321254721Semaste        {
322254721Semaste            if (name == pos->name)
323254721Semaste                return pos->create_callback;
324254721Semaste        }
325254721Semaste    }
326254721Semaste    return NULL;
327254721Semaste}
328254721Semaste
329254721Semaste
330254721Semaste#pragma mark Disassembler
331254721Semaste
332254721Semaste
333254721Semastestruct DisassemblerInstance
334254721Semaste{
335254721Semaste    DisassemblerInstance() :
336254721Semaste        name(),
337254721Semaste        description(),
338254721Semaste        create_callback(NULL)
339254721Semaste    {
340254721Semaste    }
341254721Semaste
342254721Semaste    ConstString name;
343254721Semaste    std::string description;
344254721Semaste    DisassemblerCreateInstance create_callback;
345254721Semaste};
346254721Semaste
347254721Semastetypedef std::vector<DisassemblerInstance> DisassemblerInstances;
348254721Semaste
349254721Semastestatic Mutex &
350254721SemasteGetDisassemblerMutex ()
351254721Semaste{
352254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
353254721Semaste    return g_instances_mutex;
354254721Semaste}
355254721Semaste
356254721Semastestatic DisassemblerInstances &
357254721SemasteGetDisassemblerInstances ()
358254721Semaste{
359254721Semaste    static DisassemblerInstances g_instances;
360254721Semaste    return g_instances;
361254721Semaste}
362254721Semaste
363254721Semastebool
364254721SemastePluginManager::RegisterPlugin
365254721Semaste(
366254721Semaste    const ConstString &name,
367254721Semaste    const char *description,
368254721Semaste    DisassemblerCreateInstance create_callback
369254721Semaste)
370254721Semaste{
371254721Semaste    if (create_callback)
372254721Semaste    {
373254721Semaste        DisassemblerInstance instance;
374254721Semaste        assert ((bool)name);
375254721Semaste        instance.name = name;
376254721Semaste        if (description && description[0])
377254721Semaste            instance.description = description;
378254721Semaste        instance.create_callback = create_callback;
379254721Semaste        Mutex::Locker locker (GetDisassemblerMutex ());
380254721Semaste        GetDisassemblerInstances ().push_back (instance);
381254721Semaste        return true;
382254721Semaste    }
383254721Semaste    return false;
384254721Semaste}
385254721Semaste
386254721Semastebool
387254721SemastePluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
388254721Semaste{
389254721Semaste    if (create_callback)
390254721Semaste    {
391254721Semaste        Mutex::Locker locker (GetDisassemblerMutex ());
392254721Semaste        DisassemblerInstances &instances = GetDisassemblerInstances ();
393254721Semaste
394254721Semaste        DisassemblerInstances::iterator pos, end = instances.end();
395254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
396254721Semaste        {
397254721Semaste            if (pos->create_callback == create_callback)
398254721Semaste            {
399254721Semaste                instances.erase(pos);
400254721Semaste                return true;
401254721Semaste            }
402254721Semaste        }
403254721Semaste    }
404254721Semaste    return false;
405254721Semaste}
406254721Semaste
407254721SemasteDisassemblerCreateInstance
408254721SemastePluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
409254721Semaste{
410254721Semaste    Mutex::Locker locker (GetDisassemblerMutex ());
411254721Semaste    DisassemblerInstances &instances = GetDisassemblerInstances ();
412254721Semaste    if (idx < instances.size())
413254721Semaste        return instances[idx].create_callback;
414254721Semaste    return NULL;
415254721Semaste}
416254721Semaste
417254721SemasteDisassemblerCreateInstance
418254721SemastePluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &name)
419254721Semaste{
420254721Semaste    if (name)
421254721Semaste    {
422254721Semaste        Mutex::Locker locker (GetDisassemblerMutex ());
423254721Semaste        DisassemblerInstances &instances = GetDisassemblerInstances ();
424254721Semaste
425254721Semaste        DisassemblerInstances::iterator pos, end = instances.end();
426254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
427254721Semaste        {
428254721Semaste            if (name == pos->name)
429254721Semaste                return pos->create_callback;
430254721Semaste        }
431254721Semaste    }
432254721Semaste    return NULL;
433254721Semaste}
434254721Semaste
435254721Semaste
436254721Semaste
437254721Semaste#pragma mark DynamicLoader
438254721Semaste
439254721Semaste
440254721Semastestruct DynamicLoaderInstance
441254721Semaste{
442254721Semaste    DynamicLoaderInstance() :
443254721Semaste        name(),
444254721Semaste        description(),
445254721Semaste        create_callback(NULL),
446254721Semaste        debugger_init_callback (NULL)
447254721Semaste    {
448254721Semaste    }
449254721Semaste
450254721Semaste    ConstString name;
451254721Semaste    std::string description;
452254721Semaste    DynamicLoaderCreateInstance create_callback;
453254721Semaste    DebuggerInitializeCallback debugger_init_callback;
454254721Semaste};
455254721Semaste
456254721Semastetypedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
457254721Semaste
458254721Semaste
459254721Semastestatic Mutex &
460254721SemasteGetDynamicLoaderMutex ()
461254721Semaste{
462254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
463254721Semaste    return g_instances_mutex;
464254721Semaste}
465254721Semaste
466254721Semastestatic DynamicLoaderInstances &
467254721SemasteGetDynamicLoaderInstances ()
468254721Semaste{
469254721Semaste    static DynamicLoaderInstances g_instances;
470254721Semaste    return g_instances;
471254721Semaste}
472254721Semaste
473254721Semaste
474254721Semastebool
475254721SemastePluginManager::RegisterPlugin
476254721Semaste(
477254721Semaste    const ConstString &name,
478254721Semaste    const char *description,
479254721Semaste    DynamicLoaderCreateInstance create_callback,
480254721Semaste    DebuggerInitializeCallback debugger_init_callback
481254721Semaste)
482254721Semaste{
483254721Semaste    if (create_callback)
484254721Semaste    {
485254721Semaste        DynamicLoaderInstance instance;
486254721Semaste        assert ((bool)name);
487254721Semaste        instance.name = name;
488254721Semaste        if (description && description[0])
489254721Semaste            instance.description = description;
490254721Semaste        instance.create_callback = create_callback;
491254721Semaste        instance.debugger_init_callback = debugger_init_callback;
492254721Semaste        Mutex::Locker locker (GetDynamicLoaderMutex ());
493254721Semaste        GetDynamicLoaderInstances ().push_back (instance);
494254721Semaste    }
495254721Semaste    return false;
496254721Semaste}
497254721Semaste
498254721Semastebool
499254721SemastePluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
500254721Semaste{
501254721Semaste    if (create_callback)
502254721Semaste    {
503254721Semaste        Mutex::Locker locker (GetDynamicLoaderMutex ());
504254721Semaste        DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
505254721Semaste
506254721Semaste        DynamicLoaderInstances::iterator pos, end = instances.end();
507254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
508254721Semaste        {
509254721Semaste            if (pos->create_callback == create_callback)
510254721Semaste            {
511254721Semaste                instances.erase(pos);
512254721Semaste                return true;
513254721Semaste            }
514254721Semaste        }
515254721Semaste    }
516254721Semaste    return false;
517254721Semaste}
518254721Semaste
519254721SemasteDynamicLoaderCreateInstance
520254721SemastePluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
521254721Semaste{
522254721Semaste    Mutex::Locker locker (GetDynamicLoaderMutex ());
523254721Semaste    DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
524254721Semaste    if (idx < instances.size())
525254721Semaste        return instances[idx].create_callback;
526254721Semaste    return NULL;
527254721Semaste}
528254721Semaste
529254721SemasteDynamicLoaderCreateInstance
530254721SemastePluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name)
531254721Semaste{
532254721Semaste    if (name)
533254721Semaste    {
534254721Semaste        Mutex::Locker locker (GetDynamicLoaderMutex ());
535254721Semaste        DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
536254721Semaste
537254721Semaste        DynamicLoaderInstances::iterator pos, end = instances.end();
538254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
539254721Semaste        {
540254721Semaste            if (name == pos->name)
541254721Semaste                return pos->create_callback;
542254721Semaste        }
543254721Semaste    }
544254721Semaste    return NULL;
545254721Semaste}
546254721Semaste
547254721Semaste#pragma mark EmulateInstruction
548254721Semaste
549254721Semaste
550254721Semastestruct EmulateInstructionInstance
551254721Semaste{
552254721Semaste    EmulateInstructionInstance() :
553254721Semaste    name(),
554254721Semaste    description(),
555254721Semaste    create_callback(NULL)
556254721Semaste    {
557254721Semaste    }
558254721Semaste
559254721Semaste    ConstString name;
560254721Semaste    std::string description;
561254721Semaste    EmulateInstructionCreateInstance create_callback;
562254721Semaste};
563254721Semaste
564254721Semastetypedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
565254721Semaste
566254721Semastestatic Mutex &
567254721SemasteGetEmulateInstructionMutex ()
568254721Semaste{
569254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
570254721Semaste    return g_instances_mutex;
571254721Semaste}
572254721Semaste
573254721Semastestatic EmulateInstructionInstances &
574254721SemasteGetEmulateInstructionInstances ()
575254721Semaste{
576254721Semaste    static EmulateInstructionInstances g_instances;
577254721Semaste    return g_instances;
578254721Semaste}
579254721Semaste
580254721Semaste
581254721Semastebool
582254721SemastePluginManager::RegisterPlugin
583254721Semaste(
584254721Semaste    const ConstString &name,
585254721Semaste    const char *description,
586254721Semaste    EmulateInstructionCreateInstance create_callback
587254721Semaste)
588254721Semaste{
589254721Semaste    if (create_callback)
590254721Semaste    {
591254721Semaste        EmulateInstructionInstance instance;
592254721Semaste        assert ((bool)name);
593254721Semaste        instance.name = name;
594254721Semaste        if (description && description[0])
595254721Semaste            instance.description = description;
596254721Semaste        instance.create_callback = create_callback;
597254721Semaste        Mutex::Locker locker (GetEmulateInstructionMutex ());
598254721Semaste        GetEmulateInstructionInstances ().push_back (instance);
599254721Semaste    }
600254721Semaste    return false;
601254721Semaste}
602254721Semaste
603254721Semastebool
604254721SemastePluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
605254721Semaste{
606254721Semaste    if (create_callback)
607254721Semaste    {
608254721Semaste        Mutex::Locker locker (GetEmulateInstructionMutex ());
609254721Semaste        EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
610254721Semaste
611254721Semaste        EmulateInstructionInstances::iterator pos, end = instances.end();
612254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
613254721Semaste        {
614254721Semaste            if (pos->create_callback == create_callback)
615254721Semaste            {
616254721Semaste                instances.erase(pos);
617254721Semaste                return true;
618254721Semaste            }
619254721Semaste        }
620254721Semaste    }
621254721Semaste    return false;
622254721Semaste}
623254721Semaste
624254721SemasteEmulateInstructionCreateInstance
625254721SemastePluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
626254721Semaste{
627254721Semaste    Mutex::Locker locker (GetEmulateInstructionMutex ());
628254721Semaste    EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
629254721Semaste    if (idx < instances.size())
630254721Semaste        return instances[idx].create_callback;
631254721Semaste    return NULL;
632254721Semaste}
633254721Semaste
634254721SemasteEmulateInstructionCreateInstance
635254721SemastePluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name)
636254721Semaste{
637254721Semaste    if (name)
638254721Semaste    {
639254721Semaste        Mutex::Locker locker (GetEmulateInstructionMutex ());
640254721Semaste        EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
641254721Semaste
642254721Semaste        EmulateInstructionInstances::iterator pos, end = instances.end();
643254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
644254721Semaste        {
645254721Semaste            if (name == pos->name)
646254721Semaste                return pos->create_callback;
647254721Semaste        }
648254721Semaste    }
649254721Semaste    return NULL;
650254721Semaste}
651254721Semaste#pragma mark OperatingSystem
652254721Semaste
653254721Semaste
654254721Semastestruct OperatingSystemInstance
655254721Semaste{
656254721Semaste    OperatingSystemInstance() :
657254721Semaste        name(),
658254721Semaste        description(),
659254721Semaste        create_callback(NULL)
660254721Semaste    {
661254721Semaste    }
662254721Semaste
663254721Semaste    ConstString name;
664254721Semaste    std::string description;
665254721Semaste    OperatingSystemCreateInstance create_callback;
666254721Semaste};
667254721Semaste
668254721Semastetypedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
669254721Semaste
670254721Semastestatic Mutex &
671254721SemasteGetOperatingSystemMutex ()
672254721Semaste{
673254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
674254721Semaste    return g_instances_mutex;
675254721Semaste}
676254721Semaste
677254721Semastestatic OperatingSystemInstances &
678254721SemasteGetOperatingSystemInstances ()
679254721Semaste{
680254721Semaste    static OperatingSystemInstances g_instances;
681254721Semaste    return g_instances;
682254721Semaste}
683254721Semaste
684254721Semastebool
685254721SemastePluginManager::RegisterPlugin (const ConstString &name,
686254721Semaste                               const char *description,
687254721Semaste                               OperatingSystemCreateInstance create_callback)
688254721Semaste{
689254721Semaste    if (create_callback)
690254721Semaste    {
691254721Semaste        OperatingSystemInstance instance;
692254721Semaste        assert ((bool)name);
693254721Semaste        instance.name = name;
694254721Semaste        if (description && description[0])
695254721Semaste            instance.description = description;
696254721Semaste        instance.create_callback = create_callback;
697254721Semaste        Mutex::Locker locker (GetOperatingSystemMutex ());
698254721Semaste        GetOperatingSystemInstances ().push_back (instance);
699254721Semaste    }
700254721Semaste    return false;
701254721Semaste}
702254721Semaste
703254721Semastebool
704254721SemastePluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
705254721Semaste{
706254721Semaste    if (create_callback)
707254721Semaste    {
708254721Semaste        Mutex::Locker locker (GetOperatingSystemMutex ());
709254721Semaste        OperatingSystemInstances &instances = GetOperatingSystemInstances ();
710254721Semaste
711254721Semaste        OperatingSystemInstances::iterator pos, end = instances.end();
712254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
713254721Semaste        {
714254721Semaste            if (pos->create_callback == create_callback)
715254721Semaste            {
716254721Semaste                instances.erase(pos);
717254721Semaste                return true;
718254721Semaste            }
719254721Semaste        }
720254721Semaste    }
721254721Semaste    return false;
722254721Semaste}
723254721Semaste
724254721SemasteOperatingSystemCreateInstance
725254721SemastePluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
726254721Semaste{
727254721Semaste    Mutex::Locker locker (GetOperatingSystemMutex ());
728254721Semaste    OperatingSystemInstances &instances = GetOperatingSystemInstances ();
729254721Semaste    if (idx < instances.size())
730254721Semaste        return instances[idx].create_callback;
731254721Semaste    return NULL;
732254721Semaste}
733254721Semaste
734254721SemasteOperatingSystemCreateInstance
735254721SemastePluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
736254721Semaste{
737254721Semaste    if (name)
738254721Semaste    {
739254721Semaste        Mutex::Locker locker (GetOperatingSystemMutex ());
740254721Semaste        OperatingSystemInstances &instances = GetOperatingSystemInstances ();
741254721Semaste
742254721Semaste        OperatingSystemInstances::iterator pos, end = instances.end();
743254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
744254721Semaste        {
745254721Semaste            if (name == pos->name)
746254721Semaste                return pos->create_callback;
747254721Semaste        }
748254721Semaste    }
749254721Semaste    return NULL;
750254721Semaste}
751254721Semaste
752254721Semaste
753254721Semaste#pragma mark LanguageRuntime
754254721Semaste
755254721Semaste
756254721Semastestruct LanguageRuntimeInstance
757254721Semaste{
758254721Semaste    LanguageRuntimeInstance() :
759254721Semaste        name(),
760254721Semaste        description(),
761254721Semaste        create_callback(NULL)
762254721Semaste    {
763254721Semaste    }
764254721Semaste
765254721Semaste    ConstString name;
766254721Semaste    std::string description;
767254721Semaste    LanguageRuntimeCreateInstance create_callback;
768254721Semaste};
769254721Semaste
770254721Semastetypedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
771254721Semaste
772254721Semastestatic Mutex &
773254721SemasteGetLanguageRuntimeMutex ()
774254721Semaste{
775254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
776254721Semaste    return g_instances_mutex;
777254721Semaste}
778254721Semaste
779254721Semastestatic LanguageRuntimeInstances &
780254721SemasteGetLanguageRuntimeInstances ()
781254721Semaste{
782254721Semaste    static LanguageRuntimeInstances g_instances;
783254721Semaste    return g_instances;
784254721Semaste}
785254721Semaste
786254721Semastebool
787254721SemastePluginManager::RegisterPlugin
788254721Semaste(
789254721Semaste    const ConstString &name,
790254721Semaste    const char *description,
791254721Semaste    LanguageRuntimeCreateInstance create_callback
792254721Semaste)
793254721Semaste{
794254721Semaste    if (create_callback)
795254721Semaste    {
796254721Semaste        LanguageRuntimeInstance instance;
797254721Semaste        assert ((bool)name);
798254721Semaste        instance.name = name;
799254721Semaste        if (description && description[0])
800254721Semaste            instance.description = description;
801254721Semaste        instance.create_callback = create_callback;
802254721Semaste        Mutex::Locker locker (GetLanguageRuntimeMutex ());
803254721Semaste        GetLanguageRuntimeInstances ().push_back (instance);
804254721Semaste    }
805254721Semaste    return false;
806254721Semaste}
807254721Semaste
808254721Semastebool
809254721SemastePluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
810254721Semaste{
811254721Semaste    if (create_callback)
812254721Semaste    {
813254721Semaste        Mutex::Locker locker (GetLanguageRuntimeMutex ());
814254721Semaste        LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
815254721Semaste
816254721Semaste        LanguageRuntimeInstances::iterator pos, end = instances.end();
817254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
818254721Semaste        {
819254721Semaste            if (pos->create_callback == create_callback)
820254721Semaste            {
821254721Semaste                instances.erase(pos);
822254721Semaste                return true;
823254721Semaste            }
824254721Semaste        }
825254721Semaste    }
826254721Semaste    return false;
827254721Semaste}
828254721Semaste
829254721SemasteLanguageRuntimeCreateInstance
830254721SemastePluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
831254721Semaste{
832254721Semaste    Mutex::Locker locker (GetLanguageRuntimeMutex ());
833254721Semaste    LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
834254721Semaste    if (idx < instances.size())
835254721Semaste        return instances[idx].create_callback;
836254721Semaste    return NULL;
837254721Semaste}
838254721Semaste
839254721SemasteLanguageRuntimeCreateInstance
840254721SemastePluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
841254721Semaste{
842254721Semaste    if (name)
843254721Semaste    {
844254721Semaste        Mutex::Locker locker (GetLanguageRuntimeMutex ());
845254721Semaste        LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
846254721Semaste
847254721Semaste        LanguageRuntimeInstances::iterator pos, end = instances.end();
848254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
849254721Semaste        {
850254721Semaste            if (name == pos->name)
851254721Semaste                return pos->create_callback;
852254721Semaste        }
853254721Semaste    }
854254721Semaste    return NULL;
855254721Semaste}
856254721Semaste
857263363Semaste#pragma mark SystemRuntime
858263363Semaste
859263363Semaste
860263363Semastestruct SystemRuntimeInstance
861263363Semaste{
862263363Semaste    SystemRuntimeInstance() :
863263363Semaste        name(),
864263363Semaste        description(),
865263363Semaste        create_callback(NULL)
866263363Semaste    {
867263363Semaste    }
868263363Semaste
869263363Semaste    ConstString name;
870263363Semaste    std::string description;
871263363Semaste    SystemRuntimeCreateInstance create_callback;
872263363Semaste};
873263363Semaste
874263363Semastetypedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
875263363Semaste
876263363Semastestatic Mutex &
877263363SemasteGetSystemRuntimeMutex ()
878263363Semaste{
879263363Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
880263363Semaste    return g_instances_mutex;
881263363Semaste}
882263363Semaste
883263363Semastestatic SystemRuntimeInstances &
884263363SemasteGetSystemRuntimeInstances ()
885263363Semaste{
886263363Semaste    static SystemRuntimeInstances g_instances;
887263363Semaste    return g_instances;
888263363Semaste}
889263363Semaste
890263363Semastebool
891263363SemastePluginManager::RegisterPlugin
892263363Semaste(
893263363Semaste    const ConstString &name,
894263363Semaste    const char *description,
895263363Semaste    SystemRuntimeCreateInstance create_callback
896263363Semaste)
897263363Semaste{
898263363Semaste    if (create_callback)
899263363Semaste    {
900263363Semaste        SystemRuntimeInstance instance;
901263363Semaste        assert ((bool)name);
902263363Semaste        instance.name = name;
903263363Semaste        if (description && description[0])
904263363Semaste            instance.description = description;
905263363Semaste        instance.create_callback = create_callback;
906263363Semaste        Mutex::Locker locker (GetSystemRuntimeMutex ());
907263363Semaste        GetSystemRuntimeInstances ().push_back (instance);
908263363Semaste    }
909263363Semaste    return false;
910263363Semaste}
911263363Semaste
912263363Semastebool
913263363SemastePluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
914263363Semaste{
915263363Semaste    if (create_callback)
916263363Semaste    {
917263363Semaste        Mutex::Locker locker (GetSystemRuntimeMutex ());
918263363Semaste        SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
919263363Semaste
920263363Semaste        SystemRuntimeInstances::iterator pos, end = instances.end();
921263363Semaste        for (pos = instances.begin(); pos != end; ++ pos)
922263363Semaste        {
923263363Semaste            if (pos->create_callback == create_callback)
924263363Semaste            {
925263363Semaste                instances.erase(pos);
926263363Semaste                return true;
927263363Semaste            }
928263363Semaste        }
929263363Semaste    }
930263363Semaste    return false;
931263363Semaste}
932263363Semaste
933263363SemasteSystemRuntimeCreateInstance
934263363SemastePluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
935263363Semaste{
936263363Semaste    Mutex::Locker locker (GetSystemRuntimeMutex ());
937263363Semaste    SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
938263363Semaste    if (idx < instances.size())
939263363Semaste        return instances[idx].create_callback;
940263363Semaste    return NULL;
941263363Semaste}
942263363Semaste
943263363SemasteSystemRuntimeCreateInstance
944263363SemastePluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
945263363Semaste{
946263363Semaste    if (name)
947263363Semaste    {
948263363Semaste        Mutex::Locker locker (GetSystemRuntimeMutex ());
949263363Semaste        SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
950263363Semaste
951263363Semaste        SystemRuntimeInstances::iterator pos, end = instances.end();
952263363Semaste        for (pos = instances.begin(); pos != end; ++ pos)
953263363Semaste        {
954263363Semaste            if (name == pos->name)
955263363Semaste                return pos->create_callback;
956263363Semaste        }
957263363Semaste    }
958263363Semaste    return NULL;
959263363Semaste}
960263363Semaste
961263363Semaste
962254721Semaste#pragma mark ObjectFile
963254721Semaste
964254721Semastestruct ObjectFileInstance
965254721Semaste{
966254721Semaste    ObjectFileInstance() :
967254721Semaste        name(),
968254721Semaste        description(),
969254721Semaste        create_callback(NULL),
970254721Semaste        create_memory_callback (NULL),
971254721Semaste        get_module_specifications (NULL)
972254721Semaste    {
973254721Semaste    }
974254721Semaste
975254721Semaste    ConstString name;
976254721Semaste    std::string description;
977254721Semaste    ObjectFileCreateInstance create_callback;
978254721Semaste    ObjectFileCreateMemoryInstance create_memory_callback;
979254721Semaste    ObjectFileGetModuleSpecifications get_module_specifications;
980254721Semaste};
981254721Semaste
982254721Semastetypedef std::vector<ObjectFileInstance> ObjectFileInstances;
983254721Semaste
984254721Semastestatic Mutex &
985254721SemasteGetObjectFileMutex ()
986254721Semaste{
987254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
988254721Semaste    return g_instances_mutex;
989254721Semaste}
990254721Semaste
991254721Semastestatic ObjectFileInstances &
992254721SemasteGetObjectFileInstances ()
993254721Semaste{
994254721Semaste    static ObjectFileInstances g_instances;
995254721Semaste    return g_instances;
996254721Semaste}
997254721Semaste
998254721Semaste
999254721Semastebool
1000254721SemastePluginManager::RegisterPlugin (const ConstString &name,
1001254721Semaste                               const char *description,
1002254721Semaste                               ObjectFileCreateInstance create_callback,
1003254721Semaste                               ObjectFileCreateMemoryInstance create_memory_callback,
1004254721Semaste                               ObjectFileGetModuleSpecifications get_module_specifications)
1005254721Semaste{
1006254721Semaste    if (create_callback)
1007254721Semaste    {
1008254721Semaste        ObjectFileInstance instance;
1009254721Semaste        assert ((bool)name);
1010254721Semaste        instance.name = name;
1011254721Semaste        if (description && description[0])
1012254721Semaste            instance.description = description;
1013254721Semaste        instance.create_callback = create_callback;
1014254721Semaste        instance.create_memory_callback = create_memory_callback;
1015254721Semaste        instance.get_module_specifications = get_module_specifications;
1016254721Semaste        Mutex::Locker locker (GetObjectFileMutex ());
1017254721Semaste        GetObjectFileInstances ().push_back (instance);
1018254721Semaste    }
1019254721Semaste    return false;
1020254721Semaste}
1021254721Semaste
1022254721Semastebool
1023254721SemastePluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
1024254721Semaste{
1025254721Semaste    if (create_callback)
1026254721Semaste    {
1027254721Semaste        Mutex::Locker locker (GetObjectFileMutex ());
1028254721Semaste        ObjectFileInstances &instances = GetObjectFileInstances ();
1029254721Semaste
1030254721Semaste        ObjectFileInstances::iterator pos, end = instances.end();
1031254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1032254721Semaste        {
1033254721Semaste            if (pos->create_callback == create_callback)
1034254721Semaste            {
1035254721Semaste                instances.erase(pos);
1036254721Semaste                return true;
1037254721Semaste            }
1038254721Semaste        }
1039254721Semaste    }
1040254721Semaste    return false;
1041254721Semaste}
1042254721Semaste
1043254721SemasteObjectFileCreateInstance
1044254721SemastePluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
1045254721Semaste{
1046254721Semaste    Mutex::Locker locker (GetObjectFileMutex ());
1047254721Semaste    ObjectFileInstances &instances = GetObjectFileInstances ();
1048254721Semaste    if (idx < instances.size())
1049254721Semaste        return instances[idx].create_callback;
1050254721Semaste    return NULL;
1051254721Semaste}
1052254721Semaste
1053254721Semaste
1054254721SemasteObjectFileCreateMemoryInstance
1055254721SemastePluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
1056254721Semaste{
1057254721Semaste    Mutex::Locker locker (GetObjectFileMutex ());
1058254721Semaste    ObjectFileInstances &instances = GetObjectFileInstances ();
1059254721Semaste    if (idx < instances.size())
1060254721Semaste        return instances[idx].create_memory_callback;
1061254721Semaste    return NULL;
1062254721Semaste}
1063254721Semaste
1064254721SemasteObjectFileGetModuleSpecifications
1065254721SemastePluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1066254721Semaste{
1067254721Semaste    Mutex::Locker locker (GetObjectFileMutex ());
1068254721Semaste    ObjectFileInstances &instances = GetObjectFileInstances ();
1069254721Semaste    if (idx < instances.size())
1070254721Semaste        return instances[idx].get_module_specifications;
1071254721Semaste    return NULL;
1072254721Semaste}
1073254721Semaste
1074254721SemasteObjectFileCreateInstance
1075254721SemastePluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
1076254721Semaste{
1077254721Semaste    if (name)
1078254721Semaste    {
1079254721Semaste        Mutex::Locker locker (GetObjectFileMutex ());
1080254721Semaste        ObjectFileInstances &instances = GetObjectFileInstances ();
1081254721Semaste
1082254721Semaste        ObjectFileInstances::iterator pos, end = instances.end();
1083254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1084254721Semaste        {
1085254721Semaste            if (name == pos->name)
1086254721Semaste                return pos->create_callback;
1087254721Semaste        }
1088254721Semaste    }
1089254721Semaste    return NULL;
1090254721Semaste}
1091254721Semaste
1092254721Semaste
1093254721SemasteObjectFileCreateMemoryInstance
1094254721SemastePluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
1095254721Semaste{
1096254721Semaste    if (name)
1097254721Semaste    {
1098254721Semaste        Mutex::Locker locker (GetObjectFileMutex ());
1099254721Semaste        ObjectFileInstances &instances = GetObjectFileInstances ();
1100254721Semaste
1101254721Semaste        ObjectFileInstances::iterator pos, end = instances.end();
1102254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1103254721Semaste        {
1104254721Semaste            if (name == pos->name)
1105254721Semaste                return pos->create_memory_callback;
1106254721Semaste        }
1107254721Semaste    }
1108254721Semaste    return NULL;
1109254721Semaste}
1110254721Semaste
1111254721Semaste
1112254721Semaste
1113254721Semaste#pragma mark ObjectContainer
1114254721Semaste
1115254721Semastestruct ObjectContainerInstance
1116254721Semaste{
1117254721Semaste    ObjectContainerInstance() :
1118254721Semaste        name(),
1119254721Semaste        description(),
1120254721Semaste        create_callback (NULL),
1121254721Semaste        get_module_specifications (NULL)
1122254721Semaste    {
1123254721Semaste    }
1124254721Semaste
1125254721Semaste    ConstString name;
1126254721Semaste    std::string description;
1127254721Semaste    ObjectContainerCreateInstance create_callback;
1128254721Semaste    ObjectFileGetModuleSpecifications get_module_specifications;
1129254721Semaste
1130254721Semaste};
1131254721Semaste
1132254721Semastetypedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1133254721Semaste
1134254721Semastestatic Mutex &
1135254721SemasteGetObjectContainerMutex ()
1136254721Semaste{
1137254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1138254721Semaste    return g_instances_mutex;
1139254721Semaste}
1140254721Semaste
1141254721Semastestatic ObjectContainerInstances &
1142254721SemasteGetObjectContainerInstances ()
1143254721Semaste{
1144254721Semaste    static ObjectContainerInstances g_instances;
1145254721Semaste    return g_instances;
1146254721Semaste}
1147254721Semaste
1148254721Semastebool
1149254721SemastePluginManager::RegisterPlugin (const ConstString &name,
1150254721Semaste                               const char *description,
1151254721Semaste                               ObjectContainerCreateInstance create_callback,
1152254721Semaste                               ObjectFileGetModuleSpecifications get_module_specifications)
1153254721Semaste{
1154254721Semaste    if (create_callback)
1155254721Semaste    {
1156254721Semaste        ObjectContainerInstance instance;
1157254721Semaste        assert ((bool)name);
1158254721Semaste        instance.name = name;
1159254721Semaste        if (description && description[0])
1160254721Semaste            instance.description = description;
1161254721Semaste        instance.create_callback = create_callback;
1162254721Semaste        instance.get_module_specifications = get_module_specifications;
1163254721Semaste        Mutex::Locker locker (GetObjectContainerMutex ());
1164254721Semaste        GetObjectContainerInstances ().push_back (instance);
1165254721Semaste    }
1166254721Semaste    return false;
1167254721Semaste}
1168254721Semaste
1169254721Semastebool
1170254721SemastePluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1171254721Semaste{
1172254721Semaste    if (create_callback)
1173254721Semaste    {
1174254721Semaste        Mutex::Locker locker (GetObjectContainerMutex ());
1175254721Semaste        ObjectContainerInstances &instances = GetObjectContainerInstances ();
1176254721Semaste
1177254721Semaste        ObjectContainerInstances::iterator pos, end = instances.end();
1178254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1179254721Semaste        {
1180254721Semaste            if (pos->create_callback == create_callback)
1181254721Semaste            {
1182254721Semaste                instances.erase(pos);
1183254721Semaste                return true;
1184254721Semaste            }
1185254721Semaste        }
1186254721Semaste    }
1187254721Semaste    return false;
1188254721Semaste}
1189254721Semaste
1190254721SemasteObjectContainerCreateInstance
1191254721SemastePluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1192254721Semaste{
1193254721Semaste    Mutex::Locker locker (GetObjectContainerMutex ());
1194254721Semaste    ObjectContainerInstances &instances = GetObjectContainerInstances ();
1195254721Semaste    if (idx < instances.size())
1196254721Semaste        return instances[idx].create_callback;
1197254721Semaste    return NULL;
1198254721Semaste}
1199254721Semaste
1200254721SemasteObjectContainerCreateInstance
1201254721SemastePluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
1202254721Semaste{
1203254721Semaste    if (name)
1204254721Semaste    {
1205254721Semaste        Mutex::Locker locker (GetObjectContainerMutex ());
1206254721Semaste        ObjectContainerInstances &instances = GetObjectContainerInstances ();
1207254721Semaste
1208254721Semaste        ObjectContainerInstances::iterator pos, end = instances.end();
1209254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1210254721Semaste        {
1211254721Semaste            if (name == pos->name)
1212254721Semaste                return pos->create_callback;
1213254721Semaste        }
1214254721Semaste    }
1215254721Semaste    return NULL;
1216254721Semaste}
1217254721Semaste
1218254721SemasteObjectFileGetModuleSpecifications
1219254721SemastePluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1220254721Semaste{
1221254721Semaste    Mutex::Locker locker (GetObjectContainerMutex ());
1222254721Semaste    ObjectContainerInstances &instances = GetObjectContainerInstances ();
1223254721Semaste    if (idx < instances.size())
1224254721Semaste        return instances[idx].get_module_specifications;
1225254721Semaste    return NULL;
1226254721Semaste}
1227254721Semaste
1228254721Semaste#pragma mark LogChannel
1229254721Semaste
1230254721Semastestruct LogInstance
1231254721Semaste{
1232254721Semaste    LogInstance() :
1233254721Semaste        name(),
1234254721Semaste        description(),
1235254721Semaste        create_callback(NULL)
1236254721Semaste    {
1237254721Semaste    }
1238254721Semaste
1239254721Semaste    ConstString name;
1240254721Semaste    std::string description;
1241254721Semaste    LogChannelCreateInstance create_callback;
1242254721Semaste};
1243254721Semaste
1244254721Semastetypedef std::vector<LogInstance> LogInstances;
1245254721Semaste
1246254721Semastestatic Mutex &
1247254721SemasteGetLogMutex ()
1248254721Semaste{
1249254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1250254721Semaste    return g_instances_mutex;
1251254721Semaste}
1252254721Semaste
1253254721Semastestatic LogInstances &
1254254721SemasteGetLogInstances ()
1255254721Semaste{
1256254721Semaste    static LogInstances g_instances;
1257254721Semaste    return g_instances;
1258254721Semaste}
1259254721Semaste
1260254721Semaste
1261254721Semaste
1262254721Semastebool
1263254721SemastePluginManager::RegisterPlugin
1264254721Semaste(
1265254721Semaste    const ConstString &name,
1266254721Semaste    const char *description,
1267254721Semaste    LogChannelCreateInstance create_callback
1268254721Semaste)
1269254721Semaste{
1270254721Semaste    if (create_callback)
1271254721Semaste    {
1272254721Semaste        LogInstance instance;
1273254721Semaste        assert ((bool)name);
1274254721Semaste        instance.name = name;
1275254721Semaste        if (description && description[0])
1276254721Semaste            instance.description = description;
1277254721Semaste        instance.create_callback = create_callback;
1278254721Semaste        Mutex::Locker locker (GetLogMutex ());
1279254721Semaste        GetLogInstances ().push_back (instance);
1280254721Semaste    }
1281254721Semaste    return false;
1282254721Semaste}
1283254721Semaste
1284254721Semastebool
1285254721SemastePluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1286254721Semaste{
1287254721Semaste    if (create_callback)
1288254721Semaste    {
1289254721Semaste        Mutex::Locker locker (GetLogMutex ());
1290254721Semaste        LogInstances &instances = GetLogInstances ();
1291254721Semaste
1292254721Semaste        LogInstances::iterator pos, end = instances.end();
1293254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1294254721Semaste        {
1295254721Semaste            if (pos->create_callback == create_callback)
1296254721Semaste            {
1297254721Semaste                instances.erase(pos);
1298254721Semaste                return true;
1299254721Semaste            }
1300254721Semaste        }
1301254721Semaste    }
1302254721Semaste    return false;
1303254721Semaste}
1304254721Semaste
1305254721Semasteconst char *
1306254721SemastePluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1307254721Semaste{
1308254721Semaste    Mutex::Locker locker (GetLogMutex ());
1309254721Semaste    LogInstances &instances = GetLogInstances ();
1310254721Semaste    if (idx < instances.size())
1311254721Semaste        return instances[idx].name.GetCString();
1312254721Semaste    return NULL;
1313254721Semaste}
1314254721Semaste
1315254721Semaste
1316254721SemasteLogChannelCreateInstance
1317254721SemastePluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1318254721Semaste{
1319254721Semaste    Mutex::Locker locker (GetLogMutex ());
1320254721Semaste    LogInstances &instances = GetLogInstances ();
1321254721Semaste    if (idx < instances.size())
1322254721Semaste        return instances[idx].create_callback;
1323254721Semaste    return NULL;
1324254721Semaste}
1325254721Semaste
1326254721SemasteLogChannelCreateInstance
1327254721SemastePluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
1328254721Semaste{
1329254721Semaste    if (name)
1330254721Semaste    {
1331254721Semaste        Mutex::Locker locker (GetLogMutex ());
1332254721Semaste        LogInstances &instances = GetLogInstances ();
1333254721Semaste
1334254721Semaste        LogInstances::iterator pos, end = instances.end();
1335254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1336254721Semaste        {
1337254721Semaste            if (name == pos->name)
1338254721Semaste                return pos->create_callback;
1339254721Semaste        }
1340254721Semaste    }
1341254721Semaste    return NULL;
1342254721Semaste}
1343254721Semaste
1344254721Semaste#pragma mark Platform
1345254721Semaste
1346254721Semastestruct PlatformInstance
1347254721Semaste{
1348254721Semaste    PlatformInstance() :
1349254721Semaste        name(),
1350254721Semaste        description(),
1351254721Semaste        create_callback(NULL),
1352254721Semaste        debugger_init_callback (NULL)
1353254721Semaste    {
1354254721Semaste    }
1355254721Semaste
1356254721Semaste    ConstString name;
1357254721Semaste    std::string description;
1358254721Semaste    PlatformCreateInstance create_callback;
1359254721Semaste    DebuggerInitializeCallback debugger_init_callback;
1360254721Semaste};
1361254721Semaste
1362254721Semastetypedef std::vector<PlatformInstance> PlatformInstances;
1363254721Semaste
1364254721Semastestatic Mutex &
1365254721SemasteGetPlatformInstancesMutex ()
1366254721Semaste{
1367254721Semaste    static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1368254721Semaste    return g_platform_instances_mutex;
1369254721Semaste}
1370254721Semaste
1371254721Semastestatic PlatformInstances &
1372254721SemasteGetPlatformInstances ()
1373254721Semaste{
1374254721Semaste    static PlatformInstances g_platform_instances;
1375254721Semaste    return g_platform_instances;
1376254721Semaste}
1377254721Semaste
1378254721Semaste
1379254721Semastebool
1380254721SemastePluginManager::RegisterPlugin (const ConstString &name,
1381254721Semaste                               const char *description,
1382254721Semaste                               PlatformCreateInstance create_callback,
1383254721Semaste                               DebuggerInitializeCallback debugger_init_callback)
1384254721Semaste{
1385254721Semaste    if (create_callback)
1386254721Semaste    {
1387254721Semaste        Mutex::Locker locker (GetPlatformInstancesMutex ());
1388254721Semaste
1389254721Semaste        PlatformInstance instance;
1390254721Semaste        assert ((bool)name);
1391254721Semaste        instance.name = name;
1392254721Semaste        if (description && description[0])
1393254721Semaste            instance.description = description;
1394254721Semaste        instance.create_callback = create_callback;
1395254721Semaste        instance.debugger_init_callback = debugger_init_callback;
1396254721Semaste        GetPlatformInstances ().push_back (instance);
1397254721Semaste        return true;
1398254721Semaste    }
1399254721Semaste    return false;
1400254721Semaste}
1401254721Semaste
1402254721Semaste
1403254721Semasteconst char *
1404254721SemastePluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1405254721Semaste{
1406254721Semaste    Mutex::Locker locker (GetPlatformInstancesMutex ());
1407254721Semaste    PlatformInstances &instances = GetPlatformInstances ();
1408254721Semaste    if (idx < instances.size())
1409254721Semaste        return instances[idx].name.GetCString();
1410254721Semaste    return NULL;
1411254721Semaste}
1412254721Semaste
1413254721Semasteconst char *
1414254721SemastePluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1415254721Semaste{
1416254721Semaste    Mutex::Locker locker (GetPlatformInstancesMutex ());
1417254721Semaste    PlatformInstances &instances = GetPlatformInstances ();
1418254721Semaste    if (idx < instances.size())
1419254721Semaste        return instances[idx].description.c_str();
1420254721Semaste    return NULL;
1421254721Semaste}
1422254721Semaste
1423254721Semastebool
1424254721SemastePluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1425254721Semaste{
1426254721Semaste    if (create_callback)
1427254721Semaste    {
1428254721Semaste        Mutex::Locker locker (GetPlatformInstancesMutex ());
1429254721Semaste        PlatformInstances &instances = GetPlatformInstances ();
1430254721Semaste
1431254721Semaste        PlatformInstances::iterator pos, end = instances.end();
1432254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1433254721Semaste        {
1434254721Semaste            if (pos->create_callback == create_callback)
1435254721Semaste            {
1436254721Semaste                instances.erase(pos);
1437254721Semaste                return true;
1438254721Semaste            }
1439254721Semaste        }
1440254721Semaste    }
1441254721Semaste    return false;
1442254721Semaste}
1443254721Semaste
1444254721SemastePlatformCreateInstance
1445254721SemastePluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1446254721Semaste{
1447254721Semaste    Mutex::Locker locker (GetPlatformInstancesMutex ());
1448254721Semaste    PlatformInstances &instances = GetPlatformInstances ();
1449254721Semaste    if (idx < instances.size())
1450254721Semaste        return instances[idx].create_callback;
1451254721Semaste    return NULL;
1452254721Semaste}
1453254721Semaste
1454254721SemastePlatformCreateInstance
1455254721SemastePluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
1456254721Semaste{
1457254721Semaste    if (name)
1458254721Semaste    {
1459254721Semaste        Mutex::Locker locker (GetPlatformInstancesMutex ());
1460254721Semaste        PlatformInstances &instances = GetPlatformInstances ();
1461254721Semaste
1462254721Semaste        PlatformInstances::iterator pos, end = instances.end();
1463254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1464254721Semaste        {
1465254721Semaste            if (name == pos->name)
1466254721Semaste                return pos->create_callback;
1467254721Semaste        }
1468254721Semaste    }
1469254721Semaste    return NULL;
1470254721Semaste}
1471254721Semaste
1472254721Semastesize_t
1473254721SemastePluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1474254721Semaste{
1475254721Semaste    if (name)
1476254721Semaste    {
1477254721Semaste        Mutex::Locker locker (GetPlatformInstancesMutex ());
1478254721Semaste        PlatformInstances &instances = GetPlatformInstances ();
1479254721Semaste        llvm::StringRef name_sref(name);
1480254721Semaste
1481254721Semaste        PlatformInstances::iterator pos, end = instances.end();
1482254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1483254721Semaste        {
1484254721Semaste            llvm::StringRef plugin_name (pos->name.GetCString());
1485254721Semaste            if (plugin_name.startswith(name_sref))
1486254721Semaste                matches.AppendString (plugin_name.data());
1487254721Semaste        }
1488254721Semaste    }
1489254721Semaste    return matches.GetSize();
1490254721Semaste}
1491254721Semaste#pragma mark Process
1492254721Semaste
1493254721Semastestruct ProcessInstance
1494254721Semaste{
1495254721Semaste    ProcessInstance() :
1496254721Semaste        name(),
1497254721Semaste        description(),
1498254721Semaste        create_callback(NULL),
1499254721Semaste        debugger_init_callback(NULL)
1500254721Semaste    {
1501254721Semaste    }
1502254721Semaste
1503254721Semaste    ConstString name;
1504254721Semaste    std::string description;
1505254721Semaste    ProcessCreateInstance create_callback;
1506254721Semaste    DebuggerInitializeCallback debugger_init_callback;
1507254721Semaste};
1508254721Semaste
1509254721Semastetypedef std::vector<ProcessInstance> ProcessInstances;
1510254721Semaste
1511254721Semastestatic Mutex &
1512254721SemasteGetProcessMutex ()
1513254721Semaste{
1514254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1515254721Semaste    return g_instances_mutex;
1516254721Semaste}
1517254721Semaste
1518254721Semastestatic ProcessInstances &
1519254721SemasteGetProcessInstances ()
1520254721Semaste{
1521254721Semaste    static ProcessInstances g_instances;
1522254721Semaste    return g_instances;
1523254721Semaste}
1524254721Semaste
1525254721Semaste
1526254721Semastebool
1527254721SemastePluginManager::RegisterPlugin (const ConstString &name,
1528254721Semaste                               const char *description,
1529254721Semaste                               ProcessCreateInstance create_callback,
1530254721Semaste                               DebuggerInitializeCallback debugger_init_callback)
1531254721Semaste{
1532254721Semaste    if (create_callback)
1533254721Semaste    {
1534254721Semaste        ProcessInstance instance;
1535254721Semaste        assert ((bool)name);
1536254721Semaste        instance.name = name;
1537254721Semaste        if (description && description[0])
1538254721Semaste            instance.description = description;
1539254721Semaste        instance.create_callback = create_callback;
1540254721Semaste        instance.debugger_init_callback = debugger_init_callback;
1541254721Semaste        Mutex::Locker locker (GetProcessMutex ());
1542254721Semaste        GetProcessInstances ().push_back (instance);
1543254721Semaste    }
1544254721Semaste    return false;
1545254721Semaste}
1546254721Semaste
1547254721Semasteconst char *
1548254721SemastePluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1549254721Semaste{
1550254721Semaste    Mutex::Locker locker (GetProcessMutex ());
1551254721Semaste    ProcessInstances &instances = GetProcessInstances ();
1552254721Semaste    if (idx < instances.size())
1553254721Semaste        return instances[idx].name.GetCString();
1554254721Semaste    return NULL;
1555254721Semaste}
1556254721Semaste
1557254721Semasteconst char *
1558254721SemastePluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1559254721Semaste{
1560254721Semaste    Mutex::Locker locker (GetProcessMutex ());
1561254721Semaste    ProcessInstances &instances = GetProcessInstances ();
1562254721Semaste    if (idx < instances.size())
1563254721Semaste        return instances[idx].description.c_str();
1564254721Semaste    return NULL;
1565254721Semaste}
1566254721Semaste
1567254721Semastebool
1568254721SemastePluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1569254721Semaste{
1570254721Semaste    if (create_callback)
1571254721Semaste    {
1572254721Semaste        Mutex::Locker locker (GetProcessMutex ());
1573254721Semaste        ProcessInstances &instances = GetProcessInstances ();
1574254721Semaste
1575254721Semaste        ProcessInstances::iterator pos, end = instances.end();
1576254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1577254721Semaste        {
1578254721Semaste            if (pos->create_callback == create_callback)
1579254721Semaste            {
1580254721Semaste                instances.erase(pos);
1581254721Semaste                return true;
1582254721Semaste            }
1583254721Semaste        }
1584254721Semaste    }
1585254721Semaste    return false;
1586254721Semaste}
1587254721Semaste
1588254721SemasteProcessCreateInstance
1589254721SemastePluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1590254721Semaste{
1591254721Semaste    Mutex::Locker locker (GetProcessMutex ());
1592254721Semaste    ProcessInstances &instances = GetProcessInstances ();
1593254721Semaste    if (idx < instances.size())
1594254721Semaste        return instances[idx].create_callback;
1595254721Semaste    return NULL;
1596254721Semaste}
1597254721Semaste
1598254721Semaste
1599254721SemasteProcessCreateInstance
1600254721SemastePluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
1601254721Semaste{
1602254721Semaste    if (name)
1603254721Semaste    {
1604254721Semaste        Mutex::Locker locker (GetProcessMutex ());
1605254721Semaste        ProcessInstances &instances = GetProcessInstances ();
1606254721Semaste
1607254721Semaste        ProcessInstances::iterator pos, end = instances.end();
1608254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1609254721Semaste        {
1610254721Semaste            if (name == pos->name)
1611254721Semaste                return pos->create_callback;
1612254721Semaste        }
1613254721Semaste    }
1614254721Semaste    return NULL;
1615254721Semaste}
1616254721Semaste
1617254721Semaste#pragma mark SymbolFile
1618254721Semaste
1619254721Semastestruct SymbolFileInstance
1620254721Semaste{
1621254721Semaste    SymbolFileInstance() :
1622254721Semaste        name(),
1623254721Semaste        description(),
1624254721Semaste        create_callback(NULL)
1625254721Semaste    {
1626254721Semaste    }
1627254721Semaste
1628254721Semaste    ConstString name;
1629254721Semaste    std::string description;
1630254721Semaste    SymbolFileCreateInstance create_callback;
1631254721Semaste};
1632254721Semaste
1633254721Semastetypedef std::vector<SymbolFileInstance> SymbolFileInstances;
1634254721Semaste
1635254721Semastestatic Mutex &
1636254721SemasteGetSymbolFileMutex ()
1637254721Semaste{
1638254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1639254721Semaste    return g_instances_mutex;
1640254721Semaste}
1641254721Semaste
1642254721Semastestatic SymbolFileInstances &
1643254721SemasteGetSymbolFileInstances ()
1644254721Semaste{
1645254721Semaste    static SymbolFileInstances g_instances;
1646254721Semaste    return g_instances;
1647254721Semaste}
1648254721Semaste
1649254721Semaste
1650254721Semastebool
1651254721SemastePluginManager::RegisterPlugin
1652254721Semaste(
1653254721Semaste    const ConstString &name,
1654254721Semaste    const char *description,
1655254721Semaste    SymbolFileCreateInstance create_callback
1656254721Semaste)
1657254721Semaste{
1658254721Semaste    if (create_callback)
1659254721Semaste    {
1660254721Semaste        SymbolFileInstance instance;
1661254721Semaste        assert ((bool)name);
1662254721Semaste        instance.name = name;
1663254721Semaste        if (description && description[0])
1664254721Semaste            instance.description = description;
1665254721Semaste        instance.create_callback = create_callback;
1666254721Semaste        Mutex::Locker locker (GetSymbolFileMutex ());
1667254721Semaste        GetSymbolFileInstances ().push_back (instance);
1668254721Semaste    }
1669254721Semaste    return false;
1670254721Semaste}
1671254721Semaste
1672254721Semastebool
1673254721SemastePluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1674254721Semaste{
1675254721Semaste    if (create_callback)
1676254721Semaste    {
1677254721Semaste        Mutex::Locker locker (GetSymbolFileMutex ());
1678254721Semaste        SymbolFileInstances &instances = GetSymbolFileInstances ();
1679254721Semaste
1680254721Semaste        SymbolFileInstances::iterator pos, end = instances.end();
1681254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1682254721Semaste        {
1683254721Semaste            if (pos->create_callback == create_callback)
1684254721Semaste            {
1685254721Semaste                instances.erase(pos);
1686254721Semaste                return true;
1687254721Semaste            }
1688254721Semaste        }
1689254721Semaste    }
1690254721Semaste    return false;
1691254721Semaste}
1692254721Semaste
1693254721SemasteSymbolFileCreateInstance
1694254721SemastePluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1695254721Semaste{
1696254721Semaste    Mutex::Locker locker (GetSymbolFileMutex ());
1697254721Semaste    SymbolFileInstances &instances = GetSymbolFileInstances ();
1698254721Semaste    if (idx < instances.size())
1699254721Semaste        return instances[idx].create_callback;
1700254721Semaste    return NULL;
1701254721Semaste}
1702254721Semaste
1703254721SemasteSymbolFileCreateInstance
1704254721SemastePluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
1705254721Semaste{
1706254721Semaste    if (name)
1707254721Semaste    {
1708254721Semaste        Mutex::Locker locker (GetSymbolFileMutex ());
1709254721Semaste        SymbolFileInstances &instances = GetSymbolFileInstances ();
1710254721Semaste
1711254721Semaste        SymbolFileInstances::iterator pos, end = instances.end();
1712254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1713254721Semaste        {
1714254721Semaste            if (name == pos->name)
1715254721Semaste                return pos->create_callback;
1716254721Semaste        }
1717254721Semaste    }
1718254721Semaste    return NULL;
1719254721Semaste}
1720254721Semaste
1721254721Semaste
1722254721Semaste
1723254721Semaste#pragma mark SymbolVendor
1724254721Semaste
1725254721Semastestruct SymbolVendorInstance
1726254721Semaste{
1727254721Semaste    SymbolVendorInstance() :
1728254721Semaste        name(),
1729254721Semaste        description(),
1730254721Semaste        create_callback(NULL)
1731254721Semaste    {
1732254721Semaste    }
1733254721Semaste
1734254721Semaste    ConstString name;
1735254721Semaste    std::string description;
1736254721Semaste    SymbolVendorCreateInstance create_callback;
1737254721Semaste};
1738254721Semaste
1739254721Semastetypedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1740254721Semaste
1741254721Semastestatic Mutex &
1742254721SemasteGetSymbolVendorMutex ()
1743254721Semaste{
1744254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1745254721Semaste    return g_instances_mutex;
1746254721Semaste}
1747254721Semaste
1748254721Semastestatic SymbolVendorInstances &
1749254721SemasteGetSymbolVendorInstances ()
1750254721Semaste{
1751254721Semaste    static SymbolVendorInstances g_instances;
1752254721Semaste    return g_instances;
1753254721Semaste}
1754254721Semaste
1755254721Semastebool
1756254721SemastePluginManager::RegisterPlugin
1757254721Semaste(
1758254721Semaste    const ConstString &name,
1759254721Semaste    const char *description,
1760254721Semaste    SymbolVendorCreateInstance create_callback
1761254721Semaste)
1762254721Semaste{
1763254721Semaste    if (create_callback)
1764254721Semaste    {
1765254721Semaste        SymbolVendorInstance instance;
1766254721Semaste        assert ((bool)name);
1767254721Semaste        instance.name = name;
1768254721Semaste        if (description && description[0])
1769254721Semaste            instance.description = description;
1770254721Semaste        instance.create_callback = create_callback;
1771254721Semaste        Mutex::Locker locker (GetSymbolVendorMutex ());
1772254721Semaste        GetSymbolVendorInstances ().push_back (instance);
1773254721Semaste    }
1774254721Semaste    return false;
1775254721Semaste}
1776254721Semaste
1777254721Semastebool
1778254721SemastePluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1779254721Semaste{
1780254721Semaste    if (create_callback)
1781254721Semaste    {
1782254721Semaste        Mutex::Locker locker (GetSymbolVendorMutex ());
1783254721Semaste        SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1784254721Semaste
1785254721Semaste        SymbolVendorInstances::iterator pos, end = instances.end();
1786254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1787254721Semaste        {
1788254721Semaste            if (pos->create_callback == create_callback)
1789254721Semaste            {
1790254721Semaste                instances.erase(pos);
1791254721Semaste                return true;
1792254721Semaste            }
1793254721Semaste        }
1794254721Semaste    }
1795254721Semaste    return false;
1796254721Semaste}
1797254721Semaste
1798254721SemasteSymbolVendorCreateInstance
1799254721SemastePluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1800254721Semaste{
1801254721Semaste    Mutex::Locker locker (GetSymbolVendorMutex ());
1802254721Semaste    SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1803254721Semaste    if (idx < instances.size())
1804254721Semaste        return instances[idx].create_callback;
1805254721Semaste    return NULL;
1806254721Semaste}
1807254721Semaste
1808254721Semaste
1809254721SemasteSymbolVendorCreateInstance
1810254721SemastePluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
1811254721Semaste{
1812254721Semaste    if (name)
1813254721Semaste    {
1814254721Semaste        Mutex::Locker locker (GetSymbolVendorMutex ());
1815254721Semaste        SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1816254721Semaste
1817254721Semaste        SymbolVendorInstances::iterator pos, end = instances.end();
1818254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1819254721Semaste        {
1820254721Semaste            if (name == pos->name)
1821254721Semaste                return pos->create_callback;
1822254721Semaste        }
1823254721Semaste    }
1824254721Semaste    return NULL;
1825254721Semaste}
1826254721Semaste
1827254721Semaste
1828254721Semaste#pragma mark UnwindAssembly
1829254721Semaste
1830254721Semastestruct UnwindAssemblyInstance
1831254721Semaste{
1832254721Semaste    UnwindAssemblyInstance() :
1833254721Semaste        name(),
1834254721Semaste        description(),
1835254721Semaste        create_callback(NULL)
1836254721Semaste    {
1837254721Semaste    }
1838254721Semaste
1839254721Semaste    ConstString name;
1840254721Semaste    std::string description;
1841254721Semaste    UnwindAssemblyCreateInstance create_callback;
1842254721Semaste};
1843254721Semaste
1844254721Semastetypedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
1845254721Semaste
1846254721Semastestatic Mutex &
1847254721SemasteGetUnwindAssemblyMutex ()
1848254721Semaste{
1849254721Semaste    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1850254721Semaste    return g_instances_mutex;
1851254721Semaste}
1852254721Semaste
1853254721Semastestatic UnwindAssemblyInstances &
1854254721SemasteGetUnwindAssemblyInstances ()
1855254721Semaste{
1856254721Semaste    static UnwindAssemblyInstances g_instances;
1857254721Semaste    return g_instances;
1858254721Semaste}
1859254721Semaste
1860254721Semastebool
1861254721SemastePluginManager::RegisterPlugin
1862254721Semaste(
1863254721Semaste    const ConstString &name,
1864254721Semaste    const char *description,
1865254721Semaste    UnwindAssemblyCreateInstance create_callback
1866254721Semaste)
1867254721Semaste{
1868254721Semaste    if (create_callback)
1869254721Semaste    {
1870254721Semaste        UnwindAssemblyInstance instance;
1871254721Semaste        assert ((bool)name);
1872254721Semaste        instance.name = name;
1873254721Semaste        if (description && description[0])
1874254721Semaste            instance.description = description;
1875254721Semaste        instance.create_callback = create_callback;
1876254721Semaste        Mutex::Locker locker (GetUnwindAssemblyMutex ());
1877254721Semaste        GetUnwindAssemblyInstances ().push_back (instance);
1878254721Semaste    }
1879254721Semaste    return false;
1880254721Semaste}
1881254721Semaste
1882254721Semastebool
1883254721SemastePluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
1884254721Semaste{
1885254721Semaste    if (create_callback)
1886254721Semaste    {
1887254721Semaste        Mutex::Locker locker (GetUnwindAssemblyMutex ());
1888254721Semaste        UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
1889254721Semaste
1890254721Semaste        UnwindAssemblyInstances::iterator pos, end = instances.end();
1891254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1892254721Semaste        {
1893254721Semaste            if (pos->create_callback == create_callback)
1894254721Semaste            {
1895254721Semaste                instances.erase(pos);
1896254721Semaste                return true;
1897254721Semaste            }
1898254721Semaste        }
1899254721Semaste    }
1900254721Semaste    return false;
1901254721Semaste}
1902254721Semaste
1903254721SemasteUnwindAssemblyCreateInstance
1904254721SemastePluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
1905254721Semaste{
1906254721Semaste    Mutex::Locker locker (GetUnwindAssemblyMutex ());
1907254721Semaste    UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
1908254721Semaste    if (idx < instances.size())
1909254721Semaste        return instances[idx].create_callback;
1910254721Semaste    return NULL;
1911254721Semaste}
1912254721Semaste
1913254721Semaste
1914254721SemasteUnwindAssemblyCreateInstance
1915254721SemastePluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
1916254721Semaste{
1917254721Semaste    if (name)
1918254721Semaste    {
1919254721Semaste        Mutex::Locker locker (GetUnwindAssemblyMutex ());
1920254721Semaste        UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
1921254721Semaste
1922254721Semaste        UnwindAssemblyInstances::iterator pos, end = instances.end();
1923254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1924254721Semaste        {
1925254721Semaste            if (name == pos->name)
1926254721Semaste                return pos->create_callback;
1927254721Semaste        }
1928254721Semaste    }
1929254721Semaste    return NULL;
1930254721Semaste}
1931254721Semaste
1932254721Semastevoid
1933254721SemastePluginManager::DebuggerInitialize (Debugger &debugger)
1934254721Semaste{
1935254721Semaste    // Initialize the DynamicLoader plugins
1936254721Semaste    {
1937254721Semaste        Mutex::Locker locker (GetDynamicLoaderMutex ());
1938254721Semaste        DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
1939254721Semaste
1940254721Semaste        DynamicLoaderInstances::iterator pos, end = instances.end();
1941254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1942254721Semaste        {
1943254721Semaste            if (pos->debugger_init_callback)
1944254721Semaste                pos->debugger_init_callback (debugger);
1945254721Semaste        }
1946254721Semaste    }
1947254721Semaste
1948254721Semaste    // Initialize the Platform plugins
1949254721Semaste    {
1950254721Semaste        Mutex::Locker locker (GetPlatformInstancesMutex ());
1951254721Semaste        PlatformInstances &instances = GetPlatformInstances ();
1952254721Semaste
1953254721Semaste        PlatformInstances::iterator pos, end = instances.end();
1954254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1955254721Semaste        {
1956254721Semaste            if (pos->debugger_init_callback)
1957254721Semaste                pos->debugger_init_callback (debugger);
1958254721Semaste        }
1959254721Semaste    }
1960254721Semaste
1961254721Semaste    // Initialize the Process plugins
1962254721Semaste    {
1963254721Semaste        Mutex::Locker locker (GetProcessMutex());
1964254721Semaste        ProcessInstances &instances = GetProcessInstances();
1965254721Semaste
1966254721Semaste        ProcessInstances::iterator pos, end = instances.end();
1967254721Semaste        for (pos = instances.begin(); pos != end; ++ pos)
1968254721Semaste        {
1969254721Semaste            if (pos->debugger_init_callback)
1970254721Semaste                pos->debugger_init_callback (debugger);
1971254721Semaste        }
1972254721Semaste    }
1973254721Semaste
1974254721Semaste}
1975254721Semaste
1976254721Semaste// This is the preferred new way to register plugin specific settings.  e.g.
1977254721Semaste// This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1978254721Semastestatic lldb::OptionValuePropertiesSP
1979254721SemasteGetDebuggerPropertyForPlugins (Debugger &debugger,
1980254721Semaste                                       const ConstString &plugin_type_name,
1981254721Semaste                                       const ConstString &plugin_type_desc,
1982254721Semaste                                       bool can_create)
1983254721Semaste{
1984254721Semaste    lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
1985254721Semaste    if (parent_properties_sp)
1986254721Semaste    {
1987254721Semaste        static ConstString g_property_name("plugin");
1988254721Semaste
1989254721Semaste        OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
1990254721Semaste        if (!plugin_properties_sp && can_create)
1991254721Semaste        {
1992254721Semaste            plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
1993254721Semaste            parent_properties_sp->AppendProperty (g_property_name,
1994254721Semaste                                                  ConstString("Settings specify to plugins."),
1995254721Semaste                                                  true,
1996254721Semaste                                                  plugin_properties_sp);
1997254721Semaste        }
1998254721Semaste
1999254721Semaste        if (plugin_properties_sp)
2000254721Semaste        {
2001254721Semaste            lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
2002254721Semaste            if (!plugin_type_properties_sp && can_create)
2003254721Semaste            {
2004254721Semaste                plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2005254721Semaste                plugin_properties_sp->AppendProperty (plugin_type_name,
2006254721Semaste                                                      plugin_type_desc,
2007254721Semaste                                                      true,
2008254721Semaste                                                      plugin_type_properties_sp);
2009254721Semaste            }
2010254721Semaste            return plugin_type_properties_sp;
2011254721Semaste        }
2012254721Semaste    }
2013254721Semaste    return lldb::OptionValuePropertiesSP();
2014254721Semaste}
2015254721Semaste
2016254721Semaste// This is deprecated way to register plugin specific settings.  e.g.
2017254721Semaste// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
2018254721Semaste// and Platform generic settings would be under "platform.SETTINGNAME".
2019254721Semastestatic lldb::OptionValuePropertiesSP
2020254721SemasteGetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
2021254721Semaste                                       const ConstString &plugin_type_name,
2022254721Semaste                                       const ConstString &plugin_type_desc,
2023254721Semaste                                       bool can_create)
2024254721Semaste{
2025254721Semaste    static ConstString g_property_name("plugin");
2026254721Semaste    lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
2027254721Semaste    if (parent_properties_sp)
2028254721Semaste    {
2029254721Semaste        OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
2030254721Semaste        if (!plugin_properties_sp && can_create)
2031254721Semaste        {
2032254721Semaste            plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
2033254721Semaste            parent_properties_sp->AppendProperty (plugin_type_name,
2034254721Semaste                                                  plugin_type_desc,
2035254721Semaste                                                  true,
2036254721Semaste                                                  plugin_properties_sp);
2037254721Semaste        }
2038254721Semaste
2039254721Semaste        if (plugin_properties_sp)
2040254721Semaste        {
2041254721Semaste            lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
2042254721Semaste            if (!plugin_type_properties_sp && can_create)
2043254721Semaste            {
2044254721Semaste                plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
2045254721Semaste                plugin_properties_sp->AppendProperty (g_property_name,
2046254721Semaste                                                      ConstString("Settings specific to plugins"),
2047254721Semaste                                                      true,
2048254721Semaste                                                      plugin_type_properties_sp);
2049254721Semaste            }
2050254721Semaste            return plugin_type_properties_sp;
2051254721Semaste        }
2052254721Semaste    }
2053254721Semaste    return lldb::OptionValuePropertiesSP();
2054254721Semaste}
2055254721Semaste
2056254721Semaste
2057254721Semastelldb::OptionValuePropertiesSP
2058254721SemastePluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name)
2059254721Semaste{
2060254721Semaste    lldb::OptionValuePropertiesSP properties_sp;
2061254721Semaste    lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2062254721Semaste                                                                                            ConstString("dynamic-loader"),
2063254721Semaste                                                                                            ConstString(), // not creating to so we don't need the description
2064254721Semaste                                                                                            false));
2065254721Semaste    if (plugin_type_properties_sp)
2066254721Semaste        properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2067254721Semaste    return properties_sp;
2068254721Semaste}
2069254721Semaste
2070254721Semastebool
2071254721SemastePluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
2072254721Semaste                                                    const lldb::OptionValuePropertiesSP &properties_sp,
2073254721Semaste                                                    const ConstString &description,
2074254721Semaste                                                    bool is_global_property)
2075254721Semaste{
2076254721Semaste    if (properties_sp)
2077254721Semaste    {
2078254721Semaste        lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2079254721Semaste                                                                                                ConstString("dynamic-loader"),
2080254721Semaste                                                                                                ConstString("Settings for dynamic loader plug-ins"),
2081254721Semaste                                                                                                true));
2082254721Semaste        if (plugin_type_properties_sp)
2083254721Semaste        {
2084254721Semaste            plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2085254721Semaste                                                       description,
2086254721Semaste                                                       is_global_property,
2087254721Semaste                                                       properties_sp);
2088254721Semaste            return true;
2089254721Semaste        }
2090254721Semaste    }
2091254721Semaste    return false;
2092254721Semaste}
2093254721Semaste
2094254721Semaste
2095254721Semastelldb::OptionValuePropertiesSP
2096254721SemastePluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
2097254721Semaste{
2098254721Semaste    lldb::OptionValuePropertiesSP properties_sp;
2099254721Semaste    lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2100254721Semaste                                                                                                    ConstString("platform"),
2101254721Semaste                                                                                                    ConstString(), // not creating to so we don't need the description
2102254721Semaste                                                                                                    false));
2103254721Semaste    if (plugin_type_properties_sp)
2104254721Semaste        properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2105254721Semaste    return properties_sp;
2106254721Semaste}
2107254721Semaste
2108254721Semastebool
2109254721SemastePluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
2110254721Semaste                                                    const lldb::OptionValuePropertiesSP &properties_sp,
2111254721Semaste                                                    const ConstString &description,
2112254721Semaste                                                    bool is_global_property)
2113254721Semaste{
2114254721Semaste    if (properties_sp)
2115254721Semaste    {
2116254721Semaste        lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2117254721Semaste                                                                                                        ConstString("platform"),
2118254721Semaste                                                                                                        ConstString("Settings for platform plug-ins"),
2119254721Semaste                                                                                                        true));
2120254721Semaste        if (plugin_type_properties_sp)
2121254721Semaste        {
2122254721Semaste            plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2123254721Semaste                                                       description,
2124254721Semaste                                                       is_global_property,
2125254721Semaste                                                       properties_sp);
2126254721Semaste            return true;
2127254721Semaste        }
2128254721Semaste    }
2129254721Semaste    return false;
2130254721Semaste}
2131254721Semaste
2132254721Semaste
2133254721Semastelldb::OptionValuePropertiesSP
2134254721SemastePluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
2135254721Semaste{
2136254721Semaste    lldb::OptionValuePropertiesSP properties_sp;
2137254721Semaste    lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2138254721Semaste                                                                                            ConstString("process"),
2139254721Semaste                                                                                            ConstString(), // not creating to so we don't need the description
2140254721Semaste                                                                                            false));
2141254721Semaste    if (plugin_type_properties_sp)
2142254721Semaste        properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2143254721Semaste    return properties_sp;
2144254721Semaste}
2145254721Semaste
2146254721Semastebool
2147254721SemastePluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
2148254721Semaste                                              const lldb::OptionValuePropertiesSP &properties_sp,
2149254721Semaste                                              const ConstString &description,
2150254721Semaste                                              bool is_global_property)
2151254721Semaste{
2152254721Semaste    if (properties_sp)
2153254721Semaste    {
2154254721Semaste        lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2155254721Semaste                                                                                                ConstString("process"),
2156254721Semaste                                                                                                ConstString("Settings for process plug-ins"),
2157254721Semaste                                                                                                true));
2158254721Semaste        if (plugin_type_properties_sp)
2159254721Semaste        {
2160254721Semaste            plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2161254721Semaste                                                       description,
2162254721Semaste                                                       is_global_property,
2163254721Semaste                                                       properties_sp);
2164254721Semaste            return true;
2165254721Semaste        }
2166254721Semaste    }
2167254721Semaste    return false;
2168254721Semaste}
2169254721Semaste
2170