llvm-project/lldb/source/Core/PluginManager.cpp

3052 lines
91 KiB
C++

//===-- 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"
// C Includes
// C++ Includes
#include <climits>
#include <mutex>
#include <string>
#include <vector>
// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DynamicLibrary.h"
// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/OptionValueProperties.h"
using namespace lldb;
using namespace lldb_private;
enum PluginAction
{
ePluginRegisterInstance,
ePluginUnregisterInstance,
ePluginGetInstanceAtIndex
};
typedef bool (*PluginInitCallback)();
typedef void (*PluginTermCallback)();
struct PluginInfo
{
PluginInfo()
: plugin_init_callback(nullptr), plugin_term_callback(nullptr)
{
}
llvm::sys::DynamicLibrary library;
PluginInitCallback plugin_init_callback;
PluginTermCallback plugin_term_callback;
};
typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
static std::recursive_mutex &
GetPluginMapMutex()
{
static std::recursive_mutex g_plugin_map_mutex;
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)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
PluginTerminateMap &plugin_map = GetPluginMap ();
assert (plugin_map.find (plugin_file_spec) == plugin_map.end());
plugin_map[plugin_file_spec] = plugin_info;
}
template <typename FPtrTy>
static FPtrTy
CastToFPtr (void *VPtr)
{
return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
}
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;
std::string pluginLoadError;
plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary (plugin_file_spec.GetPath().c_str(), &pluginLoadError);
if (plugin_info.library.isValid())
{
bool success = false;
plugin_info.plugin_init_callback =
CastToFPtr<PluginInitCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
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 nullptr
plugin_info.plugin_term_callback =
CastToFPtr<PluginTermCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
}
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. Set it to a default-constructed instance to invalidate it.
plugin_info = PluginInfo();
}
// 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 enumerating 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 (HostInfo::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,
nullptr);
}
}
if (HostInfo::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,
nullptr);
}
}
#endif
}
void
PluginManager::Terminate ()
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr).
if (pos->second.library.isValid())
{
if (pos->second.plugin_term_callback)
pos->second.plugin_term_callback();
}
}
plugin_map.clear();
}
#pragma mark ABI
struct ABIInstance
{
ABIInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
ABICreateInstance create_callback;
};
typedef std::vector<ABIInstance> ABIInstances;
static std::recursive_mutex &
GetABIInstancesMutex()
{
static std::recursive_mutex g_instances_mutex;
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;
std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
GetABIInstances ().push_back (instance);
return true;
}
return false;
}
bool
PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
ABIInstances &instances = GetABIInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
ABICreateInstance
PluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
#pragma mark Disassembler
struct DisassemblerInstance
{
DisassemblerInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
DisassemblerCreateInstance create_callback;
};
typedef std::vector<DisassemblerInstance> DisassemblerInstances;
static std::recursive_mutex &
GetDisassemblerMutex()
{
static std::recursive_mutex g_instances_mutex;
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;
std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
GetDisassemblerInstances ().push_back (instance);
return true;
}
return false;
}
bool
PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
DisassemblerInstances &instances = GetDisassemblerInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
DisassemblerCreateInstance
PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
#pragma mark DynamicLoader
struct DynamicLoaderInstance
{
DynamicLoaderInstance() :
name(),
description(),
create_callback(nullptr),
debugger_init_callback(nullptr)
{
}
ConstString name;
std::string description;
DynamicLoaderCreateInstance create_callback;
DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
static std::recursive_mutex &
GetDynamicLoaderMutex()
{
static std::recursive_mutex g_instances_mutex;
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;
std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
GetDynamicLoaderInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
DynamicLoaderCreateInstance
PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
#pragma mark JITLoader
struct JITLoaderInstance
{
JITLoaderInstance() :
name(),
description(),
create_callback(nullptr),
debugger_init_callback(nullptr)
{
}
ConstString name;
std::string description;
JITLoaderCreateInstance create_callback;
DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<JITLoaderInstance> JITLoaderInstances;
static std::recursive_mutex &
GetJITLoaderMutex()
{
static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
static JITLoaderInstances &
GetJITLoaderInstances ()
{
static JITLoaderInstances g_instances;
return g_instances;
}
bool
PluginManager::RegisterPlugin(const ConstString &name,
const char *description,
JITLoaderCreateInstance create_callback,
DebuggerInitializeCallback debugger_init_callback)
{
if (create_callback)
{
JITLoaderInstance 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;
std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
GetJITLoaderInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (JITLoaderCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
JITLoaderInstances &instances = GetJITLoaderInstances ();
JITLoaderInstances::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;
}
JITLoaderCreateInstance
PluginManager::GetJITLoaderCreateCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
JITLoaderInstances &instances = GetJITLoaderInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
JITLoaderCreateInstance
PluginManager::GetJITLoaderCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
JITLoaderInstances &instances = GetJITLoaderInstances ();
JITLoaderInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (name == pos->name)
return pos->create_callback;
}
}
return nullptr;
}
#pragma mark EmulateInstruction
struct EmulateInstructionInstance
{
EmulateInstructionInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
EmulateInstructionCreateInstance create_callback;
};
typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
static std::recursive_mutex &
GetEmulateInstructionMutex()
{
static std::recursive_mutex g_instances_mutex;
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;
std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
GetEmulateInstructionInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
EmulateInstructionCreateInstance
PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
#pragma mark OperatingSystem
struct OperatingSystemInstance
{
OperatingSystemInstance () :
name (),
description (),
create_callback (nullptr),
debugger_init_callback (nullptr)
{
}
ConstString name;
std::string description;
OperatingSystemCreateInstance create_callback;
DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
static std::recursive_mutex &
GetOperatingSystemMutex()
{
static std::recursive_mutex g_instances_mutex;
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,
DebuggerInitializeCallback debugger_init_callback)
{
if (create_callback)
{
OperatingSystemInstance 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;
std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
GetOperatingSystemInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
OperatingSystemInstances &instances = GetOperatingSystemInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
OperatingSystemCreateInstance
PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
#pragma mark Language
struct LanguageInstance
{
LanguageInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
LanguageCreateInstance create_callback;
};
typedef std::vector<LanguageInstance> LanguageInstances;
static std::recursive_mutex &
GetLanguageMutex()
{
static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
static LanguageInstances &
GetLanguageInstances ()
{
static LanguageInstances g_instances;
return g_instances;
}
bool
PluginManager::RegisterPlugin(const ConstString &name,
const char *description,
LanguageCreateInstance create_callback)
{
if (create_callback)
{
LanguageInstance instance;
assert ((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
GetLanguageInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (LanguageCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
LanguageInstances &instances = GetLanguageInstances ();
LanguageInstances::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;
}
LanguageCreateInstance
PluginManager::GetLanguageCreateCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
LanguageInstances &instances = GetLanguageInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
LanguageCreateInstance
PluginManager::GetLanguageCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
LanguageInstances &instances = GetLanguageInstances ();
LanguageInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (name == pos->name)
return pos->create_callback;
}
}
return nullptr;
}
#pragma mark LanguageRuntime
struct LanguageRuntimeInstance
{
LanguageRuntimeInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
LanguageRuntimeCreateInstance create_callback;
LanguageRuntimeGetCommandObject command_callback;
};
typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
static std::recursive_mutex &
GetLanguageRuntimeMutex()
{
static std::recursive_mutex g_instances_mutex;
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,
LanguageRuntimeGetCommandObject command_callback)
{
if (create_callback)
{
LanguageRuntimeInstance instance;
assert ((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
instance.command_callback = command_callback;
std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
GetLanguageRuntimeInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
LanguageRuntimeGetCommandObject
PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
if (idx < instances.size())
return instances[idx].command_callback;
return nullptr;
}
LanguageRuntimeCreateInstance
PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
#pragma mark SystemRuntime
struct SystemRuntimeInstance
{
SystemRuntimeInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
SystemRuntimeCreateInstance create_callback;
};
typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
static std::recursive_mutex &
GetSystemRuntimeMutex()
{
static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
static SystemRuntimeInstances &
GetSystemRuntimeInstances ()
{
static SystemRuntimeInstances g_instances;
return g_instances;
}
bool
PluginManager::RegisterPlugin(const ConstString &name,
const char *description,
SystemRuntimeCreateInstance create_callback)
{
if (create_callback)
{
SystemRuntimeInstance instance;
assert ((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
GetSystemRuntimeInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
SystemRuntimeInstances::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;
}
SystemRuntimeCreateInstance
PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
SystemRuntimeCreateInstance
PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
SystemRuntimeInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (name == pos->name)
return pos->create_callback;
}
}
return nullptr;
}
#pragma mark ObjectFile
struct ObjectFileInstance
{
ObjectFileInstance() :
name(),
description(),
create_callback(nullptr),
create_memory_callback(nullptr),
get_module_specifications(nullptr),
save_core(nullptr)
{
}
ConstString name;
std::string description;
ObjectFileCreateInstance create_callback;
ObjectFileCreateMemoryInstance create_memory_callback;
ObjectFileGetModuleSpecifications get_module_specifications;
ObjectFileSaveCore save_core;
};
typedef std::vector<ObjectFileInstance> ObjectFileInstances;
static std::recursive_mutex &
GetObjectFileMutex()
{
static std::recursive_mutex g_instances_mutex;
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,
ObjectFileSaveCore save_core)
{
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.save_core = save_core;
instance.get_module_specifications = get_module_specifications;
std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
GetObjectFileInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
ObjectFileCreateMemoryInstance
PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
if (idx < instances.size())
return instances[idx].create_memory_callback;
return nullptr;
}
ObjectFileGetModuleSpecifications
PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
if (idx < instances.size())
return instances[idx].get_module_specifications;
return nullptr;
}
ObjectFileCreateInstance
PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
ObjectFileCreateMemoryInstance
PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
Error
PluginManager::SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile)
{
Error error;
std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
ObjectFileInstances &instances = GetObjectFileInstances ();
ObjectFileInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (pos->save_core && pos->save_core (process_sp, outfile, error))
return error;
}
error.SetErrorString("no ObjectFile plugins were able to save a core for this process");
return error;
}
#pragma mark ObjectContainer
struct ObjectContainerInstance
{
ObjectContainerInstance() :
name(),
description(),
create_callback(nullptr),
get_module_specifications(nullptr)
{
}
ConstString name;
std::string description;
ObjectContainerCreateInstance create_callback;
ObjectFileGetModuleSpecifications get_module_specifications;
};
typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
static std::recursive_mutex &
GetObjectContainerMutex()
{
static std::recursive_mutex g_instances_mutex;
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;
std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
GetObjectContainerInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
ObjectContainerInstances &instances = GetObjectContainerInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
ObjectContainerCreateInstance
PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
ObjectFileGetModuleSpecifications
PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
ObjectContainerInstances &instances = GetObjectContainerInstances ();
if (idx < instances.size())
return instances[idx].get_module_specifications;
return nullptr;
}
#pragma mark LogChannel
struct LogInstance
{
LogInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
LogChannelCreateInstance create_callback;
};
typedef std::vector<LogInstance> LogInstances;
static std::recursive_mutex &
GetLogMutex()
{
static std::recursive_mutex g_instances_mutex;
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;
std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
GetLogInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> gard(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)
{
std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
LogInstances &instances = GetLogInstances ();
if (idx < instances.size())
return instances[idx].name.GetCString();
return nullptr;
}
LogChannelCreateInstance
PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
LogInstances &instances = GetLogInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
LogChannelCreateInstance
PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> gard(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 nullptr;
}
#pragma mark Platform
struct PlatformInstance
{
PlatformInstance() :
name(),
description(),
create_callback(nullptr),
debugger_init_callback(nullptr)
{
}
ConstString name;
std::string description;
PlatformCreateInstance create_callback;
DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<PlatformInstance> PlatformInstances;
static std::recursive_mutex &
GetPlatformInstancesMutex()
{
static std::recursive_mutex g_platform_instances_mutex;
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)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances ();
if (idx < instances.size())
return instances[idx].name.GetCString();
return nullptr;
}
const char *
PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances ();
if (idx < instances.size())
return instances[idx].description.c_str();
return nullptr;
}
bool
PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
PlatformCreateInstance
PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
size_t
PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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(nullptr),
debugger_init_callback(nullptr)
{
}
ConstString name;
std::string description;
ProcessCreateInstance create_callback;
DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<ProcessInstance> ProcessInstances;
static std::recursive_mutex &
GetProcessMutex()
{
static std::recursive_mutex g_instances_mutex;
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;
std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
GetProcessInstances ().push_back (instance);
}
return false;
}
const char *
PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
ProcessInstances &instances = GetProcessInstances ();
if (idx < instances.size())
return instances[idx].name.GetCString();
return nullptr;
}
const char *
PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
ProcessInstances &instances = GetProcessInstances ();
if (idx < instances.size())
return instances[idx].description.c_str();
return nullptr;
}
bool
PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
ProcessInstances &instances = GetProcessInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
ProcessCreateInstance
PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
#pragma mark ScriptInterpreter
struct ScriptInterpreterInstance
{
ScriptInterpreterInstance()
: name()
, language(lldb::eScriptLanguageNone)
, description()
, create_callback(nullptr)
{
}
ConstString name;
lldb::ScriptLanguage language;
std::string description;
ScriptInterpreterCreateInstance create_callback;
};
typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
static std::recursive_mutex &
GetScriptInterpreterMutex()
{
static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
static ScriptInterpreterInstances &
GetScriptInterpreterInstances()
{
static ScriptInterpreterInstances g_instances;
return g_instances;
}
bool
PluginManager::RegisterPlugin(const ConstString &name, const char *description, lldb::ScriptLanguage script_language,
ScriptInterpreterCreateInstance create_callback)
{
if (!create_callback)
return false;
ScriptInterpreterInstance instance;
assert((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
instance.language = script_language;
std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
GetScriptInterpreterInstances().push_back(instance);
return false;
}
bool
PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)
{
if (!create_callback)
return false;
std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
ScriptInterpreterInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++pos)
{
if (pos->create_callback != create_callback)
continue;
instances.erase(pos);
return true;
}
return false;
}
ScriptInterpreterCreateInstance
PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
lldb::ScriptInterpreterSP
PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter)
{
std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
ScriptInterpreterInstances::iterator pos, end = instances.end();
ScriptInterpreterCreateInstance none_instance = nullptr;
for (pos = instances.begin(); pos != end; ++pos)
{
if (pos->language == lldb::eScriptLanguageNone)
none_instance = pos->create_callback;
if (script_lang == pos->language)
return pos->create_callback(interpreter);
}
// If we didn't find one, return the ScriptInterpreter for the null language.
assert(none_instance != nullptr);
return none_instance(interpreter);
}
#pragma mark SymbolFile
struct SymbolFileInstance
{
SymbolFileInstance() :
name(),
description(),
create_callback(nullptr),
debugger_init_callback(nullptr)
{
}
ConstString name;
std::string description;
SymbolFileCreateInstance create_callback;
DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<SymbolFileInstance> SymbolFileInstances;
static std::recursive_mutex &
GetSymbolFileMutex()
{
static std::recursive_mutex g_instances_mutex;
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,
DebuggerInitializeCallback debugger_init_callback)
{
if (create_callback)
{
SymbolFileInstance 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;
std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
GetSymbolFileInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
SymbolFileInstances &instances = GetSymbolFileInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
SymbolFileCreateInstance
PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
#pragma mark SymbolVendor
struct SymbolVendorInstance
{
SymbolVendorInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
SymbolVendorCreateInstance create_callback;
};
typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
static std::recursive_mutex &
GetSymbolVendorMutex()
{
static std::recursive_mutex g_instances_mutex;
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;
std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
GetSymbolVendorInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
SymbolVendorInstances &instances = GetSymbolVendorInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
SymbolVendorCreateInstance
PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
#pragma mark UnwindAssembly
struct UnwindAssemblyInstance
{
UnwindAssemblyInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
UnwindAssemblyCreateInstance create_callback;
};
typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
static std::recursive_mutex &
GetUnwindAssemblyMutex()
{
static std::recursive_mutex g_instances_mutex;
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;
std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
GetUnwindAssemblyInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(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)
{
std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
UnwindAssemblyCreateInstance
PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}
#pragma mark MemoryHistory
struct MemoryHistoryInstance
{
MemoryHistoryInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
MemoryHistoryCreateInstance create_callback;
};
typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
static std::recursive_mutex &
GetMemoryHistoryMutex()
{
static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
static MemoryHistoryInstances &
GetMemoryHistoryInstances ()
{
static MemoryHistoryInstances g_instances;
return g_instances;
}
bool
PluginManager::RegisterPlugin(const ConstString &name,
const char *description,
MemoryHistoryCreateInstance create_callback)
{
if (create_callback)
{
MemoryHistoryInstance instance;
assert ((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
GetMemoryHistoryInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
MemoryHistoryInstances::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;
}
MemoryHistoryCreateInstance
PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
MemoryHistoryCreateInstance
PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
MemoryHistoryInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (name == pos->name)
return pos->create_callback;
}
}
return nullptr;
}
#pragma mark InstrumentationRuntime
struct InstrumentationRuntimeInstance
{
InstrumentationRuntimeInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
InstrumentationRuntimeCreateInstance create_callback;
InstrumentationRuntimeGetType get_type_callback;
};
typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances;
static std::recursive_mutex &
GetInstrumentationRuntimeMutex()
{
static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
static InstrumentationRuntimeInstances &
GetInstrumentationRuntimeInstances ()
{
static InstrumentationRuntimeInstances g_instances;
return g_instances;
}
bool
PluginManager::RegisterPlugin(const ConstString &name,
const char *description,
InstrumentationRuntimeCreateInstance create_callback,
InstrumentationRuntimeGetType get_type_callback)
{
if (create_callback)
{
InstrumentationRuntimeInstance instance;
assert ((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
instance.get_type_callback = get_type_callback;
std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
GetInstrumentationRuntimeInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
InstrumentationRuntimeInstances::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;
}
InstrumentationRuntimeGetType
PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
if (idx < instances.size())
return instances[idx].get_type_callback;
return nullptr;
}
InstrumentationRuntimeCreateInstance
PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
InstrumentationRuntimeCreateInstance
PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
InstrumentationRuntimeInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (name == pos->name)
return pos->create_callback;
}
}
return nullptr;
}
#pragma mark TypeSystem
struct TypeSystemInstance
{
TypeSystemInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
TypeSystemCreateInstance create_callback;
TypeSystemEnumerateSupportedLanguages enumerate_callback;
};
typedef std::vector<TypeSystemInstance> TypeSystemInstances;
static std::recursive_mutex &
GetTypeSystemMutex()
{
static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
static TypeSystemInstances &
GetTypeSystemInstances ()
{
static TypeSystemInstances g_instances;
return g_instances;
}
bool
PluginManager::RegisterPlugin (const ConstString &name,
const char *description,
TypeSystemCreateInstance create_callback,
TypeSystemEnumerateSupportedLanguages enumerate_supported_languages_callback)
{
if (create_callback)
{
TypeSystemInstance instance;
assert ((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
instance.enumerate_callback = enumerate_supported_languages_callback;
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
GetTypeSystemInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (TypeSystemCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances ();
TypeSystemInstances::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;
}
TypeSystemCreateInstance
PluginManager::GetTypeSystemCreateCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
TypeSystemCreateInstance
PluginManager::GetTypeSystemCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances ();
TypeSystemInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (name == pos->name)
return pos->create_callback;
}
}
return nullptr;
}
TypeSystemEnumerateSupportedLanguages
PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances ();
if (idx < instances.size())
return instances[idx].enumerate_callback;
return nullptr;
}
TypeSystemEnumerateSupportedLanguages
PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
TypeSystemInstances &instances = GetTypeSystemInstances ();
TypeSystemInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (name == pos->name)
return pos->enumerate_callback;
}
}
return nullptr;
}
#pragma mark REPL
struct REPLInstance
{
REPLInstance() :
name(),
description(),
create_callback(nullptr)
{
}
ConstString name;
std::string description;
REPLCreateInstance create_callback;
REPLEnumerateSupportedLanguages enumerate_languages_callback;
};
typedef std::vector<REPLInstance> REPLInstances;
static std::recursive_mutex &
GetREPLMutex()
{
static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
static REPLInstances &
GetREPLInstances ()
{
static REPLInstances g_instances;
return g_instances;
}
bool
PluginManager::RegisterPlugin (const ConstString &name,
const char *description,
REPLCreateInstance create_callback,
REPLEnumerateSupportedLanguages enumerate_languages_callback)
{
if (create_callback)
{
REPLInstance instance;
assert ((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
instance.enumerate_languages_callback = enumerate_languages_callback;
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
GetREPLInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (REPLCreateInstance create_callback)
{
if (create_callback)
{
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances ();
REPLInstances::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;
}
REPLCreateInstance
PluginManager::GetREPLCreateCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
REPLCreateInstance
PluginManager::GetREPLCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances ();
REPLInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (name == pos->name)
return pos->create_callback;
}
}
return nullptr;
}
REPLEnumerateSupportedLanguages
PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
{
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances ();
if (idx < instances.size())
return instances[idx].enumerate_languages_callback;
return nullptr;
}
REPLEnumerateSupportedLanguages
PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name)
{
if (name)
{
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
REPLInstances &instances = GetREPLInstances ();
REPLInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (name == pos->name)
return pos->enumerate_languages_callback;
}
}
return nullptr;
}
#pragma mark PluginManager
void
PluginManager::DebuggerInitialize (Debugger &debugger)
{
// Initialize the DynamicLoader plugins
{
std::lock_guard<std::recursive_mutex> guard(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 JITLoader plugins
{
std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
JITLoaderInstances &instances = GetJITLoaderInstances ();
JITLoaderInstances::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
{
std::lock_guard<std::recursive_mutex> guard(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
{
std::lock_guard<std::recursive_mutex> guard(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);
}
}
// Initialize the SymbolFile plugins
{
std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
for (auto& sym_file: GetSymbolFileInstances())
{
if (sym_file.debugger_init_callback)
sym_file.debugger_init_callback (debugger);
}
}
// Initialize the OperatingSystem plugins
{
std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
for (auto &os : GetOperatingSystemInstances())
{
if (os.debugger_init_callback)
os.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(nullptr, 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(nullptr, 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(nullptr, 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(nullptr, 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();
}
namespace {
typedef lldb::OptionValuePropertiesSP
GetDebuggerPropertyForPluginsPtr (Debugger&, const ConstString&, const ConstString&, bool can_create);
lldb::OptionValuePropertiesSP
GetSettingForPlugin (Debugger &debugger,
const ConstString &setting_name,
const ConstString &plugin_type_name,
GetDebuggerPropertyForPluginsPtr get_debugger_property= GetDebuggerPropertyForPlugins)
{
lldb::OptionValuePropertiesSP properties_sp;
lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (debugger,
plugin_type_name,
ConstString(), // not creating to so we don't need the description
false));
if (plugin_type_properties_sp)
properties_sp = plugin_type_properties_sp->GetSubProperty (nullptr, setting_name);
return properties_sp;
}
bool
CreateSettingForPlugin (Debugger &debugger,
const ConstString &plugin_type_name,
const ConstString &plugin_type_desc,
const lldb::OptionValuePropertiesSP &properties_sp,
const ConstString &description,
bool is_global_property,
GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins)
{
if (properties_sp)
{
lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (
debugger, plugin_type_name, plugin_type_desc, true));
if (plugin_type_properties_sp)
{
plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
description,
is_global_property,
properties_sp);
return true;
}
}
return false;
}
const char* kDynamicLoaderPluginName("dynamic-loader");
const char* kPlatformPluginName("platform");
const char* kProcessPluginName("process");
const char* kSymbolFilePluginName("symbol-file");
const char* kJITLoaderPluginName("jit-loader");
} // anonymous namespace
lldb::OptionValuePropertiesSP
PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger,
const ConstString &setting_name)
{
return GetSettingForPlugin(debugger, setting_name, ConstString(kDynamicLoaderPluginName));
}
bool
PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
const lldb::OptionValuePropertiesSP &properties_sp,
const ConstString &description,
bool is_global_property)
{
return CreateSettingForPlugin(debugger,
ConstString(kDynamicLoaderPluginName),
ConstString("Settings for dynamic loader plug-ins"),
properties_sp,
description,
is_global_property);
}
lldb::OptionValuePropertiesSP
PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
{
return GetSettingForPlugin(debugger,
setting_name,
ConstString(kPlatformPluginName),
GetDebuggerPropertyForPluginsOldStyle);
}
bool
PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
const lldb::OptionValuePropertiesSP &properties_sp,
const ConstString &description,
bool is_global_property)
{
return CreateSettingForPlugin(debugger,
ConstString(kPlatformPluginName),
ConstString("Settings for platform plug-ins"),
properties_sp,
description,
is_global_property,
GetDebuggerPropertyForPluginsOldStyle);
}
lldb::OptionValuePropertiesSP
PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
{
return GetSettingForPlugin(debugger, setting_name, ConstString(kProcessPluginName));
}
bool
PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
const lldb::OptionValuePropertiesSP &properties_sp,
const ConstString &description,
bool is_global_property)
{
return CreateSettingForPlugin(debugger,
ConstString(kProcessPluginName),
ConstString("Settings for process plug-ins"),
properties_sp,
description,
is_global_property);
}
lldb::OptionValuePropertiesSP
PluginManager::GetSettingForSymbolFilePlugin (Debugger &debugger,
const ConstString &setting_name)
{
return GetSettingForPlugin(debugger, setting_name, ConstString(kSymbolFilePluginName));
}
bool
PluginManager::CreateSettingForSymbolFilePlugin (Debugger &debugger,
const lldb::OptionValuePropertiesSP &properties_sp,
const ConstString &description,
bool is_global_property)
{
return CreateSettingForPlugin(debugger,
ConstString(kSymbolFilePluginName),
ConstString("Settings for symbol file plug-ins"),
properties_sp,
description,
is_global_property);
}
lldb::OptionValuePropertiesSP
PluginManager::GetSettingForJITLoaderPlugin (Debugger &debugger,
const ConstString &setting_name)
{
return GetSettingForPlugin(debugger, setting_name, ConstString(kJITLoaderPluginName));
}
bool
PluginManager::CreateSettingForJITLoaderPlugin (Debugger &debugger,
const lldb::OptionValuePropertiesSP &properties_sp,
const ConstString &description,
bool is_global_property)
{
return CreateSettingForPlugin(debugger,
ConstString(kJITLoaderPluginName),
ConstString("Settings for JIT loader plug-ins"),
properties_sp,
description,
is_global_property);
}
static const char *kOperatingSystemPluginName("os");
lldb::OptionValuePropertiesSP
PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, const ConstString &setting_name)
{
lldb::OptionValuePropertiesSP properties_sp;
lldb::OptionValuePropertiesSP plugin_type_properties_sp(
GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName),
ConstString(), // not creating to so we don't need the description
false));
if (plugin_type_properties_sp)
properties_sp = plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
return properties_sp;
}
bool
PluginManager::CreateSettingForOperatingSystemPlugin(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(kOperatingSystemPluginName),
ConstString("Settings for operating system 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;
}