mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-19 03:25:54 -04:00

Summary: A *.cpp file header in LLDB (and in LLDB) should like this: ``` //===-- TestUtilities.cpp -------------------------------------------------===// ``` However in LLDB most of our source files have arbitrary changes to this format and these changes are spreading through LLDB as folks usually just use the existing source files as templates for their new files (most notably the unnecessary editor language indicator `-*- C++ -*-` is spreading and in every review someone is pointing out that this is wrong, resulting in people pointing out that this is done in the same way in other files). This patch removes most of these inconsistencies including the editor language indicators, all the different missing/additional '-' characters, files that center the file name, missing trailing `===//` (mostly caused by clang-format breaking the line). Reviewers: aprantl, espindola, jfb, shafik, JDevlieghere Reviewed By: JDevlieghere Subscribers: dexonsmith, wuzish, emaste, sdardis, nemanjai, kbarton, MaskRay, atanasyan, arphaman, jfb, abidh, jsji, JDevlieghere, usaxena95, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D73258
2600 lines
84 KiB
C++
2600 lines
84 KiB
C++
//===-- PluginManager.cpp -------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Core/PluginManager.h"
|
|
|
|
#include "lldb/Core/Debugger.h"
|
|
#include "lldb/Host/FileSystem.h"
|
|
#include "lldb/Host/HostInfo.h"
|
|
#include "lldb/Interpreter/OptionValueProperties.h"
|
|
#include "lldb/Utility/ConstString.h"
|
|
#include "lldb/Utility/FileSpec.h"
|
|
#include "lldb/Utility/Status.h"
|
|
#include "lldb/Utility/StringList.h"
|
|
|
|
#if defined(_WIN32)
|
|
#include "lldb/Host/windows/PosixApi.h"
|
|
#endif
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/DynamicLibrary.h"
|
|
#include "llvm/Support/FileSystem.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include <map>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include <assert.h>
|
|
|
|
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>(VPtr);
|
|
}
|
|
|
|
static FileSystem::EnumerateDirectoryResult
|
|
LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
|
|
llvm::StringRef path) {
|
|
// 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(path);
|
|
FileSystem::Instance().Resolve(plugin_file_spec);
|
|
|
|
if (PluginIsLoaded(plugin_file_spec))
|
|
return FileSystem::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 FileSystem::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 FileSystem::eEnumerateDirectoryResultEnter;
|
|
}
|
|
|
|
return FileSystem::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 (FileSystem::Instance().Exists(dir_spec) &&
|
|
dir_spec.GetPath(dir_path, sizeof(dir_path))) {
|
|
FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
|
|
find_files, find_other,
|
|
LoadPluginCallback, nullptr);
|
|
}
|
|
}
|
|
|
|
if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
|
|
if (FileSystem::Instance().Exists(dir_spec) &&
|
|
dir_spec.GetPath(dir_path, sizeof(dir_path))) {
|
|
FileSystem::Instance().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(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(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 &GetArchitectureMutex() {
|
|
static std::mutex g_architecture_mutex;
|
|
return g_architecture_mutex;
|
|
}
|
|
|
|
static ArchitectureInstances &GetArchitectureInstances() {
|
|
static ArchitectureInstances g_instances;
|
|
return g_instances;
|
|
}
|
|
|
|
void PluginManager::RegisterPlugin(ConstString name,
|
|
llvm::StringRef description,
|
|
ArchitectureCreateInstance create_callback) {
|
|
std::lock_guard<std::mutex> guard(GetArchitectureMutex());
|
|
GetArchitectureInstances().push_back({name, description, create_callback});
|
|
}
|
|
|
|
void PluginManager::UnregisterPlugin(
|
|
ArchitectureCreateInstance create_callback) {
|
|
std::lock_guard<std::mutex> guard(GetArchitectureMutex());
|
|
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(GetArchitectureMutex());
|
|
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(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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(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(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;
|
|
LanguageRuntimeGetExceptionPrecondition precondition_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(
|
|
ConstString name, const char *description,
|
|
LanguageRuntimeCreateInstance create_callback,
|
|
LanguageRuntimeGetCommandObject command_callback,
|
|
LanguageRuntimeGetExceptionPrecondition precondition_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;
|
|
instance.precondition_callback = precondition_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;
|
|
}
|
|
|
|
LanguageRuntimeGetExceptionPrecondition
|
|
PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
|
|
std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
|
|
LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
|
|
if (idx < instances.size())
|
|
return instances[idx].precondition_callback;
|
|
return nullptr;
|
|
}
|
|
|
|
LanguageRuntimeCreateInstance
|
|
PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(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;
|
|
}
|
|
|
|
void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
|
|
CompletionRequest &request) {
|
|
if (name.empty())
|
|
return;
|
|
|
|
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))
|
|
request.AddCompletion(plugin_name.data());
|
|
}
|
|
}
|
|
|
|
#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(
|
|
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(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(
|
|
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,
|
|
Debugger &debugger) {
|
|
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(debugger);
|
|
}
|
|
|
|
// If we didn't find one, return the ScriptInterpreter for the null language.
|
|
assert(none_instance != nullptr);
|
|
return none_instance(debugger);
|
|
}
|
|
|
|
#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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 {
|
|
ConstString name;
|
|
std::string description;
|
|
TypeSystemCreateInstance create_callback;
|
|
LanguageSet supported_languages_for_types;
|
|
LanguageSet supported_languages_for_expressions;
|
|
};
|
|
|
|
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(
|
|
ConstString name, const char *description,
|
|
TypeSystemCreateInstance create_callback,
|
|
LanguageSet supported_languages_for_types,
|
|
LanguageSet supported_languages_for_expressions) {
|
|
if (create_callback) {
|
|
TypeSystemInstance instance;
|
|
assert((bool)name);
|
|
instance.name = name;
|
|
if (description && description[0])
|
|
instance.description = description;
|
|
instance.create_callback = create_callback;
|
|
instance.supported_languages_for_types = supported_languages_for_types;
|
|
instance.supported_languages_for_expressions = supported_languages_for_expressions;
|
|
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(
|
|
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;
|
|
}
|
|
|
|
LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
|
|
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
|
|
LanguageSet all;
|
|
TypeSystemInstances &instances = GetTypeSystemInstances();
|
|
for (unsigned i = 0; i < instances.size(); ++i)
|
|
all.bitvector |= instances[i].supported_languages_for_types.bitvector;
|
|
return all;
|
|
}
|
|
|
|
LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
|
|
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
|
|
LanguageSet all;
|
|
TypeSystemInstances &instances = GetTypeSystemInstances();
|
|
for (unsigned i = 0; i < instances.size(); ++i)
|
|
all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
|
|
return all;
|
|
}
|
|
|
|
#pragma mark REPL
|
|
|
|
struct REPLInstance {
|
|
REPLInstance() : name(), description(), create_callback(nullptr) {}
|
|
|
|
ConstString name;
|
|
std::string description;
|
|
REPLCreateInstance create_callback;
|
|
LanguageSet supported_languages;
|
|
};
|
|
|
|
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(ConstString name, const char *description,
|
|
REPLCreateInstance create_callback,
|
|
LanguageSet supported_languages) {
|
|
if (create_callback) {
|
|
REPLInstance instance;
|
|
assert((bool)name);
|
|
instance.name = name;
|
|
if (description && description[0])
|
|
instance.description = description;
|
|
instance.create_callback = create_callback;
|
|
instance.supported_languages = supported_languages;
|
|
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(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;
|
|
}
|
|
|
|
LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
|
|
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
|
|
LanguageSet all;
|
|
REPLInstances &instances = GetREPLInstances();
|
|
for (unsigned i = 0; i < instances.size(); ++i)
|
|
all.bitvector |= instances[i].supported_languages.bitvector;
|
|
return all;
|
|
}
|
|
|
|
#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, ConstString plugin_type_name,
|
|
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, ConstString plugin_type_name,
|
|
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 &, ConstString ,
|
|
ConstString , bool can_create);
|
|
|
|
lldb::OptionValuePropertiesSP
|
|
GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
|
|
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, ConstString plugin_type_name,
|
|
ConstString plugin_type_desc,
|
|
const lldb::OptionValuePropertiesSP &properties_sp,
|
|
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, ConstString setting_name) {
|
|
return GetSettingForPlugin(debugger, setting_name,
|
|
ConstString(kDynamicLoaderPluginName));
|
|
}
|
|
|
|
bool PluginManager::CreateSettingForDynamicLoaderPlugin(
|
|
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
|
|
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,
|
|
ConstString setting_name) {
|
|
return GetSettingForPlugin(debugger, setting_name,
|
|
ConstString(kPlatformPluginName),
|
|
GetDebuggerPropertyForPluginsOldStyle);
|
|
}
|
|
|
|
bool PluginManager::CreateSettingForPlatformPlugin(
|
|
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
|
|
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,
|
|
ConstString setting_name) {
|
|
return GetSettingForPlugin(debugger, setting_name,
|
|
ConstString(kProcessPluginName));
|
|
}
|
|
|
|
bool PluginManager::CreateSettingForProcessPlugin(
|
|
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
|
|
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,
|
|
ConstString setting_name) {
|
|
return GetSettingForPlugin(debugger, setting_name,
|
|
ConstString(kSymbolFilePluginName));
|
|
}
|
|
|
|
bool PluginManager::CreateSettingForSymbolFilePlugin(
|
|
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
|
|
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,
|
|
ConstString setting_name) {
|
|
return GetSettingForPlugin(debugger, setting_name,
|
|
ConstString(kJITLoaderPluginName));
|
|
}
|
|
|
|
bool PluginManager::CreateSettingForJITLoaderPlugin(
|
|
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
|
|
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, 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,
|
|
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, ConstString setting_name) {
|
|
return GetSettingForPlugin(debugger, setting_name,
|
|
ConstString(kStructuredDataPluginName));
|
|
}
|
|
|
|
bool PluginManager::CreateSettingForStructuredDataPlugin(
|
|
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
|
|
ConstString description, bool is_global_property) {
|
|
return CreateSettingForPlugin(
|
|
debugger, ConstString(kStructuredDataPluginName),
|
|
ConstString("Settings for structured data plug-ins"), properties_sp,
|
|
description, is_global_property);
|
|
}
|