| //===-- 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 <limits.h> |
| |
| #include <string> |
| #include <vector> |
| |
| #include "lldb/Core/Error.h" |
| #include "lldb/Host/FileSpec.h" |
| #include "lldb/Host/Host.h" |
| #include "lldb/Host/Mutex.h" |
| |
| #include "llvm/ADT/StringRef.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| enum PluginAction |
| { |
| ePluginRegisterInstance, |
| ePluginUnregisterInstance, |
| ePluginGetInstanceAtIndex |
| }; |
| |
| struct PluginInfo |
| { |
| void *plugin_handle; |
| void *plugin_init_callback; |
| void *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 = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error); |
| if (plugin_info.plugin_init_callback) |
| { |
| // Call the plug-in "bool LLDBPluginInitialize(void)" function |
| success = ((bool (*)(void))plugin_info.plugin_init_callback)(); |
| } |
| |
| if (success) |
| { |
| // It is ok for the "LLDBPluginTerminate" symbol to be NULL |
| plugin_info.plugin_term_callback = 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) |
| ((void (*)(void))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) |
| { |
| } |
| |
| std::string 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 char *name, |
| const char *description, |
| ABICreateInstance create_callback |
| ) |
| { |
| if (create_callback) |
| { |
| ABIInstance instance; |
| assert (name && name[0]); |
| instance.name.assign (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 char *name) |
| { |
| if (name && name[0]) |
| { |
| Mutex::Locker locker (GetABIInstancesMutex ()); |
| llvm::StringRef name_sref(name); |
| ABIInstances &instances = GetABIInstances (); |
| |
| ABIInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| |
| #pragma mark Disassembler |
| |
| |
| struct DisassemblerInstance |
| { |
| DisassemblerInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string 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 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; |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetDisassemblerMutex ()); |
| DisassemblerInstances &instances = GetDisassemblerInstances (); |
| |
| DisassemblerInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| |
| |
| #pragma mark DynamicLoader |
| |
| |
| struct DynamicLoaderInstance |
| { |
| DynamicLoaderInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string name; |
| std::string description; |
| DynamicLoaderCreateInstance create_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 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; |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetDynamicLoaderMutex ()); |
| DynamicLoaderInstances &instances = GetDynamicLoaderInstances (); |
| |
| DynamicLoaderInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| #pragma mark EmulateInstruction |
| |
| |
| struct EmulateInstructionInstance |
| { |
| EmulateInstructionInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string 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 char *name, |
| const char *description, |
| EmulateInstructionCreateInstance create_callback |
| ) |
| { |
| if (create_callback) |
| { |
| EmulateInstructionInstance instance; |
| assert (name && name[0]); |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetEmulateInstructionMutex ()); |
| EmulateInstructionInstances &instances = GetEmulateInstructionInstances (); |
| |
| EmulateInstructionInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| |
| #pragma mark LanguageRuntime |
| |
| |
| struct LanguageRuntimeInstance |
| { |
| LanguageRuntimeInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string 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 char *name, |
| const char *description, |
| LanguageRuntimeCreateInstance create_callback |
| ) |
| { |
| if (create_callback) |
| { |
| LanguageRuntimeInstance instance; |
| assert (name && name[0]); |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetLanguageRuntimeMutex ()); |
| LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances (); |
| |
| LanguageRuntimeInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| #pragma mark ObjectFile |
| |
| struct ObjectFileInstance |
| { |
| ObjectFileInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string name; |
| std::string description; |
| ObjectFileCreateInstance create_callback; |
| }; |
| |
| 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 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; |
| 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; |
| } |
| |
| ObjectFileCreateInstance |
| PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetObjectFileMutex ()); |
| ObjectFileInstances &instances = GetObjectFileInstances (); |
| |
| ObjectFileInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| |
| |
| #pragma mark ObjectContainer |
| |
| struct ObjectContainerInstance |
| { |
| ObjectContainerInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string name; |
| std::string description; |
| ObjectContainerCreateInstance create_callback; |
| }; |
| |
| 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 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; |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetObjectContainerMutex ()); |
| ObjectContainerInstances &instances = GetObjectContainerInstances (); |
| |
| ObjectContainerInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| #pragma mark LogChannel |
| |
| struct LogInstance |
| { |
| LogInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string 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 char *name, |
| const char *description, |
| LogChannelCreateInstance create_callback |
| ) |
| { |
| if (create_callback) |
| { |
| LogInstance instance; |
| assert (name && name[0]); |
| 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.c_str(); |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetLogMutex ()); |
| LogInstances &instances = GetLogInstances (); |
| |
| LogInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| #pragma mark Platform |
| |
| struct PlatformInstance |
| { |
| PlatformInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string name; |
| std::string description; |
| PlatformCreateInstance create_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 char *name, |
| const char *description, |
| PlatformCreateInstance create_callback) |
| { |
| if (create_callback) |
| { |
| Mutex::Locker locker (GetPlatformInstancesMutex ()); |
| |
| PlatformInstance instance; |
| assert (name && name[0]); |
| instance.name = name; |
| if (description && description[0]) |
| instance.description = description; |
| instance.create_callback = create_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.c_str(); |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| 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) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| uint32_t |
| PluginManager::AutoCompletePlatformName (const char *name, StringList &matches) |
| { |
| if (name && name[0]) |
| { |
| 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); |
| 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) |
| { |
| } |
| |
| std::string name; |
| std::string description; |
| ProcessCreateInstance create_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 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; |
| 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.c_str(); |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetProcessMutex ()); |
| ProcessInstances &instances = GetProcessInstances (); |
| |
| ProcessInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| #pragma mark SymbolFile |
| |
| struct SymbolFileInstance |
| { |
| SymbolFileInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string 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 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; |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetSymbolFileMutex ()); |
| SymbolFileInstances &instances = GetSymbolFileInstances (); |
| |
| SymbolFileInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| |
| |
| #pragma mark SymbolVendor |
| |
| struct SymbolVendorInstance |
| { |
| SymbolVendorInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string 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 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; |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetSymbolVendorMutex ()); |
| SymbolVendorInstances &instances = GetSymbolVendorInstances (); |
| |
| SymbolVendorInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| |
| #pragma mark UnwindAssembly |
| |
| struct UnwindAssemblyInstance |
| { |
| UnwindAssemblyInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string 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 char *name, |
| const char *description, |
| UnwindAssemblyCreateInstance create_callback |
| ) |
| { |
| if (create_callback) |
| { |
| UnwindAssemblyInstance instance; |
| assert (name && name[0]); |
| 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 char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetUnwindAssemblyMutex ()); |
| UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances (); |
| |
| UnwindAssemblyInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| #pragma mark ArchDefaultUnwindPlan |
| |
| struct ArchDefaultUnwindPlanInstance |
| { |
| ArchDefaultUnwindPlanInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string name; |
| std::string description; |
| ArchDefaultUnwindPlanCreateInstance create_callback; |
| }; |
| |
| typedef std::vector<ArchDefaultUnwindPlanInstance> ArchDefaultUnwindPlanInstances; |
| |
| static Mutex & |
| GetArchDefaultUnwindPlanMutex () |
| { |
| static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); |
| return g_instances_mutex; |
| } |
| |
| static ArchDefaultUnwindPlanInstances & |
| GetArchDefaultUnwindPlanInstances () |
| { |
| static ArchDefaultUnwindPlanInstances g_instances; |
| return g_instances; |
| } |
| |
| |
| bool |
| PluginManager::RegisterPlugin |
| ( |
| const char *name, |
| const char *description, |
| ArchDefaultUnwindPlanCreateInstance create_callback |
| ) |
| { |
| if (create_callback) |
| { |
| ArchDefaultUnwindPlanInstance instance; |
| assert (name && name[0]); |
| instance.name = name; |
| if (description && description[0]) |
| instance.description = description; |
| instance.create_callback = create_callback; |
| Mutex::Locker locker (GetArchDefaultUnwindPlanMutex ()); |
| GetArchDefaultUnwindPlanInstances ().push_back (instance); |
| } |
| return false; |
| } |
| |
| bool |
| PluginManager::UnregisterPlugin (ArchDefaultUnwindPlanCreateInstance create_callback) |
| { |
| if (create_callback) |
| { |
| Mutex::Locker locker (GetArchDefaultUnwindPlanMutex ()); |
| ArchDefaultUnwindPlanInstances &instances = GetArchDefaultUnwindPlanInstances (); |
| |
| ArchDefaultUnwindPlanInstances::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; |
| } |
| |
| ArchDefaultUnwindPlanCreateInstance |
| PluginManager::GetArchDefaultUnwindPlanCreateCallbackAtIndex (uint32_t idx) |
| { |
| Mutex::Locker locker (GetArchDefaultUnwindPlanMutex ()); |
| ArchDefaultUnwindPlanInstances &instances = GetArchDefaultUnwindPlanInstances (); |
| if (idx < instances.size()) |
| return instances[idx].create_callback; |
| return NULL; |
| } |
| |
| |
| ArchDefaultUnwindPlanCreateInstance |
| PluginManager::GetArchDefaultUnwindPlanCreateCallbackForPluginName (const char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetArchDefaultUnwindPlanMutex ()); |
| ArchDefaultUnwindPlanInstances &instances = GetArchDefaultUnwindPlanInstances (); |
| |
| ArchDefaultUnwindPlanInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |
| #pragma mark ArchVolatileRegs |
| |
| struct ArchVolatileRegsInstance |
| { |
| ArchVolatileRegsInstance() : |
| name(), |
| description(), |
| create_callback(NULL) |
| { |
| } |
| |
| std::string name; |
| std::string description; |
| ArchVolatileRegsCreateInstance create_callback; |
| }; |
| |
| typedef std::vector<ArchVolatileRegsInstance> ArchVolatileRegsInstances; |
| |
| static Mutex & |
| GetArchVolatileRegsMutex () |
| { |
| static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); |
| return g_instances_mutex; |
| } |
| |
| static ArchVolatileRegsInstances & |
| GetArchVolatileRegsInstances () |
| { |
| static ArchVolatileRegsInstances g_instances; |
| return g_instances; |
| } |
| |
| bool |
| PluginManager::RegisterPlugin |
| ( |
| const char *name, |
| const char *description, |
| ArchVolatileRegsCreateInstance create_callback |
| ) |
| { |
| if (create_callback) |
| { |
| ArchVolatileRegsInstance instance; |
| assert (name && name[0]); |
| instance.name = name; |
| if (description && description[0]) |
| instance.description = description; |
| instance.create_callback = create_callback; |
| Mutex::Locker locker (GetArchVolatileRegsMutex ()); |
| GetArchVolatileRegsInstances ().push_back (instance); |
| } |
| return false; |
| } |
| |
| bool |
| PluginManager::UnregisterPlugin (ArchVolatileRegsCreateInstance create_callback) |
| { |
| if (create_callback) |
| { |
| Mutex::Locker locker (GetArchVolatileRegsMutex ()); |
| ArchVolatileRegsInstances &instances = GetArchVolatileRegsInstances (); |
| |
| ArchVolatileRegsInstances::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; |
| } |
| |
| ArchVolatileRegsCreateInstance |
| PluginManager::GetArchVolatileRegsCreateCallbackAtIndex (uint32_t idx) |
| { |
| Mutex::Locker locker (GetArchVolatileRegsMutex ()); |
| ArchVolatileRegsInstances &instances = GetArchVolatileRegsInstances (); |
| if (idx < instances.size()) |
| return instances[idx].create_callback; |
| return NULL; |
| } |
| |
| ArchVolatileRegsCreateInstance |
| PluginManager::GetArchVolatileRegsCreateCallbackForPluginName (const char *name) |
| { |
| if (name && name[0]) |
| { |
| llvm::StringRef name_sref(name); |
| Mutex::Locker locker (GetArchVolatileRegsMutex ()); |
| ArchVolatileRegsInstances &instances = GetArchVolatileRegsInstances (); |
| |
| ArchVolatileRegsInstances::iterator pos, end = instances.end(); |
| for (pos = instances.begin(); pos != end; ++ pos) |
| { |
| if (name_sref.equals (pos->name)) |
| return pos->create_callback; |
| } |
| } |
| return NULL; |
| } |
| |