blob: a49fbc3f90fefdd6ca1e5d7dae585196b69d7ecc [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
20#if defined(LLVM_ON_WIN32)
21#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;
Kate Stoneb9c1b512016-09-06 20:57:50 +000099 // If we have a regular file, a symbolic link or unknown file type, try
100 // and process the file. We must handle unknown as sometimes the directory
101 // 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
131 // might not be
132 // compatible, or might be too new or too old, or might not want to
133 // run on this
134 // machine. Set it to a default-constructed instance to invalidate
135 // it.
136 plugin_info = PluginInfo();
137 }
138
139 // Regardless of success or failure, cache the plug-in load
140 // in our plug-in info so we don't try to load it again and
141 // again.
142 SetPluginInfo(plugin_file_spec, plugin_info);
143
144 return FileSpec::eEnumerateDirectoryResultNext;
145 }
146 }
147 }
148
Zachary Turner7d86ee52017-03-08 17:56:08 +0000149 if (ft == fs::file_type::directory_file ||
150 ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 // Try and recurse into anything that a directory or symbolic link.
152 // We must also do this for unknown as sometimes the directory enumeration
153 // might be enumerating a file system that doesn't have correct file type
154 // information.
155 return FileSpec::eEnumerateDirectoryResultEnter;
156 }
157
158 return FileSpec::eEnumerateDirectoryResultNext;
Greg Clayton4272cc72011-02-02 02:24:04 +0000159}
160
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161void PluginManager::Initialize() {
Greg Clayton1cb64962011-03-24 04:28:38 +0000162#if 1
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 FileSpec dir_spec;
164 const bool find_directories = true;
165 const bool find_files = true;
166 const bool find_other = true;
167 char dir_path[PATH_MAX];
168 if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) {
169 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
170 FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
171 find_other, LoadPluginCallback, nullptr);
Greg Clayton4272cc72011-02-02 02:24:04 +0000172 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173 }
Greg Clayton4272cc72011-02-02 02:24:04 +0000174
Kate Stoneb9c1b512016-09-06 20:57:50 +0000175 if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) {
176 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
177 FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
178 find_other, LoadPluginCallback, nullptr);
Greg Clayton4272cc72011-02-02 02:24:04 +0000179 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000181#endif
Greg Clayton4272cc72011-02-02 02:24:04 +0000182}
183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184void PluginManager::Terminate() {
185 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
186 PluginTerminateMap &plugin_map = GetPluginMap();
187
188 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
189 for (pos = plugin_map.begin(); pos != end; ++pos) {
190 // Call the plug-in "void LLDBPluginTerminate (void)" function if there
191 // is one (if the symbol was not nullptr).
192 if (pos->second.library.isValid()) {
193 if (pos->second.plugin_term_callback)
194 pos->second.plugin_term_callback();
Greg Clayton4272cc72011-02-02 02:24:04 +0000195 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196 }
197 plugin_map.clear();
Greg Clayton4272cc72011-02-02 02:24:04 +0000198}
199
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000200#pragma mark ABI
201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202struct ABIInstance {
203 ABIInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205 ConstString name;
206 std::string description;
207 ABICreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208};
209
210typedef std::vector<ABIInstance> ABIInstances;
211
Kate Stoneb9c1b512016-09-06 20:57:50 +0000212static std::recursive_mutex &GetABIInstancesMutex() {
213 static std::recursive_mutex g_instances_mutex;
214 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215}
216
Kate Stoneb9c1b512016-09-06 20:57:50 +0000217static ABIInstances &GetABIInstances() {
218 static ABIInstances g_instances;
219 return g_instances;
Greg Claytonded470d2011-03-19 01:12:21 +0000220}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222bool PluginManager::RegisterPlugin(const ConstString &name,
223 const char *description,
224 ABICreateInstance create_callback) {
225 if (create_callback) {
226 ABIInstance instance;
227 assert((bool)name);
228 instance.name = name;
229 if (description && description[0])
230 instance.description = description;
231 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000232 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 GetABIInstances().push_back(instance);
234 return true;
235 }
236 return false;
237}
238
239bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
240 if (create_callback) {
241 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
242 ABIInstances &instances = GetABIInstances();
243
244 ABIInstances::iterator pos, end = instances.end();
245 for (pos = instances.begin(); pos != end; ++pos) {
246 if (pos->create_callback == create_callback) {
247 instances.erase(pos);
248 return true;
249 }
250 }
251 }
252 return false;
253}
254
255ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
256 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
257 ABIInstances &instances = GetABIInstances();
258 if (idx < instances.size())
259 return instances[idx].create_callback;
260 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261}
262
263ABICreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264PluginManager::GetABICreateCallbackForPluginName(const ConstString &name) {
265 if (name) {
266 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
267 ABIInstances &instances = GetABIInstances();
Greg Claytonded470d2011-03-19 01:12:21 +0000268
Kate Stoneb9c1b512016-09-06 20:57:50 +0000269 ABIInstances::iterator pos, end = instances.end();
270 for (pos = instances.begin(); pos != end; ++pos) {
271 if (name == pos->name)
272 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000274 }
275 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276}
277
Pavel Labath13e37d42017-10-25 21:05:31 +0000278#pragma mark Architecture
279
280struct ArchitectureInstance {
281 ConstString name;
282 std::string description;
283 PluginManager::ArchitectureCreateInstance create_callback;
284};
285
286typedef std::vector<ArchitectureInstance> ArchitectureInstances;
287
288static std::mutex g_architecture_mutex;
289
290static ArchitectureInstances &GetArchitectureInstances() {
291 static ArchitectureInstances g_instances;
292 return g_instances;
293}
294
295void PluginManager::RegisterPlugin(const ConstString &name,
296 llvm::StringRef description,
297 ArchitectureCreateInstance create_callback) {
298 std::lock_guard<std::mutex> guard(g_architecture_mutex);
299 GetArchitectureInstances().push_back({name, description, create_callback});
300}
301
302void PluginManager::UnregisterPlugin(
303 ArchitectureCreateInstance create_callback) {
304 std::lock_guard<std::mutex> guard(g_architecture_mutex);
305 auto &instances = GetArchitectureInstances();
306
307 for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
308 if (pos->create_callback == create_callback) {
309 instances.erase(pos);
310 return;
311 }
312 }
313 llvm_unreachable("Plugin not found");
314}
315
316std::unique_ptr<Architecture>
317PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
318 std::lock_guard<std::mutex> guard(g_architecture_mutex);
319 for (const auto &instances : GetArchitectureInstances()) {
320 if (auto plugin_up = instances.create_callback(arch))
321 return plugin_up;
322 }
323 return nullptr;
324}
325
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326#pragma mark Disassembler
327
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328struct DisassemblerInstance {
329 DisassemblerInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330
Kate Stoneb9c1b512016-09-06 20:57:50 +0000331 ConstString name;
332 std::string description;
333 DisassemblerCreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000334};
335
336typedef std::vector<DisassemblerInstance> DisassemblerInstances;
337
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338static std::recursive_mutex &GetDisassemblerMutex() {
339 static std::recursive_mutex g_instances_mutex;
340 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341}
342
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343static DisassemblerInstances &GetDisassemblerInstances() {
344 static DisassemblerInstances g_instances;
345 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +0000346}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347
Kate Stoneb9c1b512016-09-06 20:57:50 +0000348bool PluginManager::RegisterPlugin(const ConstString &name,
349 const char *description,
350 DisassemblerCreateInstance create_callback) {
351 if (create_callback) {
352 DisassemblerInstance instance;
353 assert((bool)name);
354 instance.name = name;
355 if (description && description[0])
356 instance.description = description;
357 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000358 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359 GetDisassemblerInstances().push_back(instance);
360 return true;
361 }
362 return false;
363}
364
365bool PluginManager::UnregisterPlugin(
366 DisassemblerCreateInstance create_callback) {
367 if (create_callback) {
368 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
369 DisassemblerInstances &instances = GetDisassemblerInstances();
370
371 DisassemblerInstances::iterator pos, end = instances.end();
372 for (pos = instances.begin(); pos != end; ++pos) {
373 if (pos->create_callback == create_callback) {
374 instances.erase(pos);
375 return true;
376 }
377 }
378 }
379 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380}
381
382DisassemblerCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
384 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
385 DisassemblerInstances &instances = GetDisassemblerInstances();
386 if (idx < instances.size())
387 return instances[idx].create_callback;
388 return nullptr;
389}
390
391DisassemblerCreateInstance
392PluginManager::GetDisassemblerCreateCallbackForPluginName(
393 const ConstString &name) {
394 if (name) {
395 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
396 DisassemblerInstances &instances = GetDisassemblerInstances();
397
398 DisassemblerInstances::iterator pos, end = instances.end();
399 for (pos = instances.begin(); pos != end; ++pos) {
400 if (name == pos->name)
401 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000403 }
404 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405}
406
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407#pragma mark DynamicLoader
408
Kate Stoneb9c1b512016-09-06 20:57:50 +0000409struct DynamicLoaderInstance {
410 DynamicLoaderInstance()
411 : name(), description(), create_callback(nullptr),
412 debugger_init_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000413
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414 ConstString name;
415 std::string description;
416 DynamicLoaderCreateInstance create_callback;
417 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000418};
419
420typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
421
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422static std::recursive_mutex &GetDynamicLoaderMutex() {
423 static std::recursive_mutex g_instances_mutex;
424 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +0000425}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000426
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427static DynamicLoaderInstances &GetDynamicLoaderInstances() {
428 static DynamicLoaderInstances g_instances;
429 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000430}
431
Kate Stoneb9c1b512016-09-06 20:57:50 +0000432bool PluginManager::RegisterPlugin(
433 const ConstString &name, const char *description,
434 DynamicLoaderCreateInstance create_callback,
435 DebuggerInitializeCallback debugger_init_callback) {
436 if (create_callback) {
437 DynamicLoaderInstance instance;
438 assert((bool)name);
439 instance.name = name;
440 if (description && description[0])
441 instance.description = description;
442 instance.create_callback = create_callback;
443 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000444 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000445 GetDynamicLoaderInstances().push_back(instance);
446 }
447 return false;
448}
449
450bool PluginManager::UnregisterPlugin(
451 DynamicLoaderCreateInstance create_callback) {
452 if (create_callback) {
453 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
454 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
455
456 DynamicLoaderInstances::iterator pos, end = instances.end();
457 for (pos = instances.begin(); pos != end; ++pos) {
458 if (pos->create_callback == create_callback) {
459 instances.erase(pos);
460 return true;
461 }
462 }
463 }
464 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465}
466
467DynamicLoaderCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000468PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
469 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
470 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
471 if (idx < instances.size())
472 return instances[idx].create_callback;
473 return nullptr;
474}
475
476DynamicLoaderCreateInstance
477PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
478 const ConstString &name) {
479 if (name) {
480 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
481 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
482
483 DynamicLoaderInstances::iterator pos, end = instances.end();
484 for (pos = instances.begin(); pos != end; ++pos) {
485 if (name == pos->name)
486 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000488 }
489 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490}
491
Andrew MacPherson17220c12014-03-05 10:12:43 +0000492#pragma mark JITLoader
493
Kate Stoneb9c1b512016-09-06 20:57:50 +0000494struct JITLoaderInstance {
495 JITLoaderInstance()
496 : name(), description(), create_callback(nullptr),
497 debugger_init_callback(nullptr) {}
Andrew MacPherson17220c12014-03-05 10:12:43 +0000498
Kate Stoneb9c1b512016-09-06 20:57:50 +0000499 ConstString name;
500 std::string description;
501 JITLoaderCreateInstance create_callback;
502 DebuggerInitializeCallback debugger_init_callback;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000503};
504
505typedef std::vector<JITLoaderInstance> JITLoaderInstances;
506
Kate Stoneb9c1b512016-09-06 20:57:50 +0000507static std::recursive_mutex &GetJITLoaderMutex() {
508 static std::recursive_mutex g_instances_mutex;
509 return g_instances_mutex;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000510}
511
Kate Stoneb9c1b512016-09-06 20:57:50 +0000512static JITLoaderInstances &GetJITLoaderInstances() {
513 static JITLoaderInstances g_instances;
514 return g_instances;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000515}
516
Kate Stoneb9c1b512016-09-06 20:57:50 +0000517bool PluginManager::RegisterPlugin(
518 const ConstString &name, const char *description,
519 JITLoaderCreateInstance create_callback,
520 DebuggerInitializeCallback debugger_init_callback) {
521 if (create_callback) {
522 JITLoaderInstance instance;
523 assert((bool)name);
524 instance.name = name;
525 if (description && description[0])
526 instance.description = description;
527 instance.create_callback = create_callback;
528 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000529 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530 GetJITLoaderInstances().push_back(instance);
531 }
532 return false;
533}
534
535bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
536 if (create_callback) {
537 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
538 JITLoaderInstances &instances = GetJITLoaderInstances();
539
540 JITLoaderInstances::iterator pos, end = instances.end();
541 for (pos = instances.begin(); pos != end; ++pos) {
542 if (pos->create_callback == create_callback) {
543 instances.erase(pos);
544 return true;
545 }
546 }
547 }
548 return false;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000549}
550
551JITLoaderCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000552PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
553 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
554 JITLoaderInstances &instances = GetJITLoaderInstances();
555 if (idx < instances.size())
556 return instances[idx].create_callback;
557 return nullptr;
558}
559
560JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName(
561 const ConstString &name) {
562 if (name) {
563 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
564 JITLoaderInstances &instances = GetJITLoaderInstances();
565
566 JITLoaderInstances::iterator pos, end = instances.end();
567 for (pos = instances.begin(); pos != end; ++pos) {
568 if (name == pos->name)
569 return pos->create_callback;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000570 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000571 }
572 return nullptr;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000573}
574
Greg Claytonf03bbe22011-02-01 01:37:45 +0000575#pragma mark EmulateInstruction
576
Kate Stoneb9c1b512016-09-06 20:57:50 +0000577struct EmulateInstructionInstance {
578 EmulateInstructionInstance()
579 : name(), description(), create_callback(nullptr) {}
580
581 ConstString name;
582 std::string description;
583 EmulateInstructionCreateInstance create_callback;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000584};
585
586typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
587
Kate Stoneb9c1b512016-09-06 20:57:50 +0000588static std::recursive_mutex &GetEmulateInstructionMutex() {
589 static std::recursive_mutex g_instances_mutex;
590 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +0000591}
592
Kate Stoneb9c1b512016-09-06 20:57:50 +0000593static EmulateInstructionInstances &GetEmulateInstructionInstances() {
594 static EmulateInstructionInstances g_instances;
595 return g_instances;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000596}
597
Kate Stoneb9c1b512016-09-06 20:57:50 +0000598bool PluginManager::RegisterPlugin(
599 const ConstString &name, const char *description,
600 EmulateInstructionCreateInstance create_callback) {
601 if (create_callback) {
602 EmulateInstructionInstance instance;
603 assert((bool)name);
604 instance.name = name;
605 if (description && description[0])
606 instance.description = description;
607 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000608 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000609 GetEmulateInstructionInstances().push_back(instance);
610 }
611 return false;
612}
613
614bool PluginManager::UnregisterPlugin(
615 EmulateInstructionCreateInstance create_callback) {
616 if (create_callback) {
617 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
618 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
619
620 EmulateInstructionInstances::iterator pos, end = instances.end();
621 for (pos = instances.begin(); pos != end; ++pos) {
622 if (pos->create_callback == create_callback) {
623 instances.erase(pos);
624 return true;
625 }
626 }
627 }
628 return false;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000629}
630
631EmulateInstructionCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000632PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
633 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
634 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
635 if (idx < instances.size())
636 return instances[idx].create_callback;
637 return nullptr;
638}
639
640EmulateInstructionCreateInstance
641PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
642 const ConstString &name) {
643 if (name) {
644 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
645 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
646
647 EmulateInstructionInstances::iterator pos, end = instances.end();
648 for (pos = instances.begin(); pos != end; ++pos) {
649 if (name == pos->name)
650 return pos->create_callback;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000651 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000652 }
653 return nullptr;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000654}
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000655
Eugene Zelenko89183722016-03-11 21:55:47 +0000656#pragma mark OperatingSystem
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000657
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658struct OperatingSystemInstance {
659 OperatingSystemInstance()
660 : name(), description(), create_callback(nullptr),
661 debugger_init_callback(nullptr) {}
662
663 ConstString name;
664 std::string description;
665 OperatingSystemCreateInstance create_callback;
666 DebuggerInitializeCallback debugger_init_callback;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000667};
668
669typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
670
Kate Stoneb9c1b512016-09-06 20:57:50 +0000671static std::recursive_mutex &GetOperatingSystemMutex() {
672 static std::recursive_mutex g_instances_mutex;
673 return g_instances_mutex;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000674}
675
Kate Stoneb9c1b512016-09-06 20:57:50 +0000676static OperatingSystemInstances &GetOperatingSystemInstances() {
677 static OperatingSystemInstances g_instances;
678 return g_instances;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000679}
680
Kate Stoneb9c1b512016-09-06 20:57:50 +0000681bool PluginManager::RegisterPlugin(
682 const ConstString &name, const char *description,
683 OperatingSystemCreateInstance create_callback,
684 DebuggerInitializeCallback debugger_init_callback) {
685 if (create_callback) {
686 OperatingSystemInstance instance;
687 assert((bool)name);
688 instance.name = name;
689 if (description && description[0])
690 instance.description = description;
691 instance.create_callback = create_callback;
692 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000693 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000694 GetOperatingSystemInstances().push_back(instance);
695 }
696 return false;
697}
698
699bool PluginManager::UnregisterPlugin(
700 OperatingSystemCreateInstance create_callback) {
701 if (create_callback) {
702 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
703 OperatingSystemInstances &instances = GetOperatingSystemInstances();
704
705 OperatingSystemInstances::iterator pos, end = instances.end();
706 for (pos = instances.begin(); pos != end; ++pos) {
707 if (pos->create_callback == create_callback) {
708 instances.erase(pos);
709 return true;
710 }
711 }
712 }
713 return false;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000714}
715
716OperatingSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000717PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
718 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
719 OperatingSystemInstances &instances = GetOperatingSystemInstances();
720 if (idx < instances.size())
721 return instances[idx].create_callback;
722 return nullptr;
723}
724
725OperatingSystemCreateInstance
726PluginManager::GetOperatingSystemCreateCallbackForPluginName(
727 const ConstString &name) {
728 if (name) {
729 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
730 OperatingSystemInstances &instances = GetOperatingSystemInstances();
731
732 OperatingSystemInstances::iterator pos, end = instances.end();
733 for (pos = instances.begin(); pos != end; ++pos) {
734 if (name == pos->name)
735 return pos->create_callback;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000736 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000737 }
738 return nullptr;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000739}
Greg Claytonf03bbe22011-02-01 01:37:45 +0000740
Enrico Granata5f9d3102015-08-27 21:33:50 +0000741#pragma mark Language
742
Kate Stoneb9c1b512016-09-06 20:57:50 +0000743struct LanguageInstance {
744 LanguageInstance() : name(), description(), create_callback(nullptr) {}
745
746 ConstString name;
747 std::string description;
748 LanguageCreateInstance create_callback;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000749};
750
751typedef std::vector<LanguageInstance> LanguageInstances;
752
Kate Stoneb9c1b512016-09-06 20:57:50 +0000753static std::recursive_mutex &GetLanguageMutex() {
754 static std::recursive_mutex g_instances_mutex;
755 return g_instances_mutex;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000756}
757
Kate Stoneb9c1b512016-09-06 20:57:50 +0000758static LanguageInstances &GetLanguageInstances() {
759 static LanguageInstances g_instances;
760 return g_instances;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000761}
762
Kate Stoneb9c1b512016-09-06 20:57:50 +0000763bool PluginManager::RegisterPlugin(const ConstString &name,
764 const char *description,
765 LanguageCreateInstance create_callback) {
766 if (create_callback) {
767 LanguageInstance instance;
768 assert((bool)name);
769 instance.name = name;
770 if (description && description[0])
771 instance.description = description;
772 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000773 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000774 GetLanguageInstances().push_back(instance);
775 }
776 return false;
777}
778
779bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
780 if (create_callback) {
781 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
782 LanguageInstances &instances = GetLanguageInstances();
783
784 LanguageInstances::iterator pos, end = instances.end();
785 for (pos = instances.begin(); pos != end; ++pos) {
786 if (pos->create_callback == create_callback) {
787 instances.erase(pos);
788 return true;
789 }
790 }
791 }
792 return false;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000793}
794
795LanguageCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000796PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
797 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
798 LanguageInstances &instances = GetLanguageInstances();
799 if (idx < instances.size())
800 return instances[idx].create_callback;
801 return nullptr;
802}
803
804LanguageCreateInstance
805PluginManager::GetLanguageCreateCallbackForPluginName(const ConstString &name) {
806 if (name) {
807 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
808 LanguageInstances &instances = GetLanguageInstances();
809
810 LanguageInstances::iterator pos, end = instances.end();
811 for (pos = instances.begin(); pos != end; ++pos) {
812 if (name == pos->name)
813 return pos->create_callback;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000814 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000815 }
816 return nullptr;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000817}
818
Jim Ingham22777012010-09-23 02:01:19 +0000819#pragma mark LanguageRuntime
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000820
Kate Stoneb9c1b512016-09-06 20:57:50 +0000821struct LanguageRuntimeInstance {
822 LanguageRuntimeInstance() : name(), description(), create_callback(nullptr) {}
Jim Ingham22777012010-09-23 02:01:19 +0000823
Kate Stoneb9c1b512016-09-06 20:57:50 +0000824 ConstString name;
825 std::string description;
826 LanguageRuntimeCreateInstance create_callback;
827 LanguageRuntimeGetCommandObject command_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000828};
829
830typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
831
Kate Stoneb9c1b512016-09-06 20:57:50 +0000832static std::recursive_mutex &GetLanguageRuntimeMutex() {
833 static std::recursive_mutex g_instances_mutex;
834 return g_instances_mutex;
Jim Ingham22777012010-09-23 02:01:19 +0000835}
836
Kate Stoneb9c1b512016-09-06 20:57:50 +0000837static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
838 static LanguageRuntimeInstances g_instances;
839 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +0000840}
Jim Ingham22777012010-09-23 02:01:19 +0000841
Kate Stoneb9c1b512016-09-06 20:57:50 +0000842bool PluginManager::RegisterPlugin(
843 const ConstString &name, const char *description,
844 LanguageRuntimeCreateInstance create_callback,
845 LanguageRuntimeGetCommandObject command_callback) {
846 if (create_callback) {
847 LanguageRuntimeInstance instance;
848 assert((bool)name);
849 instance.name = name;
850 if (description && description[0])
851 instance.description = description;
852 instance.create_callback = create_callback;
853 instance.command_callback = command_callback;
854 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
855 GetLanguageRuntimeInstances().push_back(instance);
856 }
857 return false;
858}
859
860bool PluginManager::UnregisterPlugin(
861 LanguageRuntimeCreateInstance create_callback) {
862 if (create_callback) {
863 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
864 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
865
866 LanguageRuntimeInstances::iterator pos, end = instances.end();
867 for (pos = instances.begin(); pos != end; ++pos) {
868 if (pos->create_callback == create_callback) {
869 instances.erase(pos);
870 return true;
871 }
Jim Ingham22777012010-09-23 02:01:19 +0000872 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000873 }
874 return false;
Jim Ingham22777012010-09-23 02:01:19 +0000875}
876
877LanguageRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000878PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
879 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
880 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
881 if (idx < instances.size())
882 return instances[idx].create_callback;
883 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000884}
885
Colin Rileyc9c55a22015-05-04 18:39:38 +0000886LanguageRuntimeGetCommandObject
Kate Stoneb9c1b512016-09-06 20:57:50 +0000887PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
888 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
889 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
890 if (idx < instances.size())
891 return instances[idx].command_callback;
892 return nullptr;
Colin Rileyc9c55a22015-05-04 18:39:38 +0000893}
894
Jim Ingham22777012010-09-23 02:01:19 +0000895LanguageRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000896PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
897 const ConstString &name) {
898 if (name) {
899 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
900 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
901
902 LanguageRuntimeInstances::iterator pos, end = instances.end();
903 for (pos = instances.begin(); pos != end; ++pos) {
904 if (name == pos->name)
905 return pos->create_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000906 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000907 }
908 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000909}
910
Jason Molendaeef51062013-11-05 03:57:19 +0000911#pragma mark SystemRuntime
912
Kate Stoneb9c1b512016-09-06 20:57:50 +0000913struct SystemRuntimeInstance {
914 SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {}
Jason Molendaeef51062013-11-05 03:57:19 +0000915
Kate Stoneb9c1b512016-09-06 20:57:50 +0000916 ConstString name;
917 std::string description;
918 SystemRuntimeCreateInstance create_callback;
Jason Molendaeef51062013-11-05 03:57:19 +0000919};
920
921typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
922
Kate Stoneb9c1b512016-09-06 20:57:50 +0000923static std::recursive_mutex &GetSystemRuntimeMutex() {
924 static std::recursive_mutex g_instances_mutex;
925 return g_instances_mutex;
Jason Molendaeef51062013-11-05 03:57:19 +0000926}
927
Kate Stoneb9c1b512016-09-06 20:57:50 +0000928static SystemRuntimeInstances &GetSystemRuntimeInstances() {
929 static SystemRuntimeInstances g_instances;
930 return g_instances;
Jason Molendaeef51062013-11-05 03:57:19 +0000931}
932
Kate Stoneb9c1b512016-09-06 20:57:50 +0000933bool PluginManager::RegisterPlugin(
934 const ConstString &name, const char *description,
935 SystemRuntimeCreateInstance create_callback) {
936 if (create_callback) {
937 SystemRuntimeInstance instance;
938 assert((bool)name);
939 instance.name = name;
940 if (description && description[0])
941 instance.description = description;
942 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000943 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000944 GetSystemRuntimeInstances().push_back(instance);
945 }
946 return false;
947}
948
949bool PluginManager::UnregisterPlugin(
950 SystemRuntimeCreateInstance create_callback) {
951 if (create_callback) {
952 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
953 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
954
955 SystemRuntimeInstances::iterator pos, end = instances.end();
956 for (pos = instances.begin(); pos != end; ++pos) {
957 if (pos->create_callback == create_callback) {
958 instances.erase(pos);
959 return true;
960 }
961 }
962 }
963 return false;
Jason Molendaeef51062013-11-05 03:57:19 +0000964}
965
966SystemRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000967PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
968 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
969 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
970 if (idx < instances.size())
971 return instances[idx].create_callback;
972 return nullptr;
973}
974
975SystemRuntimeCreateInstance
976PluginManager::GetSystemRuntimeCreateCallbackForPluginName(
977 const ConstString &name) {
978 if (name) {
979 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
980 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
981
982 SystemRuntimeInstances::iterator pos, end = instances.end();
983 for (pos = instances.begin(); pos != end; ++pos) {
984 if (name == pos->name)
985 return pos->create_callback;
Jason Molendaeef51062013-11-05 03:57:19 +0000986 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000987 }
988 return nullptr;
Jason Molendaeef51062013-11-05 03:57:19 +0000989}
990
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000991#pragma mark ObjectFile
992
Kate Stoneb9c1b512016-09-06 20:57:50 +0000993struct ObjectFileInstance {
994 ObjectFileInstance()
995 : name(), description(), create_callback(nullptr),
996 create_memory_callback(nullptr), get_module_specifications(nullptr),
997 save_core(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000998
Kate Stoneb9c1b512016-09-06 20:57:50 +0000999 ConstString name;
1000 std::string description;
1001 ObjectFileCreateInstance create_callback;
1002 ObjectFileCreateMemoryInstance create_memory_callback;
1003 ObjectFileGetModuleSpecifications get_module_specifications;
1004 ObjectFileSaveCore save_core;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001005};
1006
1007typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1008
Kate Stoneb9c1b512016-09-06 20:57:50 +00001009static std::recursive_mutex &GetObjectFileMutex() {
1010 static std::recursive_mutex g_instances_mutex;
1011 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001012}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013
Kate Stoneb9c1b512016-09-06 20:57:50 +00001014static ObjectFileInstances &GetObjectFileInstances() {
1015 static ObjectFileInstances g_instances;
1016 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017}
1018
Kate Stoneb9c1b512016-09-06 20:57:50 +00001019bool PluginManager::RegisterPlugin(
1020 const ConstString &name, const char *description,
1021 ObjectFileCreateInstance create_callback,
1022 ObjectFileCreateMemoryInstance create_memory_callback,
1023 ObjectFileGetModuleSpecifications get_module_specifications,
1024 ObjectFileSaveCore save_core) {
1025 if (create_callback) {
1026 ObjectFileInstance instance;
1027 assert((bool)name);
1028 instance.name = name;
1029 if (description && description[0])
1030 instance.description = description;
1031 instance.create_callback = create_callback;
1032 instance.create_memory_callback = create_memory_callback;
1033 instance.save_core = save_core;
1034 instance.get_module_specifications = get_module_specifications;
1035 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1036 GetObjectFileInstances().push_back(instance);
1037 }
1038 return false;
1039}
1040
1041bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
1042 if (create_callback) {
1043 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1044 ObjectFileInstances &instances = GetObjectFileInstances();
1045
1046 ObjectFileInstances::iterator pos, end = instances.end();
1047 for (pos = instances.begin(); pos != end; ++pos) {
1048 if (pos->create_callback == create_callback) {
1049 instances.erase(pos);
1050 return true;
1051 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001053 }
1054 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001055}
1056
1057ObjectFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001058PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
1059 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1060 ObjectFileInstances &instances = GetObjectFileInstances();
1061 if (idx < instances.size())
1062 return instances[idx].create_callback;
1063 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001064}
Greg Claytonab65b342011-04-13 22:47:15 +00001065
Greg Claytonc9660542012-02-05 02:38:54 +00001066ObjectFileCreateMemoryInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001067PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
1068 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1069 ObjectFileInstances &instances = GetObjectFileInstances();
1070 if (idx < instances.size())
1071 return instances[idx].create_memory_callback;
1072 return nullptr;
Greg Claytonc9660542012-02-05 02:38:54 +00001073}
1074
Greg Claytonf4d6de62013-04-24 22:29:28 +00001075ObjectFileGetModuleSpecifications
Kate Stoneb9c1b512016-09-06 20:57:50 +00001076PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
1077 uint32_t idx) {
1078 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1079 ObjectFileInstances &instances = GetObjectFileInstances();
1080 if (idx < instances.size())
1081 return instances[idx].get_module_specifications;
1082 return nullptr;
Greg Claytonf4d6de62013-04-24 22:29:28 +00001083}
1084
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001085ObjectFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001086PluginManager::GetObjectFileCreateCallbackForPluginName(
1087 const ConstString &name) {
1088 if (name) {
1089 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1090 ObjectFileInstances &instances = GetObjectFileInstances();
1091
1092 ObjectFileInstances::iterator pos, end = instances.end();
1093 for (pos = instances.begin(); pos != end; ++pos) {
1094 if (name == pos->name)
1095 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001096 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001097 }
1098 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099}
1100
Greg Claytonc9660542012-02-05 02:38:54 +00001101ObjectFileCreateMemoryInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001102PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
1103 const ConstString &name) {
1104 if (name) {
1105 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1106 ObjectFileInstances &instances = GetObjectFileInstances();
1107
1108 ObjectFileInstances::iterator pos, end = instances.end();
1109 for (pos = instances.begin(); pos != end; ++pos) {
1110 if (name == pos->name)
1111 return pos->create_memory_callback;
Greg Claytonc9660542012-02-05 02:38:54 +00001112 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001113 }
1114 return nullptr;
Greg Claytonc9660542012-02-05 02:38:54 +00001115}
1116
Zachary Turner97206d52017-05-12 04:51:55 +00001117Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
1118 const FileSpec &outfile) {
1119 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1121 ObjectFileInstances &instances = GetObjectFileInstances();
1122
1123 ObjectFileInstances::iterator pos, end = instances.end();
1124 for (pos = instances.begin(); pos != end; ++pos) {
1125 if (pos->save_core && pos->save_core(process_sp, outfile, error))
1126 return error;
1127 }
1128 error.SetErrorString(
1129 "no ObjectFile plugins were able to save a core for this process");
1130 return error;
Greg Claytona2715cf2014-06-13 00:54:12 +00001131}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001132
1133#pragma mark ObjectContainer
1134
Kate Stoneb9c1b512016-09-06 20:57:50 +00001135struct ObjectContainerInstance {
1136 ObjectContainerInstance()
1137 : name(), description(), create_callback(nullptr),
1138 get_module_specifications(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001139
Kate Stoneb9c1b512016-09-06 20:57:50 +00001140 ConstString name;
1141 std::string description;
1142 ObjectContainerCreateInstance create_callback;
1143 ObjectFileGetModuleSpecifications get_module_specifications;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001144};
1145
1146typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1147
Kate Stoneb9c1b512016-09-06 20:57:50 +00001148static std::recursive_mutex &GetObjectContainerMutex() {
1149 static std::recursive_mutex g_instances_mutex;
1150 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001151}
1152
Kate Stoneb9c1b512016-09-06 20:57:50 +00001153static ObjectContainerInstances &GetObjectContainerInstances() {
1154 static ObjectContainerInstances g_instances;
1155 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +00001156}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157
Kate Stoneb9c1b512016-09-06 20:57:50 +00001158bool PluginManager::RegisterPlugin(
1159 const ConstString &name, const char *description,
1160 ObjectContainerCreateInstance create_callback,
1161 ObjectFileGetModuleSpecifications get_module_specifications) {
1162 if (create_callback) {
1163 ObjectContainerInstance instance;
1164 assert((bool)name);
1165 instance.name = name;
1166 if (description && description[0])
1167 instance.description = description;
1168 instance.create_callback = create_callback;
1169 instance.get_module_specifications = get_module_specifications;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001170 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001171 GetObjectContainerInstances().push_back(instance);
1172 }
1173 return false;
1174}
1175
1176bool PluginManager::UnregisterPlugin(
1177 ObjectContainerCreateInstance create_callback) {
1178 if (create_callback) {
1179 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1180 ObjectContainerInstances &instances = GetObjectContainerInstances();
1181
1182 ObjectContainerInstances::iterator pos, end = instances.end();
1183 for (pos = instances.begin(); pos != end; ++pos) {
1184 if (pos->create_callback == create_callback) {
1185 instances.erase(pos);
1186 return true;
1187 }
1188 }
1189 }
1190 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191}
Greg Claytonab65b342011-04-13 22:47:15 +00001192
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001193ObjectContainerCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001194PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
1195 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1196 ObjectContainerInstances &instances = GetObjectContainerInstances();
1197 if (idx < instances.size())
1198 return instances[idx].create_callback;
1199 return nullptr;
1200}
1201
1202ObjectContainerCreateInstance
1203PluginManager::GetObjectContainerCreateCallbackForPluginName(
1204 const ConstString &name) {
1205 if (name) {
1206 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1207 ObjectContainerInstances &instances = GetObjectContainerInstances();
1208
1209 ObjectContainerInstances::iterator pos, end = instances.end();
1210 for (pos = instances.begin(); pos != end; ++pos) {
1211 if (name == pos->name)
1212 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001213 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001214 }
1215 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001216}
1217
Greg Claytonf4d6de62013-04-24 22:29:28 +00001218ObjectFileGetModuleSpecifications
Kate Stoneb9c1b512016-09-06 20:57:50 +00001219PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
1220 uint32_t idx) {
1221 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1222 ObjectContainerInstances &instances = GetObjectContainerInstances();
1223 if (idx < instances.size())
1224 return instances[idx].get_module_specifications;
1225 return nullptr;
Greg Claytonf4d6de62013-04-24 22:29:28 +00001226}
1227
Greg Claytone996fd32011-03-08 22:40:15 +00001228#pragma mark Platform
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001229
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230struct PlatformInstance {
1231 PlatformInstance()
1232 : name(), description(), create_callback(nullptr),
1233 debugger_init_callback(nullptr) {}
1234
1235 ConstString name;
1236 std::string description;
1237 PlatformCreateInstance create_callback;
1238 DebuggerInitializeCallback debugger_init_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001239};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001240
Greg Claytone996fd32011-03-08 22:40:15 +00001241typedef std::vector<PlatformInstance> PlatformInstances;
1242
Kate Stoneb9c1b512016-09-06 20:57:50 +00001243static std::recursive_mutex &GetPlatformInstancesMutex() {
1244 static std::recursive_mutex g_platform_instances_mutex;
1245 return g_platform_instances_mutex;
Greg Claytone996fd32011-03-08 22:40:15 +00001246}
1247
Kate Stoneb9c1b512016-09-06 20:57:50 +00001248static PlatformInstances &GetPlatformInstances() {
1249 static PlatformInstances g_platform_instances;
1250 return g_platform_instances;
Greg Claytonded470d2011-03-19 01:12:21 +00001251}
Greg Claytone996fd32011-03-08 22:40:15 +00001252
Kate Stoneb9c1b512016-09-06 20:57:50 +00001253bool PluginManager::RegisterPlugin(
1254 const ConstString &name, const char *description,
1255 PlatformCreateInstance create_callback,
1256 DebuggerInitializeCallback debugger_init_callback) {
1257 if (create_callback) {
1258 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001259
Kate Stoneb9c1b512016-09-06 20:57:50 +00001260 PlatformInstance instance;
1261 assert((bool)name);
1262 instance.name = name;
1263 if (description && description[0])
1264 instance.description = description;
1265 instance.create_callback = create_callback;
1266 instance.debugger_init_callback = debugger_init_callback;
1267 GetPlatformInstances().push_back(instance);
1268 return true;
1269 }
1270 return false;
1271}
1272
1273const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
1274 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1275 PlatformInstances &instances = GetPlatformInstances();
1276 if (idx < instances.size())
1277 return instances[idx].name.GetCString();
1278 return nullptr;
1279}
1280
1281const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
1282 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1283 PlatformInstances &instances = GetPlatformInstances();
1284 if (idx < instances.size())
1285 return instances[idx].description.c_str();
1286 return nullptr;
1287}
1288
1289bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
1290 if (create_callback) {
1291 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1292 PlatformInstances &instances = GetPlatformInstances();
1293
1294 PlatformInstances::iterator pos, end = instances.end();
1295 for (pos = instances.begin(); pos != end; ++pos) {
1296 if (pos->create_callback == create_callback) {
1297 instances.erase(pos);
Greg Claytonded470d2011-03-19 01:12:21 +00001298 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001299 }
Greg Claytone996fd32011-03-08 22:40:15 +00001300 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001301 }
1302 return false;
Greg Claytone996fd32011-03-08 22:40:15 +00001303}
1304
1305PlatformCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001306PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
1307 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1308 PlatformInstances &instances = GetPlatformInstances();
1309 if (idx < instances.size())
1310 return instances[idx].create_callback;
1311 return nullptr;
Greg Claytone996fd32011-03-08 22:40:15 +00001312}
1313
1314PlatformCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001315PluginManager::GetPlatformCreateCallbackForPluginName(const ConstString &name) {
1316 if (name) {
1317 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1318 PlatformInstances &instances = GetPlatformInstances();
Greg Claytonded470d2011-03-19 01:12:21 +00001319
Kate Stoneb9c1b512016-09-06 20:57:50 +00001320 PlatformInstances::iterator pos, end = instances.end();
1321 for (pos = instances.begin(); pos != end; ++pos) {
1322 if (name == pos->name)
1323 return pos->create_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001324 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001325 }
1326 return nullptr;
Greg Claytone996fd32011-03-08 22:40:15 +00001327}
1328
Zachary Turner4aa87532016-11-17 01:37:42 +00001329size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001330 StringList &matches) {
Zachary Turner4aa87532016-11-17 01:37:42 +00001331 if (name.empty())
1332 return matches.GetSize();
Greg Claytonab65b342011-04-13 22:47:15 +00001333
Zachary Turner4aa87532016-11-17 01:37:42 +00001334 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1335 PlatformInstances &instances = GetPlatformInstances();
1336 llvm::StringRef name_sref(name);
1337
1338 PlatformInstances::iterator pos, end = instances.end();
1339 for (pos = instances.begin(); pos != end; ++pos) {
1340 llvm::StringRef plugin_name(pos->name.GetCString());
1341 if (plugin_name.startswith(name_sref))
1342 matches.AppendString(plugin_name.data());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001343 }
1344 return matches.GetSize();
Greg Claytonab65b342011-04-13 22:47:15 +00001345}
Eugene Zelenko89183722016-03-11 21:55:47 +00001346
Greg Claytone996fd32011-03-08 22:40:15 +00001347#pragma mark Process
1348
Kate Stoneb9c1b512016-09-06 20:57:50 +00001349struct ProcessInstance {
1350 ProcessInstance()
1351 : name(), description(), create_callback(nullptr),
1352 debugger_init_callback(nullptr) {}
1353
1354 ConstString name;
1355 std::string description;
1356 ProcessCreateInstance create_callback;
1357 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001358};
1359
1360typedef std::vector<ProcessInstance> ProcessInstances;
1361
Kate Stoneb9c1b512016-09-06 20:57:50 +00001362static std::recursive_mutex &GetProcessMutex() {
1363 static std::recursive_mutex g_instances_mutex;
1364 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001365}
1366
Kate Stoneb9c1b512016-09-06 20:57:50 +00001367static ProcessInstances &GetProcessInstances() {
1368 static ProcessInstances g_instances;
1369 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001370}
1371
Kate Stoneb9c1b512016-09-06 20:57:50 +00001372bool PluginManager::RegisterPlugin(
1373 const ConstString &name, const char *description,
1374 ProcessCreateInstance create_callback,
1375 DebuggerInitializeCallback debugger_init_callback) {
1376 if (create_callback) {
1377 ProcessInstance instance;
1378 assert((bool)name);
1379 instance.name = name;
1380 if (description && description[0])
1381 instance.description = description;
1382 instance.create_callback = create_callback;
1383 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001384 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001385 GetProcessInstances().push_back(instance);
1386 }
1387 return false;
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001388}
1389
Kate Stoneb9c1b512016-09-06 20:57:50 +00001390const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
1391 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1392 ProcessInstances &instances = GetProcessInstances();
1393 if (idx < instances.size())
1394 return instances[idx].name.GetCString();
1395 return nullptr;
1396}
1397
1398const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
1399 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1400 ProcessInstances &instances = GetProcessInstances();
1401 if (idx < instances.size())
1402 return instances[idx].description.c_str();
1403 return nullptr;
1404}
1405
1406bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
1407 if (create_callback) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001408 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001409 ProcessInstances &instances = GetProcessInstances();
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001410
Kate Stoneb9c1b512016-09-06 20:57:50 +00001411 ProcessInstances::iterator pos, end = instances.end();
1412 for (pos = instances.begin(); pos != end; ++pos) {
1413 if (pos->create_callback == create_callback) {
1414 instances.erase(pos);
1415 return true;
1416 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001417 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001418 }
1419 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001420}
1421
1422ProcessCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001423PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
1424 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1425 ProcessInstances &instances = GetProcessInstances();
1426 if (idx < instances.size())
1427 return instances[idx].create_callback;
1428 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001429}
1430
1431ProcessCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001432PluginManager::GetProcessCreateCallbackForPluginName(const ConstString &name) {
1433 if (name) {
1434 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1435 ProcessInstances &instances = GetProcessInstances();
1436
1437 ProcessInstances::iterator pos, end = instances.end();
1438 for (pos = instances.begin(); pos != end; ++pos) {
1439 if (name == pos->name)
1440 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001441 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001442 }
1443 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001444}
1445
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001446#pragma mark ScriptInterpreter
1447
Kate Stoneb9c1b512016-09-06 20:57:50 +00001448struct ScriptInterpreterInstance {
1449 ScriptInterpreterInstance()
1450 : name(), language(lldb::eScriptLanguageNone), description(),
1451 create_callback(nullptr) {}
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001452
Kate Stoneb9c1b512016-09-06 20:57:50 +00001453 ConstString name;
1454 lldb::ScriptLanguage language;
1455 std::string description;
1456 ScriptInterpreterCreateInstance create_callback;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001457};
1458
1459typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
1460
Kate Stoneb9c1b512016-09-06 20:57:50 +00001461static std::recursive_mutex &GetScriptInterpreterMutex() {
1462 static std::recursive_mutex g_instances_mutex;
1463 return g_instances_mutex;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001464}
1465
Kate Stoneb9c1b512016-09-06 20:57:50 +00001466static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
1467 static ScriptInterpreterInstances g_instances;
1468 return g_instances;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001469}
1470
Kate Stoneb9c1b512016-09-06 20:57:50 +00001471bool PluginManager::RegisterPlugin(
1472 const ConstString &name, const char *description,
1473 lldb::ScriptLanguage script_language,
1474 ScriptInterpreterCreateInstance create_callback) {
1475 if (!create_callback)
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001476 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001477 ScriptInterpreterInstance instance;
1478 assert((bool)name);
1479 instance.name = name;
1480 if (description && description[0])
1481 instance.description = description;
1482 instance.create_callback = create_callback;
1483 instance.language = script_language;
1484 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1485 GetScriptInterpreterInstances().push_back(instance);
1486 return false;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001487}
1488
Kate Stoneb9c1b512016-09-06 20:57:50 +00001489bool PluginManager::UnregisterPlugin(
1490 ScriptInterpreterCreateInstance create_callback) {
1491 if (!create_callback)
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001492 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001493 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1494 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1495
1496 ScriptInterpreterInstances::iterator pos, end = instances.end();
1497 for (pos = instances.begin(); pos != end; ++pos) {
1498 if (pos->create_callback != create_callback)
1499 continue;
1500
1501 instances.erase(pos);
1502 return true;
1503 }
1504 return false;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001505}
1506
1507ScriptInterpreterCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001508PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
1509 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1510 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1511 if (idx < instances.size())
1512 return instances[idx].create_callback;
1513 return nullptr;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001514}
1515
Kate Stoneb9c1b512016-09-06 20:57:50 +00001516lldb::ScriptInterpreterSP PluginManager::GetScriptInterpreterForLanguage(
1517 lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter) {
1518 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1519 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001520
Kate Stoneb9c1b512016-09-06 20:57:50 +00001521 ScriptInterpreterInstances::iterator pos, end = instances.end();
1522 ScriptInterpreterCreateInstance none_instance = nullptr;
1523 for (pos = instances.begin(); pos != end; ++pos) {
1524 if (pos->language == lldb::eScriptLanguageNone)
1525 none_instance = pos->create_callback;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001526
Kate Stoneb9c1b512016-09-06 20:57:50 +00001527 if (script_lang == pos->language)
1528 return pos->create_callback(interpreter);
1529 }
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001530
Kate Stoneb9c1b512016-09-06 20:57:50 +00001531 // If we didn't find one, return the ScriptInterpreter for the null language.
1532 assert(none_instance != nullptr);
1533 return none_instance(interpreter);
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001534}
1535
Todd Fiala75930012016-08-19 04:21:48 +00001536#pragma mark -
1537#pragma mark StructuredDataPlugin
1538
1539// -----------------------------------------------------------------------------
1540// StructuredDataPlugin
1541// -----------------------------------------------------------------------------
1542
Kate Stoneb9c1b512016-09-06 20:57:50 +00001543struct StructuredDataPluginInstance {
1544 StructuredDataPluginInstance()
1545 : name(), description(), create_callback(nullptr),
1546 debugger_init_callback(nullptr), filter_callback(nullptr) {}
Todd Fiala75930012016-08-19 04:21:48 +00001547
Kate Stoneb9c1b512016-09-06 20:57:50 +00001548 ConstString name;
1549 std::string description;
1550 StructuredDataPluginCreateInstance create_callback;
1551 DebuggerInitializeCallback debugger_init_callback;
1552 StructuredDataFilterLaunchInfo filter_callback;
Todd Fiala75930012016-08-19 04:21:48 +00001553};
1554
1555typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;
1556
Kate Stoneb9c1b512016-09-06 20:57:50 +00001557static std::recursive_mutex &GetStructuredDataPluginMutex() {
1558 static std::recursive_mutex g_instances_mutex;
1559 return g_instances_mutex;
Todd Fiala75930012016-08-19 04:21:48 +00001560}
1561
Kate Stoneb9c1b512016-09-06 20:57:50 +00001562static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
1563 static StructuredDataPluginInstances g_instances;
1564 return g_instances;
Todd Fiala75930012016-08-19 04:21:48 +00001565}
1566
Kate Stoneb9c1b512016-09-06 20:57:50 +00001567bool PluginManager::RegisterPlugin(
1568 const ConstString &name, const char *description,
1569 StructuredDataPluginCreateInstance create_callback,
1570 DebuggerInitializeCallback debugger_init_callback,
1571 StructuredDataFilterLaunchInfo filter_callback) {
1572 if (create_callback) {
1573 StructuredDataPluginInstance instance;
1574 assert((bool)name);
1575 instance.name = name;
1576 if (description && description[0])
1577 instance.description = description;
1578 instance.create_callback = create_callback;
1579 instance.debugger_init_callback = debugger_init_callback;
1580 instance.filter_callback = filter_callback;
1581 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1582 GetStructuredDataPluginInstances().push_back(instance);
1583 }
1584 return false;
Todd Fiala75930012016-08-19 04:21:48 +00001585}
1586
Kate Stoneb9c1b512016-09-06 20:57:50 +00001587bool PluginManager::UnregisterPlugin(
1588 StructuredDataPluginCreateInstance create_callback) {
1589 if (create_callback) {
Todd Fiala75930012016-08-19 04:21:48 +00001590 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1591 StructuredDataPluginInstances &instances =
1592 GetStructuredDataPluginInstances();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001593
1594 StructuredDataPluginInstances::iterator pos, end = instances.end();
1595 for (pos = instances.begin(); pos != end; ++pos) {
1596 if (pos->create_callback == create_callback) {
1597 instances.erase(pos);
1598 return true;
1599 }
1600 }
1601 }
1602 return false;
1603}
1604
1605StructuredDataPluginCreateInstance
1606PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
1607 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1608 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
1609 if (idx < instances.size())
1610 return instances[idx].create_callback;
1611 return nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00001612}
1613
1614StructuredDataPluginCreateInstance
1615PluginManager::GetStructuredDataPluginCreateCallbackForPluginName(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001616 const ConstString &name) {
1617 if (name) {
Todd Fiala75930012016-08-19 04:21:48 +00001618 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1619 StructuredDataPluginInstances &instances =
1620 GetStructuredDataPluginInstances();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001621
1622 StructuredDataPluginInstances::iterator pos, end = instances.end();
1623 for (pos = instances.begin(); pos != end; ++pos) {
1624 if (name == pos->name)
1625 return pos->create_callback;
Todd Fiala75930012016-08-19 04:21:48 +00001626 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001627 }
1628 return nullptr;
1629}
1630
1631StructuredDataFilterLaunchInfo
1632PluginManager::GetStructuredDataFilterCallbackAtIndex(
1633 uint32_t idx, bool &iteration_complete) {
1634 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1635 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
1636 if (idx < instances.size()) {
1637 iteration_complete = false;
1638 return instances[idx].filter_callback;
1639 } else {
1640 iteration_complete = true;
1641 }
1642 return nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00001643}
1644
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001645#pragma mark SymbolFile
1646
Kate Stoneb9c1b512016-09-06 20:57:50 +00001647struct SymbolFileInstance {
1648 SymbolFileInstance()
1649 : name(), description(), create_callback(nullptr),
1650 debugger_init_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651
Kate Stoneb9c1b512016-09-06 20:57:50 +00001652 ConstString name;
1653 std::string description;
1654 SymbolFileCreateInstance create_callback;
1655 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001656};
1657
1658typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1659
Kate Stoneb9c1b512016-09-06 20:57:50 +00001660static std::recursive_mutex &GetSymbolFileMutex() {
1661 static std::recursive_mutex g_instances_mutex;
1662 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001663}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001664
Kate Stoneb9c1b512016-09-06 20:57:50 +00001665static SymbolFileInstances &GetSymbolFileInstances() {
1666 static SymbolFileInstances g_instances;
1667 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001668}
1669
Kate Stoneb9c1b512016-09-06 20:57:50 +00001670bool PluginManager::RegisterPlugin(
1671 const ConstString &name, const char *description,
1672 SymbolFileCreateInstance create_callback,
1673 DebuggerInitializeCallback debugger_init_callback) {
1674 if (create_callback) {
1675 SymbolFileInstance instance;
1676 assert((bool)name);
1677 instance.name = name;
1678 if (description && description[0])
1679 instance.description = description;
1680 instance.create_callback = create_callback;
1681 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001682 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001683 GetSymbolFileInstances().push_back(instance);
1684 }
1685 return false;
1686}
1687
1688bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
1689 if (create_callback) {
1690 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1691 SymbolFileInstances &instances = GetSymbolFileInstances();
1692
1693 SymbolFileInstances::iterator pos, end = instances.end();
1694 for (pos = instances.begin(); pos != end; ++pos) {
1695 if (pos->create_callback == create_callback) {
1696 instances.erase(pos);
1697 return true;
1698 }
1699 }
1700 }
1701 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001702}
Greg Claytonab65b342011-04-13 22:47:15 +00001703
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001704SymbolFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001705PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1706 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1707 SymbolFileInstances &instances = GetSymbolFileInstances();
1708 if (idx < instances.size())
1709 return instances[idx].create_callback;
1710 return nullptr;
1711}
1712
1713SymbolFileCreateInstance
1714PluginManager::GetSymbolFileCreateCallbackForPluginName(
1715 const ConstString &name) {
1716 if (name) {
1717 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1718 SymbolFileInstances &instances = GetSymbolFileInstances();
1719
1720 SymbolFileInstances::iterator pos, end = instances.end();
1721 for (pos = instances.begin(); pos != end; ++pos) {
1722 if (name == pos->name)
1723 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001724 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001725 }
1726 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001727}
1728
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001729#pragma mark SymbolVendor
1730
Kate Stoneb9c1b512016-09-06 20:57:50 +00001731struct SymbolVendorInstance {
1732 SymbolVendorInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001733
Kate Stoneb9c1b512016-09-06 20:57:50 +00001734 ConstString name;
1735 std::string description;
1736 SymbolVendorCreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001737};
1738
1739typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1740
Kate Stoneb9c1b512016-09-06 20:57:50 +00001741static std::recursive_mutex &GetSymbolVendorMutex() {
1742 static std::recursive_mutex g_instances_mutex;
1743 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001744}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001745
Kate Stoneb9c1b512016-09-06 20:57:50 +00001746static SymbolVendorInstances &GetSymbolVendorInstances() {
1747 static SymbolVendorInstances g_instances;
1748 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001749}
1750
Kate Stoneb9c1b512016-09-06 20:57:50 +00001751bool PluginManager::RegisterPlugin(const ConstString &name,
1752 const char *description,
1753 SymbolVendorCreateInstance create_callback) {
1754 if (create_callback) {
1755 SymbolVendorInstance instance;
1756 assert((bool)name);
1757 instance.name = name;
1758 if (description && description[0])
1759 instance.description = description;
1760 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001761 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001762 GetSymbolVendorInstances().push_back(instance);
1763 }
1764 return false;
1765}
1766
1767bool PluginManager::UnregisterPlugin(
1768 SymbolVendorCreateInstance create_callback) {
1769 if (create_callback) {
1770 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1771 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1772
1773 SymbolVendorInstances::iterator pos, end = instances.end();
1774 for (pos = instances.begin(); pos != end; ++pos) {
1775 if (pos->create_callback == create_callback) {
1776 instances.erase(pos);
1777 return true;
1778 }
1779 }
1780 }
1781 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001782}
1783
1784SymbolVendorCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001785PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1786 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1787 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1788 if (idx < instances.size())
1789 return instances[idx].create_callback;
1790 return nullptr;
1791}
1792
1793SymbolVendorCreateInstance
1794PluginManager::GetSymbolVendorCreateCallbackForPluginName(
1795 const ConstString &name) {
1796 if (name) {
1797 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1798 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1799
1800 SymbolVendorInstances::iterator pos, end = instances.end();
1801 for (pos = instances.begin(); pos != end; ++pos) {
1802 if (name == pos->name)
1803 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001804 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001805 }
1806 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001807}
1808
Greg Clayton7be25422011-04-25 21:14:26 +00001809#pragma mark UnwindAssembly
Jason Molendafbcb7f22010-09-10 07:49:16 +00001810
Kate Stoneb9c1b512016-09-06 20:57:50 +00001811struct UnwindAssemblyInstance {
1812 UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001813
Kate Stoneb9c1b512016-09-06 20:57:50 +00001814 ConstString name;
1815 std::string description;
1816 UnwindAssemblyCreateInstance create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001817};
1818
Greg Clayton7be25422011-04-25 21:14:26 +00001819typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001820
Kate Stoneb9c1b512016-09-06 20:57:50 +00001821static std::recursive_mutex &GetUnwindAssemblyMutex() {
1822 static std::recursive_mutex g_instances_mutex;
1823 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001824}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001825
Kate Stoneb9c1b512016-09-06 20:57:50 +00001826static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1827 static UnwindAssemblyInstances g_instances;
1828 return g_instances;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001829}
1830
Kate Stoneb9c1b512016-09-06 20:57:50 +00001831bool PluginManager::RegisterPlugin(
1832 const ConstString &name, const char *description,
1833 UnwindAssemblyCreateInstance create_callback) {
1834 if (create_callback) {
1835 UnwindAssemblyInstance instance;
1836 assert((bool)name);
1837 instance.name = name;
1838 if (description && description[0])
1839 instance.description = description;
1840 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001841 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001842 GetUnwindAssemblyInstances().push_back(instance);
1843 }
1844 return false;
1845}
1846
1847bool PluginManager::UnregisterPlugin(
1848 UnwindAssemblyCreateInstance create_callback) {
1849 if (create_callback) {
1850 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1851 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1852
1853 UnwindAssemblyInstances::iterator pos, end = instances.end();
1854 for (pos = instances.begin(); pos != end; ++pos) {
1855 if (pos->create_callback == create_callback) {
1856 instances.erase(pos);
1857 return true;
1858 }
1859 }
1860 }
1861 return false;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001862}
1863
Greg Clayton7be25422011-04-25 21:14:26 +00001864UnwindAssemblyCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001865PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1866 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1867 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1868 if (idx < instances.size())
1869 return instances[idx].create_callback;
1870 return nullptr;
1871}
1872
1873UnwindAssemblyCreateInstance
1874PluginManager::GetUnwindAssemblyCreateCallbackForPluginName(
1875 const ConstString &name) {
1876 if (name) {
1877 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1878 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1879
1880 UnwindAssemblyInstances::iterator pos, end = instances.end();
1881 for (pos = instances.begin(); pos != end; ++pos) {
1882 if (name == pos->name)
1883 return pos->create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001884 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001885 }
1886 return nullptr;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001887}
1888
Kuba Breckabeed8212014-09-04 01:03:18 +00001889#pragma mark MemoryHistory
1890
Kate Stoneb9c1b512016-09-06 20:57:50 +00001891struct MemoryHistoryInstance {
1892 MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {}
1893
1894 ConstString name;
1895 std::string description;
1896 MemoryHistoryCreateInstance create_callback;
Kuba Breckabeed8212014-09-04 01:03:18 +00001897};
1898
1899typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
1900
Kate Stoneb9c1b512016-09-06 20:57:50 +00001901static std::recursive_mutex &GetMemoryHistoryMutex() {
1902 static std::recursive_mutex g_instances_mutex;
1903 return g_instances_mutex;
Kuba Breckabeed8212014-09-04 01:03:18 +00001904}
1905
Kate Stoneb9c1b512016-09-06 20:57:50 +00001906static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1907 static MemoryHistoryInstances g_instances;
1908 return g_instances;
Kuba Breckabeed8212014-09-04 01:03:18 +00001909}
1910
Kate Stoneb9c1b512016-09-06 20:57:50 +00001911bool PluginManager::RegisterPlugin(
1912 const ConstString &name, const char *description,
1913 MemoryHistoryCreateInstance create_callback) {
1914 if (create_callback) {
1915 MemoryHistoryInstance instance;
1916 assert((bool)name);
1917 instance.name = name;
1918 if (description && description[0])
1919 instance.description = description;
1920 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001921 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001922 GetMemoryHistoryInstances().push_back(instance);
1923 }
1924 return false;
1925}
1926
1927bool PluginManager::UnregisterPlugin(
1928 MemoryHistoryCreateInstance create_callback) {
1929 if (create_callback) {
1930 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1931 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1932
1933 MemoryHistoryInstances::iterator pos, end = instances.end();
1934 for (pos = instances.begin(); pos != end; ++pos) {
1935 if (pos->create_callback == create_callback) {
1936 instances.erase(pos);
1937 return true;
1938 }
1939 }
1940 }
1941 return false;
Kuba Breckabeed8212014-09-04 01:03:18 +00001942}
1943
Kuba Breckabeed8212014-09-04 01:03:18 +00001944MemoryHistoryCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001945PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1946 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1947 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1948 if (idx < instances.size())
1949 return instances[idx].create_callback;
1950 return nullptr;
1951}
1952
1953MemoryHistoryCreateInstance
1954PluginManager::GetMemoryHistoryCreateCallbackForPluginName(
1955 const ConstString &name) {
1956 if (name) {
1957 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1958 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1959
1960 MemoryHistoryInstances::iterator pos, end = instances.end();
1961 for (pos = instances.begin(); pos != end; ++pos) {
1962 if (name == pos->name)
1963 return pos->create_callback;
Kuba Breckabeed8212014-09-04 01:03:18 +00001964 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001965 }
1966 return nullptr;
Kuba Breckabeed8212014-09-04 01:03:18 +00001967}
1968
Kuba Breckaafdf8422014-10-10 23:43:03 +00001969#pragma mark InstrumentationRuntime
1970
Kate Stoneb9c1b512016-09-06 20:57:50 +00001971struct InstrumentationRuntimeInstance {
1972 InstrumentationRuntimeInstance()
1973 : name(), description(), create_callback(nullptr) {}
1974
1975 ConstString name;
1976 std::string description;
1977 InstrumentationRuntimeCreateInstance create_callback;
1978 InstrumentationRuntimeGetType get_type_callback;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001979};
1980
Kate Stoneb9c1b512016-09-06 20:57:50 +00001981typedef std::vector<InstrumentationRuntimeInstance>
1982 InstrumentationRuntimeInstances;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001983
Kate Stoneb9c1b512016-09-06 20:57:50 +00001984static std::recursive_mutex &GetInstrumentationRuntimeMutex() {
1985 static std::recursive_mutex g_instances_mutex;
1986 return g_instances_mutex;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001987}
1988
Kate Stoneb9c1b512016-09-06 20:57:50 +00001989static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1990 static InstrumentationRuntimeInstances g_instances;
1991 return g_instances;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001992}
1993
Kate Stoneb9c1b512016-09-06 20:57:50 +00001994bool PluginManager::RegisterPlugin(
1995 const ConstString &name, const char *description,
1996 InstrumentationRuntimeCreateInstance create_callback,
1997 InstrumentationRuntimeGetType get_type_callback) {
1998 if (create_callback) {
1999 InstrumentationRuntimeInstance instance;
2000 assert((bool)name);
2001 instance.name = name;
2002 if (description && description[0])
2003 instance.description = description;
2004 instance.create_callback = create_callback;
2005 instance.get_type_callback = get_type_callback;
2006 std::lock_guard<std::recursive_mutex> guard(
2007 GetInstrumentationRuntimeMutex());
2008 GetInstrumentationRuntimeInstances().push_back(instance);
2009 }
2010 return false;
2011}
2012
2013bool PluginManager::UnregisterPlugin(
2014 InstrumentationRuntimeCreateInstance create_callback) {
2015 if (create_callback) {
2016 std::lock_guard<std::recursive_mutex> guard(
2017 GetInstrumentationRuntimeMutex());
2018 InstrumentationRuntimeInstances &instances =
2019 GetInstrumentationRuntimeInstances();
2020
2021 InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2022 for (pos = instances.begin(); pos != end; ++pos) {
2023 if (pos->create_callback == create_callback) {
2024 instances.erase(pos);
2025 return true;
2026 }
Kuba Breckaafdf8422014-10-10 23:43:03 +00002027 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002028 }
2029 return false;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002030}
2031
2032InstrumentationRuntimeGetType
Kate Stoneb9c1b512016-09-06 20:57:50 +00002033PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
2034 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
2035 InstrumentationRuntimeInstances &instances =
2036 GetInstrumentationRuntimeInstances();
2037 if (idx < instances.size())
2038 return instances[idx].get_type_callback;
2039 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002040}
2041
2042InstrumentationRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002043PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
2044 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
2045 InstrumentationRuntimeInstances &instances =
2046 GetInstrumentationRuntimeInstances();
2047 if (idx < instances.size())
2048 return instances[idx].create_callback;
2049 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002050}
2051
Kuba Breckaafdf8422014-10-10 23:43:03 +00002052InstrumentationRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002053PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName(
2054 const ConstString &name) {
2055 if (name) {
2056 std::lock_guard<std::recursive_mutex> guard(
2057 GetInstrumentationRuntimeMutex());
2058 InstrumentationRuntimeInstances &instances =
2059 GetInstrumentationRuntimeInstances();
2060
2061 InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2062 for (pos = instances.begin(); pos != end; ++pos) {
2063 if (name == pos->name)
2064 return pos->create_callback;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002065 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002066 }
2067 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002068}
2069
Greg Clayton56939cb2015-09-17 22:23:34 +00002070#pragma mark TypeSystem
2071
Kate Stoneb9c1b512016-09-06 20:57:50 +00002072struct TypeSystemInstance {
2073 TypeSystemInstance() : name(), description(), create_callback(nullptr) {}
Greg Clayton56939cb2015-09-17 22:23:34 +00002074
Kate Stoneb9c1b512016-09-06 20:57:50 +00002075 ConstString name;
2076 std::string description;
2077 TypeSystemCreateInstance create_callback;
2078 TypeSystemEnumerateSupportedLanguages enumerate_callback;
Greg Clayton56939cb2015-09-17 22:23:34 +00002079};
2080
2081typedef std::vector<TypeSystemInstance> TypeSystemInstances;
2082
Kate Stoneb9c1b512016-09-06 20:57:50 +00002083static std::recursive_mutex &GetTypeSystemMutex() {
2084 static std::recursive_mutex g_instances_mutex;
2085 return g_instances_mutex;
Greg Clayton56939cb2015-09-17 22:23:34 +00002086}
2087
Kate Stoneb9c1b512016-09-06 20:57:50 +00002088static TypeSystemInstances &GetTypeSystemInstances() {
2089 static TypeSystemInstances g_instances;
2090 return g_instances;
Greg Clayton56939cb2015-09-17 22:23:34 +00002091}
2092
Kate Stoneb9c1b512016-09-06 20:57:50 +00002093bool PluginManager::RegisterPlugin(const ConstString &name,
2094 const char *description,
2095 TypeSystemCreateInstance create_callback,
2096 TypeSystemEnumerateSupportedLanguages
2097 enumerate_supported_languages_callback) {
2098 if (create_callback) {
2099 TypeSystemInstance instance;
2100 assert((bool)name);
2101 instance.name = name;
2102 if (description && description[0])
2103 instance.description = description;
2104 instance.create_callback = create_callback;
2105 instance.enumerate_callback = enumerate_supported_languages_callback;
2106 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2107 GetTypeSystemInstances().push_back(instance);
2108 }
2109 return false;
2110}
2111
2112bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
2113 if (create_callback) {
2114 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2115 TypeSystemInstances &instances = GetTypeSystemInstances();
2116
2117 TypeSystemInstances::iterator pos, end = instances.end();
2118 for (pos = instances.begin(); pos != end; ++pos) {
2119 if (pos->create_callback == create_callback) {
2120 instances.erase(pos);
2121 return true;
2122 }
Greg Clayton56939cb2015-09-17 22:23:34 +00002123 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002124 }
2125 return false;
Greg Clayton56939cb2015-09-17 22:23:34 +00002126}
2127
2128TypeSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002129PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
2130 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2131 TypeSystemInstances &instances = GetTypeSystemInstances();
2132 if (idx < instances.size())
2133 return instances[idx].create_callback;
2134 return nullptr;
Greg Clayton56939cb2015-09-17 22:23:34 +00002135}
2136
2137TypeSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002138PluginManager::GetTypeSystemCreateCallbackForPluginName(
2139 const ConstString &name) {
2140 if (name) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00002141 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002142 TypeSystemInstances &instances = GetTypeSystemInstances();
2143
2144 TypeSystemInstances::iterator pos, end = instances.end();
2145 for (pos = instances.begin(); pos != end; ++pos) {
2146 if (name == pos->name)
2147 return pos->create_callback;
2148 }
2149 }
2150 return nullptr;
Sean Callananfe38c852015-10-08 23:07:53 +00002151}
2152
2153TypeSystemEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002154PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(
2155 uint32_t idx) {
2156 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2157 TypeSystemInstances &instances = GetTypeSystemInstances();
2158 if (idx < instances.size())
2159 return instances[idx].enumerate_callback;
2160 return nullptr;
2161}
2162
2163TypeSystemEnumerateSupportedLanguages
2164PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
2165 const ConstString &name) {
2166 if (name) {
2167 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2168 TypeSystemInstances &instances = GetTypeSystemInstances();
2169
2170 TypeSystemInstances::iterator pos, end = instances.end();
2171 for (pos = instances.begin(); pos != end; ++pos) {
2172 if (name == pos->name)
2173 return pos->enumerate_callback;
Sean Callananfe38c852015-10-08 23:07:53 +00002174 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002175 }
2176 return nullptr;
Sean Callananfe38c852015-10-08 23:07:53 +00002177}
Greg Clayton56939cb2015-09-17 22:23:34 +00002178
Sean Callanan66810412015-10-19 23:11:07 +00002179#pragma mark REPL
2180
Kate Stoneb9c1b512016-09-06 20:57:50 +00002181struct REPLInstance {
2182 REPLInstance() : name(), description(), create_callback(nullptr) {}
2183
2184 ConstString name;
2185 std::string description;
2186 REPLCreateInstance create_callback;
2187 REPLEnumerateSupportedLanguages enumerate_languages_callback;
Sean Callanan66810412015-10-19 23:11:07 +00002188};
2189
2190typedef std::vector<REPLInstance> REPLInstances;
2191
Kate Stoneb9c1b512016-09-06 20:57:50 +00002192static std::recursive_mutex &GetREPLMutex() {
2193 static std::recursive_mutex g_instances_mutex;
2194 return g_instances_mutex;
Sean Callanan66810412015-10-19 23:11:07 +00002195}
2196
Kate Stoneb9c1b512016-09-06 20:57:50 +00002197static REPLInstances &GetREPLInstances() {
2198 static REPLInstances g_instances;
2199 return g_instances;
Sean Callanan66810412015-10-19 23:11:07 +00002200}
2201
Kate Stoneb9c1b512016-09-06 20:57:50 +00002202bool PluginManager::RegisterPlugin(
2203 const ConstString &name, const char *description,
2204 REPLCreateInstance create_callback,
2205 REPLEnumerateSupportedLanguages enumerate_languages_callback) {
2206 if (create_callback) {
2207 REPLInstance instance;
2208 assert((bool)name);
2209 instance.name = name;
2210 if (description && description[0])
2211 instance.description = description;
2212 instance.create_callback = create_callback;
2213 instance.enumerate_languages_callback = enumerate_languages_callback;
2214 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2215 GetREPLInstances().push_back(instance);
2216 }
2217 return false;
2218}
2219
2220bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
2221 if (create_callback) {
2222 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2223 REPLInstances &instances = GetREPLInstances();
2224
2225 REPLInstances::iterator pos, end = instances.end();
2226 for (pos = instances.begin(); pos != end; ++pos) {
2227 if (pos->create_callback == create_callback) {
2228 instances.erase(pos);
2229 return true;
2230 }
Sean Callanan66810412015-10-19 23:11:07 +00002231 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002232 }
2233 return false;
Sean Callanan66810412015-10-19 23:11:07 +00002234}
2235
Kate Stoneb9c1b512016-09-06 20:57:50 +00002236REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
2237 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2238 REPLInstances &instances = GetREPLInstances();
2239 if (idx < instances.size())
2240 return instances[idx].create_callback;
2241 return nullptr;
Sean Callanan66810412015-10-19 23:11:07 +00002242}
2243
2244REPLCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002245PluginManager::GetREPLCreateCallbackForPluginName(const ConstString &name) {
2246 if (name) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00002247 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002248 REPLInstances &instances = GetREPLInstances();
Sean Callanan66810412015-10-19 23:11:07 +00002249
Kate Stoneb9c1b512016-09-06 20:57:50 +00002250 REPLInstances::iterator pos, end = instances.end();
2251 for (pos = instances.begin(); pos != end; ++pos) {
2252 if (name == pos->name)
2253 return pos->create_callback;
Sean Callanan66810412015-10-19 23:11:07 +00002254 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002255 }
2256 return nullptr;
Sean Callanan66810412015-10-19 23:11:07 +00002257}
2258
Sean Callanan93c0b002015-10-21 19:14:33 +00002259REPLEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002260PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) {
2261 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2262 REPLInstances &instances = GetREPLInstances();
2263 if (idx < instances.size())
2264 return instances[idx].enumerate_languages_callback;
2265 return nullptr;
Sean Callanan93c0b002015-10-21 19:14:33 +00002266}
2267
Sean Callanan93c0b002015-10-21 19:14:33 +00002268REPLEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002269PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
2270 const ConstString &name) {
2271 if (name) {
2272 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2273 REPLInstances &instances = GetREPLInstances();
2274
2275 REPLInstances::iterator pos, end = instances.end();
2276 for (pos = instances.begin(); pos != end; ++pos) {
2277 if (name == pos->name)
2278 return pos->enumerate_languages_callback;
Sean Callanan93c0b002015-10-21 19:14:33 +00002279 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002280 }
2281 return nullptr;
Sean Callanan93c0b002015-10-21 19:14:33 +00002282}
2283
Kuba Breckaafdf8422014-10-10 23:43:03 +00002284#pragma mark PluginManager
2285
Kate Stoneb9c1b512016-09-06 20:57:50 +00002286void PluginManager::DebuggerInitialize(Debugger &debugger) {
2287 // Initialize the DynamicLoader plugins
2288 {
2289 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
2290 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
Jason Molenda9b837a12013-04-05 05:06:39 +00002291
Kate Stoneb9c1b512016-09-06 20:57:50 +00002292 DynamicLoaderInstances::iterator pos, end = instances.end();
2293 for (pos = instances.begin(); pos != end; ++pos) {
2294 if (pos->debugger_init_callback)
2295 pos->debugger_init_callback(debugger);
Andrew MacPherson17220c12014-03-05 10:12:43 +00002296 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002297 }
Andrew MacPherson17220c12014-03-05 10:12:43 +00002298
Kate Stoneb9c1b512016-09-06 20:57:50 +00002299 // Initialize the JITLoader plugins
2300 {
2301 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
2302 JITLoaderInstances &instances = GetJITLoaderInstances();
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002303
Kate Stoneb9c1b512016-09-06 20:57:50 +00002304 JITLoaderInstances::iterator pos, end = instances.end();
2305 for (pos = instances.begin(); pos != end; ++pos) {
2306 if (pos->debugger_init_callback)
2307 pos->debugger_init_callback(debugger);
Greg Clayton7f982402013-07-15 22:54:20 +00002308 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002309 }
Greg Clayton7f982402013-07-15 22:54:20 +00002310
Kate Stoneb9c1b512016-09-06 20:57:50 +00002311 // Initialize the Platform plugins
2312 {
2313 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
2314 PlatformInstances &instances = GetPlatformInstances();
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002315
Kate Stoneb9c1b512016-09-06 20:57:50 +00002316 PlatformInstances::iterator pos, end = instances.end();
2317 for (pos = instances.begin(); pos != end; ++pos) {
2318 if (pos->debugger_init_callback)
2319 pos->debugger_init_callback(debugger);
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002320 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002321 }
Todd Fiala75930012016-08-19 04:21:48 +00002322
Kate Stoneb9c1b512016-09-06 20:57:50 +00002323 // Initialize the Process plugins
2324 {
2325 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
2326 ProcessInstances &instances = GetProcessInstances();
2327
2328 ProcessInstances::iterator pos, end = instances.end();
2329 for (pos = instances.begin(); pos != end; ++pos) {
2330 if (pos->debugger_init_callback)
2331 pos->debugger_init_callback(debugger);
Todd Fiala75930012016-08-19 04:21:48 +00002332 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002333 }
2334
2335 // Initialize the SymbolFile plugins
2336 {
2337 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
2338 for (auto &sym_file : GetSymbolFileInstances()) {
2339 if (sym_file.debugger_init_callback)
2340 sym_file.debugger_init_callback(debugger);
2341 }
2342 }
2343
2344 // Initialize the OperatingSystem plugins
2345 {
2346 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
2347 for (auto &os : GetOperatingSystemInstances()) {
2348 if (os.debugger_init_callback)
2349 os.debugger_init_callback(debugger);
2350 }
2351 }
2352
2353 // Initialize the StructuredDataPlugin plugins
2354 {
2355 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
2356 for (auto &plugin : GetStructuredDataPluginInstances()) {
2357 if (plugin.debugger_init_callback)
2358 plugin.debugger_init_callback(debugger);
2359 }
2360 }
Greg Claytone8cd0c92012-10-19 18:02:49 +00002361}
2362
Greg Clayton7f982402013-07-15 22:54:20 +00002363// This is the preferred new way to register plugin specific settings. e.g.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002364// This will put a plugin's settings under e.g.
2365// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2366static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins(
2367 Debugger &debugger, const ConstString &plugin_type_name,
2368 const ConstString &plugin_type_desc, bool can_create) {
2369 lldb::OptionValuePropertiesSP parent_properties_sp(
2370 debugger.GetValueProperties());
2371 if (parent_properties_sp) {
2372 static ConstString g_property_name("plugin");
2373
2374 OptionValuePropertiesSP plugin_properties_sp =
2375 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
2376 if (!plugin_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002377 plugin_properties_sp =
2378 std::make_shared<OptionValueProperties>(g_property_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002379 parent_properties_sp->AppendProperty(
2380 g_property_name, ConstString("Settings specify to plugins."), true,
2381 plugin_properties_sp);
Greg Claytone8cd0c92012-10-19 18:02:49 +00002382 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002383
2384 if (plugin_properties_sp) {
2385 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2386 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2387 if (!plugin_type_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002388 plugin_type_properties_sp =
2389 std::make_shared<OptionValueProperties>(plugin_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002390 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2391 true, plugin_type_properties_sp);
2392 }
2393 return plugin_type_properties_sp;
2394 }
2395 }
2396 return lldb::OptionValuePropertiesSP();
Greg Claytone8cd0c92012-10-19 18:02:49 +00002397}
2398
Greg Clayton7f982402013-07-15 22:54:20 +00002399// This is deprecated way to register plugin specific settings. e.g.
2400// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002401// and Platform generic settings would be under "platform.SETTINGNAME".
Kate Stoneb9c1b512016-09-06 20:57:50 +00002402static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
2403 Debugger &debugger, const ConstString &plugin_type_name,
2404 const ConstString &plugin_type_desc, bool can_create) {
2405 static ConstString g_property_name("plugin");
2406 lldb::OptionValuePropertiesSP parent_properties_sp(
2407 debugger.GetValueProperties());
2408 if (parent_properties_sp) {
2409 OptionValuePropertiesSP plugin_properties_sp =
2410 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2411 if (!plugin_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002412 plugin_properties_sp =
2413 std::make_shared<OptionValueProperties>(plugin_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002414 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2415 true, plugin_properties_sp);
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002416 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002417
2418 if (plugin_properties_sp) {
2419 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2420 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
2421 if (!plugin_type_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002422 plugin_type_properties_sp =
2423 std::make_shared<OptionValueProperties>(g_property_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002424 plugin_properties_sp->AppendProperty(
2425 g_property_name, ConstString("Settings specific to plugins"), true,
2426 plugin_type_properties_sp);
2427 }
2428 return plugin_type_properties_sp;
2429 }
2430 }
2431 return lldb::OptionValuePropertiesSP();
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002432}
2433
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002434namespace {
2435
2436typedef lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002437GetDebuggerPropertyForPluginsPtr(Debugger &, const ConstString &,
2438 const ConstString &, bool can_create);
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002439
Greg Claytone8cd0c92012-10-19 18:02:49 +00002440lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002441GetSettingForPlugin(Debugger &debugger, const ConstString &setting_name,
2442 const ConstString &plugin_type_name,
2443 GetDebuggerPropertyForPluginsPtr get_debugger_property =
2444 GetDebuggerPropertyForPlugins) {
2445 lldb::OptionValuePropertiesSP properties_sp;
2446 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
2447 debugger, plugin_type_name,
2448 ConstString(), // not creating to so we don't need the description
2449 false));
2450 if (plugin_type_properties_sp)
2451 properties_sp =
2452 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2453 return properties_sp;
Greg Claytone8cd0c92012-10-19 18:02:49 +00002454}
2455
Kate Stoneb9c1b512016-09-06 20:57:50 +00002456bool CreateSettingForPlugin(
2457 Debugger &debugger, const ConstString &plugin_type_name,
2458 const ConstString &plugin_type_desc,
2459 const lldb::OptionValuePropertiesSP &properties_sp,
2460 const ConstString &description, bool is_global_property,
2461 GetDebuggerPropertyForPluginsPtr get_debugger_property =
2462 GetDebuggerPropertyForPlugins) {
2463 if (properties_sp) {
2464 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2465 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
2466 true));
2467 if (plugin_type_properties_sp) {
2468 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2469 description, is_global_property,
2470 properties_sp);
2471 return true;
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002472 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002473 }
2474 return false;
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002475}
2476
Kate Stoneb9c1b512016-09-06 20:57:50 +00002477const char *kDynamicLoaderPluginName("dynamic-loader");
2478const char *kPlatformPluginName("platform");
2479const char *kProcessPluginName("process");
2480const char *kSymbolFilePluginName("symbol-file");
2481const char *kJITLoaderPluginName("jit-loader");
2482const char *kStructuredDataPluginName("structured-data");
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002483
Eugene Zelenko89183722016-03-11 21:55:47 +00002484} // anonymous namespace
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002485
Kate Stoneb9c1b512016-09-06 20:57:50 +00002486lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(
2487 Debugger &debugger, const ConstString &setting_name) {
2488 return GetSettingForPlugin(debugger, setting_name,
2489 ConstString(kDynamicLoaderPluginName));
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002490}
2491
Kate Stoneb9c1b512016-09-06 20:57:50 +00002492bool PluginManager::CreateSettingForDynamicLoaderPlugin(
2493 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2494 const ConstString &description, bool is_global_property) {
2495 return CreateSettingForPlugin(
2496 debugger, ConstString(kDynamicLoaderPluginName),
2497 ConstString("Settings for dynamic loader plug-ins"), properties_sp,
2498 description, is_global_property);
Greg Claytone8cd0c92012-10-19 18:02:49 +00002499}
2500
Jason Molenda9b837a12013-04-05 05:06:39 +00002501lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002502PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
2503 const ConstString &setting_name) {
2504 return GetSettingForPlugin(debugger, setting_name,
2505 ConstString(kPlatformPluginName),
2506 GetDebuggerPropertyForPluginsOldStyle);
Jason Molenda9b837a12013-04-05 05:06:39 +00002507}
2508
Kate Stoneb9c1b512016-09-06 20:57:50 +00002509bool PluginManager::CreateSettingForPlatformPlugin(
2510 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2511 const ConstString &description, bool is_global_property) {
2512 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
2513 ConstString("Settings for platform plug-ins"),
2514 properties_sp, description, is_global_property,
2515 GetDebuggerPropertyForPluginsOldStyle);
Greg Clayton7f982402013-07-15 22:54:20 +00002516}
2517
Greg Clayton7f982402013-07-15 22:54:20 +00002518lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002519PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
2520 const ConstString &setting_name) {
2521 return GetSettingForPlugin(debugger, setting_name,
2522 ConstString(kProcessPluginName));
Greg Clayton7f982402013-07-15 22:54:20 +00002523}
2524
Kate Stoneb9c1b512016-09-06 20:57:50 +00002525bool PluginManager::CreateSettingForProcessPlugin(
2526 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2527 const ConstString &description, bool is_global_property) {
2528 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
2529 ConstString("Settings for process plug-ins"),
2530 properties_sp, description, is_global_property);
Jason Molenda9b837a12013-04-05 05:06:39 +00002531}
2532
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002533lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002534PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
2535 const ConstString &setting_name) {
2536 return GetSettingForPlugin(debugger, setting_name,
2537 ConstString(kSymbolFilePluginName));
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002538}
2539
Kate Stoneb9c1b512016-09-06 20:57:50 +00002540bool PluginManager::CreateSettingForSymbolFilePlugin(
2541 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2542 const ConstString &description, bool is_global_property) {
2543 return CreateSettingForPlugin(
2544 debugger, ConstString(kSymbolFilePluginName),
2545 ConstString("Settings for symbol file plug-ins"), properties_sp,
2546 description, is_global_property);
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002547}
2548
2549lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002550PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
2551 const ConstString &setting_name) {
2552 return GetSettingForPlugin(debugger, setting_name,
2553 ConstString(kJITLoaderPluginName));
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002554}
2555
Kate Stoneb9c1b512016-09-06 20:57:50 +00002556bool PluginManager::CreateSettingForJITLoaderPlugin(
2557 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2558 const ConstString &description, bool is_global_property) {
2559 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
2560 ConstString("Settings for JIT loader plug-ins"),
2561 properties_sp, description, is_global_property);
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002562}
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002563
2564static const char *kOperatingSystemPluginName("os");
2565
Kate Stoneb9c1b512016-09-06 20:57:50 +00002566lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin(
2567 Debugger &debugger, const ConstString &setting_name) {
2568 lldb::OptionValuePropertiesSP properties_sp;
2569 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2570 GetDebuggerPropertyForPlugins(
2571 debugger, ConstString(kOperatingSystemPluginName),
2572 ConstString(), // not creating to so we don't need the description
2573 false));
2574 if (plugin_type_properties_sp)
2575 properties_sp =
2576 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2577 return properties_sp;
2578}
2579
2580bool PluginManager::CreateSettingForOperatingSystemPlugin(
2581 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2582 const ConstString &description, bool is_global_property) {
2583 if (properties_sp) {
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002584 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002585 GetDebuggerPropertyForPlugins(
2586 debugger, ConstString(kOperatingSystemPluginName),
2587 ConstString("Settings for operating system plug-ins"), true));
2588 if (plugin_type_properties_sp) {
2589 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2590 description, is_global_property,
2591 properties_sp);
2592 return true;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002593 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002594 }
2595 return false;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002596}
Todd Fiala75930012016-08-19 04:21:48 +00002597
Kate Stoneb9c1b512016-09-06 20:57:50 +00002598lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin(
2599 Debugger &debugger, const ConstString &setting_name) {
2600 return GetSettingForPlugin(debugger, setting_name,
2601 ConstString(kStructuredDataPluginName));
Todd Fiala75930012016-08-19 04:21:48 +00002602}
2603
Kate Stoneb9c1b512016-09-06 20:57:50 +00002604bool PluginManager::CreateSettingForStructuredDataPlugin(
2605 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2606 const ConstString &description, bool is_global_property) {
2607 return CreateSettingForPlugin(
2608 debugger, ConstString(kStructuredDataPluginName),
2609 ConstString("Settings for structured data plug-ins"), properties_sp,
2610 description, is_global_property);
Todd Fiala75930012016-08-19 04:21:48 +00002611}