blob: 44a37a0a62d55b4c8d286cadee9fe266a68cdfb9 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- PluginManager.cpp ---------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/PluginManager.h"
11
Greg Claytone8cd0c92012-10-19 18:02:49 +000012#include "lldb/Core/Debugger.h"
Zachary Turner42ff0ad2014-08-21 17:29:12 +000013#include "lldb/Host/HostInfo.h"
Greg Claytone8cd0c92012-10-19 18:02:49 +000014#include "lldb/Interpreter/OptionValueProperties.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000015#include "lldb/Utility/ConstString.h" // for ConstString
Zachary Turner5713a052017-03-22 18:40:07 +000016#include "lldb/Utility/FileSpec.h"
Zachary Turner97206d52017-05-12 04:51:55 +000017#include "lldb/Utility/Status.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000018#include "lldb/Utility/StringList.h" // for StringList
19
Nico Weberb1cb0b792018-04-10 13:33:45 +000020#if defined(_WIN32)
Zachary Turner2f3df612017-04-06 21:28:29 +000021#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX
22#endif
23
24#include "llvm/ADT/StringRef.h"
25#include "llvm/Support/DynamicLibrary.h"
26#include "llvm/Support/FileSystem.h" // for file_type, file_...
27#include "llvm/Support/raw_ostream.h" // for fs
28
29#include <map> // for map<>::const_ite...
30#include <memory> // for shared_ptr
31#include <mutex>
32#include <string>
33#include <utility> // for pair
34#include <vector>
35
36#include <assert.h> // for assert
37
38namespace lldb_private {
39class CommandInterpreter;
40}
Greg Clayton4272cc72011-02-02 02:24:04 +000041
42using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043using namespace lldb_private;
44
Kate Stoneb9c1b512016-09-06 20:57:50 +000045enum PluginAction {
46 ePluginRegisterInstance,
47 ePluginUnregisterInstance,
48 ePluginGetInstanceAtIndex
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049};
50
Eugene Zelenko89183722016-03-11 21:55:47 +000051typedef bool (*PluginInitCallback)();
52typedef void (*PluginTermCallback)();
Greg Clayton03da4cc2013-04-19 21:31:16 +000053
Kate Stoneb9c1b512016-09-06 20:57:50 +000054struct PluginInfo {
55 PluginInfo() : plugin_init_callback(nullptr), plugin_term_callback(nullptr) {}
Zachary Turner58a559c2014-08-27 20:15:09 +000056
Kate Stoneb9c1b512016-09-06 20:57:50 +000057 llvm::sys::DynamicLibrary library;
58 PluginInitCallback plugin_init_callback;
59 PluginTermCallback plugin_term_callback;
Greg Clayton4272cc72011-02-02 02:24:04 +000060};
61
62typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
63
Kate Stoneb9c1b512016-09-06 20:57:50 +000064static std::recursive_mutex &GetPluginMapMutex() {
65 static std::recursive_mutex g_plugin_map_mutex;
66 return g_plugin_map_mutex;
Greg Clayton4272cc72011-02-02 02:24:04 +000067}
68
Kate Stoneb9c1b512016-09-06 20:57:50 +000069static PluginTerminateMap &GetPluginMap() {
70 static PluginTerminateMap g_plugin_map;
71 return g_plugin_map;
Greg Clayton4272cc72011-02-02 02:24:04 +000072}
73
Kate Stoneb9c1b512016-09-06 20:57:50 +000074static bool PluginIsLoaded(const FileSpec &plugin_file_spec) {
75 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
76 PluginTerminateMap &plugin_map = GetPluginMap();
77 return plugin_map.find(plugin_file_spec) != plugin_map.end();
Greg Clayton4272cc72011-02-02 02:24:04 +000078}
79
Kate Stoneb9c1b512016-09-06 20:57:50 +000080static void SetPluginInfo(const FileSpec &plugin_file_spec,
81 const PluginInfo &plugin_info) {
82 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
83 PluginTerminateMap &plugin_map = GetPluginMap();
84 assert(plugin_map.find(plugin_file_spec) == plugin_map.end());
85 plugin_map[plugin_file_spec] = plugin_info;
David Majnemer5ff02782014-07-22 21:59:22 +000086}
Greg Clayton4272cc72011-02-02 02:24:04 +000087
Kate Stoneb9c1b512016-09-06 20:57:50 +000088template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
89 return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
90}
Greg Clayton45319462011-02-08 00:35:34 +000091
Kate Stoneb9c1b512016-09-06 20:57:50 +000092static FileSpec::EnumerateDirectoryResult
Zachary Turner7d86ee52017-03-08 17:56:08 +000093LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
Kate Stoneb9c1b512016-09-06 20:57:50 +000094 const FileSpec &file_spec) {
95 // PluginManager *plugin_manager = (PluginManager *)baton;
Zachary Turner97206d52017-05-12 04:51:55 +000096 Status error;
Greg Clayton4272cc72011-02-02 02:24:04 +000097
Zachary Turner7d86ee52017-03-08 17:56:08 +000098 namespace fs = llvm::sys::fs;
Adrian Prantl05097242018-04-30 16:49:04 +000099 // If we have a regular file, a symbolic link or unknown file type, try and
100 // process the file. We must handle unknown as sometimes the directory
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101 // enumeration might be enumerating a file system that doesn't have correct
102 // file type information.
Zachary Turner7d86ee52017-03-08 17:56:08 +0000103 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
104 ft == fs::file_type::type_unknown) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105 FileSpec plugin_file_spec(file_spec);
106 plugin_file_spec.ResolvePath();
Greg Clayton4272cc72011-02-02 02:24:04 +0000107
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108 if (PluginIsLoaded(plugin_file_spec))
109 return FileSpec::eEnumerateDirectoryResultNext;
110 else {
111 PluginInfo plugin_info;
Greg Clayton4272cc72011-02-02 02:24:04 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113 std::string pluginLoadError;
114 plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary(
115 plugin_file_spec.GetPath().c_str(), &pluginLoadError);
116 if (plugin_info.library.isValid()) {
117 bool success = false;
118 plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>(
119 plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
120 if (plugin_info.plugin_init_callback) {
121 // Call the plug-in "bool LLDBPluginInitialize(void)" function
122 success = plugin_info.plugin_init_callback();
Greg Clayton4272cc72011-02-02 02:24:04 +0000123 }
Greg Clayton4272cc72011-02-02 02:24:04 +0000124
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125 if (success) {
126 // It is ok for the "LLDBPluginTerminate" symbol to be nullptr
127 plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>(
128 plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
129 } else {
130 // The initialize function returned FALSE which means the plug-in
Adrian Prantl05097242018-04-30 16:49:04 +0000131 // might not be compatible, or might be too new or too old, or might
132 // not want to run on this machine. Set it to a default-constructed
133 // instance to invalidate it.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 plugin_info = PluginInfo();
135 }
136
Adrian Prantl05097242018-04-30 16:49:04 +0000137 // Regardless of success or failure, cache the plug-in load in our
138 // plug-in info so we don't try to load it again and again.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 SetPluginInfo(plugin_file_spec, plugin_info);
140
141 return FileSpec::eEnumerateDirectoryResultNext;
142 }
143 }
144 }
145
Zachary Turner7d86ee52017-03-08 17:56:08 +0000146 if (ft == fs::file_type::directory_file ||
147 ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
Adrian Prantl05097242018-04-30 16:49:04 +0000148 // Try and recurse into anything that a directory or symbolic link. We must
149 // also do this for unknown as sometimes the directory enumeration might be
150 // enumerating a file system that doesn't have correct file type
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 // information.
152 return FileSpec::eEnumerateDirectoryResultEnter;
153 }
154
155 return FileSpec::eEnumerateDirectoryResultNext;
Greg Clayton4272cc72011-02-02 02:24:04 +0000156}
157
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158void PluginManager::Initialize() {
Greg Clayton1cb64962011-03-24 04:28:38 +0000159#if 1
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160 FileSpec dir_spec;
161 const bool find_directories = true;
162 const bool find_files = true;
163 const bool find_other = true;
164 char dir_path[PATH_MAX];
165 if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) {
166 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
167 FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
168 find_other, LoadPluginCallback, nullptr);
Greg Clayton4272cc72011-02-02 02:24:04 +0000169 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170 }
Greg Clayton4272cc72011-02-02 02:24:04 +0000171
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172 if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) {
173 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
174 FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
175 find_other, LoadPluginCallback, nullptr);
Greg Clayton4272cc72011-02-02 02:24:04 +0000176 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000178#endif
Greg Clayton4272cc72011-02-02 02:24:04 +0000179}
180
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181void PluginManager::Terminate() {
182 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
183 PluginTerminateMap &plugin_map = GetPluginMap();
184
185 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
186 for (pos = plugin_map.begin(); pos != end; ++pos) {
Adrian Prantl05097242018-04-30 16:49:04 +0000187 // Call the plug-in "void LLDBPluginTerminate (void)" function if there is
188 // one (if the symbol was not nullptr).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000189 if (pos->second.library.isValid()) {
190 if (pos->second.plugin_term_callback)
191 pos->second.plugin_term_callback();
Greg Clayton4272cc72011-02-02 02:24:04 +0000192 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 }
194 plugin_map.clear();
Greg Clayton4272cc72011-02-02 02:24:04 +0000195}
196
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000197#pragma mark ABI
198
Kate Stoneb9c1b512016-09-06 20:57:50 +0000199struct ABIInstance {
200 ABIInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 ConstString name;
203 std::string description;
204 ABICreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205};
206
207typedef std::vector<ABIInstance> ABIInstances;
208
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209static std::recursive_mutex &GetABIInstancesMutex() {
210 static std::recursive_mutex g_instances_mutex;
211 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000212}
213
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214static ABIInstances &GetABIInstances() {
215 static ABIInstances g_instances;
216 return g_instances;
Greg Claytonded470d2011-03-19 01:12:21 +0000217}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000218
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219bool PluginManager::RegisterPlugin(const ConstString &name,
220 const char *description,
221 ABICreateInstance create_callback) {
222 if (create_callback) {
223 ABIInstance instance;
224 assert((bool)name);
225 instance.name = name;
226 if (description && description[0])
227 instance.description = description;
228 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000229 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230 GetABIInstances().push_back(instance);
231 return true;
232 }
233 return false;
234}
235
236bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
237 if (create_callback) {
238 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
239 ABIInstances &instances = GetABIInstances();
240
241 ABIInstances::iterator pos, end = instances.end();
242 for (pos = instances.begin(); pos != end; ++pos) {
243 if (pos->create_callback == create_callback) {
244 instances.erase(pos);
245 return true;
246 }
247 }
248 }
249 return false;
250}
251
252ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
253 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
254 ABIInstances &instances = GetABIInstances();
255 if (idx < instances.size())
256 return instances[idx].create_callback;
257 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258}
259
260ABICreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000261PluginManager::GetABICreateCallbackForPluginName(const ConstString &name) {
262 if (name) {
263 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
264 ABIInstances &instances = GetABIInstances();
Greg Claytonded470d2011-03-19 01:12:21 +0000265
Kate Stoneb9c1b512016-09-06 20:57:50 +0000266 ABIInstances::iterator pos, end = instances.end();
267 for (pos = instances.begin(); pos != end; ++pos) {
268 if (name == pos->name)
269 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000270 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271 }
272 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273}
274
Pavel Labath13e37d42017-10-25 21:05:31 +0000275#pragma mark Architecture
276
277struct ArchitectureInstance {
278 ConstString name;
279 std::string description;
280 PluginManager::ArchitectureCreateInstance create_callback;
281};
282
283typedef std::vector<ArchitectureInstance> ArchitectureInstances;
284
285static std::mutex g_architecture_mutex;
286
287static ArchitectureInstances &GetArchitectureInstances() {
288 static ArchitectureInstances g_instances;
289 return g_instances;
290}
291
292void PluginManager::RegisterPlugin(const ConstString &name,
293 llvm::StringRef description,
294 ArchitectureCreateInstance create_callback) {
295 std::lock_guard<std::mutex> guard(g_architecture_mutex);
296 GetArchitectureInstances().push_back({name, description, create_callback});
297}
298
299void PluginManager::UnregisterPlugin(
300 ArchitectureCreateInstance create_callback) {
301 std::lock_guard<std::mutex> guard(g_architecture_mutex);
302 auto &instances = GetArchitectureInstances();
303
304 for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
305 if (pos->create_callback == create_callback) {
306 instances.erase(pos);
307 return;
308 }
309 }
310 llvm_unreachable("Plugin not found");
311}
312
313std::unique_ptr<Architecture>
314PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
315 std::lock_guard<std::mutex> guard(g_architecture_mutex);
316 for (const auto &instances : GetArchitectureInstances()) {
317 if (auto plugin_up = instances.create_callback(arch))
318 return plugin_up;
319 }
320 return nullptr;
321}
322
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000323#pragma mark Disassembler
324
Kate Stoneb9c1b512016-09-06 20:57:50 +0000325struct DisassemblerInstance {
326 DisassemblerInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328 ConstString name;
329 std::string description;
330 DisassemblerCreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331};
332
333typedef std::vector<DisassemblerInstance> DisassemblerInstances;
334
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335static std::recursive_mutex &GetDisassemblerMutex() {
336 static std::recursive_mutex g_instances_mutex;
337 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000338}
339
Kate Stoneb9c1b512016-09-06 20:57:50 +0000340static DisassemblerInstances &GetDisassemblerInstances() {
341 static DisassemblerInstances g_instances;
342 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +0000343}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344
Kate Stoneb9c1b512016-09-06 20:57:50 +0000345bool PluginManager::RegisterPlugin(const ConstString &name,
346 const char *description,
347 DisassemblerCreateInstance create_callback) {
348 if (create_callback) {
349 DisassemblerInstance instance;
350 assert((bool)name);
351 instance.name = name;
352 if (description && description[0])
353 instance.description = description;
354 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000355 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000356 GetDisassemblerInstances().push_back(instance);
357 return true;
358 }
359 return false;
360}
361
362bool PluginManager::UnregisterPlugin(
363 DisassemblerCreateInstance create_callback) {
364 if (create_callback) {
365 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
366 DisassemblerInstances &instances = GetDisassemblerInstances();
367
368 DisassemblerInstances::iterator pos, end = instances.end();
369 for (pos = instances.begin(); pos != end; ++pos) {
370 if (pos->create_callback == create_callback) {
371 instances.erase(pos);
372 return true;
373 }
374 }
375 }
376 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000377}
378
379DisassemblerCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000380PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
381 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
382 DisassemblerInstances &instances = GetDisassemblerInstances();
383 if (idx < instances.size())
384 return instances[idx].create_callback;
385 return nullptr;
386}
387
388DisassemblerCreateInstance
389PluginManager::GetDisassemblerCreateCallbackForPluginName(
390 const ConstString &name) {
391 if (name) {
392 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
393 DisassemblerInstances &instances = GetDisassemblerInstances();
394
395 DisassemblerInstances::iterator pos, end = instances.end();
396 for (pos = instances.begin(); pos != end; ++pos) {
397 if (name == pos->name)
398 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400 }
401 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402}
403
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404#pragma mark DynamicLoader
405
Kate Stoneb9c1b512016-09-06 20:57:50 +0000406struct DynamicLoaderInstance {
407 DynamicLoaderInstance()
408 : name(), description(), create_callback(nullptr),
409 debugger_init_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410
Kate Stoneb9c1b512016-09-06 20:57:50 +0000411 ConstString name;
412 std::string description;
413 DynamicLoaderCreateInstance create_callback;
414 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000415};
416
417typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
418
Kate Stoneb9c1b512016-09-06 20:57:50 +0000419static std::recursive_mutex &GetDynamicLoaderMutex() {
420 static std::recursive_mutex g_instances_mutex;
421 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +0000422}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423
Kate Stoneb9c1b512016-09-06 20:57:50 +0000424static DynamicLoaderInstances &GetDynamicLoaderInstances() {
425 static DynamicLoaderInstances g_instances;
426 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427}
428
Kate Stoneb9c1b512016-09-06 20:57:50 +0000429bool PluginManager::RegisterPlugin(
430 const ConstString &name, const char *description,
431 DynamicLoaderCreateInstance create_callback,
432 DebuggerInitializeCallback debugger_init_callback) {
433 if (create_callback) {
434 DynamicLoaderInstance instance;
435 assert((bool)name);
436 instance.name = name;
437 if (description && description[0])
438 instance.description = description;
439 instance.create_callback = create_callback;
440 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000441 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 GetDynamicLoaderInstances().push_back(instance);
443 }
444 return false;
445}
446
447bool PluginManager::UnregisterPlugin(
448 DynamicLoaderCreateInstance create_callback) {
449 if (create_callback) {
450 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
451 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
452
453 DynamicLoaderInstances::iterator pos, end = instances.end();
454 for (pos = instances.begin(); pos != end; ++pos) {
455 if (pos->create_callback == create_callback) {
456 instances.erase(pos);
457 return true;
458 }
459 }
460 }
461 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462}
463
464DynamicLoaderCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000465PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
466 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
467 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
468 if (idx < instances.size())
469 return instances[idx].create_callback;
470 return nullptr;
471}
472
473DynamicLoaderCreateInstance
474PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
475 const ConstString &name) {
476 if (name) {
477 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
478 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
479
480 DynamicLoaderInstances::iterator pos, end = instances.end();
481 for (pos = instances.begin(); pos != end; ++pos) {
482 if (name == pos->name)
483 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000485 }
486 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487}
488
Andrew MacPherson17220c12014-03-05 10:12:43 +0000489#pragma mark JITLoader
490
Kate Stoneb9c1b512016-09-06 20:57:50 +0000491struct JITLoaderInstance {
492 JITLoaderInstance()
493 : name(), description(), create_callback(nullptr),
494 debugger_init_callback(nullptr) {}
Andrew MacPherson17220c12014-03-05 10:12:43 +0000495
Kate Stoneb9c1b512016-09-06 20:57:50 +0000496 ConstString name;
497 std::string description;
498 JITLoaderCreateInstance create_callback;
499 DebuggerInitializeCallback debugger_init_callback;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000500};
501
502typedef std::vector<JITLoaderInstance> JITLoaderInstances;
503
Kate Stoneb9c1b512016-09-06 20:57:50 +0000504static std::recursive_mutex &GetJITLoaderMutex() {
505 static std::recursive_mutex g_instances_mutex;
506 return g_instances_mutex;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000507}
508
Kate Stoneb9c1b512016-09-06 20:57:50 +0000509static JITLoaderInstances &GetJITLoaderInstances() {
510 static JITLoaderInstances g_instances;
511 return g_instances;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000512}
513
Kate Stoneb9c1b512016-09-06 20:57:50 +0000514bool PluginManager::RegisterPlugin(
515 const ConstString &name, const char *description,
516 JITLoaderCreateInstance create_callback,
517 DebuggerInitializeCallback debugger_init_callback) {
518 if (create_callback) {
519 JITLoaderInstance instance;
520 assert((bool)name);
521 instance.name = name;
522 if (description && description[0])
523 instance.description = description;
524 instance.create_callback = create_callback;
525 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000526 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527 GetJITLoaderInstances().push_back(instance);
528 }
529 return false;
530}
531
532bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
533 if (create_callback) {
534 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
535 JITLoaderInstances &instances = GetJITLoaderInstances();
536
537 JITLoaderInstances::iterator pos, end = instances.end();
538 for (pos = instances.begin(); pos != end; ++pos) {
539 if (pos->create_callback == create_callback) {
540 instances.erase(pos);
541 return true;
542 }
543 }
544 }
545 return false;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000546}
547
548JITLoaderCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
550 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
551 JITLoaderInstances &instances = GetJITLoaderInstances();
552 if (idx < instances.size())
553 return instances[idx].create_callback;
554 return nullptr;
555}
556
557JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName(
558 const ConstString &name) {
559 if (name) {
560 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
561 JITLoaderInstances &instances = GetJITLoaderInstances();
562
563 JITLoaderInstances::iterator pos, end = instances.end();
564 for (pos = instances.begin(); pos != end; ++pos) {
565 if (name == pos->name)
566 return pos->create_callback;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000567 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000568 }
569 return nullptr;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000570}
571
Greg Claytonf03bbe22011-02-01 01:37:45 +0000572#pragma mark EmulateInstruction
573
Kate Stoneb9c1b512016-09-06 20:57:50 +0000574struct EmulateInstructionInstance {
575 EmulateInstructionInstance()
576 : name(), description(), create_callback(nullptr) {}
577
578 ConstString name;
579 std::string description;
580 EmulateInstructionCreateInstance create_callback;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000581};
582
583typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
584
Kate Stoneb9c1b512016-09-06 20:57:50 +0000585static std::recursive_mutex &GetEmulateInstructionMutex() {
586 static std::recursive_mutex g_instances_mutex;
587 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +0000588}
589
Kate Stoneb9c1b512016-09-06 20:57:50 +0000590static EmulateInstructionInstances &GetEmulateInstructionInstances() {
591 static EmulateInstructionInstances g_instances;
592 return g_instances;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000593}
594
Kate Stoneb9c1b512016-09-06 20:57:50 +0000595bool PluginManager::RegisterPlugin(
596 const ConstString &name, const char *description,
597 EmulateInstructionCreateInstance create_callback) {
598 if (create_callback) {
599 EmulateInstructionInstance instance;
600 assert((bool)name);
601 instance.name = name;
602 if (description && description[0])
603 instance.description = description;
604 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000605 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000606 GetEmulateInstructionInstances().push_back(instance);
607 }
608 return false;
609}
610
611bool PluginManager::UnregisterPlugin(
612 EmulateInstructionCreateInstance create_callback) {
613 if (create_callback) {
614 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
615 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
616
617 EmulateInstructionInstances::iterator pos, end = instances.end();
618 for (pos = instances.begin(); pos != end; ++pos) {
619 if (pos->create_callback == create_callback) {
620 instances.erase(pos);
621 return true;
622 }
623 }
624 }
625 return false;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000626}
627
628EmulateInstructionCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000629PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
630 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
631 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
632 if (idx < instances.size())
633 return instances[idx].create_callback;
634 return nullptr;
635}
636
637EmulateInstructionCreateInstance
638PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
639 const ConstString &name) {
640 if (name) {
641 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
642 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
643
644 EmulateInstructionInstances::iterator pos, end = instances.end();
645 for (pos = instances.begin(); pos != end; ++pos) {
646 if (name == pos->name)
647 return pos->create_callback;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000648 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000649 }
650 return nullptr;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000651}
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000652
Eugene Zelenko89183722016-03-11 21:55:47 +0000653#pragma mark OperatingSystem
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000654
Kate Stoneb9c1b512016-09-06 20:57:50 +0000655struct OperatingSystemInstance {
656 OperatingSystemInstance()
657 : name(), description(), create_callback(nullptr),
658 debugger_init_callback(nullptr) {}
659
660 ConstString name;
661 std::string description;
662 OperatingSystemCreateInstance create_callback;
663 DebuggerInitializeCallback debugger_init_callback;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000664};
665
666typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
667
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668static std::recursive_mutex &GetOperatingSystemMutex() {
669 static std::recursive_mutex g_instances_mutex;
670 return g_instances_mutex;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000671}
672
Kate Stoneb9c1b512016-09-06 20:57:50 +0000673static OperatingSystemInstances &GetOperatingSystemInstances() {
674 static OperatingSystemInstances g_instances;
675 return g_instances;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000676}
677
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678bool PluginManager::RegisterPlugin(
679 const ConstString &name, const char *description,
680 OperatingSystemCreateInstance create_callback,
681 DebuggerInitializeCallback debugger_init_callback) {
682 if (create_callback) {
683 OperatingSystemInstance instance;
684 assert((bool)name);
685 instance.name = name;
686 if (description && description[0])
687 instance.description = description;
688 instance.create_callback = create_callback;
689 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000690 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000691 GetOperatingSystemInstances().push_back(instance);
692 }
693 return false;
694}
695
696bool PluginManager::UnregisterPlugin(
697 OperatingSystemCreateInstance create_callback) {
698 if (create_callback) {
699 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
700 OperatingSystemInstances &instances = GetOperatingSystemInstances();
701
702 OperatingSystemInstances::iterator pos, end = instances.end();
703 for (pos = instances.begin(); pos != end; ++pos) {
704 if (pos->create_callback == create_callback) {
705 instances.erase(pos);
706 return true;
707 }
708 }
709 }
710 return false;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000711}
712
713OperatingSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000714PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
715 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
716 OperatingSystemInstances &instances = GetOperatingSystemInstances();
717 if (idx < instances.size())
718 return instances[idx].create_callback;
719 return nullptr;
720}
721
722OperatingSystemCreateInstance
723PluginManager::GetOperatingSystemCreateCallbackForPluginName(
724 const ConstString &name) {
725 if (name) {
726 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
727 OperatingSystemInstances &instances = GetOperatingSystemInstances();
728
729 OperatingSystemInstances::iterator pos, end = instances.end();
730 for (pos = instances.begin(); pos != end; ++pos) {
731 if (name == pos->name)
732 return pos->create_callback;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000733 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000734 }
735 return nullptr;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000736}
Greg Claytonf03bbe22011-02-01 01:37:45 +0000737
Enrico Granata5f9d3102015-08-27 21:33:50 +0000738#pragma mark Language
739
Kate Stoneb9c1b512016-09-06 20:57:50 +0000740struct LanguageInstance {
741 LanguageInstance() : name(), description(), create_callback(nullptr) {}
742
743 ConstString name;
744 std::string description;
745 LanguageCreateInstance create_callback;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000746};
747
748typedef std::vector<LanguageInstance> LanguageInstances;
749
Kate Stoneb9c1b512016-09-06 20:57:50 +0000750static std::recursive_mutex &GetLanguageMutex() {
751 static std::recursive_mutex g_instances_mutex;
752 return g_instances_mutex;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000753}
754
Kate Stoneb9c1b512016-09-06 20:57:50 +0000755static LanguageInstances &GetLanguageInstances() {
756 static LanguageInstances g_instances;
757 return g_instances;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000758}
759
Kate Stoneb9c1b512016-09-06 20:57:50 +0000760bool PluginManager::RegisterPlugin(const ConstString &name,
761 const char *description,
762 LanguageCreateInstance create_callback) {
763 if (create_callback) {
764 LanguageInstance instance;
765 assert((bool)name);
766 instance.name = name;
767 if (description && description[0])
768 instance.description = description;
769 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000770 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000771 GetLanguageInstances().push_back(instance);
772 }
773 return false;
774}
775
776bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
777 if (create_callback) {
778 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
779 LanguageInstances &instances = GetLanguageInstances();
780
781 LanguageInstances::iterator pos, end = instances.end();
782 for (pos = instances.begin(); pos != end; ++pos) {
783 if (pos->create_callback == create_callback) {
784 instances.erase(pos);
785 return true;
786 }
787 }
788 }
789 return false;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000790}
791
792LanguageCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000793PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
794 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
795 LanguageInstances &instances = GetLanguageInstances();
796 if (idx < instances.size())
797 return instances[idx].create_callback;
798 return nullptr;
799}
800
801LanguageCreateInstance
802PluginManager::GetLanguageCreateCallbackForPluginName(const ConstString &name) {
803 if (name) {
804 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
805 LanguageInstances &instances = GetLanguageInstances();
806
807 LanguageInstances::iterator pos, end = instances.end();
808 for (pos = instances.begin(); pos != end; ++pos) {
809 if (name == pos->name)
810 return pos->create_callback;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000811 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000812 }
813 return nullptr;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000814}
815
Jim Ingham22777012010-09-23 02:01:19 +0000816#pragma mark LanguageRuntime
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000817
Kate Stoneb9c1b512016-09-06 20:57:50 +0000818struct LanguageRuntimeInstance {
819 LanguageRuntimeInstance() : name(), description(), create_callback(nullptr) {}
Jim Ingham22777012010-09-23 02:01:19 +0000820
Kate Stoneb9c1b512016-09-06 20:57:50 +0000821 ConstString name;
822 std::string description;
823 LanguageRuntimeCreateInstance create_callback;
824 LanguageRuntimeGetCommandObject command_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000825};
826
827typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
828
Kate Stoneb9c1b512016-09-06 20:57:50 +0000829static std::recursive_mutex &GetLanguageRuntimeMutex() {
830 static std::recursive_mutex g_instances_mutex;
831 return g_instances_mutex;
Jim Ingham22777012010-09-23 02:01:19 +0000832}
833
Kate Stoneb9c1b512016-09-06 20:57:50 +0000834static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
835 static LanguageRuntimeInstances g_instances;
836 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +0000837}
Jim Ingham22777012010-09-23 02:01:19 +0000838
Kate Stoneb9c1b512016-09-06 20:57:50 +0000839bool PluginManager::RegisterPlugin(
840 const ConstString &name, const char *description,
841 LanguageRuntimeCreateInstance create_callback,
842 LanguageRuntimeGetCommandObject command_callback) {
843 if (create_callback) {
844 LanguageRuntimeInstance instance;
845 assert((bool)name);
846 instance.name = name;
847 if (description && description[0])
848 instance.description = description;
849 instance.create_callback = create_callback;
850 instance.command_callback = command_callback;
851 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
852 GetLanguageRuntimeInstances().push_back(instance);
853 }
854 return false;
855}
856
857bool PluginManager::UnregisterPlugin(
858 LanguageRuntimeCreateInstance create_callback) {
859 if (create_callback) {
860 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
861 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
862
863 LanguageRuntimeInstances::iterator pos, end = instances.end();
864 for (pos = instances.begin(); pos != end; ++pos) {
865 if (pos->create_callback == create_callback) {
866 instances.erase(pos);
867 return true;
868 }
Jim Ingham22777012010-09-23 02:01:19 +0000869 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870 }
871 return false;
Jim Ingham22777012010-09-23 02:01:19 +0000872}
873
874LanguageRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000875PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
876 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
877 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
878 if (idx < instances.size())
879 return instances[idx].create_callback;
880 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000881}
882
Colin Rileyc9c55a22015-05-04 18:39:38 +0000883LanguageRuntimeGetCommandObject
Kate Stoneb9c1b512016-09-06 20:57:50 +0000884PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
885 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
886 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
887 if (idx < instances.size())
888 return instances[idx].command_callback;
889 return nullptr;
Colin Rileyc9c55a22015-05-04 18:39:38 +0000890}
891
Jim Ingham22777012010-09-23 02:01:19 +0000892LanguageRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000893PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
894 const ConstString &name) {
895 if (name) {
896 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
897 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
898
899 LanguageRuntimeInstances::iterator pos, end = instances.end();
900 for (pos = instances.begin(); pos != end; ++pos) {
901 if (name == pos->name)
902 return pos->create_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000903 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000904 }
905 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000906}
907
Jason Molendaeef51062013-11-05 03:57:19 +0000908#pragma mark SystemRuntime
909
Kate Stoneb9c1b512016-09-06 20:57:50 +0000910struct SystemRuntimeInstance {
911 SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {}
Jason Molendaeef51062013-11-05 03:57:19 +0000912
Kate Stoneb9c1b512016-09-06 20:57:50 +0000913 ConstString name;
914 std::string description;
915 SystemRuntimeCreateInstance create_callback;
Jason Molendaeef51062013-11-05 03:57:19 +0000916};
917
918typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
919
Kate Stoneb9c1b512016-09-06 20:57:50 +0000920static std::recursive_mutex &GetSystemRuntimeMutex() {
921 static std::recursive_mutex g_instances_mutex;
922 return g_instances_mutex;
Jason Molendaeef51062013-11-05 03:57:19 +0000923}
924
Kate Stoneb9c1b512016-09-06 20:57:50 +0000925static SystemRuntimeInstances &GetSystemRuntimeInstances() {
926 static SystemRuntimeInstances g_instances;
927 return g_instances;
Jason Molendaeef51062013-11-05 03:57:19 +0000928}
929
Kate Stoneb9c1b512016-09-06 20:57:50 +0000930bool PluginManager::RegisterPlugin(
931 const ConstString &name, const char *description,
932 SystemRuntimeCreateInstance create_callback) {
933 if (create_callback) {
934 SystemRuntimeInstance instance;
935 assert((bool)name);
936 instance.name = name;
937 if (description && description[0])
938 instance.description = description;
939 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000940 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000941 GetSystemRuntimeInstances().push_back(instance);
942 }
943 return false;
944}
945
946bool PluginManager::UnregisterPlugin(
947 SystemRuntimeCreateInstance create_callback) {
948 if (create_callback) {
949 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
950 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
951
952 SystemRuntimeInstances::iterator pos, end = instances.end();
953 for (pos = instances.begin(); pos != end; ++pos) {
954 if (pos->create_callback == create_callback) {
955 instances.erase(pos);
956 return true;
957 }
958 }
959 }
960 return false;
Jason Molendaeef51062013-11-05 03:57:19 +0000961}
962
963SystemRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000964PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
965 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
966 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
967 if (idx < instances.size())
968 return instances[idx].create_callback;
969 return nullptr;
970}
971
972SystemRuntimeCreateInstance
973PluginManager::GetSystemRuntimeCreateCallbackForPluginName(
974 const ConstString &name) {
975 if (name) {
976 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
977 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
978
979 SystemRuntimeInstances::iterator pos, end = instances.end();
980 for (pos = instances.begin(); pos != end; ++pos) {
981 if (name == pos->name)
982 return pos->create_callback;
Jason Molendaeef51062013-11-05 03:57:19 +0000983 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000984 }
985 return nullptr;
Jason Molendaeef51062013-11-05 03:57:19 +0000986}
987
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000988#pragma mark ObjectFile
989
Kate Stoneb9c1b512016-09-06 20:57:50 +0000990struct ObjectFileInstance {
991 ObjectFileInstance()
992 : name(), description(), create_callback(nullptr),
993 create_memory_callback(nullptr), get_module_specifications(nullptr),
994 save_core(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000995
Kate Stoneb9c1b512016-09-06 20:57:50 +0000996 ConstString name;
997 std::string description;
998 ObjectFileCreateInstance create_callback;
999 ObjectFileCreateMemoryInstance create_memory_callback;
1000 ObjectFileGetModuleSpecifications get_module_specifications;
1001 ObjectFileSaveCore save_core;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001002};
1003
1004typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1005
Kate Stoneb9c1b512016-09-06 20:57:50 +00001006static std::recursive_mutex &GetObjectFileMutex() {
1007 static std::recursive_mutex g_instances_mutex;
1008 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001009}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001010
Kate Stoneb9c1b512016-09-06 20:57:50 +00001011static ObjectFileInstances &GetObjectFileInstances() {
1012 static ObjectFileInstances g_instances;
1013 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014}
1015
Kate Stoneb9c1b512016-09-06 20:57:50 +00001016bool PluginManager::RegisterPlugin(
1017 const ConstString &name, const char *description,
1018 ObjectFileCreateInstance create_callback,
1019 ObjectFileCreateMemoryInstance create_memory_callback,
1020 ObjectFileGetModuleSpecifications get_module_specifications,
1021 ObjectFileSaveCore save_core) {
1022 if (create_callback) {
1023 ObjectFileInstance instance;
1024 assert((bool)name);
1025 instance.name = name;
1026 if (description && description[0])
1027 instance.description = description;
1028 instance.create_callback = create_callback;
1029 instance.create_memory_callback = create_memory_callback;
1030 instance.save_core = save_core;
1031 instance.get_module_specifications = get_module_specifications;
1032 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1033 GetObjectFileInstances().push_back(instance);
1034 }
1035 return false;
1036}
1037
1038bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
1039 if (create_callback) {
1040 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1041 ObjectFileInstances &instances = GetObjectFileInstances();
1042
1043 ObjectFileInstances::iterator pos, end = instances.end();
1044 for (pos = instances.begin(); pos != end; ++pos) {
1045 if (pos->create_callback == create_callback) {
1046 instances.erase(pos);
1047 return true;
1048 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001049 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001050 }
1051 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052}
1053
1054ObjectFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001055PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
1056 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1057 ObjectFileInstances &instances = GetObjectFileInstances();
1058 if (idx < instances.size())
1059 return instances[idx].create_callback;
1060 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061}
Greg Claytonab65b342011-04-13 22:47:15 +00001062
Greg Claytonc9660542012-02-05 02:38:54 +00001063ObjectFileCreateMemoryInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001064PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
1065 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1066 ObjectFileInstances &instances = GetObjectFileInstances();
1067 if (idx < instances.size())
1068 return instances[idx].create_memory_callback;
1069 return nullptr;
Greg Claytonc9660542012-02-05 02:38:54 +00001070}
1071
Greg Claytonf4d6de62013-04-24 22:29:28 +00001072ObjectFileGetModuleSpecifications
Kate Stoneb9c1b512016-09-06 20:57:50 +00001073PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
1074 uint32_t idx) {
1075 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1076 ObjectFileInstances &instances = GetObjectFileInstances();
1077 if (idx < instances.size())
1078 return instances[idx].get_module_specifications;
1079 return nullptr;
Greg Claytonf4d6de62013-04-24 22:29:28 +00001080}
1081
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082ObjectFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083PluginManager::GetObjectFileCreateCallbackForPluginName(
1084 const ConstString &name) {
1085 if (name) {
1086 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1087 ObjectFileInstances &instances = GetObjectFileInstances();
1088
1089 ObjectFileInstances::iterator pos, end = instances.end();
1090 for (pos = instances.begin(); pos != end; ++pos) {
1091 if (name == pos->name)
1092 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001094 }
1095 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001096}
1097
Greg Claytonc9660542012-02-05 02:38:54 +00001098ObjectFileCreateMemoryInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001099PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
1100 const ConstString &name) {
1101 if (name) {
1102 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1103 ObjectFileInstances &instances = GetObjectFileInstances();
1104
1105 ObjectFileInstances::iterator pos, end = instances.end();
1106 for (pos = instances.begin(); pos != end; ++pos) {
1107 if (name == pos->name)
1108 return pos->create_memory_callback;
Greg Claytonc9660542012-02-05 02:38:54 +00001109 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001110 }
1111 return nullptr;
Greg Claytonc9660542012-02-05 02:38:54 +00001112}
1113
Zachary Turner97206d52017-05-12 04:51:55 +00001114Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
1115 const FileSpec &outfile) {
1116 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001117 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1118 ObjectFileInstances &instances = GetObjectFileInstances();
1119
1120 ObjectFileInstances::iterator pos, end = instances.end();
1121 for (pos = instances.begin(); pos != end; ++pos) {
1122 if (pos->save_core && pos->save_core(process_sp, outfile, error))
1123 return error;
1124 }
1125 error.SetErrorString(
1126 "no ObjectFile plugins were able to save a core for this process");
1127 return error;
Greg Claytona2715cf2014-06-13 00:54:12 +00001128}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129
1130#pragma mark ObjectContainer
1131
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132struct ObjectContainerInstance {
1133 ObjectContainerInstance()
1134 : name(), description(), create_callback(nullptr),
1135 get_module_specifications(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001136
Kate Stoneb9c1b512016-09-06 20:57:50 +00001137 ConstString name;
1138 std::string description;
1139 ObjectContainerCreateInstance create_callback;
1140 ObjectFileGetModuleSpecifications get_module_specifications;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001141};
1142
1143typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1144
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145static std::recursive_mutex &GetObjectContainerMutex() {
1146 static std::recursive_mutex g_instances_mutex;
1147 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001148}
1149
Kate Stoneb9c1b512016-09-06 20:57:50 +00001150static ObjectContainerInstances &GetObjectContainerInstances() {
1151 static ObjectContainerInstances g_instances;
1152 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +00001153}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001154
Kate Stoneb9c1b512016-09-06 20:57:50 +00001155bool PluginManager::RegisterPlugin(
1156 const ConstString &name, const char *description,
1157 ObjectContainerCreateInstance create_callback,
1158 ObjectFileGetModuleSpecifications get_module_specifications) {
1159 if (create_callback) {
1160 ObjectContainerInstance instance;
1161 assert((bool)name);
1162 instance.name = name;
1163 if (description && description[0])
1164 instance.description = description;
1165 instance.create_callback = create_callback;
1166 instance.get_module_specifications = get_module_specifications;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001167 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001168 GetObjectContainerInstances().push_back(instance);
1169 }
1170 return false;
1171}
1172
1173bool PluginManager::UnregisterPlugin(
1174 ObjectContainerCreateInstance create_callback) {
1175 if (create_callback) {
1176 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1177 ObjectContainerInstances &instances = GetObjectContainerInstances();
1178
1179 ObjectContainerInstances::iterator pos, end = instances.end();
1180 for (pos = instances.begin(); pos != end; ++pos) {
1181 if (pos->create_callback == create_callback) {
1182 instances.erase(pos);
1183 return true;
1184 }
1185 }
1186 }
1187 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001188}
Greg Claytonab65b342011-04-13 22:47:15 +00001189
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001190ObjectContainerCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001191PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
1192 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1193 ObjectContainerInstances &instances = GetObjectContainerInstances();
1194 if (idx < instances.size())
1195 return instances[idx].create_callback;
1196 return nullptr;
1197}
1198
1199ObjectContainerCreateInstance
1200PluginManager::GetObjectContainerCreateCallbackForPluginName(
1201 const ConstString &name) {
1202 if (name) {
1203 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1204 ObjectContainerInstances &instances = GetObjectContainerInstances();
1205
1206 ObjectContainerInstances::iterator pos, end = instances.end();
1207 for (pos = instances.begin(); pos != end; ++pos) {
1208 if (name == pos->name)
1209 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001210 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001211 }
1212 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001213}
1214
Greg Claytonf4d6de62013-04-24 22:29:28 +00001215ObjectFileGetModuleSpecifications
Kate Stoneb9c1b512016-09-06 20:57:50 +00001216PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
1217 uint32_t idx) {
1218 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1219 ObjectContainerInstances &instances = GetObjectContainerInstances();
1220 if (idx < instances.size())
1221 return instances[idx].get_module_specifications;
1222 return nullptr;
Greg Claytonf4d6de62013-04-24 22:29:28 +00001223}
1224
Greg Claytone996fd32011-03-08 22:40:15 +00001225#pragma mark Platform
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001226
Kate Stoneb9c1b512016-09-06 20:57:50 +00001227struct PlatformInstance {
1228 PlatformInstance()
1229 : name(), description(), create_callback(nullptr),
1230 debugger_init_callback(nullptr) {}
1231
1232 ConstString name;
1233 std::string description;
1234 PlatformCreateInstance create_callback;
1235 DebuggerInitializeCallback debugger_init_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001236};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001237
Greg Claytone996fd32011-03-08 22:40:15 +00001238typedef std::vector<PlatformInstance> PlatformInstances;
1239
Kate Stoneb9c1b512016-09-06 20:57:50 +00001240static std::recursive_mutex &GetPlatformInstancesMutex() {
1241 static std::recursive_mutex g_platform_instances_mutex;
1242 return g_platform_instances_mutex;
Greg Claytone996fd32011-03-08 22:40:15 +00001243}
1244
Kate Stoneb9c1b512016-09-06 20:57:50 +00001245static PlatformInstances &GetPlatformInstances() {
1246 static PlatformInstances g_platform_instances;
1247 return g_platform_instances;
Greg Claytonded470d2011-03-19 01:12:21 +00001248}
Greg Claytone996fd32011-03-08 22:40:15 +00001249
Kate Stoneb9c1b512016-09-06 20:57:50 +00001250bool PluginManager::RegisterPlugin(
1251 const ConstString &name, const char *description,
1252 PlatformCreateInstance create_callback,
1253 DebuggerInitializeCallback debugger_init_callback) {
1254 if (create_callback) {
1255 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001256
Kate Stoneb9c1b512016-09-06 20:57:50 +00001257 PlatformInstance instance;
1258 assert((bool)name);
1259 instance.name = name;
1260 if (description && description[0])
1261 instance.description = description;
1262 instance.create_callback = create_callback;
1263 instance.debugger_init_callback = debugger_init_callback;
1264 GetPlatformInstances().push_back(instance);
1265 return true;
1266 }
1267 return false;
1268}
1269
1270const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
1271 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1272 PlatformInstances &instances = GetPlatformInstances();
1273 if (idx < instances.size())
1274 return instances[idx].name.GetCString();
1275 return nullptr;
1276}
1277
1278const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
1279 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1280 PlatformInstances &instances = GetPlatformInstances();
1281 if (idx < instances.size())
1282 return instances[idx].description.c_str();
1283 return nullptr;
1284}
1285
1286bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
1287 if (create_callback) {
1288 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1289 PlatformInstances &instances = GetPlatformInstances();
1290
1291 PlatformInstances::iterator pos, end = instances.end();
1292 for (pos = instances.begin(); pos != end; ++pos) {
1293 if (pos->create_callback == create_callback) {
1294 instances.erase(pos);
Greg Claytonded470d2011-03-19 01:12:21 +00001295 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001296 }
Greg Claytone996fd32011-03-08 22:40:15 +00001297 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001298 }
1299 return false;
Greg Claytone996fd32011-03-08 22:40:15 +00001300}
1301
1302PlatformCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001303PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
1304 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1305 PlatformInstances &instances = GetPlatformInstances();
1306 if (idx < instances.size())
1307 return instances[idx].create_callback;
1308 return nullptr;
Greg Claytone996fd32011-03-08 22:40:15 +00001309}
1310
1311PlatformCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001312PluginManager::GetPlatformCreateCallbackForPluginName(const ConstString &name) {
1313 if (name) {
1314 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1315 PlatformInstances &instances = GetPlatformInstances();
Greg Claytonded470d2011-03-19 01:12:21 +00001316
Kate Stoneb9c1b512016-09-06 20:57:50 +00001317 PlatformInstances::iterator pos, end = instances.end();
1318 for (pos = instances.begin(); pos != end; ++pos) {
1319 if (name == pos->name)
1320 return pos->create_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001321 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001322 }
1323 return nullptr;
Greg Claytone996fd32011-03-08 22:40:15 +00001324}
1325
Zachary Turner4aa87532016-11-17 01:37:42 +00001326size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001327 StringList &matches) {
Zachary Turner4aa87532016-11-17 01:37:42 +00001328 if (name.empty())
1329 return matches.GetSize();
Greg Claytonab65b342011-04-13 22:47:15 +00001330
Zachary Turner4aa87532016-11-17 01:37:42 +00001331 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1332 PlatformInstances &instances = GetPlatformInstances();
1333 llvm::StringRef name_sref(name);
1334
1335 PlatformInstances::iterator pos, end = instances.end();
1336 for (pos = instances.begin(); pos != end; ++pos) {
1337 llvm::StringRef plugin_name(pos->name.GetCString());
1338 if (plugin_name.startswith(name_sref))
1339 matches.AppendString(plugin_name.data());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001340 }
1341 return matches.GetSize();
Greg Claytonab65b342011-04-13 22:47:15 +00001342}
Eugene Zelenko89183722016-03-11 21:55:47 +00001343
Greg Claytone996fd32011-03-08 22:40:15 +00001344#pragma mark Process
1345
Kate Stoneb9c1b512016-09-06 20:57:50 +00001346struct ProcessInstance {
1347 ProcessInstance()
1348 : name(), description(), create_callback(nullptr),
1349 debugger_init_callback(nullptr) {}
1350
1351 ConstString name;
1352 std::string description;
1353 ProcessCreateInstance create_callback;
1354 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001355};
1356
1357typedef std::vector<ProcessInstance> ProcessInstances;
1358
Kate Stoneb9c1b512016-09-06 20:57:50 +00001359static std::recursive_mutex &GetProcessMutex() {
1360 static std::recursive_mutex g_instances_mutex;
1361 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001362}
1363
Kate Stoneb9c1b512016-09-06 20:57:50 +00001364static ProcessInstances &GetProcessInstances() {
1365 static ProcessInstances g_instances;
1366 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001367}
1368
Kate Stoneb9c1b512016-09-06 20:57:50 +00001369bool PluginManager::RegisterPlugin(
1370 const ConstString &name, const char *description,
1371 ProcessCreateInstance create_callback,
1372 DebuggerInitializeCallback debugger_init_callback) {
1373 if (create_callback) {
1374 ProcessInstance instance;
1375 assert((bool)name);
1376 instance.name = name;
1377 if (description && description[0])
1378 instance.description = description;
1379 instance.create_callback = create_callback;
1380 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001381 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001382 GetProcessInstances().push_back(instance);
1383 }
1384 return false;
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001385}
1386
Kate Stoneb9c1b512016-09-06 20:57:50 +00001387const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
1388 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1389 ProcessInstances &instances = GetProcessInstances();
1390 if (idx < instances.size())
1391 return instances[idx].name.GetCString();
1392 return nullptr;
1393}
1394
1395const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
1396 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1397 ProcessInstances &instances = GetProcessInstances();
1398 if (idx < instances.size())
1399 return instances[idx].description.c_str();
1400 return nullptr;
1401}
1402
1403bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
1404 if (create_callback) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001405 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001406 ProcessInstances &instances = GetProcessInstances();
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001407
Kate Stoneb9c1b512016-09-06 20:57:50 +00001408 ProcessInstances::iterator pos, end = instances.end();
1409 for (pos = instances.begin(); pos != end; ++pos) {
1410 if (pos->create_callback == create_callback) {
1411 instances.erase(pos);
1412 return true;
1413 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001414 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001415 }
1416 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001417}
1418
1419ProcessCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001420PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
1421 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1422 ProcessInstances &instances = GetProcessInstances();
1423 if (idx < instances.size())
1424 return instances[idx].create_callback;
1425 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001426}
1427
1428ProcessCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001429PluginManager::GetProcessCreateCallbackForPluginName(const ConstString &name) {
1430 if (name) {
1431 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1432 ProcessInstances &instances = GetProcessInstances();
1433
1434 ProcessInstances::iterator pos, end = instances.end();
1435 for (pos = instances.begin(); pos != end; ++pos) {
1436 if (name == pos->name)
1437 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001438 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001439 }
1440 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001441}
1442
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001443#pragma mark ScriptInterpreter
1444
Kate Stoneb9c1b512016-09-06 20:57:50 +00001445struct ScriptInterpreterInstance {
1446 ScriptInterpreterInstance()
1447 : name(), language(lldb::eScriptLanguageNone), description(),
1448 create_callback(nullptr) {}
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001449
Kate Stoneb9c1b512016-09-06 20:57:50 +00001450 ConstString name;
1451 lldb::ScriptLanguage language;
1452 std::string description;
1453 ScriptInterpreterCreateInstance create_callback;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001454};
1455
1456typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
1457
Kate Stoneb9c1b512016-09-06 20:57:50 +00001458static std::recursive_mutex &GetScriptInterpreterMutex() {
1459 static std::recursive_mutex g_instances_mutex;
1460 return g_instances_mutex;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001461}
1462
Kate Stoneb9c1b512016-09-06 20:57:50 +00001463static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
1464 static ScriptInterpreterInstances g_instances;
1465 return g_instances;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001466}
1467
Kate Stoneb9c1b512016-09-06 20:57:50 +00001468bool PluginManager::RegisterPlugin(
1469 const ConstString &name, const char *description,
1470 lldb::ScriptLanguage script_language,
1471 ScriptInterpreterCreateInstance create_callback) {
1472 if (!create_callback)
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001473 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001474 ScriptInterpreterInstance instance;
1475 assert((bool)name);
1476 instance.name = name;
1477 if (description && description[0])
1478 instance.description = description;
1479 instance.create_callback = create_callback;
1480 instance.language = script_language;
1481 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1482 GetScriptInterpreterInstances().push_back(instance);
1483 return false;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001484}
1485
Kate Stoneb9c1b512016-09-06 20:57:50 +00001486bool PluginManager::UnregisterPlugin(
1487 ScriptInterpreterCreateInstance create_callback) {
1488 if (!create_callback)
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001489 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001490 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1491 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1492
1493 ScriptInterpreterInstances::iterator pos, end = instances.end();
1494 for (pos = instances.begin(); pos != end; ++pos) {
1495 if (pos->create_callback != create_callback)
1496 continue;
1497
1498 instances.erase(pos);
1499 return true;
1500 }
1501 return false;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001502}
1503
1504ScriptInterpreterCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001505PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
1506 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1507 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1508 if (idx < instances.size())
1509 return instances[idx].create_callback;
1510 return nullptr;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001511}
1512
Kate Stoneb9c1b512016-09-06 20:57:50 +00001513lldb::ScriptInterpreterSP PluginManager::GetScriptInterpreterForLanguage(
1514 lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter) {
1515 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1516 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001517
Kate Stoneb9c1b512016-09-06 20:57:50 +00001518 ScriptInterpreterInstances::iterator pos, end = instances.end();
1519 ScriptInterpreterCreateInstance none_instance = nullptr;
1520 for (pos = instances.begin(); pos != end; ++pos) {
1521 if (pos->language == lldb::eScriptLanguageNone)
1522 none_instance = pos->create_callback;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001523
Kate Stoneb9c1b512016-09-06 20:57:50 +00001524 if (script_lang == pos->language)
1525 return pos->create_callback(interpreter);
1526 }
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001527
Kate Stoneb9c1b512016-09-06 20:57:50 +00001528 // If we didn't find one, return the ScriptInterpreter for the null language.
1529 assert(none_instance != nullptr);
1530 return none_instance(interpreter);
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001531}
1532
Todd Fiala75930012016-08-19 04:21:48 +00001533#pragma mark -
1534#pragma mark StructuredDataPlugin
1535
1536// -----------------------------------------------------------------------------
1537// StructuredDataPlugin
1538// -----------------------------------------------------------------------------
1539
Kate Stoneb9c1b512016-09-06 20:57:50 +00001540struct StructuredDataPluginInstance {
1541 StructuredDataPluginInstance()
1542 : name(), description(), create_callback(nullptr),
1543 debugger_init_callback(nullptr), filter_callback(nullptr) {}
Todd Fiala75930012016-08-19 04:21:48 +00001544
Kate Stoneb9c1b512016-09-06 20:57:50 +00001545 ConstString name;
1546 std::string description;
1547 StructuredDataPluginCreateInstance create_callback;
1548 DebuggerInitializeCallback debugger_init_callback;
1549 StructuredDataFilterLaunchInfo filter_callback;
Todd Fiala75930012016-08-19 04:21:48 +00001550};
1551
1552typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;
1553
Kate Stoneb9c1b512016-09-06 20:57:50 +00001554static std::recursive_mutex &GetStructuredDataPluginMutex() {
1555 static std::recursive_mutex g_instances_mutex;
1556 return g_instances_mutex;
Todd Fiala75930012016-08-19 04:21:48 +00001557}
1558
Kate Stoneb9c1b512016-09-06 20:57:50 +00001559static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
1560 static StructuredDataPluginInstances g_instances;
1561 return g_instances;
Todd Fiala75930012016-08-19 04:21:48 +00001562}
1563
Kate Stoneb9c1b512016-09-06 20:57:50 +00001564bool PluginManager::RegisterPlugin(
1565 const ConstString &name, const char *description,
1566 StructuredDataPluginCreateInstance create_callback,
1567 DebuggerInitializeCallback debugger_init_callback,
1568 StructuredDataFilterLaunchInfo filter_callback) {
1569 if (create_callback) {
1570 StructuredDataPluginInstance instance;
1571 assert((bool)name);
1572 instance.name = name;
1573 if (description && description[0])
1574 instance.description = description;
1575 instance.create_callback = create_callback;
1576 instance.debugger_init_callback = debugger_init_callback;
1577 instance.filter_callback = filter_callback;
1578 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1579 GetStructuredDataPluginInstances().push_back(instance);
1580 }
1581 return false;
Todd Fiala75930012016-08-19 04:21:48 +00001582}
1583
Kate Stoneb9c1b512016-09-06 20:57:50 +00001584bool PluginManager::UnregisterPlugin(
1585 StructuredDataPluginCreateInstance create_callback) {
1586 if (create_callback) {
Todd Fiala75930012016-08-19 04:21:48 +00001587 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1588 StructuredDataPluginInstances &instances =
1589 GetStructuredDataPluginInstances();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001590
1591 StructuredDataPluginInstances::iterator pos, end = instances.end();
1592 for (pos = instances.begin(); pos != end; ++pos) {
1593 if (pos->create_callback == create_callback) {
1594 instances.erase(pos);
1595 return true;
1596 }
1597 }
1598 }
1599 return false;
1600}
1601
1602StructuredDataPluginCreateInstance
1603PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
1604 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1605 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
1606 if (idx < instances.size())
1607 return instances[idx].create_callback;
1608 return nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00001609}
1610
1611StructuredDataPluginCreateInstance
1612PluginManager::GetStructuredDataPluginCreateCallbackForPluginName(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001613 const ConstString &name) {
1614 if (name) {
Todd Fiala75930012016-08-19 04:21:48 +00001615 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1616 StructuredDataPluginInstances &instances =
1617 GetStructuredDataPluginInstances();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001618
1619 StructuredDataPluginInstances::iterator pos, end = instances.end();
1620 for (pos = instances.begin(); pos != end; ++pos) {
1621 if (name == pos->name)
1622 return pos->create_callback;
Todd Fiala75930012016-08-19 04:21:48 +00001623 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001624 }
1625 return nullptr;
1626}
1627
1628StructuredDataFilterLaunchInfo
1629PluginManager::GetStructuredDataFilterCallbackAtIndex(
1630 uint32_t idx, bool &iteration_complete) {
1631 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1632 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
1633 if (idx < instances.size()) {
1634 iteration_complete = false;
1635 return instances[idx].filter_callback;
1636 } else {
1637 iteration_complete = true;
1638 }
1639 return nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00001640}
1641
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001642#pragma mark SymbolFile
1643
Kate Stoneb9c1b512016-09-06 20:57:50 +00001644struct SymbolFileInstance {
1645 SymbolFileInstance()
1646 : name(), description(), create_callback(nullptr),
1647 debugger_init_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001648
Kate Stoneb9c1b512016-09-06 20:57:50 +00001649 ConstString name;
1650 std::string description;
1651 SymbolFileCreateInstance create_callback;
1652 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001653};
1654
1655typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1656
Kate Stoneb9c1b512016-09-06 20:57:50 +00001657static std::recursive_mutex &GetSymbolFileMutex() {
1658 static std::recursive_mutex g_instances_mutex;
1659 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001660}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001661
Kate Stoneb9c1b512016-09-06 20:57:50 +00001662static SymbolFileInstances &GetSymbolFileInstances() {
1663 static SymbolFileInstances g_instances;
1664 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001665}
1666
Kate Stoneb9c1b512016-09-06 20:57:50 +00001667bool PluginManager::RegisterPlugin(
1668 const ConstString &name, const char *description,
1669 SymbolFileCreateInstance create_callback,
1670 DebuggerInitializeCallback debugger_init_callback) {
1671 if (create_callback) {
1672 SymbolFileInstance instance;
1673 assert((bool)name);
1674 instance.name = name;
1675 if (description && description[0])
1676 instance.description = description;
1677 instance.create_callback = create_callback;
1678 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001679 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001680 GetSymbolFileInstances().push_back(instance);
1681 }
1682 return false;
1683}
1684
1685bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
1686 if (create_callback) {
1687 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1688 SymbolFileInstances &instances = GetSymbolFileInstances();
1689
1690 SymbolFileInstances::iterator pos, end = instances.end();
1691 for (pos = instances.begin(); pos != end; ++pos) {
1692 if (pos->create_callback == create_callback) {
1693 instances.erase(pos);
1694 return true;
1695 }
1696 }
1697 }
1698 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001699}
Greg Claytonab65b342011-04-13 22:47:15 +00001700
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001701SymbolFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001702PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1703 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1704 SymbolFileInstances &instances = GetSymbolFileInstances();
1705 if (idx < instances.size())
1706 return instances[idx].create_callback;
1707 return nullptr;
1708}
1709
1710SymbolFileCreateInstance
1711PluginManager::GetSymbolFileCreateCallbackForPluginName(
1712 const ConstString &name) {
1713 if (name) {
1714 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1715 SymbolFileInstances &instances = GetSymbolFileInstances();
1716
1717 SymbolFileInstances::iterator pos, end = instances.end();
1718 for (pos = instances.begin(); pos != end; ++pos) {
1719 if (name == pos->name)
1720 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001721 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001722 }
1723 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001724}
1725
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001726#pragma mark SymbolVendor
1727
Kate Stoneb9c1b512016-09-06 20:57:50 +00001728struct SymbolVendorInstance {
1729 SymbolVendorInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001730
Kate Stoneb9c1b512016-09-06 20:57:50 +00001731 ConstString name;
1732 std::string description;
1733 SymbolVendorCreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001734};
1735
1736typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1737
Kate Stoneb9c1b512016-09-06 20:57:50 +00001738static std::recursive_mutex &GetSymbolVendorMutex() {
1739 static std::recursive_mutex g_instances_mutex;
1740 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001741}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001742
Kate Stoneb9c1b512016-09-06 20:57:50 +00001743static SymbolVendorInstances &GetSymbolVendorInstances() {
1744 static SymbolVendorInstances g_instances;
1745 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001746}
1747
Kate Stoneb9c1b512016-09-06 20:57:50 +00001748bool PluginManager::RegisterPlugin(const ConstString &name,
1749 const char *description,
1750 SymbolVendorCreateInstance create_callback) {
1751 if (create_callback) {
1752 SymbolVendorInstance instance;
1753 assert((bool)name);
1754 instance.name = name;
1755 if (description && description[0])
1756 instance.description = description;
1757 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001758 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001759 GetSymbolVendorInstances().push_back(instance);
1760 }
1761 return false;
1762}
1763
1764bool PluginManager::UnregisterPlugin(
1765 SymbolVendorCreateInstance create_callback) {
1766 if (create_callback) {
1767 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1768 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1769
1770 SymbolVendorInstances::iterator pos, end = instances.end();
1771 for (pos = instances.begin(); pos != end; ++pos) {
1772 if (pos->create_callback == create_callback) {
1773 instances.erase(pos);
1774 return true;
1775 }
1776 }
1777 }
1778 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001779}
1780
1781SymbolVendorCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001782PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1783 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1784 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1785 if (idx < instances.size())
1786 return instances[idx].create_callback;
1787 return nullptr;
1788}
1789
1790SymbolVendorCreateInstance
1791PluginManager::GetSymbolVendorCreateCallbackForPluginName(
1792 const ConstString &name) {
1793 if (name) {
1794 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1795 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1796
1797 SymbolVendorInstances::iterator pos, end = instances.end();
1798 for (pos = instances.begin(); pos != end; ++pos) {
1799 if (name == pos->name)
1800 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001801 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001802 }
1803 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001804}
1805
Greg Clayton7be25422011-04-25 21:14:26 +00001806#pragma mark UnwindAssembly
Jason Molendafbcb7f22010-09-10 07:49:16 +00001807
Kate Stoneb9c1b512016-09-06 20:57:50 +00001808struct UnwindAssemblyInstance {
1809 UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001810
Kate Stoneb9c1b512016-09-06 20:57:50 +00001811 ConstString name;
1812 std::string description;
1813 UnwindAssemblyCreateInstance create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001814};
1815
Greg Clayton7be25422011-04-25 21:14:26 +00001816typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001817
Kate Stoneb9c1b512016-09-06 20:57:50 +00001818static std::recursive_mutex &GetUnwindAssemblyMutex() {
1819 static std::recursive_mutex g_instances_mutex;
1820 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001821}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001822
Kate Stoneb9c1b512016-09-06 20:57:50 +00001823static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1824 static UnwindAssemblyInstances g_instances;
1825 return g_instances;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001826}
1827
Kate Stoneb9c1b512016-09-06 20:57:50 +00001828bool PluginManager::RegisterPlugin(
1829 const ConstString &name, const char *description,
1830 UnwindAssemblyCreateInstance create_callback) {
1831 if (create_callback) {
1832 UnwindAssemblyInstance instance;
1833 assert((bool)name);
1834 instance.name = name;
1835 if (description && description[0])
1836 instance.description = description;
1837 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001838 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001839 GetUnwindAssemblyInstances().push_back(instance);
1840 }
1841 return false;
1842}
1843
1844bool PluginManager::UnregisterPlugin(
1845 UnwindAssemblyCreateInstance create_callback) {
1846 if (create_callback) {
1847 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1848 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1849
1850 UnwindAssemblyInstances::iterator pos, end = instances.end();
1851 for (pos = instances.begin(); pos != end; ++pos) {
1852 if (pos->create_callback == create_callback) {
1853 instances.erase(pos);
1854 return true;
1855 }
1856 }
1857 }
1858 return false;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001859}
1860
Greg Clayton7be25422011-04-25 21:14:26 +00001861UnwindAssemblyCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001862PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1863 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1864 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1865 if (idx < instances.size())
1866 return instances[idx].create_callback;
1867 return nullptr;
1868}
1869
1870UnwindAssemblyCreateInstance
1871PluginManager::GetUnwindAssemblyCreateCallbackForPluginName(
1872 const ConstString &name) {
1873 if (name) {
1874 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1875 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1876
1877 UnwindAssemblyInstances::iterator pos, end = instances.end();
1878 for (pos = instances.begin(); pos != end; ++pos) {
1879 if (name == pos->name)
1880 return pos->create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001881 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001882 }
1883 return nullptr;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001884}
1885
Kuba Breckabeed8212014-09-04 01:03:18 +00001886#pragma mark MemoryHistory
1887
Kate Stoneb9c1b512016-09-06 20:57:50 +00001888struct MemoryHistoryInstance {
1889 MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {}
1890
1891 ConstString name;
1892 std::string description;
1893 MemoryHistoryCreateInstance create_callback;
Kuba Breckabeed8212014-09-04 01:03:18 +00001894};
1895
1896typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
1897
Kate Stoneb9c1b512016-09-06 20:57:50 +00001898static std::recursive_mutex &GetMemoryHistoryMutex() {
1899 static std::recursive_mutex g_instances_mutex;
1900 return g_instances_mutex;
Kuba Breckabeed8212014-09-04 01:03:18 +00001901}
1902
Kate Stoneb9c1b512016-09-06 20:57:50 +00001903static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1904 static MemoryHistoryInstances g_instances;
1905 return g_instances;
Kuba Breckabeed8212014-09-04 01:03:18 +00001906}
1907
Kate Stoneb9c1b512016-09-06 20:57:50 +00001908bool PluginManager::RegisterPlugin(
1909 const ConstString &name, const char *description,
1910 MemoryHistoryCreateInstance create_callback) {
1911 if (create_callback) {
1912 MemoryHistoryInstance instance;
1913 assert((bool)name);
1914 instance.name = name;
1915 if (description && description[0])
1916 instance.description = description;
1917 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001918 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001919 GetMemoryHistoryInstances().push_back(instance);
1920 }
1921 return false;
1922}
1923
1924bool PluginManager::UnregisterPlugin(
1925 MemoryHistoryCreateInstance create_callback) {
1926 if (create_callback) {
1927 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1928 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1929
1930 MemoryHistoryInstances::iterator pos, end = instances.end();
1931 for (pos = instances.begin(); pos != end; ++pos) {
1932 if (pos->create_callback == create_callback) {
1933 instances.erase(pos);
1934 return true;
1935 }
1936 }
1937 }
1938 return false;
Kuba Breckabeed8212014-09-04 01:03:18 +00001939}
1940
Kuba Breckabeed8212014-09-04 01:03:18 +00001941MemoryHistoryCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001942PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1943 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1944 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1945 if (idx < instances.size())
1946 return instances[idx].create_callback;
1947 return nullptr;
1948}
1949
1950MemoryHistoryCreateInstance
1951PluginManager::GetMemoryHistoryCreateCallbackForPluginName(
1952 const ConstString &name) {
1953 if (name) {
1954 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1955 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1956
1957 MemoryHistoryInstances::iterator pos, end = instances.end();
1958 for (pos = instances.begin(); pos != end; ++pos) {
1959 if (name == pos->name)
1960 return pos->create_callback;
Kuba Breckabeed8212014-09-04 01:03:18 +00001961 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001962 }
1963 return nullptr;
Kuba Breckabeed8212014-09-04 01:03:18 +00001964}
1965
Kuba Breckaafdf8422014-10-10 23:43:03 +00001966#pragma mark InstrumentationRuntime
1967
Kate Stoneb9c1b512016-09-06 20:57:50 +00001968struct InstrumentationRuntimeInstance {
1969 InstrumentationRuntimeInstance()
1970 : name(), description(), create_callback(nullptr) {}
1971
1972 ConstString name;
1973 std::string description;
1974 InstrumentationRuntimeCreateInstance create_callback;
1975 InstrumentationRuntimeGetType get_type_callback;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001976};
1977
Kate Stoneb9c1b512016-09-06 20:57:50 +00001978typedef std::vector<InstrumentationRuntimeInstance>
1979 InstrumentationRuntimeInstances;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001980
Kate Stoneb9c1b512016-09-06 20:57:50 +00001981static std::recursive_mutex &GetInstrumentationRuntimeMutex() {
1982 static std::recursive_mutex g_instances_mutex;
1983 return g_instances_mutex;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001984}
1985
Kate Stoneb9c1b512016-09-06 20:57:50 +00001986static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1987 static InstrumentationRuntimeInstances g_instances;
1988 return g_instances;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001989}
1990
Kate Stoneb9c1b512016-09-06 20:57:50 +00001991bool PluginManager::RegisterPlugin(
1992 const ConstString &name, const char *description,
1993 InstrumentationRuntimeCreateInstance create_callback,
1994 InstrumentationRuntimeGetType get_type_callback) {
1995 if (create_callback) {
1996 InstrumentationRuntimeInstance instance;
1997 assert((bool)name);
1998 instance.name = name;
1999 if (description && description[0])
2000 instance.description = description;
2001 instance.create_callback = create_callback;
2002 instance.get_type_callback = get_type_callback;
2003 std::lock_guard<std::recursive_mutex> guard(
2004 GetInstrumentationRuntimeMutex());
2005 GetInstrumentationRuntimeInstances().push_back(instance);
2006 }
2007 return false;
2008}
2009
2010bool PluginManager::UnregisterPlugin(
2011 InstrumentationRuntimeCreateInstance create_callback) {
2012 if (create_callback) {
2013 std::lock_guard<std::recursive_mutex> guard(
2014 GetInstrumentationRuntimeMutex());
2015 InstrumentationRuntimeInstances &instances =
2016 GetInstrumentationRuntimeInstances();
2017
2018 InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2019 for (pos = instances.begin(); pos != end; ++pos) {
2020 if (pos->create_callback == create_callback) {
2021 instances.erase(pos);
2022 return true;
2023 }
Kuba Breckaafdf8422014-10-10 23:43:03 +00002024 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002025 }
2026 return false;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002027}
2028
2029InstrumentationRuntimeGetType
Kate Stoneb9c1b512016-09-06 20:57:50 +00002030PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
2031 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
2032 InstrumentationRuntimeInstances &instances =
2033 GetInstrumentationRuntimeInstances();
2034 if (idx < instances.size())
2035 return instances[idx].get_type_callback;
2036 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002037}
2038
2039InstrumentationRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002040PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
2041 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
2042 InstrumentationRuntimeInstances &instances =
2043 GetInstrumentationRuntimeInstances();
2044 if (idx < instances.size())
2045 return instances[idx].create_callback;
2046 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002047}
2048
Kuba Breckaafdf8422014-10-10 23:43:03 +00002049InstrumentationRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002050PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName(
2051 const ConstString &name) {
2052 if (name) {
2053 std::lock_guard<std::recursive_mutex> guard(
2054 GetInstrumentationRuntimeMutex());
2055 InstrumentationRuntimeInstances &instances =
2056 GetInstrumentationRuntimeInstances();
2057
2058 InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2059 for (pos = instances.begin(); pos != end; ++pos) {
2060 if (name == pos->name)
2061 return pos->create_callback;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002062 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002063 }
2064 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002065}
2066
Greg Clayton56939cb2015-09-17 22:23:34 +00002067#pragma mark TypeSystem
2068
Kate Stoneb9c1b512016-09-06 20:57:50 +00002069struct TypeSystemInstance {
2070 TypeSystemInstance() : name(), description(), create_callback(nullptr) {}
Greg Clayton56939cb2015-09-17 22:23:34 +00002071
Kate Stoneb9c1b512016-09-06 20:57:50 +00002072 ConstString name;
2073 std::string description;
2074 TypeSystemCreateInstance create_callback;
2075 TypeSystemEnumerateSupportedLanguages enumerate_callback;
Greg Clayton56939cb2015-09-17 22:23:34 +00002076};
2077
2078typedef std::vector<TypeSystemInstance> TypeSystemInstances;
2079
Kate Stoneb9c1b512016-09-06 20:57:50 +00002080static std::recursive_mutex &GetTypeSystemMutex() {
2081 static std::recursive_mutex g_instances_mutex;
2082 return g_instances_mutex;
Greg Clayton56939cb2015-09-17 22:23:34 +00002083}
2084
Kate Stoneb9c1b512016-09-06 20:57:50 +00002085static TypeSystemInstances &GetTypeSystemInstances() {
2086 static TypeSystemInstances g_instances;
2087 return g_instances;
Greg Clayton56939cb2015-09-17 22:23:34 +00002088}
2089
Kate Stoneb9c1b512016-09-06 20:57:50 +00002090bool PluginManager::RegisterPlugin(const ConstString &name,
2091 const char *description,
2092 TypeSystemCreateInstance create_callback,
2093 TypeSystemEnumerateSupportedLanguages
2094 enumerate_supported_languages_callback) {
2095 if (create_callback) {
2096 TypeSystemInstance instance;
2097 assert((bool)name);
2098 instance.name = name;
2099 if (description && description[0])
2100 instance.description = description;
2101 instance.create_callback = create_callback;
2102 instance.enumerate_callback = enumerate_supported_languages_callback;
2103 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2104 GetTypeSystemInstances().push_back(instance);
2105 }
2106 return false;
2107}
2108
2109bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
2110 if (create_callback) {
2111 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2112 TypeSystemInstances &instances = GetTypeSystemInstances();
2113
2114 TypeSystemInstances::iterator pos, end = instances.end();
2115 for (pos = instances.begin(); pos != end; ++pos) {
2116 if (pos->create_callback == create_callback) {
2117 instances.erase(pos);
2118 return true;
2119 }
Greg Clayton56939cb2015-09-17 22:23:34 +00002120 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002121 }
2122 return false;
Greg Clayton56939cb2015-09-17 22:23:34 +00002123}
2124
2125TypeSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002126PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
2127 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2128 TypeSystemInstances &instances = GetTypeSystemInstances();
2129 if (idx < instances.size())
2130 return instances[idx].create_callback;
2131 return nullptr;
Greg Clayton56939cb2015-09-17 22:23:34 +00002132}
2133
2134TypeSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002135PluginManager::GetTypeSystemCreateCallbackForPluginName(
2136 const ConstString &name) {
2137 if (name) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00002138 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002139 TypeSystemInstances &instances = GetTypeSystemInstances();
2140
2141 TypeSystemInstances::iterator pos, end = instances.end();
2142 for (pos = instances.begin(); pos != end; ++pos) {
2143 if (name == pos->name)
2144 return pos->create_callback;
2145 }
2146 }
2147 return nullptr;
Sean Callananfe38c852015-10-08 23:07:53 +00002148}
2149
2150TypeSystemEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002151PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(
2152 uint32_t idx) {
2153 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2154 TypeSystemInstances &instances = GetTypeSystemInstances();
2155 if (idx < instances.size())
2156 return instances[idx].enumerate_callback;
2157 return nullptr;
2158}
2159
2160TypeSystemEnumerateSupportedLanguages
2161PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
2162 const ConstString &name) {
2163 if (name) {
2164 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2165 TypeSystemInstances &instances = GetTypeSystemInstances();
2166
2167 TypeSystemInstances::iterator pos, end = instances.end();
2168 for (pos = instances.begin(); pos != end; ++pos) {
2169 if (name == pos->name)
2170 return pos->enumerate_callback;
Sean Callananfe38c852015-10-08 23:07:53 +00002171 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002172 }
2173 return nullptr;
Sean Callananfe38c852015-10-08 23:07:53 +00002174}
Greg Clayton56939cb2015-09-17 22:23:34 +00002175
Sean Callanan66810412015-10-19 23:11:07 +00002176#pragma mark REPL
2177
Kate Stoneb9c1b512016-09-06 20:57:50 +00002178struct REPLInstance {
2179 REPLInstance() : name(), description(), create_callback(nullptr) {}
2180
2181 ConstString name;
2182 std::string description;
2183 REPLCreateInstance create_callback;
2184 REPLEnumerateSupportedLanguages enumerate_languages_callback;
Sean Callanan66810412015-10-19 23:11:07 +00002185};
2186
2187typedef std::vector<REPLInstance> REPLInstances;
2188
Kate Stoneb9c1b512016-09-06 20:57:50 +00002189static std::recursive_mutex &GetREPLMutex() {
2190 static std::recursive_mutex g_instances_mutex;
2191 return g_instances_mutex;
Sean Callanan66810412015-10-19 23:11:07 +00002192}
2193
Kate Stoneb9c1b512016-09-06 20:57:50 +00002194static REPLInstances &GetREPLInstances() {
2195 static REPLInstances g_instances;
2196 return g_instances;
Sean Callanan66810412015-10-19 23:11:07 +00002197}
2198
Kate Stoneb9c1b512016-09-06 20:57:50 +00002199bool PluginManager::RegisterPlugin(
2200 const ConstString &name, const char *description,
2201 REPLCreateInstance create_callback,
2202 REPLEnumerateSupportedLanguages enumerate_languages_callback) {
2203 if (create_callback) {
2204 REPLInstance instance;
2205 assert((bool)name);
2206 instance.name = name;
2207 if (description && description[0])
2208 instance.description = description;
2209 instance.create_callback = create_callback;
2210 instance.enumerate_languages_callback = enumerate_languages_callback;
2211 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2212 GetREPLInstances().push_back(instance);
2213 }
2214 return false;
2215}
2216
2217bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
2218 if (create_callback) {
2219 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2220 REPLInstances &instances = GetREPLInstances();
2221
2222 REPLInstances::iterator pos, end = instances.end();
2223 for (pos = instances.begin(); pos != end; ++pos) {
2224 if (pos->create_callback == create_callback) {
2225 instances.erase(pos);
2226 return true;
2227 }
Sean Callanan66810412015-10-19 23:11:07 +00002228 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002229 }
2230 return false;
Sean Callanan66810412015-10-19 23:11:07 +00002231}
2232
Kate Stoneb9c1b512016-09-06 20:57:50 +00002233REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
2234 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2235 REPLInstances &instances = GetREPLInstances();
2236 if (idx < instances.size())
2237 return instances[idx].create_callback;
2238 return nullptr;
Sean Callanan66810412015-10-19 23:11:07 +00002239}
2240
2241REPLCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002242PluginManager::GetREPLCreateCallbackForPluginName(const ConstString &name) {
2243 if (name) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00002244 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002245 REPLInstances &instances = GetREPLInstances();
Sean Callanan66810412015-10-19 23:11:07 +00002246
Kate Stoneb9c1b512016-09-06 20:57:50 +00002247 REPLInstances::iterator pos, end = instances.end();
2248 for (pos = instances.begin(); pos != end; ++pos) {
2249 if (name == pos->name)
2250 return pos->create_callback;
Sean Callanan66810412015-10-19 23:11:07 +00002251 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002252 }
2253 return nullptr;
Sean Callanan66810412015-10-19 23:11:07 +00002254}
2255
Sean Callanan93c0b002015-10-21 19:14:33 +00002256REPLEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002257PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) {
2258 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2259 REPLInstances &instances = GetREPLInstances();
2260 if (idx < instances.size())
2261 return instances[idx].enumerate_languages_callback;
2262 return nullptr;
Sean Callanan93c0b002015-10-21 19:14:33 +00002263}
2264
Sean Callanan93c0b002015-10-21 19:14:33 +00002265REPLEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002266PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
2267 const ConstString &name) {
2268 if (name) {
2269 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2270 REPLInstances &instances = GetREPLInstances();
2271
2272 REPLInstances::iterator pos, end = instances.end();
2273 for (pos = instances.begin(); pos != end; ++pos) {
2274 if (name == pos->name)
2275 return pos->enumerate_languages_callback;
Sean Callanan93c0b002015-10-21 19:14:33 +00002276 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002277 }
2278 return nullptr;
Sean Callanan93c0b002015-10-21 19:14:33 +00002279}
2280
Kuba Breckaafdf8422014-10-10 23:43:03 +00002281#pragma mark PluginManager
2282
Kate Stoneb9c1b512016-09-06 20:57:50 +00002283void PluginManager::DebuggerInitialize(Debugger &debugger) {
2284 // Initialize the DynamicLoader plugins
2285 {
2286 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
2287 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
Jason Molenda9b837a12013-04-05 05:06:39 +00002288
Kate Stoneb9c1b512016-09-06 20:57:50 +00002289 DynamicLoaderInstances::iterator pos, end = instances.end();
2290 for (pos = instances.begin(); pos != end; ++pos) {
2291 if (pos->debugger_init_callback)
2292 pos->debugger_init_callback(debugger);
Andrew MacPherson17220c12014-03-05 10:12:43 +00002293 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002294 }
Andrew MacPherson17220c12014-03-05 10:12:43 +00002295
Kate Stoneb9c1b512016-09-06 20:57:50 +00002296 // Initialize the JITLoader plugins
2297 {
2298 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
2299 JITLoaderInstances &instances = GetJITLoaderInstances();
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002300
Kate Stoneb9c1b512016-09-06 20:57:50 +00002301 JITLoaderInstances::iterator pos, end = instances.end();
2302 for (pos = instances.begin(); pos != end; ++pos) {
2303 if (pos->debugger_init_callback)
2304 pos->debugger_init_callback(debugger);
Greg Clayton7f982402013-07-15 22:54:20 +00002305 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002306 }
Greg Clayton7f982402013-07-15 22:54:20 +00002307
Kate Stoneb9c1b512016-09-06 20:57:50 +00002308 // Initialize the Platform plugins
2309 {
2310 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
2311 PlatformInstances &instances = GetPlatformInstances();
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002312
Kate Stoneb9c1b512016-09-06 20:57:50 +00002313 PlatformInstances::iterator pos, end = instances.end();
2314 for (pos = instances.begin(); pos != end; ++pos) {
2315 if (pos->debugger_init_callback)
2316 pos->debugger_init_callback(debugger);
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002317 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002318 }
Todd Fiala75930012016-08-19 04:21:48 +00002319
Kate Stoneb9c1b512016-09-06 20:57:50 +00002320 // Initialize the Process plugins
2321 {
2322 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
2323 ProcessInstances &instances = GetProcessInstances();
2324
2325 ProcessInstances::iterator pos, end = instances.end();
2326 for (pos = instances.begin(); pos != end; ++pos) {
2327 if (pos->debugger_init_callback)
2328 pos->debugger_init_callback(debugger);
Todd Fiala75930012016-08-19 04:21:48 +00002329 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002330 }
2331
2332 // Initialize the SymbolFile plugins
2333 {
2334 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
2335 for (auto &sym_file : GetSymbolFileInstances()) {
2336 if (sym_file.debugger_init_callback)
2337 sym_file.debugger_init_callback(debugger);
2338 }
2339 }
2340
2341 // Initialize the OperatingSystem plugins
2342 {
2343 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
2344 for (auto &os : GetOperatingSystemInstances()) {
2345 if (os.debugger_init_callback)
2346 os.debugger_init_callback(debugger);
2347 }
2348 }
2349
2350 // Initialize the StructuredDataPlugin plugins
2351 {
2352 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
2353 for (auto &plugin : GetStructuredDataPluginInstances()) {
2354 if (plugin.debugger_init_callback)
2355 plugin.debugger_init_callback(debugger);
2356 }
2357 }
Greg Claytone8cd0c92012-10-19 18:02:49 +00002358}
2359
Greg Clayton7f982402013-07-15 22:54:20 +00002360// This is the preferred new way to register plugin specific settings. e.g.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002361// This will put a plugin's settings under e.g.
2362// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2363static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins(
2364 Debugger &debugger, const ConstString &plugin_type_name,
2365 const ConstString &plugin_type_desc, bool can_create) {
2366 lldb::OptionValuePropertiesSP parent_properties_sp(
2367 debugger.GetValueProperties());
2368 if (parent_properties_sp) {
2369 static ConstString g_property_name("plugin");
2370
2371 OptionValuePropertiesSP plugin_properties_sp =
2372 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
2373 if (!plugin_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002374 plugin_properties_sp =
2375 std::make_shared<OptionValueProperties>(g_property_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002376 parent_properties_sp->AppendProperty(
2377 g_property_name, ConstString("Settings specify to plugins."), true,
2378 plugin_properties_sp);
Greg Claytone8cd0c92012-10-19 18:02:49 +00002379 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002380
2381 if (plugin_properties_sp) {
2382 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2383 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2384 if (!plugin_type_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002385 plugin_type_properties_sp =
2386 std::make_shared<OptionValueProperties>(plugin_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002387 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2388 true, plugin_type_properties_sp);
2389 }
2390 return plugin_type_properties_sp;
2391 }
2392 }
2393 return lldb::OptionValuePropertiesSP();
Greg Claytone8cd0c92012-10-19 18:02:49 +00002394}
2395
Greg Clayton7f982402013-07-15 22:54:20 +00002396// This is deprecated way to register plugin specific settings. e.g.
Adrian Prantl05097242018-04-30 16:49:04 +00002397// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
2398// generic settings would be under "platform.SETTINGNAME".
Kate Stoneb9c1b512016-09-06 20:57:50 +00002399static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
2400 Debugger &debugger, const ConstString &plugin_type_name,
2401 const ConstString &plugin_type_desc, bool can_create) {
2402 static ConstString g_property_name("plugin");
2403 lldb::OptionValuePropertiesSP parent_properties_sp(
2404 debugger.GetValueProperties());
2405 if (parent_properties_sp) {
2406 OptionValuePropertiesSP plugin_properties_sp =
2407 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2408 if (!plugin_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002409 plugin_properties_sp =
2410 std::make_shared<OptionValueProperties>(plugin_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002411 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2412 true, plugin_properties_sp);
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002413 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002414
2415 if (plugin_properties_sp) {
2416 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2417 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
2418 if (!plugin_type_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002419 plugin_type_properties_sp =
2420 std::make_shared<OptionValueProperties>(g_property_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002421 plugin_properties_sp->AppendProperty(
2422 g_property_name, ConstString("Settings specific to plugins"), true,
2423 plugin_type_properties_sp);
2424 }
2425 return plugin_type_properties_sp;
2426 }
2427 }
2428 return lldb::OptionValuePropertiesSP();
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002429}
2430
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002431namespace {
2432
2433typedef lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002434GetDebuggerPropertyForPluginsPtr(Debugger &, const ConstString &,
2435 const ConstString &, bool can_create);
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002436
Greg Claytone8cd0c92012-10-19 18:02:49 +00002437lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002438GetSettingForPlugin(Debugger &debugger, const ConstString &setting_name,
2439 const ConstString &plugin_type_name,
2440 GetDebuggerPropertyForPluginsPtr get_debugger_property =
2441 GetDebuggerPropertyForPlugins) {
2442 lldb::OptionValuePropertiesSP properties_sp;
2443 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
2444 debugger, plugin_type_name,
2445 ConstString(), // not creating to so we don't need the description
2446 false));
2447 if (plugin_type_properties_sp)
2448 properties_sp =
2449 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2450 return properties_sp;
Greg Claytone8cd0c92012-10-19 18:02:49 +00002451}
2452
Kate Stoneb9c1b512016-09-06 20:57:50 +00002453bool CreateSettingForPlugin(
2454 Debugger &debugger, const ConstString &plugin_type_name,
2455 const ConstString &plugin_type_desc,
2456 const lldb::OptionValuePropertiesSP &properties_sp,
2457 const ConstString &description, bool is_global_property,
2458 GetDebuggerPropertyForPluginsPtr get_debugger_property =
2459 GetDebuggerPropertyForPlugins) {
2460 if (properties_sp) {
2461 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2462 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
2463 true));
2464 if (plugin_type_properties_sp) {
2465 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2466 description, is_global_property,
2467 properties_sp);
2468 return true;
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002469 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002470 }
2471 return false;
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002472}
2473
Kate Stoneb9c1b512016-09-06 20:57:50 +00002474const char *kDynamicLoaderPluginName("dynamic-loader");
2475const char *kPlatformPluginName("platform");
2476const char *kProcessPluginName("process");
2477const char *kSymbolFilePluginName("symbol-file");
2478const char *kJITLoaderPluginName("jit-loader");
2479const char *kStructuredDataPluginName("structured-data");
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002480
Eugene Zelenko89183722016-03-11 21:55:47 +00002481} // anonymous namespace
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002482
Kate Stoneb9c1b512016-09-06 20:57:50 +00002483lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(
2484 Debugger &debugger, const ConstString &setting_name) {
2485 return GetSettingForPlugin(debugger, setting_name,
2486 ConstString(kDynamicLoaderPluginName));
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002487}
2488
Kate Stoneb9c1b512016-09-06 20:57:50 +00002489bool PluginManager::CreateSettingForDynamicLoaderPlugin(
2490 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2491 const ConstString &description, bool is_global_property) {
2492 return CreateSettingForPlugin(
2493 debugger, ConstString(kDynamicLoaderPluginName),
2494 ConstString("Settings for dynamic loader plug-ins"), properties_sp,
2495 description, is_global_property);
Greg Claytone8cd0c92012-10-19 18:02:49 +00002496}
2497
Jason Molenda9b837a12013-04-05 05:06:39 +00002498lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002499PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
2500 const ConstString &setting_name) {
2501 return GetSettingForPlugin(debugger, setting_name,
2502 ConstString(kPlatformPluginName),
2503 GetDebuggerPropertyForPluginsOldStyle);
Jason Molenda9b837a12013-04-05 05:06:39 +00002504}
2505
Kate Stoneb9c1b512016-09-06 20:57:50 +00002506bool PluginManager::CreateSettingForPlatformPlugin(
2507 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2508 const ConstString &description, bool is_global_property) {
2509 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
2510 ConstString("Settings for platform plug-ins"),
2511 properties_sp, description, is_global_property,
2512 GetDebuggerPropertyForPluginsOldStyle);
Greg Clayton7f982402013-07-15 22:54:20 +00002513}
2514
Greg Clayton7f982402013-07-15 22:54:20 +00002515lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002516PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
2517 const ConstString &setting_name) {
2518 return GetSettingForPlugin(debugger, setting_name,
2519 ConstString(kProcessPluginName));
Greg Clayton7f982402013-07-15 22:54:20 +00002520}
2521
Kate Stoneb9c1b512016-09-06 20:57:50 +00002522bool PluginManager::CreateSettingForProcessPlugin(
2523 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2524 const ConstString &description, bool is_global_property) {
2525 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
2526 ConstString("Settings for process plug-ins"),
2527 properties_sp, description, is_global_property);
Jason Molenda9b837a12013-04-05 05:06:39 +00002528}
2529
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002530lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002531PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
2532 const ConstString &setting_name) {
2533 return GetSettingForPlugin(debugger, setting_name,
2534 ConstString(kSymbolFilePluginName));
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002535}
2536
Kate Stoneb9c1b512016-09-06 20:57:50 +00002537bool PluginManager::CreateSettingForSymbolFilePlugin(
2538 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2539 const ConstString &description, bool is_global_property) {
2540 return CreateSettingForPlugin(
2541 debugger, ConstString(kSymbolFilePluginName),
2542 ConstString("Settings for symbol file plug-ins"), properties_sp,
2543 description, is_global_property);
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002544}
2545
2546lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002547PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
2548 const ConstString &setting_name) {
2549 return GetSettingForPlugin(debugger, setting_name,
2550 ConstString(kJITLoaderPluginName));
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002551}
2552
Kate Stoneb9c1b512016-09-06 20:57:50 +00002553bool PluginManager::CreateSettingForJITLoaderPlugin(
2554 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2555 const ConstString &description, bool is_global_property) {
2556 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
2557 ConstString("Settings for JIT loader plug-ins"),
2558 properties_sp, description, is_global_property);
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002559}
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002560
2561static const char *kOperatingSystemPluginName("os");
2562
Kate Stoneb9c1b512016-09-06 20:57:50 +00002563lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin(
2564 Debugger &debugger, const ConstString &setting_name) {
2565 lldb::OptionValuePropertiesSP properties_sp;
2566 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2567 GetDebuggerPropertyForPlugins(
2568 debugger, ConstString(kOperatingSystemPluginName),
2569 ConstString(), // not creating to so we don't need the description
2570 false));
2571 if (plugin_type_properties_sp)
2572 properties_sp =
2573 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2574 return properties_sp;
2575}
2576
2577bool PluginManager::CreateSettingForOperatingSystemPlugin(
2578 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2579 const ConstString &description, bool is_global_property) {
2580 if (properties_sp) {
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002581 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002582 GetDebuggerPropertyForPlugins(
2583 debugger, ConstString(kOperatingSystemPluginName),
2584 ConstString("Settings for operating system plug-ins"), true));
2585 if (plugin_type_properties_sp) {
2586 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2587 description, is_global_property,
2588 properties_sp);
2589 return true;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002590 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002591 }
2592 return false;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002593}
Todd Fiala75930012016-08-19 04:21:48 +00002594
Kate Stoneb9c1b512016-09-06 20:57:50 +00002595lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin(
2596 Debugger &debugger, const ConstString &setting_name) {
2597 return GetSettingForPlugin(debugger, setting_name,
2598 ConstString(kStructuredDataPluginName));
Todd Fiala75930012016-08-19 04:21:48 +00002599}
2600
Kate Stoneb9c1b512016-09-06 20:57:50 +00002601bool PluginManager::CreateSettingForStructuredDataPlugin(
2602 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2603 const ConstString &description, bool is_global_property) {
2604 return CreateSettingForPlugin(
2605 debugger, ConstString(kStructuredDataPluginName),
2606 ConstString("Settings for structured data plug-ins"), properties_sp,
2607 description, is_global_property);
Todd Fiala75930012016-08-19 04:21:48 +00002608}