diff options
Diffstat (limited to 'lldb/source/Core/PluginManager.cpp')
-rw-r--r-- | lldb/source/Core/PluginManager.cpp | 1133 |
1 files changed, 1133 insertions, 0 deletions
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp new file mode 100644 index 00000000000..3723e7cf89a --- /dev/null +++ b/lldb/source/Core/PluginManager.cpp @@ -0,0 +1,1133 @@ +//===-- 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/Core/PluginManager.h" + +#include <string> +#include <vector> + +using namespace lldb_private; + +typedef enum PluginAction +{ + ePluginRegisterInstance, + ePluginUnregisterInstance, + ePluginGetInstanceAtIndex +}; + + +#pragma mark ABI + + +typedef struct ABIInstance +{ + ABIInstance() : + name(), + description(), + create_callback(NULL) + { + } + + std::string name; + std::string description; + ABICreateInstance create_callback; +}; + +typedef std::vector<ABIInstance> ABIInstances; + +static bool +AccessABIInstances (PluginAction action, ABIInstance &instance, uint32_t index) +{ + static ABIInstances g_plugin_instances; + + switch (action) + { + case ePluginRegisterInstance: + if (instance.create_callback) + { + g_plugin_instances.push_back (instance); + return true; + } + break; + + case ePluginUnregisterInstance: + if (instance.create_callback) + { + ABIInstances::iterator pos, end = g_plugin_instances.end(); + for (pos = g_plugin_instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == instance.create_callback) + { + g_plugin_instances.erase(pos); + return true; + } + } + } + break; + + case ePluginGetInstanceAtIndex: + if (index < g_plugin_instances.size()) + { + instance = g_plugin_instances[index]; + return true; + } + break; + + default: + break; + } + return false; +} + + +bool +PluginManager::RegisterPlugin + ( + const char *name, + const char *description, + ABICreateInstance create_callback + ) +{ + if (create_callback) + { + ABIInstance instance; + assert (name && name[0]); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + return AccessABIInstances (ePluginRegisterInstance, instance, 0); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (ABICreateInstance create_callback) +{ + if (create_callback) + { + ABIInstance instance; + instance.create_callback = create_callback; + return AccessABIInstances (ePluginUnregisterInstance, instance, 0); + } + return false; +} + +ABICreateInstance +PluginManager::GetABICreateCallbackAtIndex (uint32_t idx) +{ + ABIInstance instance; + if (AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx)) + return instance.create_callback; + return false; +} + +ABICreateInstance +PluginManager::GetABICreateCallbackForPluginName (const char *name) +{ + if (name && name[0]) + { + ABIInstance instance; + std::string ss_name(name); + for (uint32_t idx = 0; AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) + { + if (instance.name == ss_name) + return instance.create_callback; + } + } + return NULL; +} + + +#pragma mark Disassembler + + +typedef struct DisassemblerInstance +{ + DisassemblerInstance() : + name(), + description(), + create_callback(NULL) + { + } + + std::string name; + std::string description; + DisassemblerCreateInstance create_callback; +}; + +typedef std::vector<DisassemblerInstance> DisassemblerInstances; + +static bool +AccessDisassemblerInstances (PluginAction action, DisassemblerInstance &instance, uint32_t index) +{ + static DisassemblerInstances g_plugin_instances; + + switch (action) + { + case ePluginRegisterInstance: + if (instance.create_callback) + { + g_plugin_instances.push_back (instance); + return true; + } + break; + + case ePluginUnregisterInstance: + if (instance.create_callback) + { + DisassemblerInstances::iterator pos, end = g_plugin_instances.end(); + for (pos = g_plugin_instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == instance.create_callback) + { + g_plugin_instances.erase(pos); + return true; + } + } + } + break; + + case ePluginGetInstanceAtIndex: + if (index < g_plugin_instances.size()) + { + instance = g_plugin_instances[index]; + return true; + } + break; + + default: + break; + } + return false; +} + + +bool +PluginManager::RegisterPlugin +( + const char *name, + const char *description, + DisassemblerCreateInstance create_callback +) +{ + if (create_callback) + { + DisassemblerInstance instance; + assert (name && name[0]); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + return AccessDisassemblerInstances (ePluginRegisterInstance, instance, 0); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback) +{ + if (create_callback) + { + DisassemblerInstance instance; + instance.create_callback = create_callback; + return AccessDisassemblerInstances (ePluginUnregisterInstance, instance, 0); + } + return false; +} + +DisassemblerCreateInstance +PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx) +{ + DisassemblerInstance instance; + if (AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx)) + return instance.create_callback; + return false; +} + +DisassemblerCreateInstance +PluginManager::GetDisassemblerCreateCallbackForPluginName (const char *name) +{ + if (name && name[0]) + { + DisassemblerInstance instance; + std::string ss_name(name); + for (uint32_t idx = 0; AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) + { + if (instance.name == ss_name) + return instance.create_callback; + } + } + return NULL; +} + + + +#pragma mark DynamicLoader + + +typedef struct DynamicLoaderInstance +{ + DynamicLoaderInstance() : + name(), + description(), + create_callback(NULL) + { + } + + std::string name; + std::string description; + DynamicLoaderCreateInstance create_callback; +}; + +typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances; + +static bool +AccessDynamicLoaderInstances (PluginAction action, DynamicLoaderInstance &instance, uint32_t index) +{ + static DynamicLoaderInstances g_plugin_instances; + + switch (action) + { + case ePluginRegisterInstance: + if (instance.create_callback) + { + g_plugin_instances.push_back (instance); + return true; + } + break; + + case ePluginUnregisterInstance: + if (instance.create_callback) + { + DynamicLoaderInstances::iterator pos, end = g_plugin_instances.end(); + for (pos = g_plugin_instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == instance.create_callback) + { + g_plugin_instances.erase(pos); + return true; + } + } + } + break; + + case ePluginGetInstanceAtIndex: + if (index < g_plugin_instances.size()) + { + instance = g_plugin_instances[index]; + return true; + } + break; + + default: + break; + } + return false; +} + + +bool +PluginManager::RegisterPlugin +( + const char *name, + const char *description, + DynamicLoaderCreateInstance create_callback +) +{ + if (create_callback) + { + DynamicLoaderInstance instance; + assert (name && name[0]); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + return AccessDynamicLoaderInstances (ePluginRegisterInstance, instance, 0); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback) +{ + if (create_callback) + { + DynamicLoaderInstance instance; + instance.create_callback = create_callback; + return AccessDynamicLoaderInstances (ePluginUnregisterInstance, instance, 0); + } + return false; +} + +DynamicLoaderCreateInstance +PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx) +{ + DynamicLoaderInstance instance; + if (AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx)) + return instance.create_callback; + return false; +} + +DynamicLoaderCreateInstance +PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const char *name) +{ + if (name && name[0]) + { + DynamicLoaderInstance instance; + std::string ss_name(name); + for (uint32_t idx = 0; AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) + { + if (instance.name == ss_name) + return instance.create_callback; + } + } + return NULL; +} + + + + +#pragma mark ObjectFile + +typedef struct ObjectFileInstance +{ + ObjectFileInstance() : + name(), + description(), + create_callback(NULL) + { + } + + std::string name; + std::string description; + ObjectFileCreateInstance create_callback; +}; + +typedef std::vector<ObjectFileInstance> ObjectFileInstances; + +static bool +AccessObjectFileInstances (PluginAction action, ObjectFileInstance &instance, uint32_t index) +{ + static ObjectFileInstances g_plugin_instances; + + switch (action) + { + case ePluginRegisterInstance: + if (instance.create_callback) + { + g_plugin_instances.push_back (instance); + return true; + } + break; + + case ePluginUnregisterInstance: + if (instance.create_callback) + { + ObjectFileInstances::iterator pos, end = g_plugin_instances.end(); + for (pos = g_plugin_instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == instance.create_callback) + { + g_plugin_instances.erase(pos); + return true; + } + } + } + break; + + case ePluginGetInstanceAtIndex: + if (index < g_plugin_instances.size()) + { + instance = g_plugin_instances[index]; + return true; + } + break; + + default: + break; + } + return false; +} + + +bool +PluginManager::RegisterPlugin +( + const char *name, + const char *description, + ObjectFileCreateInstance create_callback +) +{ + if (create_callback) + { + ObjectFileInstance instance; + assert (name && name[0]); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + return AccessObjectFileInstances (ePluginRegisterInstance, instance, 0); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback) +{ + if (create_callback) + { + ObjectFileInstance instance; + instance.create_callback = create_callback; + return AccessObjectFileInstances (ePluginUnregisterInstance, instance, 0); + } + return false; +} + +ObjectFileCreateInstance +PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx) +{ + ObjectFileInstance instance; + if (AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx)) + return instance.create_callback; + return false; +} +ObjectFileCreateInstance +PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name) +{ + if (name && name[0]) + { + ObjectFileInstance instance; + std::string ss_name(name); + for (uint32_t idx = 0; AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) + { + if (instance.name == ss_name) + return instance.create_callback; + } + } + return NULL; +} + + + +#pragma mark ObjectContainer + +typedef struct ObjectContainerInstance +{ + ObjectContainerInstance() : + name(), + description(), + create_callback(NULL) + { + } + + std::string name; + std::string description; + ObjectContainerCreateInstance create_callback; +}; + +typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; + +static bool +AccessObjectContainerInstances (PluginAction action, ObjectContainerInstance &instance, uint32_t index) +{ + static ObjectContainerInstances g_plugin_instances; + + switch (action) + { + case ePluginRegisterInstance: + if (instance.create_callback) + { + g_plugin_instances.push_back (instance); + return true; + } + break; + + case ePluginUnregisterInstance: + if (instance.create_callback) + { + ObjectContainerInstances::iterator pos, end = g_plugin_instances.end(); + for (pos = g_plugin_instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == instance.create_callback) + { + g_plugin_instances.erase(pos); + return true; + } + } + } + break; + + case ePluginGetInstanceAtIndex: + if (index < g_plugin_instances.size()) + { + instance = g_plugin_instances[index]; + return true; + } + break; + + default: + break; + } + return false; +} + + +bool +PluginManager::RegisterPlugin +( + const char *name, + const char *description, + ObjectContainerCreateInstance create_callback +) +{ + if (create_callback) + { + ObjectContainerInstance instance; + assert (name && name[0]); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + return AccessObjectContainerInstances (ePluginRegisterInstance, instance, 0); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback) +{ + if (create_callback) + { + ObjectContainerInstance instance; + instance.create_callback = create_callback; + return AccessObjectContainerInstances (ePluginUnregisterInstance, instance, 0); + } + return false; +} + +ObjectContainerCreateInstance +PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx) +{ + ObjectContainerInstance instance; + if (AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx)) + return instance.create_callback; + return false; +} +ObjectContainerCreateInstance +PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name) +{ + if (name && name[0]) + { + ObjectContainerInstance instance; + std::string ss_name(name); + for (uint32_t idx = 0; AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) + { + if (instance.name == ss_name) + return instance.create_callback; + } + } + return NULL; +} + +#pragma mark LogChannel + +typedef struct LogChannelInstance +{ + LogChannelInstance() : + name(), + description(), + create_callback(NULL) + { + } + + std::string name; + std::string description; + LogChannelCreateInstance create_callback; +}; + +typedef std::vector<LogChannelInstance> LogChannelInstances; + +static bool +AccessLogChannelInstances (PluginAction action, LogChannelInstance &instance, uint32_t index) +{ + static LogChannelInstances g_plugin_instances; + + switch (action) + { + case ePluginRegisterInstance: + if (instance.create_callback) + { + g_plugin_instances.push_back (instance); + return true; + } + break; + + case ePluginUnregisterInstance: + if (instance.create_callback) + { + LogChannelInstances::iterator pos, end = g_plugin_instances.end(); + for (pos = g_plugin_instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == instance.create_callback) + { + g_plugin_instances.erase(pos); + return true; + } + } + } + break; + + case ePluginGetInstanceAtIndex: + if (index < g_plugin_instances.size()) + { + instance = g_plugin_instances[index]; + return true; + } + break; + + default: + break; + } + return false; +} + + +bool +PluginManager::RegisterPlugin +( + const char *name, + const char *description, + LogChannelCreateInstance create_callback +) +{ + if (create_callback) + { + LogChannelInstance instance; + assert (name && name[0]); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + return AccessLogChannelInstances (ePluginRegisterInstance, instance, 0); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback) +{ + if (create_callback) + { + LogChannelInstance instance; + instance.create_callback = create_callback; + return AccessLogChannelInstances (ePluginUnregisterInstance, instance, 0); + } + return false; +} + +const char * +PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx) +{ + LogChannelInstance instance; + if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx)) + return instance.name.c_str(); + return NULL; +} + + +LogChannelCreateInstance +PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx) +{ + LogChannelInstance instance; + if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx)) + return instance.create_callback; + return false; +} + +LogChannelCreateInstance +PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name) +{ + if (name && name[0]) + { + LogChannelInstance instance; + std::string ss_name(name); + for (uint32_t idx = 0; AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) + { + if (instance.name == ss_name) + return instance.create_callback; + } + } + return NULL; +} + +#pragma mark Process + +typedef struct ProcessInstance +{ + ProcessInstance() : + name(), + description(), + create_callback(NULL) + { + } + + std::string name; + std::string description; + ProcessCreateInstance create_callback; +}; + +typedef std::vector<ProcessInstance> ProcessInstances; + +static bool +AccessProcessInstances (PluginAction action, ProcessInstance &instance, uint32_t index) +{ + static ProcessInstances g_plugin_instances; + + switch (action) + { + case ePluginRegisterInstance: + if (instance.create_callback) + { + g_plugin_instances.push_back (instance); + return true; + } + break; + + case ePluginUnregisterInstance: + if (instance.create_callback) + { + ProcessInstances::iterator pos, end = g_plugin_instances.end(); + for (pos = g_plugin_instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == instance.create_callback) + { + g_plugin_instances.erase(pos); + return true; + } + } + } + break; + + case ePluginGetInstanceAtIndex: + if (index < g_plugin_instances.size()) + { + instance = g_plugin_instances[index]; + return true; + } + break; + + default: + break; + } + return false; +} + + +bool +PluginManager::RegisterPlugin +( + const char *name, + const char *description, + ProcessCreateInstance create_callback +) +{ + if (create_callback) + { + ProcessInstance instance; + assert (name && name[0]); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + return AccessProcessInstances (ePluginRegisterInstance, instance, 0); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback) +{ + if (create_callback) + { + ProcessInstance instance; + instance.create_callback = create_callback; + return AccessProcessInstances (ePluginUnregisterInstance, instance, 0); + } + return false; +} + +ProcessCreateInstance +PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx) +{ + ProcessInstance instance; + if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx)) + return instance.create_callback; + return false; +} + +ProcessCreateInstance +PluginManager::GetProcessCreateCallbackForPluginName (const char *name) +{ + if (name && name[0]) + { + ProcessInstance instance; + std::string ss_name(name); + for (uint32_t idx = 0; AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) + { + if (instance.name == ss_name) + return instance.create_callback; + } + } + return NULL; +} + +#pragma mark SymbolFile + +typedef struct SymbolFileInstance +{ + SymbolFileInstance() : + name(), + description(), + create_callback(NULL) + { + } + + std::string name; + std::string description; + SymbolFileCreateInstance create_callback; +}; + +typedef std::vector<SymbolFileInstance> SymbolFileInstances; + +static bool +AccessSymbolFileInstances (PluginAction action, SymbolFileInstance &instance, uint32_t index) +{ + static SymbolFileInstances g_plugin_instances; + + switch (action) + { + case ePluginRegisterInstance: + if (instance.create_callback) + { + g_plugin_instances.push_back (instance); + return true; + } + break; + + case ePluginUnregisterInstance: + if (instance.create_callback) + { + SymbolFileInstances::iterator pos, end = g_plugin_instances.end(); + for (pos = g_plugin_instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == instance.create_callback) + { + g_plugin_instances.erase(pos); + return true; + } + } + } + break; + + case ePluginGetInstanceAtIndex: + if (index < g_plugin_instances.size()) + { + instance = g_plugin_instances[index]; + return true; + } + break; + + default: + break; + } + return false; +} + + +bool +PluginManager::RegisterPlugin +( + const char *name, + const char *description, + SymbolFileCreateInstance create_callback +) +{ + if (create_callback) + { + SymbolFileInstance instance; + assert (name && name[0]); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + return AccessSymbolFileInstances (ePluginRegisterInstance, instance, 0); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback) +{ + if (create_callback) + { + SymbolFileInstance instance; + instance.create_callback = create_callback; + return AccessSymbolFileInstances (ePluginUnregisterInstance, instance, 0); + } + return false; +} + +SymbolFileCreateInstance +PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx) +{ + SymbolFileInstance instance; + if (AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx)) + return instance.create_callback; + return false; +} +SymbolFileCreateInstance +PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name) +{ + if (name && name[0]) + { + SymbolFileInstance instance; + std::string ss_name(name); + for (uint32_t idx = 0; AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) + { + if (instance.name == ss_name) + return instance.create_callback; + } + } + return NULL; +} + + + +#pragma mark SymbolVendor + +typedef struct SymbolVendorInstance +{ + SymbolVendorInstance() : + name(), + description(), + create_callback(NULL) + { + } + + std::string name; + std::string description; + SymbolVendorCreateInstance create_callback; +}; + +typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; + +static bool +AccessSymbolVendorInstances (PluginAction action, SymbolVendorInstance &instance, uint32_t index) +{ + static SymbolVendorInstances g_plugin_instances; + + switch (action) + { + case ePluginRegisterInstance: + if (instance.create_callback) + { + g_plugin_instances.push_back (instance); + return true; + } + break; + + case ePluginUnregisterInstance: + if (instance.create_callback) + { + SymbolVendorInstances::iterator pos, end = g_plugin_instances.end(); + for (pos = g_plugin_instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == instance.create_callback) + { + g_plugin_instances.erase(pos); + return true; + } + } + } + break; + + case ePluginGetInstanceAtIndex: + if (index < g_plugin_instances.size()) + { + instance = g_plugin_instances[index]; + return true; + } + break; + + default: + break; + } + return false; +} + +bool +PluginManager::RegisterPlugin +( + const char *name, + const char *description, + SymbolVendorCreateInstance create_callback +) +{ + if (create_callback) + { + SymbolVendorInstance instance; + assert (name && name[0]); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + return AccessSymbolVendorInstances (ePluginRegisterInstance, instance, 0); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback) +{ + if (create_callback) + { + SymbolVendorInstance instance; + instance.create_callback = create_callback; + return AccessSymbolVendorInstances (ePluginUnregisterInstance, instance, 0); + } + return false; +} + +SymbolVendorCreateInstance +PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx) +{ + SymbolVendorInstance instance; + if (AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx)) + return instance.create_callback; + return false; +} + +SymbolVendorCreateInstance +PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name) +{ + if (name && name[0]) + { + SymbolVendorInstance instance; + std::string ss_name(name); + for (uint32_t idx = 0; AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) + { + if (instance.name == ss_name) + return instance.create_callback; + } + } + return NULL; +} + + |