aboutsummaryrefslogtreecommitdiff
path: root/source/Core/PluginManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Core/PluginManager.cpp')
-rw-r--r--source/Core/PluginManager.cpp2064
1 files changed, 2064 insertions, 0 deletions
diff --git a/source/Core/PluginManager.cpp b/source/Core/PluginManager.cpp
new file mode 100644
index 000000000000..7a2d3772e6c3
--- /dev/null
+++ b/source/Core/PluginManager.cpp
@@ -0,0 +1,2064 @@
+//===-- PluginManager.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/Core/PluginManager.h"
+
+#include <limits.h>
+
+#include <string>
+#include <vector>
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+
+#include "llvm/ADT/StringRef.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+enum PluginAction
+{
+ ePluginRegisterInstance,
+ ePluginUnregisterInstance,
+ ePluginGetInstanceAtIndex
+};
+
+
+typedef bool (*PluginInitCallback) (void);
+typedef void (*PluginTermCallback) (void);
+
+struct PluginInfo
+{
+ void *plugin_handle;
+ PluginInitCallback plugin_init_callback;
+ PluginTermCallback plugin_term_callback;
+};
+
+typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
+
+static Mutex &
+GetPluginMapMutex ()
+{
+ static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
+ return g_plugin_map_mutex;
+}
+
+static PluginTerminateMap &
+GetPluginMap ()
+{
+ static PluginTerminateMap g_plugin_map;
+ return g_plugin_map;
+}
+
+static bool
+PluginIsLoaded (const FileSpec &plugin_file_spec)
+{
+ Mutex::Locker locker (GetPluginMapMutex ());
+ PluginTerminateMap &plugin_map = GetPluginMap ();
+ return plugin_map.find (plugin_file_spec) != plugin_map.end();
+}
+
+static void
+SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
+{
+ Mutex::Locker locker (GetPluginMapMutex ());
+ PluginTerminateMap &plugin_map = GetPluginMap ();
+ assert (plugin_map.find (plugin_file_spec) == plugin_map.end());
+ plugin_map[plugin_file_spec] = plugin_info;
+}
+
+
+static FileSpec::EnumerateDirectoryResult
+LoadPluginCallback
+(
+ void *baton,
+ FileSpec::FileType file_type,
+ const FileSpec &file_spec
+)
+{
+// PluginManager *plugin_manager = (PluginManager *)baton;
+ Error error;
+
+ // If we have a regular file, a symbolic link or unknown file type, try
+ // and process the file. We must handle unknown as sometimes the directory
+ // enumeration might be enumerating a file system that doesn't have correct
+ // file type information.
+ if (file_type == FileSpec::eFileTypeRegular ||
+ file_type == FileSpec::eFileTypeSymbolicLink ||
+ file_type == FileSpec::eFileTypeUnknown )
+ {
+ FileSpec plugin_file_spec (file_spec);
+ plugin_file_spec.ResolvePath();
+
+ if (PluginIsLoaded (plugin_file_spec))
+ return FileSpec::eEnumerateDirectoryResultNext;
+ else
+ {
+ PluginInfo plugin_info = { NULL, NULL, NULL };
+ uint32_t flags = Host::eDynamicLibraryOpenOptionLazy |
+ Host::eDynamicLibraryOpenOptionLocal |
+ Host::eDynamicLibraryOpenOptionLimitGetSymbol;
+
+ plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, flags, error);
+ if (plugin_info.plugin_handle)
+ {
+ bool success = false;
+ plugin_info.plugin_init_callback = (PluginInitCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error);
+ if (plugin_info.plugin_init_callback)
+ {
+ // Call the plug-in "bool LLDBPluginInitialize(void)" function
+ success = plugin_info.plugin_init_callback();
+ }
+
+ if (success)
+ {
+ // It is ok for the "LLDBPluginTerminate" symbol to be NULL
+ plugin_info.plugin_term_callback = (PluginTermCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error);
+ }
+ else
+ {
+ // The initialize function returned FALSE which means the
+ // plug-in might not be compatible, or might be too new or
+ // too old, or might not want to run on this machine.
+ Host::DynamicLibraryClose (plugin_info.plugin_handle);
+ plugin_info.plugin_handle = NULL;
+ plugin_info.plugin_init_callback = NULL;
+ }
+
+ // Regardless of success or failure, cache the plug-in load
+ // in our plug-in info so we don't try to load it again and
+ // again.
+ SetPluginInfo (plugin_file_spec, plugin_info);
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+ }
+ }
+ }
+
+ if (file_type == FileSpec::eFileTypeUnknown ||
+ file_type == FileSpec::eFileTypeDirectory ||
+ file_type == FileSpec::eFileTypeSymbolicLink )
+ {
+ // Try and recurse into anything that a directory or symbolic link.
+ // We must also do this for unknown as sometimes the directory enumeration
+ // might be enurating a file system that doesn't have correct file type
+ // information.
+ return FileSpec::eEnumerateDirectoryResultEnter;
+ }
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+}
+
+
+void
+PluginManager::Initialize ()
+{
+#if 1
+ FileSpec dir_spec;
+ const bool find_directories = true;
+ const bool find_files = true;
+ const bool find_other = true;
+ char dir_path[PATH_MAX];
+ if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
+ {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
+ {
+ FileSpec::EnumerateDirectory (dir_path,
+ find_directories,
+ find_files,
+ find_other,
+ LoadPluginCallback,
+ NULL);
+ }
+ }
+
+ if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
+ {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
+ {
+ FileSpec::EnumerateDirectory (dir_path,
+ find_directories,
+ find_files,
+ find_other,
+ LoadPluginCallback,
+ NULL);
+ }
+ }
+#endif
+}
+
+void
+PluginManager::Terminate ()
+{
+ Mutex::Locker locker (GetPluginMapMutex ());
+ PluginTerminateMap &plugin_map = GetPluginMap ();
+
+ PluginTerminateMap::const_iterator pos, end = plugin_map.end();
+ for (pos = plugin_map.begin(); pos != end; ++pos)
+ {
+ // Call the plug-in "void LLDBPluginTerminate (void)" function if there
+ // is one (if the symbol was not NULL).
+ if (pos->second.plugin_handle)
+ {
+ if (pos->second.plugin_term_callback)
+ pos->second.plugin_term_callback();
+ Host::DynamicLibraryClose (pos->second.plugin_handle);
+ }
+ }
+ plugin_map.clear();
+}
+
+
+#pragma mark ABI
+
+
+struct ABIInstance
+{
+ ABIInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ ABICreateInstance create_callback;
+};
+
+typedef std::vector<ABIInstance> ABIInstances;
+
+static Mutex &
+GetABIInstancesMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static ABIInstances &
+GetABIInstances ()
+{
+ static ABIInstances g_instances;
+ return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ ABICreateInstance create_callback
+)
+{
+ if (create_callback)
+ {
+ ABIInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetABIInstancesMutex ());
+ GetABIInstances ().push_back (instance);
+ return true;
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetABIInstancesMutex ());
+ ABIInstances &instances = GetABIInstances ();
+
+ ABIInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+ABICreateInstance
+PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetABIInstancesMutex ());
+ ABIInstances &instances = GetABIInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+ABICreateInstance
+PluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetABIInstancesMutex ());
+ ABIInstances &instances = GetABIInstances ();
+
+ ABIInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+
+#pragma mark Disassembler
+
+
+struct DisassemblerInstance
+{
+ DisassemblerInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ DisassemblerCreateInstance create_callback;
+};
+
+typedef std::vector<DisassemblerInstance> DisassemblerInstances;
+
+static Mutex &
+GetDisassemblerMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static DisassemblerInstances &
+GetDisassemblerInstances ()
+{
+ static DisassemblerInstances g_instances;
+ return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ DisassemblerCreateInstance create_callback
+)
+{
+ if (create_callback)
+ {
+ DisassemblerInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetDisassemblerMutex ());
+ GetDisassemblerInstances ().push_back (instance);
+ return true;
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetDisassemblerMutex ());
+ DisassemblerInstances &instances = GetDisassemblerInstances ();
+
+ DisassemblerInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+DisassemblerCreateInstance
+PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetDisassemblerMutex ());
+ DisassemblerInstances &instances = GetDisassemblerInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+DisassemblerCreateInstance
+PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetDisassemblerMutex ());
+ DisassemblerInstances &instances = GetDisassemblerInstances ();
+
+ DisassemblerInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+
+
+#pragma mark DynamicLoader
+
+
+struct DynamicLoaderInstance
+{
+ DynamicLoaderInstance() :
+ name(),
+ description(),
+ create_callback(NULL),
+ debugger_init_callback (NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ DynamicLoaderCreateInstance create_callback;
+ DebuggerInitializeCallback debugger_init_callback;
+};
+
+typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
+
+
+static Mutex &
+GetDynamicLoaderMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static DynamicLoaderInstances &
+GetDynamicLoaderInstances ()
+{
+ static DynamicLoaderInstances g_instances;
+ return g_instances;
+}
+
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ DynamicLoaderCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback
+)
+{
+ if (create_callback)
+ {
+ DynamicLoaderInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.debugger_init_callback = debugger_init_callback;
+ Mutex::Locker locker (GetDynamicLoaderMutex ());
+ GetDynamicLoaderInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetDynamicLoaderMutex ());
+ DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
+
+ DynamicLoaderInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+DynamicLoaderCreateInstance
+PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetDynamicLoaderMutex ());
+ DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+DynamicLoaderCreateInstance
+PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetDynamicLoaderMutex ());
+ DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
+
+ DynamicLoaderInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+#pragma mark EmulateInstruction
+
+
+struct EmulateInstructionInstance
+{
+ EmulateInstructionInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ EmulateInstructionCreateInstance create_callback;
+};
+
+typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
+
+static Mutex &
+GetEmulateInstructionMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static EmulateInstructionInstances &
+GetEmulateInstructionInstances ()
+{
+ static EmulateInstructionInstances g_instances;
+ return g_instances;
+}
+
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ EmulateInstructionCreateInstance create_callback
+)
+{
+ if (create_callback)
+ {
+ EmulateInstructionInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetEmulateInstructionMutex ());
+ GetEmulateInstructionInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetEmulateInstructionMutex ());
+ EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
+
+ EmulateInstructionInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+EmulateInstructionCreateInstance
+PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetEmulateInstructionMutex ());
+ EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+EmulateInstructionCreateInstance
+PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetEmulateInstructionMutex ());
+ EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
+
+ EmulateInstructionInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+#pragma mark OperatingSystem
+
+
+struct OperatingSystemInstance
+{
+ OperatingSystemInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ OperatingSystemCreateInstance create_callback;
+};
+
+typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
+
+static Mutex &
+GetOperatingSystemMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static OperatingSystemInstances &
+GetOperatingSystemInstances ()
+{
+ static OperatingSystemInstances g_instances;
+ return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin (const ConstString &name,
+ const char *description,
+ OperatingSystemCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ OperatingSystemInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetOperatingSystemMutex ());
+ GetOperatingSystemInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetOperatingSystemMutex ());
+ OperatingSystemInstances &instances = GetOperatingSystemInstances ();
+
+ OperatingSystemInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+OperatingSystemCreateInstance
+PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetOperatingSystemMutex ());
+ OperatingSystemInstances &instances = GetOperatingSystemInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+OperatingSystemCreateInstance
+PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetOperatingSystemMutex ());
+ OperatingSystemInstances &instances = GetOperatingSystemInstances ();
+
+ OperatingSystemInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+
+#pragma mark LanguageRuntime
+
+
+struct LanguageRuntimeInstance
+{
+ LanguageRuntimeInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ LanguageRuntimeCreateInstance create_callback;
+};
+
+typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
+
+static Mutex &
+GetLanguageRuntimeMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static LanguageRuntimeInstances &
+GetLanguageRuntimeInstances ()
+{
+ static LanguageRuntimeInstances g_instances;
+ return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ LanguageRuntimeCreateInstance create_callback
+)
+{
+ if (create_callback)
+ {
+ LanguageRuntimeInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetLanguageRuntimeMutex ());
+ GetLanguageRuntimeInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetLanguageRuntimeMutex ());
+ LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
+
+ LanguageRuntimeInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+LanguageRuntimeCreateInstance
+PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetLanguageRuntimeMutex ());
+ LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+LanguageRuntimeCreateInstance
+PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetLanguageRuntimeMutex ());
+ LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
+
+ LanguageRuntimeInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+#pragma mark ObjectFile
+
+struct ObjectFileInstance
+{
+ ObjectFileInstance() :
+ name(),
+ description(),
+ create_callback(NULL),
+ create_memory_callback (NULL),
+ get_module_specifications (NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ ObjectFileCreateInstance create_callback;
+ ObjectFileCreateMemoryInstance create_memory_callback;
+ ObjectFileGetModuleSpecifications get_module_specifications;
+};
+
+typedef std::vector<ObjectFileInstance> ObjectFileInstances;
+
+static Mutex &
+GetObjectFileMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static ObjectFileInstances &
+GetObjectFileInstances ()
+{
+ static ObjectFileInstances g_instances;
+ return g_instances;
+}
+
+
+bool
+PluginManager::RegisterPlugin (const ConstString &name,
+ const char *description,
+ ObjectFileCreateInstance create_callback,
+ ObjectFileCreateMemoryInstance create_memory_callback,
+ ObjectFileGetModuleSpecifications get_module_specifications)
+{
+ if (create_callback)
+ {
+ ObjectFileInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.create_memory_callback = create_memory_callback;
+ instance.get_module_specifications = get_module_specifications;
+ Mutex::Locker locker (GetObjectFileMutex ());
+ GetObjectFileInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetObjectFileMutex ());
+ ObjectFileInstances &instances = GetObjectFileInstances ();
+
+ ObjectFileInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+ObjectFileCreateInstance
+PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetObjectFileMutex ());
+ ObjectFileInstances &instances = GetObjectFileInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+
+ObjectFileCreateMemoryInstance
+PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetObjectFileMutex ());
+ ObjectFileInstances &instances = GetObjectFileInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_memory_callback;
+ return NULL;
+}
+
+ObjectFileGetModuleSpecifications
+PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetObjectFileMutex ());
+ ObjectFileInstances &instances = GetObjectFileInstances ();
+ if (idx < instances.size())
+ return instances[idx].get_module_specifications;
+ return NULL;
+}
+
+ObjectFileCreateInstance
+PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetObjectFileMutex ());
+ ObjectFileInstances &instances = GetObjectFileInstances ();
+
+ ObjectFileInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+
+ObjectFileCreateMemoryInstance
+PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetObjectFileMutex ());
+ ObjectFileInstances &instances = GetObjectFileInstances ();
+
+ ObjectFileInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_memory_callback;
+ }
+ }
+ return NULL;
+}
+
+
+
+#pragma mark ObjectContainer
+
+struct ObjectContainerInstance
+{
+ ObjectContainerInstance() :
+ name(),
+ description(),
+ create_callback (NULL),
+ get_module_specifications (NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ ObjectContainerCreateInstance create_callback;
+ ObjectFileGetModuleSpecifications get_module_specifications;
+
+};
+
+typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
+
+static Mutex &
+GetObjectContainerMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static ObjectContainerInstances &
+GetObjectContainerInstances ()
+{
+ static ObjectContainerInstances g_instances;
+ return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin (const ConstString &name,
+ const char *description,
+ ObjectContainerCreateInstance create_callback,
+ ObjectFileGetModuleSpecifications get_module_specifications)
+{
+ if (create_callback)
+ {
+ ObjectContainerInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.get_module_specifications = get_module_specifications;
+ Mutex::Locker locker (GetObjectContainerMutex ());
+ GetObjectContainerInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetObjectContainerMutex ());
+ ObjectContainerInstances &instances = GetObjectContainerInstances ();
+
+ ObjectContainerInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+ObjectContainerCreateInstance
+PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetObjectContainerMutex ());
+ ObjectContainerInstances &instances = GetObjectContainerInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+ObjectContainerCreateInstance
+PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetObjectContainerMutex ());
+ ObjectContainerInstances &instances = GetObjectContainerInstances ();
+
+ ObjectContainerInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+ObjectFileGetModuleSpecifications
+PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetObjectContainerMutex ());
+ ObjectContainerInstances &instances = GetObjectContainerInstances ();
+ if (idx < instances.size())
+ return instances[idx].get_module_specifications;
+ return NULL;
+}
+
+#pragma mark LogChannel
+
+struct LogInstance
+{
+ LogInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ LogChannelCreateInstance create_callback;
+};
+
+typedef std::vector<LogInstance> LogInstances;
+
+static Mutex &
+GetLogMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static LogInstances &
+GetLogInstances ()
+{
+ static LogInstances g_instances;
+ return g_instances;
+}
+
+
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ LogChannelCreateInstance create_callback
+)
+{
+ if (create_callback)
+ {
+ LogInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetLogMutex ());
+ GetLogInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetLogMutex ());
+ LogInstances &instances = GetLogInstances ();
+
+ LogInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+const char *
+PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetLogMutex ());
+ LogInstances &instances = GetLogInstances ();
+ if (idx < instances.size())
+ return instances[idx].name.GetCString();
+ return NULL;
+}
+
+
+LogChannelCreateInstance
+PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetLogMutex ());
+ LogInstances &instances = GetLogInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+LogChannelCreateInstance
+PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetLogMutex ());
+ LogInstances &instances = GetLogInstances ();
+
+ LogInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+#pragma mark Platform
+
+struct PlatformInstance
+{
+ PlatformInstance() :
+ name(),
+ description(),
+ create_callback(NULL),
+ debugger_init_callback (NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ PlatformCreateInstance create_callback;
+ DebuggerInitializeCallback debugger_init_callback;
+};
+
+typedef std::vector<PlatformInstance> PlatformInstances;
+
+static Mutex &
+GetPlatformInstancesMutex ()
+{
+ static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_platform_instances_mutex;
+}
+
+static PlatformInstances &
+GetPlatformInstances ()
+{
+ static PlatformInstances g_platform_instances;
+ return g_platform_instances;
+}
+
+
+bool
+PluginManager::RegisterPlugin (const ConstString &name,
+ const char *description,
+ PlatformCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetPlatformInstancesMutex ());
+
+ PlatformInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.debugger_init_callback = debugger_init_callback;
+ GetPlatformInstances ().push_back (instance);
+ return true;
+ }
+ return false;
+}
+
+
+const char *
+PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetPlatformInstancesMutex ());
+ PlatformInstances &instances = GetPlatformInstances ();
+ if (idx < instances.size())
+ return instances[idx].name.GetCString();
+ return NULL;
+}
+
+const char *
+PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetPlatformInstancesMutex ());
+ PlatformInstances &instances = GetPlatformInstances ();
+ if (idx < instances.size())
+ return instances[idx].description.c_str();
+ return NULL;
+}
+
+bool
+PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetPlatformInstancesMutex ());
+ PlatformInstances &instances = GetPlatformInstances ();
+
+ PlatformInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+PlatformCreateInstance
+PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetPlatformInstancesMutex ());
+ PlatformInstances &instances = GetPlatformInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+PlatformCreateInstance
+PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetPlatformInstancesMutex ());
+ PlatformInstances &instances = GetPlatformInstances ();
+
+ PlatformInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+size_t
+PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetPlatformInstancesMutex ());
+ PlatformInstances &instances = GetPlatformInstances ();
+ llvm::StringRef name_sref(name);
+
+ PlatformInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ llvm::StringRef plugin_name (pos->name.GetCString());
+ if (plugin_name.startswith(name_sref))
+ matches.AppendString (plugin_name.data());
+ }
+ }
+ return matches.GetSize();
+}
+#pragma mark Process
+
+struct ProcessInstance
+{
+ ProcessInstance() :
+ name(),
+ description(),
+ create_callback(NULL),
+ debugger_init_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ ProcessCreateInstance create_callback;
+ DebuggerInitializeCallback debugger_init_callback;
+};
+
+typedef std::vector<ProcessInstance> ProcessInstances;
+
+static Mutex &
+GetProcessMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static ProcessInstances &
+GetProcessInstances ()
+{
+ static ProcessInstances g_instances;
+ return g_instances;
+}
+
+
+bool
+PluginManager::RegisterPlugin (const ConstString &name,
+ const char *description,
+ ProcessCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback)
+{
+ if (create_callback)
+ {
+ ProcessInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.debugger_init_callback = debugger_init_callback;
+ Mutex::Locker locker (GetProcessMutex ());
+ GetProcessInstances ().push_back (instance);
+ }
+ return false;
+}
+
+const char *
+PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetProcessMutex ());
+ ProcessInstances &instances = GetProcessInstances ();
+ if (idx < instances.size())
+ return instances[idx].name.GetCString();
+ return NULL;
+}
+
+const char *
+PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetProcessMutex ());
+ ProcessInstances &instances = GetProcessInstances ();
+ if (idx < instances.size())
+ return instances[idx].description.c_str();
+ return NULL;
+}
+
+bool
+PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetProcessMutex ());
+ ProcessInstances &instances = GetProcessInstances ();
+
+ ProcessInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+ProcessCreateInstance
+PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetProcessMutex ());
+ ProcessInstances &instances = GetProcessInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+
+ProcessCreateInstance
+PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetProcessMutex ());
+ ProcessInstances &instances = GetProcessInstances ();
+
+ ProcessInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+#pragma mark SymbolFile
+
+struct SymbolFileInstance
+{
+ SymbolFileInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ SymbolFileCreateInstance create_callback;
+};
+
+typedef std::vector<SymbolFileInstance> SymbolFileInstances;
+
+static Mutex &
+GetSymbolFileMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static SymbolFileInstances &
+GetSymbolFileInstances ()
+{
+ static SymbolFileInstances g_instances;
+ return g_instances;
+}
+
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ SymbolFileCreateInstance create_callback
+)
+{
+ if (create_callback)
+ {
+ SymbolFileInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetSymbolFileMutex ());
+ GetSymbolFileInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetSymbolFileMutex ());
+ SymbolFileInstances &instances = GetSymbolFileInstances ();
+
+ SymbolFileInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+SymbolFileCreateInstance
+PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetSymbolFileMutex ());
+ SymbolFileInstances &instances = GetSymbolFileInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+SymbolFileCreateInstance
+PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetSymbolFileMutex ());
+ SymbolFileInstances &instances = GetSymbolFileInstances ();
+
+ SymbolFileInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+
+
+#pragma mark SymbolVendor
+
+struct SymbolVendorInstance
+{
+ SymbolVendorInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ SymbolVendorCreateInstance create_callback;
+};
+
+typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
+
+static Mutex &
+GetSymbolVendorMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static SymbolVendorInstances &
+GetSymbolVendorInstances ()
+{
+ static SymbolVendorInstances g_instances;
+ return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ SymbolVendorCreateInstance create_callback
+)
+{
+ if (create_callback)
+ {
+ SymbolVendorInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetSymbolVendorMutex ());
+ GetSymbolVendorInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetSymbolVendorMutex ());
+ SymbolVendorInstances &instances = GetSymbolVendorInstances ();
+
+ SymbolVendorInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+SymbolVendorCreateInstance
+PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetSymbolVendorMutex ());
+ SymbolVendorInstances &instances = GetSymbolVendorInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+
+SymbolVendorCreateInstance
+PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetSymbolVendorMutex ());
+ SymbolVendorInstances &instances = GetSymbolVendorInstances ();
+
+ SymbolVendorInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+
+#pragma mark UnwindAssembly
+
+struct UnwindAssemblyInstance
+{
+ UnwindAssemblyInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ UnwindAssemblyCreateInstance create_callback;
+};
+
+typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
+
+static Mutex &
+GetUnwindAssemblyMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static UnwindAssemblyInstances &
+GetUnwindAssemblyInstances ()
+{
+ static UnwindAssemblyInstances g_instances;
+ return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ UnwindAssemblyCreateInstance create_callback
+)
+{
+ if (create_callback)
+ {
+ UnwindAssemblyInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetUnwindAssemblyMutex ());
+ GetUnwindAssemblyInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetUnwindAssemblyMutex ());
+ UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
+
+ UnwindAssemblyInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+UnwindAssemblyCreateInstance
+PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetUnwindAssemblyMutex ());
+ UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+
+UnwindAssemblyCreateInstance
+PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetUnwindAssemblyMutex ());
+ UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
+
+ UnwindAssemblyInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+void
+PluginManager::DebuggerInitialize (Debugger &debugger)
+{
+ // Initialize the DynamicLoader plugins
+ {
+ Mutex::Locker locker (GetDynamicLoaderMutex ());
+ DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
+
+ DynamicLoaderInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->debugger_init_callback)
+ pos->debugger_init_callback (debugger);
+ }
+ }
+
+ // Initialize the Platform plugins
+ {
+ Mutex::Locker locker (GetPlatformInstancesMutex ());
+ PlatformInstances &instances = GetPlatformInstances ();
+
+ PlatformInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->debugger_init_callback)
+ pos->debugger_init_callback (debugger);
+ }
+ }
+
+ // Initialize the Process plugins
+ {
+ Mutex::Locker locker (GetProcessMutex());
+ ProcessInstances &instances = GetProcessInstances();
+
+ ProcessInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->debugger_init_callback)
+ pos->debugger_init_callback (debugger);
+ }
+ }
+
+}
+
+// This is the preferred new way to register plugin specific settings. e.g.
+// This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
+static lldb::OptionValuePropertiesSP
+GetDebuggerPropertyForPlugins (Debugger &debugger,
+ const ConstString &plugin_type_name,
+ const ConstString &plugin_type_desc,
+ bool can_create)
+{
+ lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
+ if (parent_properties_sp)
+ {
+ static ConstString g_property_name("plugin");
+
+ OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
+ if (!plugin_properties_sp && can_create)
+ {
+ plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
+ parent_properties_sp->AppendProperty (g_property_name,
+ ConstString("Settings specify to plugins."),
+ true,
+ plugin_properties_sp);
+ }
+
+ if (plugin_properties_sp)
+ {
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
+ if (!plugin_type_properties_sp && can_create)
+ {
+ plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
+ plugin_properties_sp->AppendProperty (plugin_type_name,
+ plugin_type_desc,
+ true,
+ plugin_type_properties_sp);
+ }
+ return plugin_type_properties_sp;
+ }
+ }
+ return lldb::OptionValuePropertiesSP();
+}
+
+// This is deprecated way to register plugin specific settings. e.g.
+// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
+// and Platform generic settings would be under "platform.SETTINGNAME".
+static lldb::OptionValuePropertiesSP
+GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
+ const ConstString &plugin_type_name,
+ const ConstString &plugin_type_desc,
+ bool can_create)
+{
+ static ConstString g_property_name("plugin");
+ lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
+ if (parent_properties_sp)
+ {
+ OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
+ if (!plugin_properties_sp && can_create)
+ {
+ plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
+ parent_properties_sp->AppendProperty (plugin_type_name,
+ plugin_type_desc,
+ true,
+ plugin_properties_sp);
+ }
+
+ if (plugin_properties_sp)
+ {
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
+ if (!plugin_type_properties_sp && can_create)
+ {
+ plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
+ plugin_properties_sp->AppendProperty (g_property_name,
+ ConstString("Settings specific to plugins"),
+ true,
+ plugin_type_properties_sp);
+ }
+ return plugin_type_properties_sp;
+ }
+ }
+ return lldb::OptionValuePropertiesSP();
+}
+
+
+lldb::OptionValuePropertiesSP
+PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name)
+{
+ lldb::OptionValuePropertiesSP properties_sp;
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
+ ConstString("dynamic-loader"),
+ ConstString(), // not creating to so we don't need the description
+ false));
+ if (plugin_type_properties_sp)
+ properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
+ return properties_sp;
+}
+
+bool
+PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
+ const lldb::OptionValuePropertiesSP &properties_sp,
+ const ConstString &description,
+ bool is_global_property)
+{
+ if (properties_sp)
+ {
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
+ ConstString("dynamic-loader"),
+ ConstString("Settings for dynamic loader plug-ins"),
+ true));
+ if (plugin_type_properties_sp)
+ {
+ plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
+ description,
+ is_global_property,
+ properties_sp);
+ return true;
+ }
+ }
+ return false;
+}
+
+
+lldb::OptionValuePropertiesSP
+PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
+{
+ lldb::OptionValuePropertiesSP properties_sp;
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
+ ConstString("platform"),
+ ConstString(), // not creating to so we don't need the description
+ false));
+ if (plugin_type_properties_sp)
+ properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
+ return properties_sp;
+}
+
+bool
+PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
+ const lldb::OptionValuePropertiesSP &properties_sp,
+ const ConstString &description,
+ bool is_global_property)
+{
+ if (properties_sp)
+ {
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
+ ConstString("platform"),
+ ConstString("Settings for platform plug-ins"),
+ true));
+ if (plugin_type_properties_sp)
+ {
+ plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
+ description,
+ is_global_property,
+ properties_sp);
+ return true;
+ }
+ }
+ return false;
+}
+
+
+lldb::OptionValuePropertiesSP
+PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
+{
+ lldb::OptionValuePropertiesSP properties_sp;
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
+ ConstString("process"),
+ ConstString(), // not creating to so we don't need the description
+ false));
+ if (plugin_type_properties_sp)
+ properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
+ return properties_sp;
+}
+
+bool
+PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
+ const lldb::OptionValuePropertiesSP &properties_sp,
+ const ConstString &description,
+ bool is_global_property)
+{
+ if (properties_sp)
+ {
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
+ ConstString("process"),
+ ConstString("Settings for process plug-ins"),
+ true));
+ if (plugin_type_properties_sp)
+ {
+ plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
+ description,
+ is_global_property,
+ properties_sp);
+ return true;
+ }
+ }
+ return false;
+}
+