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

2608 lines
84 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"
#include "lldb/Core/Debugger.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Utility/ConstString.h" // for ConstString
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringList.h" // for StringList
#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX
#endif
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h" // for file_type, file_...
#include "llvm/Support/raw_ostream.h" // for fs
#include <map> // for map<>::const_ite...
#include <memory> // for shared_ptr
#include <mutex>
#include <string>
#include <utility> // for pair
#include <vector>
#include <assert.h> // for assert
namespace lldb_private {
class CommandInterpreter;
}
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, llvm::sys::fs::file_type ft,
const FileSpec &file_spec) {
// PluginManager *plugin_manager = (PluginManager *)baton;
Status error;
namespace fs = llvm::sys::fs;
// 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 (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
ft == fs::file_type::type_unknown) {
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 (ft == fs::file_type::directory_file ||
ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
// 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
const bool find_directories = true;
const bool find_files = true;
const bool find_other = true;
char dir_path[PATH_MAX];
if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
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 (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
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 Architecture
struct ArchitectureInstance {
ConstString name;
std::string description;
PluginManager::ArchitectureCreateInstance create_callback;
};
typedef std::vector<ArchitectureInstance> ArchitectureInstances;
static std::mutex g_architecture_mutex;
static ArchitectureInstances &GetArchitectureInstances() {
static ArchitectureInstances g_instances;
return g_instances;
}
void PluginManager::RegisterPlugin(const ConstString &name,
llvm::StringRef description,
ArchitectureCreateInstance create_callback) {
std::lock_guard<std::mutex> guard(g_architecture_mutex);
GetArchitectureInstances().push_back({name, description, create_callback});
}
void PluginManager::UnregisterPlugin(
ArchitectureCreateInstance create_callback) {
std::lock_guard<std::mutex> guard(g_architecture_mutex);
auto &instances = GetArchitectureInstances();
for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
if (pos->create_callback == create_callback) {
instances.erase(pos);
return;
}
}
llvm_unreachable("Plugin not found");
}
std::unique_ptr<Architecture>
PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
std::lock_guard<std::mutex> guard(g_architecture_mutex);
for (const auto &instances : GetArchitectureInstances()) {
if (auto plugin_up = instances.create_callback(arch))
return plugin_up;
}
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;
}
Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
const FileSpec &outfile) {
Status 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 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(llvm::StringRef name,
StringList &matches) {
if (name.empty())
return matches.GetSize();
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 -
#pragma mark StructuredDataPlugin
// -----------------------------------------------------------------------------
// StructuredDataPlugin
// -----------------------------------------------------------------------------
struct StructuredDataPluginInstance {
StructuredDataPluginInstance()
: name(), description(), create_callback(nullptr),
debugger_init_callback(nullptr), filter_callback(nullptr) {}
ConstString name;
std::string description;
StructuredDataPluginCreateInstance create_callback;
DebuggerInitializeCallback debugger_init_callback;
StructuredDataFilterLaunchInfo filter_callback;
};
typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;
static std::recursive_mutex &GetStructuredDataPluginMutex() {
static std::recursive_mutex g_instances_mutex;
return g_instances_mutex;
}
static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
static StructuredDataPluginInstances g_instances;
return g_instances;
}
bool PluginManager::RegisterPlugin(
const ConstString &name, const char *description,
StructuredDataPluginCreateInstance create_callback,
DebuggerInitializeCallback debugger_init_callback,
StructuredDataFilterLaunchInfo filter_callback) {
if (create_callback) {
StructuredDataPluginInstance 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;
instance.filter_callback = filter_callback;
std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
GetStructuredDataPluginInstances().push_back(instance);
}
return false;
}
bool PluginManager::UnregisterPlugin(
StructuredDataPluginCreateInstance create_callback) {
if (create_callback) {
std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
StructuredDataPluginInstances &instances =
GetStructuredDataPluginInstances();
StructuredDataPluginInstances::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;
}
StructuredDataPluginCreateInstance
PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
if (idx < instances.size())
return instances[idx].create_callback;
return nullptr;
}
StructuredDataPluginCreateInstance
PluginManager::GetStructuredDataPluginCreateCallbackForPluginName(
const ConstString &name) {
if (name) {
std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
StructuredDataPluginInstances &instances =
GetStructuredDataPluginInstances();
StructuredDataPluginInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++pos) {
if (name == pos->name)
return pos->create_callback;
}
}
return nullptr;
}
StructuredDataFilterLaunchInfo
PluginManager::GetStructuredDataFilterCallbackAtIndex(
uint32_t idx, bool &iteration_complete) {
std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
if (idx < instances.size()) {
iteration_complete = false;
return instances[idx].filter_callback;
} else {
iteration_complete = true;
}
return nullptr;
}
#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);
}
}
// Initialize the StructuredDataPlugin plugins
{
std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
for (auto &plugin : GetStructuredDataPluginInstances()) {
if (plugin.debugger_init_callback)
plugin.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 =
std::make_shared<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 =
std::make_shared<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 =
std::make_shared<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 =
std::make_shared<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");
const char *kStructuredDataPluginName("structured-data");
} // 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;
}
lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin(
Debugger &debugger, const ConstString &setting_name) {
return GetSettingForPlugin(debugger, setting_name,
ConstString(kStructuredDataPluginName));
}
bool PluginManager::CreateSettingForStructuredDataPlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
const ConstString &description, bool is_global_property) {
return CreateSettingForPlugin(
debugger, ConstString(kStructuredDataPluginName),
ConstString("Settings for structured data plug-ins"), properties_sp,
description, is_global_property);
}