blob: 55affb6a10306cdeafe14663861f4a587c310fa2 [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 const bool find_directories = true;
161 const bool find_files = true;
162 const bool find_other = true;
163 char dir_path[PATH_MAX];
Pavel Labath60f028f2018-06-19 15:09:07 +0000164 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
166 FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
167 find_other, LoadPluginCallback, nullptr);
Greg Clayton4272cc72011-02-02 02:24:04 +0000168 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169 }
Greg Clayton4272cc72011-02-02 02:24:04 +0000170
Pavel Labath60f028f2018-06-19 15:09:07 +0000171 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
173 FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
174 find_other, LoadPluginCallback, nullptr);
Greg Clayton4272cc72011-02-02 02:24:04 +0000175 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000177#endif
Greg Clayton4272cc72011-02-02 02:24:04 +0000178}
179
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180void PluginManager::Terminate() {
181 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
182 PluginTerminateMap &plugin_map = GetPluginMap();
183
184 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
185 for (pos = plugin_map.begin(); pos != end; ++pos) {
Adrian Prantl05097242018-04-30 16:49:04 +0000186 // Call the plug-in "void LLDBPluginTerminate (void)" function if there is
187 // one (if the symbol was not nullptr).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 if (pos->second.library.isValid()) {
189 if (pos->second.plugin_term_callback)
190 pos->second.plugin_term_callback();
Greg Clayton4272cc72011-02-02 02:24:04 +0000191 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 }
193 plugin_map.clear();
Greg Clayton4272cc72011-02-02 02:24:04 +0000194}
195
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196#pragma mark ABI
197
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198struct ABIInstance {
199 ABIInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000200
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201 ConstString name;
202 std::string description;
203 ABICreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204};
205
206typedef std::vector<ABIInstance> ABIInstances;
207
Kate Stoneb9c1b512016-09-06 20:57:50 +0000208static std::recursive_mutex &GetABIInstancesMutex() {
209 static std::recursive_mutex g_instances_mutex;
210 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211}
212
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213static ABIInstances &GetABIInstances() {
214 static ABIInstances g_instances;
215 return g_instances;
Greg Claytonded470d2011-03-19 01:12:21 +0000216}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218bool PluginManager::RegisterPlugin(const ConstString &name,
219 const char *description,
220 ABICreateInstance create_callback) {
221 if (create_callback) {
222 ABIInstance instance;
223 assert((bool)name);
224 instance.name = name;
225 if (description && description[0])
226 instance.description = description;
227 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000228 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000229 GetABIInstances().push_back(instance);
230 return true;
231 }
232 return false;
233}
234
235bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
236 if (create_callback) {
237 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
238 ABIInstances &instances = GetABIInstances();
239
240 ABIInstances::iterator pos, end = instances.end();
241 for (pos = instances.begin(); pos != end; ++pos) {
242 if (pos->create_callback == create_callback) {
243 instances.erase(pos);
244 return true;
245 }
246 }
247 }
248 return false;
249}
250
251ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
252 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
253 ABIInstances &instances = GetABIInstances();
254 if (idx < instances.size())
255 return instances[idx].create_callback;
256 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257}
258
259ABICreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000260PluginManager::GetABICreateCallbackForPluginName(const ConstString &name) {
261 if (name) {
262 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
263 ABIInstances &instances = GetABIInstances();
Greg Claytonded470d2011-03-19 01:12:21 +0000264
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265 ABIInstances::iterator pos, end = instances.end();
266 for (pos = instances.begin(); pos != end; ++pos) {
267 if (name == pos->name)
268 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270 }
271 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000272}
273
Pavel Labath13e37d42017-10-25 21:05:31 +0000274#pragma mark Architecture
275
276struct ArchitectureInstance {
277 ConstString name;
278 std::string description;
279 PluginManager::ArchitectureCreateInstance create_callback;
280};
281
282typedef std::vector<ArchitectureInstance> ArchitectureInstances;
283
284static std::mutex g_architecture_mutex;
285
286static ArchitectureInstances &GetArchitectureInstances() {
287 static ArchitectureInstances g_instances;
288 return g_instances;
289}
290
291void PluginManager::RegisterPlugin(const ConstString &name,
292 llvm::StringRef description,
293 ArchitectureCreateInstance create_callback) {
294 std::lock_guard<std::mutex> guard(g_architecture_mutex);
295 GetArchitectureInstances().push_back({name, description, create_callback});
296}
297
298void PluginManager::UnregisterPlugin(
299 ArchitectureCreateInstance create_callback) {
300 std::lock_guard<std::mutex> guard(g_architecture_mutex);
301 auto &instances = GetArchitectureInstances();
302
303 for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
304 if (pos->create_callback == create_callback) {
305 instances.erase(pos);
306 return;
307 }
308 }
309 llvm_unreachable("Plugin not found");
310}
311
312std::unique_ptr<Architecture>
313PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
314 std::lock_guard<std::mutex> guard(g_architecture_mutex);
315 for (const auto &instances : GetArchitectureInstances()) {
316 if (auto plugin_up = instances.create_callback(arch))
317 return plugin_up;
318 }
319 return nullptr;
320}
321
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322#pragma mark Disassembler
323
Kate Stoneb9c1b512016-09-06 20:57:50 +0000324struct DisassemblerInstance {
325 DisassemblerInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 ConstString name;
328 std::string description;
329 DisassemblerCreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330};
331
332typedef std::vector<DisassemblerInstance> DisassemblerInstances;
333
Kate Stoneb9c1b512016-09-06 20:57:50 +0000334static std::recursive_mutex &GetDisassemblerMutex() {
335 static std::recursive_mutex g_instances_mutex;
336 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337}
338
Kate Stoneb9c1b512016-09-06 20:57:50 +0000339static DisassemblerInstances &GetDisassemblerInstances() {
340 static DisassemblerInstances g_instances;
341 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +0000342}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344bool PluginManager::RegisterPlugin(const ConstString &name,
345 const char *description,
346 DisassemblerCreateInstance create_callback) {
347 if (create_callback) {
348 DisassemblerInstance instance;
349 assert((bool)name);
350 instance.name = name;
351 if (description && description[0])
352 instance.description = description;
353 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000354 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355 GetDisassemblerInstances().push_back(instance);
356 return true;
357 }
358 return false;
359}
360
361bool PluginManager::UnregisterPlugin(
362 DisassemblerCreateInstance create_callback) {
363 if (create_callback) {
364 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
365 DisassemblerInstances &instances = GetDisassemblerInstances();
366
367 DisassemblerInstances::iterator pos, end = instances.end();
368 for (pos = instances.begin(); pos != end; ++pos) {
369 if (pos->create_callback == create_callback) {
370 instances.erase(pos);
371 return true;
372 }
373 }
374 }
375 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376}
377
378DisassemblerCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000379PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
380 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
381 DisassemblerInstances &instances = GetDisassemblerInstances();
382 if (idx < instances.size())
383 return instances[idx].create_callback;
384 return nullptr;
385}
386
387DisassemblerCreateInstance
388PluginManager::GetDisassemblerCreateCallbackForPluginName(
389 const ConstString &name) {
390 if (name) {
391 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
392 DisassemblerInstances &instances = GetDisassemblerInstances();
393
394 DisassemblerInstances::iterator pos, end = instances.end();
395 for (pos = instances.begin(); pos != end; ++pos) {
396 if (name == pos->name)
397 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000399 }
400 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000401}
402
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403#pragma mark DynamicLoader
404
Kate Stoneb9c1b512016-09-06 20:57:50 +0000405struct DynamicLoaderInstance {
406 DynamicLoaderInstance()
407 : name(), description(), create_callback(nullptr),
408 debugger_init_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000409
Kate Stoneb9c1b512016-09-06 20:57:50 +0000410 ConstString name;
411 std::string description;
412 DynamicLoaderCreateInstance create_callback;
413 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000414};
415
416typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
417
Kate Stoneb9c1b512016-09-06 20:57:50 +0000418static std::recursive_mutex &GetDynamicLoaderMutex() {
419 static std::recursive_mutex g_instances_mutex;
420 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +0000421}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423static DynamicLoaderInstances &GetDynamicLoaderInstances() {
424 static DynamicLoaderInstances g_instances;
425 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000426}
427
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428bool PluginManager::RegisterPlugin(
429 const ConstString &name, const char *description,
430 DynamicLoaderCreateInstance create_callback,
431 DebuggerInitializeCallback debugger_init_callback) {
432 if (create_callback) {
433 DynamicLoaderInstance instance;
434 assert((bool)name);
435 instance.name = name;
436 if (description && description[0])
437 instance.description = description;
438 instance.create_callback = create_callback;
439 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000440 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000441 GetDynamicLoaderInstances().push_back(instance);
442 }
443 return false;
444}
445
446bool PluginManager::UnregisterPlugin(
447 DynamicLoaderCreateInstance create_callback) {
448 if (create_callback) {
449 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
450 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
451
452 DynamicLoaderInstances::iterator pos, end = instances.end();
453 for (pos = instances.begin(); pos != end; ++pos) {
454 if (pos->create_callback == create_callback) {
455 instances.erase(pos);
456 return true;
457 }
458 }
459 }
460 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461}
462
463DynamicLoaderCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
465 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
466 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
467 if (idx < instances.size())
468 return instances[idx].create_callback;
469 return nullptr;
470}
471
472DynamicLoaderCreateInstance
473PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
474 const ConstString &name) {
475 if (name) {
476 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
477 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
478
479 DynamicLoaderInstances::iterator pos, end = instances.end();
480 for (pos = instances.begin(); pos != end; ++pos) {
481 if (name == pos->name)
482 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000483 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000484 }
485 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486}
487
Andrew MacPherson17220c12014-03-05 10:12:43 +0000488#pragma mark JITLoader
489
Kate Stoneb9c1b512016-09-06 20:57:50 +0000490struct JITLoaderInstance {
491 JITLoaderInstance()
492 : name(), description(), create_callback(nullptr),
493 debugger_init_callback(nullptr) {}
Andrew MacPherson17220c12014-03-05 10:12:43 +0000494
Kate Stoneb9c1b512016-09-06 20:57:50 +0000495 ConstString name;
496 std::string description;
497 JITLoaderCreateInstance create_callback;
498 DebuggerInitializeCallback debugger_init_callback;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000499};
500
501typedef std::vector<JITLoaderInstance> JITLoaderInstances;
502
Kate Stoneb9c1b512016-09-06 20:57:50 +0000503static std::recursive_mutex &GetJITLoaderMutex() {
504 static std::recursive_mutex g_instances_mutex;
505 return g_instances_mutex;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000506}
507
Kate Stoneb9c1b512016-09-06 20:57:50 +0000508static JITLoaderInstances &GetJITLoaderInstances() {
509 static JITLoaderInstances g_instances;
510 return g_instances;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000511}
512
Kate Stoneb9c1b512016-09-06 20:57:50 +0000513bool PluginManager::RegisterPlugin(
514 const ConstString &name, const char *description,
515 JITLoaderCreateInstance create_callback,
516 DebuggerInitializeCallback debugger_init_callback) {
517 if (create_callback) {
518 JITLoaderInstance instance;
519 assert((bool)name);
520 instance.name = name;
521 if (description && description[0])
522 instance.description = description;
523 instance.create_callback = create_callback;
524 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000525 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000526 GetJITLoaderInstances().push_back(instance);
527 }
528 return false;
529}
530
531bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
532 if (create_callback) {
533 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
534 JITLoaderInstances &instances = GetJITLoaderInstances();
535
536 JITLoaderInstances::iterator pos, end = instances.end();
537 for (pos = instances.begin(); pos != end; ++pos) {
538 if (pos->create_callback == create_callback) {
539 instances.erase(pos);
540 return true;
541 }
542 }
543 }
544 return false;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000545}
546
547JITLoaderCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000548PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
549 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
550 JITLoaderInstances &instances = GetJITLoaderInstances();
551 if (idx < instances.size())
552 return instances[idx].create_callback;
553 return nullptr;
554}
555
556JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName(
557 const ConstString &name) {
558 if (name) {
559 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
560 JITLoaderInstances &instances = GetJITLoaderInstances();
561
562 JITLoaderInstances::iterator pos, end = instances.end();
563 for (pos = instances.begin(); pos != end; ++pos) {
564 if (name == pos->name)
565 return pos->create_callback;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000566 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000567 }
568 return nullptr;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000569}
570
Greg Claytonf03bbe22011-02-01 01:37:45 +0000571#pragma mark EmulateInstruction
572
Kate Stoneb9c1b512016-09-06 20:57:50 +0000573struct EmulateInstructionInstance {
574 EmulateInstructionInstance()
575 : name(), description(), create_callback(nullptr) {}
576
577 ConstString name;
578 std::string description;
579 EmulateInstructionCreateInstance create_callback;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000580};
581
582typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
583
Kate Stoneb9c1b512016-09-06 20:57:50 +0000584static std::recursive_mutex &GetEmulateInstructionMutex() {
585 static std::recursive_mutex g_instances_mutex;
586 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +0000587}
588
Kate Stoneb9c1b512016-09-06 20:57:50 +0000589static EmulateInstructionInstances &GetEmulateInstructionInstances() {
590 static EmulateInstructionInstances g_instances;
591 return g_instances;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000592}
593
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594bool PluginManager::RegisterPlugin(
595 const ConstString &name, const char *description,
596 EmulateInstructionCreateInstance create_callback) {
597 if (create_callback) {
598 EmulateInstructionInstance instance;
599 assert((bool)name);
600 instance.name = name;
601 if (description && description[0])
602 instance.description = description;
603 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000604 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605 GetEmulateInstructionInstances().push_back(instance);
606 }
607 return false;
608}
609
610bool PluginManager::UnregisterPlugin(
611 EmulateInstructionCreateInstance create_callback) {
612 if (create_callback) {
613 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
614 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
615
616 EmulateInstructionInstances::iterator pos, end = instances.end();
617 for (pos = instances.begin(); pos != end; ++pos) {
618 if (pos->create_callback == create_callback) {
619 instances.erase(pos);
620 return true;
621 }
622 }
623 }
624 return false;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000625}
626
627EmulateInstructionCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000628PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
629 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
630 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
631 if (idx < instances.size())
632 return instances[idx].create_callback;
633 return nullptr;
634}
635
636EmulateInstructionCreateInstance
637PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
638 const ConstString &name) {
639 if (name) {
640 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
641 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
642
643 EmulateInstructionInstances::iterator pos, end = instances.end();
644 for (pos = instances.begin(); pos != end; ++pos) {
645 if (name == pos->name)
646 return pos->create_callback;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000647 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000648 }
649 return nullptr;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000650}
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000651
Eugene Zelenko89183722016-03-11 21:55:47 +0000652#pragma mark OperatingSystem
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000653
Kate Stoneb9c1b512016-09-06 20:57:50 +0000654struct OperatingSystemInstance {
655 OperatingSystemInstance()
656 : name(), description(), create_callback(nullptr),
657 debugger_init_callback(nullptr) {}
658
659 ConstString name;
660 std::string description;
661 OperatingSystemCreateInstance create_callback;
662 DebuggerInitializeCallback debugger_init_callback;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000663};
664
665typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
666
Kate Stoneb9c1b512016-09-06 20:57:50 +0000667static std::recursive_mutex &GetOperatingSystemMutex() {
668 static std::recursive_mutex g_instances_mutex;
669 return g_instances_mutex;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000670}
671
Kate Stoneb9c1b512016-09-06 20:57:50 +0000672static OperatingSystemInstances &GetOperatingSystemInstances() {
673 static OperatingSystemInstances g_instances;
674 return g_instances;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000675}
676
Kate Stoneb9c1b512016-09-06 20:57:50 +0000677bool PluginManager::RegisterPlugin(
678 const ConstString &name, const char *description,
679 OperatingSystemCreateInstance create_callback,
680 DebuggerInitializeCallback debugger_init_callback) {
681 if (create_callback) {
682 OperatingSystemInstance instance;
683 assert((bool)name);
684 instance.name = name;
685 if (description && description[0])
686 instance.description = description;
687 instance.create_callback = create_callback;
688 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000689 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690 GetOperatingSystemInstances().push_back(instance);
691 }
692 return false;
693}
694
695bool PluginManager::UnregisterPlugin(
696 OperatingSystemCreateInstance create_callback) {
697 if (create_callback) {
698 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
699 OperatingSystemInstances &instances = GetOperatingSystemInstances();
700
701 OperatingSystemInstances::iterator pos, end = instances.end();
702 for (pos = instances.begin(); pos != end; ++pos) {
703 if (pos->create_callback == create_callback) {
704 instances.erase(pos);
705 return true;
706 }
707 }
708 }
709 return false;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000710}
711
712OperatingSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000713PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
714 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
715 OperatingSystemInstances &instances = GetOperatingSystemInstances();
716 if (idx < instances.size())
717 return instances[idx].create_callback;
718 return nullptr;
719}
720
721OperatingSystemCreateInstance
722PluginManager::GetOperatingSystemCreateCallbackForPluginName(
723 const ConstString &name) {
724 if (name) {
725 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
726 OperatingSystemInstances &instances = GetOperatingSystemInstances();
727
728 OperatingSystemInstances::iterator pos, end = instances.end();
729 for (pos = instances.begin(); pos != end; ++pos) {
730 if (name == pos->name)
731 return pos->create_callback;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000732 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000733 }
734 return nullptr;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000735}
Greg Claytonf03bbe22011-02-01 01:37:45 +0000736
Enrico Granata5f9d3102015-08-27 21:33:50 +0000737#pragma mark Language
738
Kate Stoneb9c1b512016-09-06 20:57:50 +0000739struct LanguageInstance {
740 LanguageInstance() : name(), description(), create_callback(nullptr) {}
741
742 ConstString name;
743 std::string description;
744 LanguageCreateInstance create_callback;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000745};
746
747typedef std::vector<LanguageInstance> LanguageInstances;
748
Kate Stoneb9c1b512016-09-06 20:57:50 +0000749static std::recursive_mutex &GetLanguageMutex() {
750 static std::recursive_mutex g_instances_mutex;
751 return g_instances_mutex;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000752}
753
Kate Stoneb9c1b512016-09-06 20:57:50 +0000754static LanguageInstances &GetLanguageInstances() {
755 static LanguageInstances g_instances;
756 return g_instances;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000757}
758
Kate Stoneb9c1b512016-09-06 20:57:50 +0000759bool PluginManager::RegisterPlugin(const ConstString &name,
760 const char *description,
761 LanguageCreateInstance create_callback) {
762 if (create_callback) {
763 LanguageInstance instance;
764 assert((bool)name);
765 instance.name = name;
766 if (description && description[0])
767 instance.description = description;
768 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000769 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000770 GetLanguageInstances().push_back(instance);
771 }
772 return false;
773}
774
775bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
776 if (create_callback) {
777 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
778 LanguageInstances &instances = GetLanguageInstances();
779
780 LanguageInstances::iterator pos, end = instances.end();
781 for (pos = instances.begin(); pos != end; ++pos) {
782 if (pos->create_callback == create_callback) {
783 instances.erase(pos);
784 return true;
785 }
786 }
787 }
788 return false;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000789}
790
791LanguageCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000792PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
793 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
794 LanguageInstances &instances = GetLanguageInstances();
795 if (idx < instances.size())
796 return instances[idx].create_callback;
797 return nullptr;
798}
799
800LanguageCreateInstance
801PluginManager::GetLanguageCreateCallbackForPluginName(const ConstString &name) {
802 if (name) {
803 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
804 LanguageInstances &instances = GetLanguageInstances();
805
806 LanguageInstances::iterator pos, end = instances.end();
807 for (pos = instances.begin(); pos != end; ++pos) {
808 if (name == pos->name)
809 return pos->create_callback;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000810 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000811 }
812 return nullptr;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000813}
814
Jim Ingham22777012010-09-23 02:01:19 +0000815#pragma mark LanguageRuntime
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000816
Kate Stoneb9c1b512016-09-06 20:57:50 +0000817struct LanguageRuntimeInstance {
818 LanguageRuntimeInstance() : name(), description(), create_callback(nullptr) {}
Jim Ingham22777012010-09-23 02:01:19 +0000819
Kate Stoneb9c1b512016-09-06 20:57:50 +0000820 ConstString name;
821 std::string description;
822 LanguageRuntimeCreateInstance create_callback;
823 LanguageRuntimeGetCommandObject command_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000824};
825
826typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
827
Kate Stoneb9c1b512016-09-06 20:57:50 +0000828static std::recursive_mutex &GetLanguageRuntimeMutex() {
829 static std::recursive_mutex g_instances_mutex;
830 return g_instances_mutex;
Jim Ingham22777012010-09-23 02:01:19 +0000831}
832
Kate Stoneb9c1b512016-09-06 20:57:50 +0000833static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
834 static LanguageRuntimeInstances g_instances;
835 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +0000836}
Jim Ingham22777012010-09-23 02:01:19 +0000837
Kate Stoneb9c1b512016-09-06 20:57:50 +0000838bool PluginManager::RegisterPlugin(
839 const ConstString &name, const char *description,
840 LanguageRuntimeCreateInstance create_callback,
841 LanguageRuntimeGetCommandObject command_callback) {
842 if (create_callback) {
843 LanguageRuntimeInstance instance;
844 assert((bool)name);
845 instance.name = name;
846 if (description && description[0])
847 instance.description = description;
848 instance.create_callback = create_callback;
849 instance.command_callback = command_callback;
850 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
851 GetLanguageRuntimeInstances().push_back(instance);
852 }
853 return false;
854}
855
856bool PluginManager::UnregisterPlugin(
857 LanguageRuntimeCreateInstance create_callback) {
858 if (create_callback) {
859 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
860 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
861
862 LanguageRuntimeInstances::iterator pos, end = instances.end();
863 for (pos = instances.begin(); pos != end; ++pos) {
864 if (pos->create_callback == create_callback) {
865 instances.erase(pos);
866 return true;
867 }
Jim Ingham22777012010-09-23 02:01:19 +0000868 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000869 }
870 return false;
Jim Ingham22777012010-09-23 02:01:19 +0000871}
872
873LanguageRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000874PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
875 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
876 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
877 if (idx < instances.size())
878 return instances[idx].create_callback;
879 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000880}
881
Colin Rileyc9c55a22015-05-04 18:39:38 +0000882LanguageRuntimeGetCommandObject
Kate Stoneb9c1b512016-09-06 20:57:50 +0000883PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
884 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
885 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
886 if (idx < instances.size())
887 return instances[idx].command_callback;
888 return nullptr;
Colin Rileyc9c55a22015-05-04 18:39:38 +0000889}
890
Jim Ingham22777012010-09-23 02:01:19 +0000891LanguageRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000892PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
893 const ConstString &name) {
894 if (name) {
895 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
896 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
897
898 LanguageRuntimeInstances::iterator pos, end = instances.end();
899 for (pos = instances.begin(); pos != end; ++pos) {
900 if (name == pos->name)
901 return pos->create_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000902 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000903 }
904 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000905}
906
Jason Molendaeef51062013-11-05 03:57:19 +0000907#pragma mark SystemRuntime
908
Kate Stoneb9c1b512016-09-06 20:57:50 +0000909struct SystemRuntimeInstance {
910 SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {}
Jason Molendaeef51062013-11-05 03:57:19 +0000911
Kate Stoneb9c1b512016-09-06 20:57:50 +0000912 ConstString name;
913 std::string description;
914 SystemRuntimeCreateInstance create_callback;
Jason Molendaeef51062013-11-05 03:57:19 +0000915};
916
917typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
918
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919static std::recursive_mutex &GetSystemRuntimeMutex() {
920 static std::recursive_mutex g_instances_mutex;
921 return g_instances_mutex;
Jason Molendaeef51062013-11-05 03:57:19 +0000922}
923
Kate Stoneb9c1b512016-09-06 20:57:50 +0000924static SystemRuntimeInstances &GetSystemRuntimeInstances() {
925 static SystemRuntimeInstances g_instances;
926 return g_instances;
Jason Molendaeef51062013-11-05 03:57:19 +0000927}
928
Kate Stoneb9c1b512016-09-06 20:57:50 +0000929bool PluginManager::RegisterPlugin(
930 const ConstString &name, const char *description,
931 SystemRuntimeCreateInstance create_callback) {
932 if (create_callback) {
933 SystemRuntimeInstance instance;
934 assert((bool)name);
935 instance.name = name;
936 if (description && description[0])
937 instance.description = description;
938 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000939 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940 GetSystemRuntimeInstances().push_back(instance);
941 }
942 return false;
943}
944
945bool PluginManager::UnregisterPlugin(
946 SystemRuntimeCreateInstance create_callback) {
947 if (create_callback) {
948 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
949 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
950
951 SystemRuntimeInstances::iterator pos, end = instances.end();
952 for (pos = instances.begin(); pos != end; ++pos) {
953 if (pos->create_callback == create_callback) {
954 instances.erase(pos);
955 return true;
956 }
957 }
958 }
959 return false;
Jason Molendaeef51062013-11-05 03:57:19 +0000960}
961
962SystemRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000963PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
964 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
965 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
966 if (idx < instances.size())
967 return instances[idx].create_callback;
968 return nullptr;
969}
970
971SystemRuntimeCreateInstance
972PluginManager::GetSystemRuntimeCreateCallbackForPluginName(
973 const ConstString &name) {
974 if (name) {
975 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
976 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
977
978 SystemRuntimeInstances::iterator pos, end = instances.end();
979 for (pos = instances.begin(); pos != end; ++pos) {
980 if (name == pos->name)
981 return pos->create_callback;
Jason Molendaeef51062013-11-05 03:57:19 +0000982 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000983 }
984 return nullptr;
Jason Molendaeef51062013-11-05 03:57:19 +0000985}
986
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000987#pragma mark ObjectFile
988
Kate Stoneb9c1b512016-09-06 20:57:50 +0000989struct ObjectFileInstance {
990 ObjectFileInstance()
991 : name(), description(), create_callback(nullptr),
992 create_memory_callback(nullptr), get_module_specifications(nullptr),
993 save_core(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000994
Kate Stoneb9c1b512016-09-06 20:57:50 +0000995 ConstString name;
996 std::string description;
997 ObjectFileCreateInstance create_callback;
998 ObjectFileCreateMemoryInstance create_memory_callback;
999 ObjectFileGetModuleSpecifications get_module_specifications;
1000 ObjectFileSaveCore save_core;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001};
1002
1003typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1004
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005static std::recursive_mutex &GetObjectFileMutex() {
1006 static std::recursive_mutex g_instances_mutex;
1007 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001008}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009
Kate Stoneb9c1b512016-09-06 20:57:50 +00001010static ObjectFileInstances &GetObjectFileInstances() {
1011 static ObjectFileInstances g_instances;
1012 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013}
1014
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015bool PluginManager::RegisterPlugin(
1016 const ConstString &name, const char *description,
1017 ObjectFileCreateInstance create_callback,
1018 ObjectFileCreateMemoryInstance create_memory_callback,
1019 ObjectFileGetModuleSpecifications get_module_specifications,
1020 ObjectFileSaveCore save_core) {
1021 if (create_callback) {
1022 ObjectFileInstance instance;
1023 assert((bool)name);
1024 instance.name = name;
1025 if (description && description[0])
1026 instance.description = description;
1027 instance.create_callback = create_callback;
1028 instance.create_memory_callback = create_memory_callback;
1029 instance.save_core = save_core;
1030 instance.get_module_specifications = get_module_specifications;
1031 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1032 GetObjectFileInstances().push_back(instance);
1033 }
1034 return false;
1035}
1036
1037bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
1038 if (create_callback) {
1039 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1040 ObjectFileInstances &instances = GetObjectFileInstances();
1041
1042 ObjectFileInstances::iterator pos, end = instances.end();
1043 for (pos = instances.begin(); pos != end; ++pos) {
1044 if (pos->create_callback == create_callback) {
1045 instances.erase(pos);
1046 return true;
1047 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001048 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001049 }
1050 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001051}
1052
1053ObjectFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001054PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
1055 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1056 ObjectFileInstances &instances = GetObjectFileInstances();
1057 if (idx < instances.size())
1058 return instances[idx].create_callback;
1059 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001060}
Greg Claytonab65b342011-04-13 22:47:15 +00001061
Greg Claytonc9660542012-02-05 02:38:54 +00001062ObjectFileCreateMemoryInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001063PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
1064 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1065 ObjectFileInstances &instances = GetObjectFileInstances();
1066 if (idx < instances.size())
1067 return instances[idx].create_memory_callback;
1068 return nullptr;
Greg Claytonc9660542012-02-05 02:38:54 +00001069}
1070
Greg Claytonf4d6de62013-04-24 22:29:28 +00001071ObjectFileGetModuleSpecifications
Kate Stoneb9c1b512016-09-06 20:57:50 +00001072PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
1073 uint32_t idx) {
1074 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1075 ObjectFileInstances &instances = GetObjectFileInstances();
1076 if (idx < instances.size())
1077 return instances[idx].get_module_specifications;
1078 return nullptr;
Greg Claytonf4d6de62013-04-24 22:29:28 +00001079}
1080
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081ObjectFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001082PluginManager::GetObjectFileCreateCallbackForPluginName(
1083 const ConstString &name) {
1084 if (name) {
1085 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1086 ObjectFileInstances &instances = GetObjectFileInstances();
1087
1088 ObjectFileInstances::iterator pos, end = instances.end();
1089 for (pos = instances.begin(); pos != end; ++pos) {
1090 if (name == pos->name)
1091 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001092 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 }
1094 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001095}
1096
Greg Claytonc9660542012-02-05 02:38:54 +00001097ObjectFileCreateMemoryInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001098PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
1099 const ConstString &name) {
1100 if (name) {
1101 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1102 ObjectFileInstances &instances = GetObjectFileInstances();
1103
1104 ObjectFileInstances::iterator pos, end = instances.end();
1105 for (pos = instances.begin(); pos != end; ++pos) {
1106 if (name == pos->name)
1107 return pos->create_memory_callback;
Greg Claytonc9660542012-02-05 02:38:54 +00001108 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001109 }
1110 return nullptr;
Greg Claytonc9660542012-02-05 02:38:54 +00001111}
1112
Zachary Turner97206d52017-05-12 04:51:55 +00001113Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
1114 const FileSpec &outfile) {
1115 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001116 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1117 ObjectFileInstances &instances = GetObjectFileInstances();
1118
1119 ObjectFileInstances::iterator pos, end = instances.end();
1120 for (pos = instances.begin(); pos != end; ++pos) {
1121 if (pos->save_core && pos->save_core(process_sp, outfile, error))
1122 return error;
1123 }
1124 error.SetErrorString(
1125 "no ObjectFile plugins were able to save a core for this process");
1126 return error;
Greg Claytona2715cf2014-06-13 00:54:12 +00001127}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001128
1129#pragma mark ObjectContainer
1130
Kate Stoneb9c1b512016-09-06 20:57:50 +00001131struct ObjectContainerInstance {
1132 ObjectContainerInstance()
1133 : name(), description(), create_callback(nullptr),
1134 get_module_specifications(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001135
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136 ConstString name;
1137 std::string description;
1138 ObjectContainerCreateInstance create_callback;
1139 ObjectFileGetModuleSpecifications get_module_specifications;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001140};
1141
1142typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1143
Kate Stoneb9c1b512016-09-06 20:57:50 +00001144static std::recursive_mutex &GetObjectContainerMutex() {
1145 static std::recursive_mutex g_instances_mutex;
1146 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001147}
1148
Kate Stoneb9c1b512016-09-06 20:57:50 +00001149static ObjectContainerInstances &GetObjectContainerInstances() {
1150 static ObjectContainerInstances g_instances;
1151 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +00001152}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001153
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154bool PluginManager::RegisterPlugin(
1155 const ConstString &name, const char *description,
1156 ObjectContainerCreateInstance create_callback,
1157 ObjectFileGetModuleSpecifications get_module_specifications) {
1158 if (create_callback) {
1159 ObjectContainerInstance instance;
1160 assert((bool)name);
1161 instance.name = name;
1162 if (description && description[0])
1163 instance.description = description;
1164 instance.create_callback = create_callback;
1165 instance.get_module_specifications = get_module_specifications;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001166 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001167 GetObjectContainerInstances().push_back(instance);
1168 }
1169 return false;
1170}
1171
1172bool PluginManager::UnregisterPlugin(
1173 ObjectContainerCreateInstance create_callback) {
1174 if (create_callback) {
1175 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1176 ObjectContainerInstances &instances = GetObjectContainerInstances();
1177
1178 ObjectContainerInstances::iterator pos, end = instances.end();
1179 for (pos = instances.begin(); pos != end; ++pos) {
1180 if (pos->create_callback == create_callback) {
1181 instances.erase(pos);
1182 return true;
1183 }
1184 }
1185 }
1186 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001187}
Greg Claytonab65b342011-04-13 22:47:15 +00001188
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001189ObjectContainerCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001190PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
1191 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1192 ObjectContainerInstances &instances = GetObjectContainerInstances();
1193 if (idx < instances.size())
1194 return instances[idx].create_callback;
1195 return nullptr;
1196}
1197
1198ObjectContainerCreateInstance
1199PluginManager::GetObjectContainerCreateCallbackForPluginName(
1200 const ConstString &name) {
1201 if (name) {
1202 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1203 ObjectContainerInstances &instances = GetObjectContainerInstances();
1204
1205 ObjectContainerInstances::iterator pos, end = instances.end();
1206 for (pos = instances.begin(); pos != end; ++pos) {
1207 if (name == pos->name)
1208 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001210 }
1211 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001212}
1213
Greg Claytonf4d6de62013-04-24 22:29:28 +00001214ObjectFileGetModuleSpecifications
Kate Stoneb9c1b512016-09-06 20:57:50 +00001215PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
1216 uint32_t idx) {
1217 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1218 ObjectContainerInstances &instances = GetObjectContainerInstances();
1219 if (idx < instances.size())
1220 return instances[idx].get_module_specifications;
1221 return nullptr;
Greg Claytonf4d6de62013-04-24 22:29:28 +00001222}
1223
Greg Claytone996fd32011-03-08 22:40:15 +00001224#pragma mark Platform
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001225
Kate Stoneb9c1b512016-09-06 20:57:50 +00001226struct PlatformInstance {
1227 PlatformInstance()
1228 : name(), description(), create_callback(nullptr),
1229 debugger_init_callback(nullptr) {}
1230
1231 ConstString name;
1232 std::string description;
1233 PlatformCreateInstance create_callback;
1234 DebuggerInitializeCallback debugger_init_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001235};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001236
Greg Claytone996fd32011-03-08 22:40:15 +00001237typedef std::vector<PlatformInstance> PlatformInstances;
1238
Kate Stoneb9c1b512016-09-06 20:57:50 +00001239static std::recursive_mutex &GetPlatformInstancesMutex() {
1240 static std::recursive_mutex g_platform_instances_mutex;
1241 return g_platform_instances_mutex;
Greg Claytone996fd32011-03-08 22:40:15 +00001242}
1243
Kate Stoneb9c1b512016-09-06 20:57:50 +00001244static PlatformInstances &GetPlatformInstances() {
1245 static PlatformInstances g_platform_instances;
1246 return g_platform_instances;
Greg Claytonded470d2011-03-19 01:12:21 +00001247}
Greg Claytone996fd32011-03-08 22:40:15 +00001248
Kate Stoneb9c1b512016-09-06 20:57:50 +00001249bool PluginManager::RegisterPlugin(
1250 const ConstString &name, const char *description,
1251 PlatformCreateInstance create_callback,
1252 DebuggerInitializeCallback debugger_init_callback) {
1253 if (create_callback) {
1254 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001255
Kate Stoneb9c1b512016-09-06 20:57:50 +00001256 PlatformInstance instance;
1257 assert((bool)name);
1258 instance.name = name;
1259 if (description && description[0])
1260 instance.description = description;
1261 instance.create_callback = create_callback;
1262 instance.debugger_init_callback = debugger_init_callback;
1263 GetPlatformInstances().push_back(instance);
1264 return true;
1265 }
1266 return false;
1267}
1268
1269const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
1270 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1271 PlatformInstances &instances = GetPlatformInstances();
1272 if (idx < instances.size())
1273 return instances[idx].name.GetCString();
1274 return nullptr;
1275}
1276
1277const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
1278 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1279 PlatformInstances &instances = GetPlatformInstances();
1280 if (idx < instances.size())
1281 return instances[idx].description.c_str();
1282 return nullptr;
1283}
1284
1285bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
1286 if (create_callback) {
1287 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1288 PlatformInstances &instances = GetPlatformInstances();
1289
1290 PlatformInstances::iterator pos, end = instances.end();
1291 for (pos = instances.begin(); pos != end; ++pos) {
1292 if (pos->create_callback == create_callback) {
1293 instances.erase(pos);
Greg Claytonded470d2011-03-19 01:12:21 +00001294 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001295 }
Greg Claytone996fd32011-03-08 22:40:15 +00001296 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001297 }
1298 return false;
Greg Claytone996fd32011-03-08 22:40:15 +00001299}
1300
1301PlatformCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001302PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
1303 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1304 PlatformInstances &instances = GetPlatformInstances();
1305 if (idx < instances.size())
1306 return instances[idx].create_callback;
1307 return nullptr;
Greg Claytone996fd32011-03-08 22:40:15 +00001308}
1309
1310PlatformCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001311PluginManager::GetPlatformCreateCallbackForPluginName(const ConstString &name) {
1312 if (name) {
1313 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1314 PlatformInstances &instances = GetPlatformInstances();
Greg Claytonded470d2011-03-19 01:12:21 +00001315
Kate Stoneb9c1b512016-09-06 20:57:50 +00001316 PlatformInstances::iterator pos, end = instances.end();
1317 for (pos = instances.begin(); pos != end; ++pos) {
1318 if (name == pos->name)
1319 return pos->create_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001320 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001321 }
1322 return nullptr;
Greg Claytone996fd32011-03-08 22:40:15 +00001323}
1324
Zachary Turner4aa87532016-11-17 01:37:42 +00001325size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001326 StringList &matches) {
Zachary Turner4aa87532016-11-17 01:37:42 +00001327 if (name.empty())
1328 return matches.GetSize();
Greg Claytonab65b342011-04-13 22:47:15 +00001329
Zachary Turner4aa87532016-11-17 01:37:42 +00001330 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1331 PlatformInstances &instances = GetPlatformInstances();
1332 llvm::StringRef name_sref(name);
1333
1334 PlatformInstances::iterator pos, end = instances.end();
1335 for (pos = instances.begin(); pos != end; ++pos) {
1336 llvm::StringRef plugin_name(pos->name.GetCString());
1337 if (plugin_name.startswith(name_sref))
1338 matches.AppendString(plugin_name.data());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001339 }
1340 return matches.GetSize();
Greg Claytonab65b342011-04-13 22:47:15 +00001341}
Eugene Zelenko89183722016-03-11 21:55:47 +00001342
Greg Claytone996fd32011-03-08 22:40:15 +00001343#pragma mark Process
1344
Kate Stoneb9c1b512016-09-06 20:57:50 +00001345struct ProcessInstance {
1346 ProcessInstance()
1347 : name(), description(), create_callback(nullptr),
1348 debugger_init_callback(nullptr) {}
1349
1350 ConstString name;
1351 std::string description;
1352 ProcessCreateInstance create_callback;
1353 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001354};
1355
1356typedef std::vector<ProcessInstance> ProcessInstances;
1357
Kate Stoneb9c1b512016-09-06 20:57:50 +00001358static std::recursive_mutex &GetProcessMutex() {
1359 static std::recursive_mutex g_instances_mutex;
1360 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001361}
1362
Kate Stoneb9c1b512016-09-06 20:57:50 +00001363static ProcessInstances &GetProcessInstances() {
1364 static ProcessInstances g_instances;
1365 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001366}
1367
Kate Stoneb9c1b512016-09-06 20:57:50 +00001368bool PluginManager::RegisterPlugin(
1369 const ConstString &name, const char *description,
1370 ProcessCreateInstance create_callback,
1371 DebuggerInitializeCallback debugger_init_callback) {
1372 if (create_callback) {
1373 ProcessInstance instance;
1374 assert((bool)name);
1375 instance.name = name;
1376 if (description && description[0])
1377 instance.description = description;
1378 instance.create_callback = create_callback;
1379 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001380 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001381 GetProcessInstances().push_back(instance);
1382 }
1383 return false;
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001384}
1385
Kate Stoneb9c1b512016-09-06 20:57:50 +00001386const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
1387 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1388 ProcessInstances &instances = GetProcessInstances();
1389 if (idx < instances.size())
1390 return instances[idx].name.GetCString();
1391 return nullptr;
1392}
1393
1394const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
1395 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1396 ProcessInstances &instances = GetProcessInstances();
1397 if (idx < instances.size())
1398 return instances[idx].description.c_str();
1399 return nullptr;
1400}
1401
1402bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
1403 if (create_callback) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001404 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001405 ProcessInstances &instances = GetProcessInstances();
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001406
Kate Stoneb9c1b512016-09-06 20:57:50 +00001407 ProcessInstances::iterator pos, end = instances.end();
1408 for (pos = instances.begin(); pos != end; ++pos) {
1409 if (pos->create_callback == create_callback) {
1410 instances.erase(pos);
1411 return true;
1412 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001413 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001414 }
1415 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001416}
1417
1418ProcessCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001419PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
1420 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1421 ProcessInstances &instances = GetProcessInstances();
1422 if (idx < instances.size())
1423 return instances[idx].create_callback;
1424 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001425}
1426
1427ProcessCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001428PluginManager::GetProcessCreateCallbackForPluginName(const ConstString &name) {
1429 if (name) {
1430 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1431 ProcessInstances &instances = GetProcessInstances();
1432
1433 ProcessInstances::iterator pos, end = instances.end();
1434 for (pos = instances.begin(); pos != end; ++pos) {
1435 if (name == pos->name)
1436 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001437 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001438 }
1439 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001440}
1441
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001442#pragma mark ScriptInterpreter
1443
Kate Stoneb9c1b512016-09-06 20:57:50 +00001444struct ScriptInterpreterInstance {
1445 ScriptInterpreterInstance()
1446 : name(), language(lldb::eScriptLanguageNone), description(),
1447 create_callback(nullptr) {}
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001448
Kate Stoneb9c1b512016-09-06 20:57:50 +00001449 ConstString name;
1450 lldb::ScriptLanguage language;
1451 std::string description;
1452 ScriptInterpreterCreateInstance create_callback;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001453};
1454
1455typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
1456
Kate Stoneb9c1b512016-09-06 20:57:50 +00001457static std::recursive_mutex &GetScriptInterpreterMutex() {
1458 static std::recursive_mutex g_instances_mutex;
1459 return g_instances_mutex;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001460}
1461
Kate Stoneb9c1b512016-09-06 20:57:50 +00001462static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
1463 static ScriptInterpreterInstances g_instances;
1464 return g_instances;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001465}
1466
Kate Stoneb9c1b512016-09-06 20:57:50 +00001467bool PluginManager::RegisterPlugin(
1468 const ConstString &name, const char *description,
1469 lldb::ScriptLanguage script_language,
1470 ScriptInterpreterCreateInstance create_callback) {
1471 if (!create_callback)
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001472 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001473 ScriptInterpreterInstance instance;
1474 assert((bool)name);
1475 instance.name = name;
1476 if (description && description[0])
1477 instance.description = description;
1478 instance.create_callback = create_callback;
1479 instance.language = script_language;
1480 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1481 GetScriptInterpreterInstances().push_back(instance);
1482 return false;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001483}
1484
Kate Stoneb9c1b512016-09-06 20:57:50 +00001485bool PluginManager::UnregisterPlugin(
1486 ScriptInterpreterCreateInstance create_callback) {
1487 if (!create_callback)
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001488 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001489 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1490 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1491
1492 ScriptInterpreterInstances::iterator pos, end = instances.end();
1493 for (pos = instances.begin(); pos != end; ++pos) {
1494 if (pos->create_callback != create_callback)
1495 continue;
1496
1497 instances.erase(pos);
1498 return true;
1499 }
1500 return false;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001501}
1502
1503ScriptInterpreterCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001504PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
1505 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1506 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1507 if (idx < instances.size())
1508 return instances[idx].create_callback;
1509 return nullptr;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001510}
1511
Kate Stoneb9c1b512016-09-06 20:57:50 +00001512lldb::ScriptInterpreterSP PluginManager::GetScriptInterpreterForLanguage(
1513 lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter) {
1514 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1515 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001516
Kate Stoneb9c1b512016-09-06 20:57:50 +00001517 ScriptInterpreterInstances::iterator pos, end = instances.end();
1518 ScriptInterpreterCreateInstance none_instance = nullptr;
1519 for (pos = instances.begin(); pos != end; ++pos) {
1520 if (pos->language == lldb::eScriptLanguageNone)
1521 none_instance = pos->create_callback;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001522
Kate Stoneb9c1b512016-09-06 20:57:50 +00001523 if (script_lang == pos->language)
1524 return pos->create_callback(interpreter);
1525 }
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001526
Kate Stoneb9c1b512016-09-06 20:57:50 +00001527 // If we didn't find one, return the ScriptInterpreter for the null language.
1528 assert(none_instance != nullptr);
1529 return none_instance(interpreter);
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001530}
1531
Todd Fiala75930012016-08-19 04:21:48 +00001532#pragma mark -
1533#pragma mark StructuredDataPlugin
1534
1535// -----------------------------------------------------------------------------
1536// StructuredDataPlugin
1537// -----------------------------------------------------------------------------
1538
Kate Stoneb9c1b512016-09-06 20:57:50 +00001539struct StructuredDataPluginInstance {
1540 StructuredDataPluginInstance()
1541 : name(), description(), create_callback(nullptr),
1542 debugger_init_callback(nullptr), filter_callback(nullptr) {}
Todd Fiala75930012016-08-19 04:21:48 +00001543
Kate Stoneb9c1b512016-09-06 20:57:50 +00001544 ConstString name;
1545 std::string description;
1546 StructuredDataPluginCreateInstance create_callback;
1547 DebuggerInitializeCallback debugger_init_callback;
1548 StructuredDataFilterLaunchInfo filter_callback;
Todd Fiala75930012016-08-19 04:21:48 +00001549};
1550
1551typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;
1552
Kate Stoneb9c1b512016-09-06 20:57:50 +00001553static std::recursive_mutex &GetStructuredDataPluginMutex() {
1554 static std::recursive_mutex g_instances_mutex;
1555 return g_instances_mutex;
Todd Fiala75930012016-08-19 04:21:48 +00001556}
1557
Kate Stoneb9c1b512016-09-06 20:57:50 +00001558static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
1559 static StructuredDataPluginInstances g_instances;
1560 return g_instances;
Todd Fiala75930012016-08-19 04:21:48 +00001561}
1562
Kate Stoneb9c1b512016-09-06 20:57:50 +00001563bool PluginManager::RegisterPlugin(
1564 const ConstString &name, const char *description,
1565 StructuredDataPluginCreateInstance create_callback,
1566 DebuggerInitializeCallback debugger_init_callback,
1567 StructuredDataFilterLaunchInfo filter_callback) {
1568 if (create_callback) {
1569 StructuredDataPluginInstance instance;
1570 assert((bool)name);
1571 instance.name = name;
1572 if (description && description[0])
1573 instance.description = description;
1574 instance.create_callback = create_callback;
1575 instance.debugger_init_callback = debugger_init_callback;
1576 instance.filter_callback = filter_callback;
1577 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1578 GetStructuredDataPluginInstances().push_back(instance);
1579 }
1580 return false;
Todd Fiala75930012016-08-19 04:21:48 +00001581}
1582
Kate Stoneb9c1b512016-09-06 20:57:50 +00001583bool PluginManager::UnregisterPlugin(
1584 StructuredDataPluginCreateInstance create_callback) {
1585 if (create_callback) {
Todd Fiala75930012016-08-19 04:21:48 +00001586 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1587 StructuredDataPluginInstances &instances =
1588 GetStructuredDataPluginInstances();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001589
1590 StructuredDataPluginInstances::iterator pos, end = instances.end();
1591 for (pos = instances.begin(); pos != end; ++pos) {
1592 if (pos->create_callback == create_callback) {
1593 instances.erase(pos);
1594 return true;
1595 }
1596 }
1597 }
1598 return false;
1599}
1600
1601StructuredDataPluginCreateInstance
1602PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
1603 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1604 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
1605 if (idx < instances.size())
1606 return instances[idx].create_callback;
1607 return nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00001608}
1609
1610StructuredDataPluginCreateInstance
1611PluginManager::GetStructuredDataPluginCreateCallbackForPluginName(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001612 const ConstString &name) {
1613 if (name) {
Todd Fiala75930012016-08-19 04:21:48 +00001614 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1615 StructuredDataPluginInstances &instances =
1616 GetStructuredDataPluginInstances();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001617
1618 StructuredDataPluginInstances::iterator pos, end = instances.end();
1619 for (pos = instances.begin(); pos != end; ++pos) {
1620 if (name == pos->name)
1621 return pos->create_callback;
Todd Fiala75930012016-08-19 04:21:48 +00001622 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001623 }
1624 return nullptr;
1625}
1626
1627StructuredDataFilterLaunchInfo
1628PluginManager::GetStructuredDataFilterCallbackAtIndex(
1629 uint32_t idx, bool &iteration_complete) {
1630 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1631 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
1632 if (idx < instances.size()) {
1633 iteration_complete = false;
1634 return instances[idx].filter_callback;
1635 } else {
1636 iteration_complete = true;
1637 }
1638 return nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00001639}
1640
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001641#pragma mark SymbolFile
1642
Kate Stoneb9c1b512016-09-06 20:57:50 +00001643struct SymbolFileInstance {
1644 SymbolFileInstance()
1645 : name(), description(), create_callback(nullptr),
1646 debugger_init_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001647
Kate Stoneb9c1b512016-09-06 20:57:50 +00001648 ConstString name;
1649 std::string description;
1650 SymbolFileCreateInstance create_callback;
1651 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001652};
1653
1654typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1655
Kate Stoneb9c1b512016-09-06 20:57:50 +00001656static std::recursive_mutex &GetSymbolFileMutex() {
1657 static std::recursive_mutex g_instances_mutex;
1658 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001659}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001660
Kate Stoneb9c1b512016-09-06 20:57:50 +00001661static SymbolFileInstances &GetSymbolFileInstances() {
1662 static SymbolFileInstances g_instances;
1663 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001664}
1665
Kate Stoneb9c1b512016-09-06 20:57:50 +00001666bool PluginManager::RegisterPlugin(
1667 const ConstString &name, const char *description,
1668 SymbolFileCreateInstance create_callback,
1669 DebuggerInitializeCallback debugger_init_callback) {
1670 if (create_callback) {
1671 SymbolFileInstance instance;
1672 assert((bool)name);
1673 instance.name = name;
1674 if (description && description[0])
1675 instance.description = description;
1676 instance.create_callback = create_callback;
1677 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001678 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001679 GetSymbolFileInstances().push_back(instance);
1680 }
1681 return false;
1682}
1683
1684bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
1685 if (create_callback) {
1686 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1687 SymbolFileInstances &instances = GetSymbolFileInstances();
1688
1689 SymbolFileInstances::iterator pos, end = instances.end();
1690 for (pos = instances.begin(); pos != end; ++pos) {
1691 if (pos->create_callback == create_callback) {
1692 instances.erase(pos);
1693 return true;
1694 }
1695 }
1696 }
1697 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001698}
Greg Claytonab65b342011-04-13 22:47:15 +00001699
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001700SymbolFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001701PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1702 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1703 SymbolFileInstances &instances = GetSymbolFileInstances();
1704 if (idx < instances.size())
1705 return instances[idx].create_callback;
1706 return nullptr;
1707}
1708
1709SymbolFileCreateInstance
1710PluginManager::GetSymbolFileCreateCallbackForPluginName(
1711 const ConstString &name) {
1712 if (name) {
1713 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1714 SymbolFileInstances &instances = GetSymbolFileInstances();
1715
1716 SymbolFileInstances::iterator pos, end = instances.end();
1717 for (pos = instances.begin(); pos != end; ++pos) {
1718 if (name == pos->name)
1719 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001720 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001721 }
1722 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001723}
1724
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001725#pragma mark SymbolVendor
1726
Kate Stoneb9c1b512016-09-06 20:57:50 +00001727struct SymbolVendorInstance {
1728 SymbolVendorInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001729
Kate Stoneb9c1b512016-09-06 20:57:50 +00001730 ConstString name;
1731 std::string description;
1732 SymbolVendorCreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001733};
1734
1735typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1736
Kate Stoneb9c1b512016-09-06 20:57:50 +00001737static std::recursive_mutex &GetSymbolVendorMutex() {
1738 static std::recursive_mutex g_instances_mutex;
1739 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001740}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001741
Kate Stoneb9c1b512016-09-06 20:57:50 +00001742static SymbolVendorInstances &GetSymbolVendorInstances() {
1743 static SymbolVendorInstances g_instances;
1744 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001745}
1746
Kate Stoneb9c1b512016-09-06 20:57:50 +00001747bool PluginManager::RegisterPlugin(const ConstString &name,
1748 const char *description,
1749 SymbolVendorCreateInstance create_callback) {
1750 if (create_callback) {
1751 SymbolVendorInstance instance;
1752 assert((bool)name);
1753 instance.name = name;
1754 if (description && description[0])
1755 instance.description = description;
1756 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001757 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001758 GetSymbolVendorInstances().push_back(instance);
1759 }
1760 return false;
1761}
1762
1763bool PluginManager::UnregisterPlugin(
1764 SymbolVendorCreateInstance create_callback) {
1765 if (create_callback) {
1766 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1767 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1768
1769 SymbolVendorInstances::iterator pos, end = instances.end();
1770 for (pos = instances.begin(); pos != end; ++pos) {
1771 if (pos->create_callback == create_callback) {
1772 instances.erase(pos);
1773 return true;
1774 }
1775 }
1776 }
1777 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001778}
1779
1780SymbolVendorCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001781PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1782 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1783 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1784 if (idx < instances.size())
1785 return instances[idx].create_callback;
1786 return nullptr;
1787}
1788
1789SymbolVendorCreateInstance
1790PluginManager::GetSymbolVendorCreateCallbackForPluginName(
1791 const ConstString &name) {
1792 if (name) {
1793 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1794 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1795
1796 SymbolVendorInstances::iterator pos, end = instances.end();
1797 for (pos = instances.begin(); pos != end; ++pos) {
1798 if (name == pos->name)
1799 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001800 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001801 }
1802 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001803}
1804
Greg Clayton7be25422011-04-25 21:14:26 +00001805#pragma mark UnwindAssembly
Jason Molendafbcb7f22010-09-10 07:49:16 +00001806
Kate Stoneb9c1b512016-09-06 20:57:50 +00001807struct UnwindAssemblyInstance {
1808 UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001809
Kate Stoneb9c1b512016-09-06 20:57:50 +00001810 ConstString name;
1811 std::string description;
1812 UnwindAssemblyCreateInstance create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001813};
1814
Greg Clayton7be25422011-04-25 21:14:26 +00001815typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001816
Kate Stoneb9c1b512016-09-06 20:57:50 +00001817static std::recursive_mutex &GetUnwindAssemblyMutex() {
1818 static std::recursive_mutex g_instances_mutex;
1819 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001820}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001821
Kate Stoneb9c1b512016-09-06 20:57:50 +00001822static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1823 static UnwindAssemblyInstances g_instances;
1824 return g_instances;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001825}
1826
Kate Stoneb9c1b512016-09-06 20:57:50 +00001827bool PluginManager::RegisterPlugin(
1828 const ConstString &name, const char *description,
1829 UnwindAssemblyCreateInstance create_callback) {
1830 if (create_callback) {
1831 UnwindAssemblyInstance instance;
1832 assert((bool)name);
1833 instance.name = name;
1834 if (description && description[0])
1835 instance.description = description;
1836 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001837 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001838 GetUnwindAssemblyInstances().push_back(instance);
1839 }
1840 return false;
1841}
1842
1843bool PluginManager::UnregisterPlugin(
1844 UnwindAssemblyCreateInstance create_callback) {
1845 if (create_callback) {
1846 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1847 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1848
1849 UnwindAssemblyInstances::iterator pos, end = instances.end();
1850 for (pos = instances.begin(); pos != end; ++pos) {
1851 if (pos->create_callback == create_callback) {
1852 instances.erase(pos);
1853 return true;
1854 }
1855 }
1856 }
1857 return false;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001858}
1859
Greg Clayton7be25422011-04-25 21:14:26 +00001860UnwindAssemblyCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001861PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1862 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1863 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1864 if (idx < instances.size())
1865 return instances[idx].create_callback;
1866 return nullptr;
1867}
1868
1869UnwindAssemblyCreateInstance
1870PluginManager::GetUnwindAssemblyCreateCallbackForPluginName(
1871 const ConstString &name) {
1872 if (name) {
1873 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1874 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1875
1876 UnwindAssemblyInstances::iterator pos, end = instances.end();
1877 for (pos = instances.begin(); pos != end; ++pos) {
1878 if (name == pos->name)
1879 return pos->create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001880 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001881 }
1882 return nullptr;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001883}
1884
Kuba Breckabeed8212014-09-04 01:03:18 +00001885#pragma mark MemoryHistory
1886
Kate Stoneb9c1b512016-09-06 20:57:50 +00001887struct MemoryHistoryInstance {
1888 MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {}
1889
1890 ConstString name;
1891 std::string description;
1892 MemoryHistoryCreateInstance create_callback;
Kuba Breckabeed8212014-09-04 01:03:18 +00001893};
1894
1895typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
1896
Kate Stoneb9c1b512016-09-06 20:57:50 +00001897static std::recursive_mutex &GetMemoryHistoryMutex() {
1898 static std::recursive_mutex g_instances_mutex;
1899 return g_instances_mutex;
Kuba Breckabeed8212014-09-04 01:03:18 +00001900}
1901
Kate Stoneb9c1b512016-09-06 20:57:50 +00001902static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1903 static MemoryHistoryInstances g_instances;
1904 return g_instances;
Kuba Breckabeed8212014-09-04 01:03:18 +00001905}
1906
Kate Stoneb9c1b512016-09-06 20:57:50 +00001907bool PluginManager::RegisterPlugin(
1908 const ConstString &name, const char *description,
1909 MemoryHistoryCreateInstance create_callback) {
1910 if (create_callback) {
1911 MemoryHistoryInstance instance;
1912 assert((bool)name);
1913 instance.name = name;
1914 if (description && description[0])
1915 instance.description = description;
1916 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001917 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001918 GetMemoryHistoryInstances().push_back(instance);
1919 }
1920 return false;
1921}
1922
1923bool PluginManager::UnregisterPlugin(
1924 MemoryHistoryCreateInstance create_callback) {
1925 if (create_callback) {
1926 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1927 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1928
1929 MemoryHistoryInstances::iterator pos, end = instances.end();
1930 for (pos = instances.begin(); pos != end; ++pos) {
1931 if (pos->create_callback == create_callback) {
1932 instances.erase(pos);
1933 return true;
1934 }
1935 }
1936 }
1937 return false;
Kuba Breckabeed8212014-09-04 01:03:18 +00001938}
1939
Kuba Breckabeed8212014-09-04 01:03:18 +00001940MemoryHistoryCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001941PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1942 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1943 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1944 if (idx < instances.size())
1945 return instances[idx].create_callback;
1946 return nullptr;
1947}
1948
1949MemoryHistoryCreateInstance
1950PluginManager::GetMemoryHistoryCreateCallbackForPluginName(
1951 const ConstString &name) {
1952 if (name) {
1953 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1954 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1955
1956 MemoryHistoryInstances::iterator pos, end = instances.end();
1957 for (pos = instances.begin(); pos != end; ++pos) {
1958 if (name == pos->name)
1959 return pos->create_callback;
Kuba Breckabeed8212014-09-04 01:03:18 +00001960 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001961 }
1962 return nullptr;
Kuba Breckabeed8212014-09-04 01:03:18 +00001963}
1964
Kuba Breckaafdf8422014-10-10 23:43:03 +00001965#pragma mark InstrumentationRuntime
1966
Kate Stoneb9c1b512016-09-06 20:57:50 +00001967struct InstrumentationRuntimeInstance {
1968 InstrumentationRuntimeInstance()
1969 : name(), description(), create_callback(nullptr) {}
1970
1971 ConstString name;
1972 std::string description;
1973 InstrumentationRuntimeCreateInstance create_callback;
1974 InstrumentationRuntimeGetType get_type_callback;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001975};
1976
Kate Stoneb9c1b512016-09-06 20:57:50 +00001977typedef std::vector<InstrumentationRuntimeInstance>
1978 InstrumentationRuntimeInstances;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001979
Kate Stoneb9c1b512016-09-06 20:57:50 +00001980static std::recursive_mutex &GetInstrumentationRuntimeMutex() {
1981 static std::recursive_mutex g_instances_mutex;
1982 return g_instances_mutex;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001983}
1984
Kate Stoneb9c1b512016-09-06 20:57:50 +00001985static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1986 static InstrumentationRuntimeInstances g_instances;
1987 return g_instances;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001988}
1989
Kate Stoneb9c1b512016-09-06 20:57:50 +00001990bool PluginManager::RegisterPlugin(
1991 const ConstString &name, const char *description,
1992 InstrumentationRuntimeCreateInstance create_callback,
1993 InstrumentationRuntimeGetType get_type_callback) {
1994 if (create_callback) {
1995 InstrumentationRuntimeInstance instance;
1996 assert((bool)name);
1997 instance.name = name;
1998 if (description && description[0])
1999 instance.description = description;
2000 instance.create_callback = create_callback;
2001 instance.get_type_callback = get_type_callback;
2002 std::lock_guard<std::recursive_mutex> guard(
2003 GetInstrumentationRuntimeMutex());
2004 GetInstrumentationRuntimeInstances().push_back(instance);
2005 }
2006 return false;
2007}
2008
2009bool PluginManager::UnregisterPlugin(
2010 InstrumentationRuntimeCreateInstance create_callback) {
2011 if (create_callback) {
2012 std::lock_guard<std::recursive_mutex> guard(
2013 GetInstrumentationRuntimeMutex());
2014 InstrumentationRuntimeInstances &instances =
2015 GetInstrumentationRuntimeInstances();
2016
2017 InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2018 for (pos = instances.begin(); pos != end; ++pos) {
2019 if (pos->create_callback == create_callback) {
2020 instances.erase(pos);
2021 return true;
2022 }
Kuba Breckaafdf8422014-10-10 23:43:03 +00002023 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002024 }
2025 return false;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002026}
2027
2028InstrumentationRuntimeGetType
Kate Stoneb9c1b512016-09-06 20:57:50 +00002029PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
2030 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
2031 InstrumentationRuntimeInstances &instances =
2032 GetInstrumentationRuntimeInstances();
2033 if (idx < instances.size())
2034 return instances[idx].get_type_callback;
2035 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002036}
2037
2038InstrumentationRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002039PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
2040 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
2041 InstrumentationRuntimeInstances &instances =
2042 GetInstrumentationRuntimeInstances();
2043 if (idx < instances.size())
2044 return instances[idx].create_callback;
2045 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002046}
2047
Kuba Breckaafdf8422014-10-10 23:43:03 +00002048InstrumentationRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002049PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName(
2050 const ConstString &name) {
2051 if (name) {
2052 std::lock_guard<std::recursive_mutex> guard(
2053 GetInstrumentationRuntimeMutex());
2054 InstrumentationRuntimeInstances &instances =
2055 GetInstrumentationRuntimeInstances();
2056
2057 InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2058 for (pos = instances.begin(); pos != end; ++pos) {
2059 if (name == pos->name)
2060 return pos->create_callback;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002061 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002062 }
2063 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002064}
2065
Greg Clayton56939cb2015-09-17 22:23:34 +00002066#pragma mark TypeSystem
2067
Kate Stoneb9c1b512016-09-06 20:57:50 +00002068struct TypeSystemInstance {
2069 TypeSystemInstance() : name(), description(), create_callback(nullptr) {}
Greg Clayton56939cb2015-09-17 22:23:34 +00002070
Kate Stoneb9c1b512016-09-06 20:57:50 +00002071 ConstString name;
2072 std::string description;
2073 TypeSystemCreateInstance create_callback;
2074 TypeSystemEnumerateSupportedLanguages enumerate_callback;
Greg Clayton56939cb2015-09-17 22:23:34 +00002075};
2076
2077typedef std::vector<TypeSystemInstance> TypeSystemInstances;
2078
Kate Stoneb9c1b512016-09-06 20:57:50 +00002079static std::recursive_mutex &GetTypeSystemMutex() {
2080 static std::recursive_mutex g_instances_mutex;
2081 return g_instances_mutex;
Greg Clayton56939cb2015-09-17 22:23:34 +00002082}
2083
Kate Stoneb9c1b512016-09-06 20:57:50 +00002084static TypeSystemInstances &GetTypeSystemInstances() {
2085 static TypeSystemInstances g_instances;
2086 return g_instances;
Greg Clayton56939cb2015-09-17 22:23:34 +00002087}
2088
Kate Stoneb9c1b512016-09-06 20:57:50 +00002089bool PluginManager::RegisterPlugin(const ConstString &name,
2090 const char *description,
2091 TypeSystemCreateInstance create_callback,
2092 TypeSystemEnumerateSupportedLanguages
2093 enumerate_supported_languages_callback) {
2094 if (create_callback) {
2095 TypeSystemInstance instance;
2096 assert((bool)name);
2097 instance.name = name;
2098 if (description && description[0])
2099 instance.description = description;
2100 instance.create_callback = create_callback;
2101 instance.enumerate_callback = enumerate_supported_languages_callback;
2102 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2103 GetTypeSystemInstances().push_back(instance);
2104 }
2105 return false;
2106}
2107
2108bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
2109 if (create_callback) {
2110 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2111 TypeSystemInstances &instances = GetTypeSystemInstances();
2112
2113 TypeSystemInstances::iterator pos, end = instances.end();
2114 for (pos = instances.begin(); pos != end; ++pos) {
2115 if (pos->create_callback == create_callback) {
2116 instances.erase(pos);
2117 return true;
2118 }
Greg Clayton56939cb2015-09-17 22:23:34 +00002119 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002120 }
2121 return false;
Greg Clayton56939cb2015-09-17 22:23:34 +00002122}
2123
2124TypeSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002125PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
2126 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2127 TypeSystemInstances &instances = GetTypeSystemInstances();
2128 if (idx < instances.size())
2129 return instances[idx].create_callback;
2130 return nullptr;
Greg Clayton56939cb2015-09-17 22:23:34 +00002131}
2132
2133TypeSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002134PluginManager::GetTypeSystemCreateCallbackForPluginName(
2135 const ConstString &name) {
2136 if (name) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00002137 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002138 TypeSystemInstances &instances = GetTypeSystemInstances();
2139
2140 TypeSystemInstances::iterator pos, end = instances.end();
2141 for (pos = instances.begin(); pos != end; ++pos) {
2142 if (name == pos->name)
2143 return pos->create_callback;
2144 }
2145 }
2146 return nullptr;
Sean Callananfe38c852015-10-08 23:07:53 +00002147}
2148
2149TypeSystemEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002150PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(
2151 uint32_t idx) {
2152 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2153 TypeSystemInstances &instances = GetTypeSystemInstances();
2154 if (idx < instances.size())
2155 return instances[idx].enumerate_callback;
2156 return nullptr;
2157}
2158
2159TypeSystemEnumerateSupportedLanguages
2160PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
2161 const ConstString &name) {
2162 if (name) {
2163 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2164 TypeSystemInstances &instances = GetTypeSystemInstances();
2165
2166 TypeSystemInstances::iterator pos, end = instances.end();
2167 for (pos = instances.begin(); pos != end; ++pos) {
2168 if (name == pos->name)
2169 return pos->enumerate_callback;
Sean Callananfe38c852015-10-08 23:07:53 +00002170 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002171 }
2172 return nullptr;
Sean Callananfe38c852015-10-08 23:07:53 +00002173}
Greg Clayton56939cb2015-09-17 22:23:34 +00002174
Sean Callanan66810412015-10-19 23:11:07 +00002175#pragma mark REPL
2176
Kate Stoneb9c1b512016-09-06 20:57:50 +00002177struct REPLInstance {
2178 REPLInstance() : name(), description(), create_callback(nullptr) {}
2179
2180 ConstString name;
2181 std::string description;
2182 REPLCreateInstance create_callback;
2183 REPLEnumerateSupportedLanguages enumerate_languages_callback;
Sean Callanan66810412015-10-19 23:11:07 +00002184};
2185
2186typedef std::vector<REPLInstance> REPLInstances;
2187
Kate Stoneb9c1b512016-09-06 20:57:50 +00002188static std::recursive_mutex &GetREPLMutex() {
2189 static std::recursive_mutex g_instances_mutex;
2190 return g_instances_mutex;
Sean Callanan66810412015-10-19 23:11:07 +00002191}
2192
Kate Stoneb9c1b512016-09-06 20:57:50 +00002193static REPLInstances &GetREPLInstances() {
2194 static REPLInstances g_instances;
2195 return g_instances;
Sean Callanan66810412015-10-19 23:11:07 +00002196}
2197
Kate Stoneb9c1b512016-09-06 20:57:50 +00002198bool PluginManager::RegisterPlugin(
2199 const ConstString &name, const char *description,
2200 REPLCreateInstance create_callback,
2201 REPLEnumerateSupportedLanguages enumerate_languages_callback) {
2202 if (create_callback) {
2203 REPLInstance instance;
2204 assert((bool)name);
2205 instance.name = name;
2206 if (description && description[0])
2207 instance.description = description;
2208 instance.create_callback = create_callback;
2209 instance.enumerate_languages_callback = enumerate_languages_callback;
2210 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2211 GetREPLInstances().push_back(instance);
2212 }
2213 return false;
2214}
2215
2216bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
2217 if (create_callback) {
2218 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2219 REPLInstances &instances = GetREPLInstances();
2220
2221 REPLInstances::iterator pos, end = instances.end();
2222 for (pos = instances.begin(); pos != end; ++pos) {
2223 if (pos->create_callback == create_callback) {
2224 instances.erase(pos);
2225 return true;
2226 }
Sean Callanan66810412015-10-19 23:11:07 +00002227 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002228 }
2229 return false;
Sean Callanan66810412015-10-19 23:11:07 +00002230}
2231
Kate Stoneb9c1b512016-09-06 20:57:50 +00002232REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
2233 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2234 REPLInstances &instances = GetREPLInstances();
2235 if (idx < instances.size())
2236 return instances[idx].create_callback;
2237 return nullptr;
Sean Callanan66810412015-10-19 23:11:07 +00002238}
2239
2240REPLCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002241PluginManager::GetREPLCreateCallbackForPluginName(const ConstString &name) {
2242 if (name) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00002243 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002244 REPLInstances &instances = GetREPLInstances();
Sean Callanan66810412015-10-19 23:11:07 +00002245
Kate Stoneb9c1b512016-09-06 20:57:50 +00002246 REPLInstances::iterator pos, end = instances.end();
2247 for (pos = instances.begin(); pos != end; ++pos) {
2248 if (name == pos->name)
2249 return pos->create_callback;
Sean Callanan66810412015-10-19 23:11:07 +00002250 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002251 }
2252 return nullptr;
Sean Callanan66810412015-10-19 23:11:07 +00002253}
2254
Sean Callanan93c0b002015-10-21 19:14:33 +00002255REPLEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002256PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) {
2257 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2258 REPLInstances &instances = GetREPLInstances();
2259 if (idx < instances.size())
2260 return instances[idx].enumerate_languages_callback;
2261 return nullptr;
Sean Callanan93c0b002015-10-21 19:14:33 +00002262}
2263
Sean Callanan93c0b002015-10-21 19:14:33 +00002264REPLEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002265PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
2266 const ConstString &name) {
2267 if (name) {
2268 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2269 REPLInstances &instances = GetREPLInstances();
2270
2271 REPLInstances::iterator pos, end = instances.end();
2272 for (pos = instances.begin(); pos != end; ++pos) {
2273 if (name == pos->name)
2274 return pos->enumerate_languages_callback;
Sean Callanan93c0b002015-10-21 19:14:33 +00002275 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002276 }
2277 return nullptr;
Sean Callanan93c0b002015-10-21 19:14:33 +00002278}
2279
Kuba Breckaafdf8422014-10-10 23:43:03 +00002280#pragma mark PluginManager
2281
Kate Stoneb9c1b512016-09-06 20:57:50 +00002282void PluginManager::DebuggerInitialize(Debugger &debugger) {
2283 // Initialize the DynamicLoader plugins
2284 {
2285 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
2286 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
Jason Molenda9b837a12013-04-05 05:06:39 +00002287
Kate Stoneb9c1b512016-09-06 20:57:50 +00002288 DynamicLoaderInstances::iterator pos, end = instances.end();
2289 for (pos = instances.begin(); pos != end; ++pos) {
2290 if (pos->debugger_init_callback)
2291 pos->debugger_init_callback(debugger);
Andrew MacPherson17220c12014-03-05 10:12:43 +00002292 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002293 }
Andrew MacPherson17220c12014-03-05 10:12:43 +00002294
Kate Stoneb9c1b512016-09-06 20:57:50 +00002295 // Initialize the JITLoader plugins
2296 {
2297 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
2298 JITLoaderInstances &instances = GetJITLoaderInstances();
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002299
Kate Stoneb9c1b512016-09-06 20:57:50 +00002300 JITLoaderInstances::iterator pos, end = instances.end();
2301 for (pos = instances.begin(); pos != end; ++pos) {
2302 if (pos->debugger_init_callback)
2303 pos->debugger_init_callback(debugger);
Greg Clayton7f982402013-07-15 22:54:20 +00002304 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002305 }
Greg Clayton7f982402013-07-15 22:54:20 +00002306
Kate Stoneb9c1b512016-09-06 20:57:50 +00002307 // Initialize the Platform plugins
2308 {
2309 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
2310 PlatformInstances &instances = GetPlatformInstances();
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002311
Kate Stoneb9c1b512016-09-06 20:57:50 +00002312 PlatformInstances::iterator pos, end = instances.end();
2313 for (pos = instances.begin(); pos != end; ++pos) {
2314 if (pos->debugger_init_callback)
2315 pos->debugger_init_callback(debugger);
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002316 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002317 }
Todd Fiala75930012016-08-19 04:21:48 +00002318
Kate Stoneb9c1b512016-09-06 20:57:50 +00002319 // Initialize the Process plugins
2320 {
2321 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
2322 ProcessInstances &instances = GetProcessInstances();
2323
2324 ProcessInstances::iterator pos, end = instances.end();
2325 for (pos = instances.begin(); pos != end; ++pos) {
2326 if (pos->debugger_init_callback)
2327 pos->debugger_init_callback(debugger);
Todd Fiala75930012016-08-19 04:21:48 +00002328 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002329 }
2330
2331 // Initialize the SymbolFile plugins
2332 {
2333 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
2334 for (auto &sym_file : GetSymbolFileInstances()) {
2335 if (sym_file.debugger_init_callback)
2336 sym_file.debugger_init_callback(debugger);
2337 }
2338 }
2339
2340 // Initialize the OperatingSystem plugins
2341 {
2342 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
2343 for (auto &os : GetOperatingSystemInstances()) {
2344 if (os.debugger_init_callback)
2345 os.debugger_init_callback(debugger);
2346 }
2347 }
2348
2349 // Initialize the StructuredDataPlugin plugins
2350 {
2351 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
2352 for (auto &plugin : GetStructuredDataPluginInstances()) {
2353 if (plugin.debugger_init_callback)
2354 plugin.debugger_init_callback(debugger);
2355 }
2356 }
Greg Claytone8cd0c92012-10-19 18:02:49 +00002357}
2358
Greg Clayton7f982402013-07-15 22:54:20 +00002359// This is the preferred new way to register plugin specific settings. e.g.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002360// This will put a plugin's settings under e.g.
2361// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2362static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins(
2363 Debugger &debugger, const ConstString &plugin_type_name,
2364 const ConstString &plugin_type_desc, bool can_create) {
2365 lldb::OptionValuePropertiesSP parent_properties_sp(
2366 debugger.GetValueProperties());
2367 if (parent_properties_sp) {
2368 static ConstString g_property_name("plugin");
2369
2370 OptionValuePropertiesSP plugin_properties_sp =
2371 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
2372 if (!plugin_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002373 plugin_properties_sp =
2374 std::make_shared<OptionValueProperties>(g_property_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002375 parent_properties_sp->AppendProperty(
2376 g_property_name, ConstString("Settings specify to plugins."), true,
2377 plugin_properties_sp);
Greg Claytone8cd0c92012-10-19 18:02:49 +00002378 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002379
2380 if (plugin_properties_sp) {
2381 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2382 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2383 if (!plugin_type_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002384 plugin_type_properties_sp =
2385 std::make_shared<OptionValueProperties>(plugin_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002386 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2387 true, plugin_type_properties_sp);
2388 }
2389 return plugin_type_properties_sp;
2390 }
2391 }
2392 return lldb::OptionValuePropertiesSP();
Greg Claytone8cd0c92012-10-19 18:02:49 +00002393}
2394
Greg Clayton7f982402013-07-15 22:54:20 +00002395// This is deprecated way to register plugin specific settings. e.g.
Adrian Prantl05097242018-04-30 16:49:04 +00002396// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
2397// generic settings would be under "platform.SETTINGNAME".
Kate Stoneb9c1b512016-09-06 20:57:50 +00002398static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
2399 Debugger &debugger, const ConstString &plugin_type_name,
2400 const ConstString &plugin_type_desc, bool can_create) {
2401 static ConstString g_property_name("plugin");
2402 lldb::OptionValuePropertiesSP parent_properties_sp(
2403 debugger.GetValueProperties());
2404 if (parent_properties_sp) {
2405 OptionValuePropertiesSP plugin_properties_sp =
2406 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2407 if (!plugin_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002408 plugin_properties_sp =
2409 std::make_shared<OptionValueProperties>(plugin_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002410 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2411 true, plugin_properties_sp);
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002412 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002413
2414 if (plugin_properties_sp) {
2415 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2416 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
2417 if (!plugin_type_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002418 plugin_type_properties_sp =
2419 std::make_shared<OptionValueProperties>(g_property_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002420 plugin_properties_sp->AppendProperty(
2421 g_property_name, ConstString("Settings specific to plugins"), true,
2422 plugin_type_properties_sp);
2423 }
2424 return plugin_type_properties_sp;
2425 }
2426 }
2427 return lldb::OptionValuePropertiesSP();
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002428}
2429
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002430namespace {
2431
2432typedef lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002433GetDebuggerPropertyForPluginsPtr(Debugger &, const ConstString &,
2434 const ConstString &, bool can_create);
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002435
Greg Claytone8cd0c92012-10-19 18:02:49 +00002436lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002437GetSettingForPlugin(Debugger &debugger, const ConstString &setting_name,
2438 const ConstString &plugin_type_name,
2439 GetDebuggerPropertyForPluginsPtr get_debugger_property =
2440 GetDebuggerPropertyForPlugins) {
2441 lldb::OptionValuePropertiesSP properties_sp;
2442 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
2443 debugger, plugin_type_name,
2444 ConstString(), // not creating to so we don't need the description
2445 false));
2446 if (plugin_type_properties_sp)
2447 properties_sp =
2448 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2449 return properties_sp;
Greg Claytone8cd0c92012-10-19 18:02:49 +00002450}
2451
Kate Stoneb9c1b512016-09-06 20:57:50 +00002452bool CreateSettingForPlugin(
2453 Debugger &debugger, const ConstString &plugin_type_name,
2454 const ConstString &plugin_type_desc,
2455 const lldb::OptionValuePropertiesSP &properties_sp,
2456 const ConstString &description, bool is_global_property,
2457 GetDebuggerPropertyForPluginsPtr get_debugger_property =
2458 GetDebuggerPropertyForPlugins) {
2459 if (properties_sp) {
2460 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2461 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
2462 true));
2463 if (plugin_type_properties_sp) {
2464 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2465 description, is_global_property,
2466 properties_sp);
2467 return true;
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002468 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002469 }
2470 return false;
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002471}
2472
Kate Stoneb9c1b512016-09-06 20:57:50 +00002473const char *kDynamicLoaderPluginName("dynamic-loader");
2474const char *kPlatformPluginName("platform");
2475const char *kProcessPluginName("process");
2476const char *kSymbolFilePluginName("symbol-file");
2477const char *kJITLoaderPluginName("jit-loader");
2478const char *kStructuredDataPluginName("structured-data");
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002479
Eugene Zelenko89183722016-03-11 21:55:47 +00002480} // anonymous namespace
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002481
Kate Stoneb9c1b512016-09-06 20:57:50 +00002482lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(
2483 Debugger &debugger, const ConstString &setting_name) {
2484 return GetSettingForPlugin(debugger, setting_name,
2485 ConstString(kDynamicLoaderPluginName));
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002486}
2487
Kate Stoneb9c1b512016-09-06 20:57:50 +00002488bool PluginManager::CreateSettingForDynamicLoaderPlugin(
2489 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2490 const ConstString &description, bool is_global_property) {
2491 return CreateSettingForPlugin(
2492 debugger, ConstString(kDynamicLoaderPluginName),
2493 ConstString("Settings for dynamic loader plug-ins"), properties_sp,
2494 description, is_global_property);
Greg Claytone8cd0c92012-10-19 18:02:49 +00002495}
2496
Jason Molenda9b837a12013-04-05 05:06:39 +00002497lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002498PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
2499 const ConstString &setting_name) {
2500 return GetSettingForPlugin(debugger, setting_name,
2501 ConstString(kPlatformPluginName),
2502 GetDebuggerPropertyForPluginsOldStyle);
Jason Molenda9b837a12013-04-05 05:06:39 +00002503}
2504
Kate Stoneb9c1b512016-09-06 20:57:50 +00002505bool PluginManager::CreateSettingForPlatformPlugin(
2506 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2507 const ConstString &description, bool is_global_property) {
2508 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
2509 ConstString("Settings for platform plug-ins"),
2510 properties_sp, description, is_global_property,
2511 GetDebuggerPropertyForPluginsOldStyle);
Greg Clayton7f982402013-07-15 22:54:20 +00002512}
2513
Greg Clayton7f982402013-07-15 22:54:20 +00002514lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002515PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
2516 const ConstString &setting_name) {
2517 return GetSettingForPlugin(debugger, setting_name,
2518 ConstString(kProcessPluginName));
Greg Clayton7f982402013-07-15 22:54:20 +00002519}
2520
Kate Stoneb9c1b512016-09-06 20:57:50 +00002521bool PluginManager::CreateSettingForProcessPlugin(
2522 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2523 const ConstString &description, bool is_global_property) {
2524 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
2525 ConstString("Settings for process plug-ins"),
2526 properties_sp, description, is_global_property);
Jason Molenda9b837a12013-04-05 05:06:39 +00002527}
2528
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002529lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002530PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
2531 const ConstString &setting_name) {
2532 return GetSettingForPlugin(debugger, setting_name,
2533 ConstString(kSymbolFilePluginName));
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002534}
2535
Kate Stoneb9c1b512016-09-06 20:57:50 +00002536bool PluginManager::CreateSettingForSymbolFilePlugin(
2537 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2538 const ConstString &description, bool is_global_property) {
2539 return CreateSettingForPlugin(
2540 debugger, ConstString(kSymbolFilePluginName),
2541 ConstString("Settings for symbol file plug-ins"), properties_sp,
2542 description, is_global_property);
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002543}
2544
2545lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002546PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
2547 const ConstString &setting_name) {
2548 return GetSettingForPlugin(debugger, setting_name,
2549 ConstString(kJITLoaderPluginName));
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002550}
2551
Kate Stoneb9c1b512016-09-06 20:57:50 +00002552bool PluginManager::CreateSettingForJITLoaderPlugin(
2553 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2554 const ConstString &description, bool is_global_property) {
2555 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
2556 ConstString("Settings for JIT loader plug-ins"),
2557 properties_sp, description, is_global_property);
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002558}
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002559
2560static const char *kOperatingSystemPluginName("os");
2561
Kate Stoneb9c1b512016-09-06 20:57:50 +00002562lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin(
2563 Debugger &debugger, const ConstString &setting_name) {
2564 lldb::OptionValuePropertiesSP properties_sp;
2565 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2566 GetDebuggerPropertyForPlugins(
2567 debugger, ConstString(kOperatingSystemPluginName),
2568 ConstString(), // not creating to so we don't need the description
2569 false));
2570 if (plugin_type_properties_sp)
2571 properties_sp =
2572 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2573 return properties_sp;
2574}
2575
2576bool PluginManager::CreateSettingForOperatingSystemPlugin(
2577 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2578 const ConstString &description, bool is_global_property) {
2579 if (properties_sp) {
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002580 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002581 GetDebuggerPropertyForPlugins(
2582 debugger, ConstString(kOperatingSystemPluginName),
2583 ConstString("Settings for operating system plug-ins"), true));
2584 if (plugin_type_properties_sp) {
2585 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2586 description, is_global_property,
2587 properties_sp);
2588 return true;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002589 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002590 }
2591 return false;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002592}
Todd Fiala75930012016-08-19 04:21:48 +00002593
Kate Stoneb9c1b512016-09-06 20:57:50 +00002594lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin(
2595 Debugger &debugger, const ConstString &setting_name) {
2596 return GetSettingForPlugin(debugger, setting_name,
2597 ConstString(kStructuredDataPluginName));
Todd Fiala75930012016-08-19 04:21:48 +00002598}
2599
Kate Stoneb9c1b512016-09-06 20:57:50 +00002600bool PluginManager::CreateSettingForStructuredDataPlugin(
2601 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2602 const ConstString &description, bool is_global_property) {
2603 return CreateSettingForPlugin(
2604 debugger, ConstString(kStructuredDataPluginName),
2605 ConstString("Settings for structured data plug-ins"), properties_sp,
2606 description, is_global_property);
Todd Fiala75930012016-08-19 04:21:48 +00002607}