blob: f0a81117293bf678d5a8d1ba75387c1670eda50d [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"
Jonas Devlieghere35e4c842018-11-01 00:33:27 +000013#include "lldb/Host/FileSystem.h"
Zachary Turner42ff0ad2014-08-21 17:29:12 +000014#include "lldb/Host/HostInfo.h"
Greg Claytone8cd0c92012-10-19 18:02:49 +000015#include "lldb/Interpreter/OptionValueProperties.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000016#include "lldb/Utility/ConstString.h" // for ConstString
Zachary Turner5713a052017-03-22 18:40:07 +000017#include "lldb/Utility/FileSpec.h"
Zachary Turner97206d52017-05-12 04:51:55 +000018#include "lldb/Utility/Status.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000019#include "lldb/Utility/StringList.h" // for StringList
20
Nico Weberb1cb0b792018-04-10 13:33:45 +000021#if defined(_WIN32)
Zachary Turner2f3df612017-04-06 21:28:29 +000022#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX
23#endif
24
25#include "llvm/ADT/StringRef.h"
26#include "llvm/Support/DynamicLibrary.h"
27#include "llvm/Support/FileSystem.h" // for file_type, file_...
28#include "llvm/Support/raw_ostream.h" // for fs
29
30#include <map> // for map<>::const_ite...
31#include <memory> // for shared_ptr
32#include <mutex>
33#include <string>
34#include <utility> // for pair
35#include <vector>
36
37#include <assert.h> // for assert
38
39namespace lldb_private {
40class CommandInterpreter;
41}
Greg Clayton4272cc72011-02-02 02:24:04 +000042
43using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044using namespace lldb_private;
45
Kate Stoneb9c1b512016-09-06 20:57:50 +000046enum PluginAction {
47 ePluginRegisterInstance,
48 ePluginUnregisterInstance,
49 ePluginGetInstanceAtIndex
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050};
51
Eugene Zelenko89183722016-03-11 21:55:47 +000052typedef bool (*PluginInitCallback)();
53typedef void (*PluginTermCallback)();
Greg Clayton03da4cc2013-04-19 21:31:16 +000054
Kate Stoneb9c1b512016-09-06 20:57:50 +000055struct PluginInfo {
56 PluginInfo() : plugin_init_callback(nullptr), plugin_term_callback(nullptr) {}
Zachary Turner58a559c2014-08-27 20:15:09 +000057
Kate Stoneb9c1b512016-09-06 20:57:50 +000058 llvm::sys::DynamicLibrary library;
59 PluginInitCallback plugin_init_callback;
60 PluginTermCallback plugin_term_callback;
Greg Clayton4272cc72011-02-02 02:24:04 +000061};
62
63typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
64
Kate Stoneb9c1b512016-09-06 20:57:50 +000065static std::recursive_mutex &GetPluginMapMutex() {
66 static std::recursive_mutex g_plugin_map_mutex;
67 return g_plugin_map_mutex;
Greg Clayton4272cc72011-02-02 02:24:04 +000068}
69
Kate Stoneb9c1b512016-09-06 20:57:50 +000070static PluginTerminateMap &GetPluginMap() {
71 static PluginTerminateMap g_plugin_map;
72 return g_plugin_map;
Greg Clayton4272cc72011-02-02 02:24:04 +000073}
74
Kate Stoneb9c1b512016-09-06 20:57:50 +000075static bool PluginIsLoaded(const FileSpec &plugin_file_spec) {
76 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
77 PluginTerminateMap &plugin_map = GetPluginMap();
78 return plugin_map.find(plugin_file_spec) != plugin_map.end();
Greg Clayton4272cc72011-02-02 02:24:04 +000079}
80
Kate Stoneb9c1b512016-09-06 20:57:50 +000081static void SetPluginInfo(const FileSpec &plugin_file_spec,
82 const PluginInfo &plugin_info) {
83 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
84 PluginTerminateMap &plugin_map = GetPluginMap();
85 assert(plugin_map.find(plugin_file_spec) == plugin_map.end());
86 plugin_map[plugin_file_spec] = plugin_info;
David Majnemer5ff02782014-07-22 21:59:22 +000087}
Greg Clayton4272cc72011-02-02 02:24:04 +000088
Kate Stoneb9c1b512016-09-06 20:57:50 +000089template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
90 return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
91}
Greg Clayton45319462011-02-08 00:35:34 +000092
Jonas Devlieghere35e4c842018-11-01 00:33:27 +000093static FileSystem::EnumerateDirectoryResult
Zachary Turner7d86ee52017-03-08 17:56:08 +000094LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
Jonas Devlieghere35e4c842018-11-01 00:33:27 +000095 llvm::StringRef path) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000096 // PluginManager *plugin_manager = (PluginManager *)baton;
Zachary Turner97206d52017-05-12 04:51:55 +000097 Status error;
Greg Clayton4272cc72011-02-02 02:24:04 +000098
Zachary Turner7d86ee52017-03-08 17:56:08 +000099 namespace fs = llvm::sys::fs;
Adrian Prantl05097242018-04-30 16:49:04 +0000100 // If we have a regular file, a symbolic link or unknown file type, try and
101 // process the file. We must handle unknown as sometimes the directory
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102 // enumeration might be enumerating a file system that doesn't have correct
103 // file type information.
Zachary Turner7d86ee52017-03-08 17:56:08 +0000104 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
105 ft == fs::file_type::type_unknown) {
Jonas Devlieghere35e4c842018-11-01 00:33:27 +0000106 FileSpec plugin_file_spec(path, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107 plugin_file_spec.ResolvePath();
Greg Clayton4272cc72011-02-02 02:24:04 +0000108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 if (PluginIsLoaded(plugin_file_spec))
Jonas Devlieghere35e4c842018-11-01 00:33:27 +0000110 return FileSystem::eEnumerateDirectoryResultNext;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111 else {
112 PluginInfo plugin_info;
Greg Clayton4272cc72011-02-02 02:24:04 +0000113
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 std::string pluginLoadError;
115 plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary(
116 plugin_file_spec.GetPath().c_str(), &pluginLoadError);
117 if (plugin_info.library.isValid()) {
118 bool success = false;
119 plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>(
120 plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
121 if (plugin_info.plugin_init_callback) {
122 // Call the plug-in "bool LLDBPluginInitialize(void)" function
123 success = plugin_info.plugin_init_callback();
Greg Clayton4272cc72011-02-02 02:24:04 +0000124 }
Greg Clayton4272cc72011-02-02 02:24:04 +0000125
Kate Stoneb9c1b512016-09-06 20:57:50 +0000126 if (success) {
127 // It is ok for the "LLDBPluginTerminate" symbol to be nullptr
128 plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>(
129 plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
130 } else {
131 // The initialize function returned FALSE which means the plug-in
Adrian Prantl05097242018-04-30 16:49:04 +0000132 // might not be compatible, or might be too new or too old, or might
133 // not want to run on this machine. Set it to a default-constructed
134 // instance to invalidate it.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135 plugin_info = PluginInfo();
136 }
137
Adrian Prantl05097242018-04-30 16:49:04 +0000138 // Regardless of success or failure, cache the plug-in load in our
139 // plug-in info so we don't try to load it again and again.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 SetPluginInfo(plugin_file_spec, plugin_info);
141
Jonas Devlieghere35e4c842018-11-01 00:33:27 +0000142 return FileSystem::eEnumerateDirectoryResultNext;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 }
144 }
145 }
146
Zachary Turner7d86ee52017-03-08 17:56:08 +0000147 if (ft == fs::file_type::directory_file ||
148 ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
Adrian Prantl05097242018-04-30 16:49:04 +0000149 // Try and recurse into anything that a directory or symbolic link. We must
150 // also do this for unknown as sometimes the directory enumeration might be
151 // enumerating a file system that doesn't have correct file type
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152 // information.
Jonas Devlieghere35e4c842018-11-01 00:33:27 +0000153 return FileSystem::eEnumerateDirectoryResultEnter;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 }
155
Jonas Devlieghere35e4c842018-11-01 00:33:27 +0000156 return FileSystem::eEnumerateDirectoryResultNext;
Greg Clayton4272cc72011-02-02 02:24:04 +0000157}
158
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159void PluginManager::Initialize() {
Greg Clayton1cb64962011-03-24 04:28:38 +0000160#if 1
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 const bool find_directories = true;
162 const bool find_files = true;
163 const bool find_other = true;
164 char dir_path[PATH_MAX];
Pavel Labath60f028f2018-06-19 15:09:07 +0000165 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
Jonas Devliegheredbd7fab2018-11-01 17:09:25 +0000166 if (FileSystem::Instance().Exists(dir_spec) &&
167 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
Jonas Devlieghere35e4c842018-11-01 00:33:27 +0000168 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
169 find_files, find_other,
170 LoadPluginCallback, nullptr);
Greg Clayton4272cc72011-02-02 02:24:04 +0000171 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172 }
Greg Clayton4272cc72011-02-02 02:24:04 +0000173
Pavel Labath60f028f2018-06-19 15:09:07 +0000174 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
Jonas Devliegheredbd7fab2018-11-01 17:09:25 +0000175 if (FileSystem::Instance().Exists(dir_spec) &&
176 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
Jonas Devlieghere35e4c842018-11-01 00:33:27 +0000177 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
178 find_files, find_other,
179 LoadPluginCallback, nullptr);
Greg Clayton4272cc72011-02-02 02:24:04 +0000180 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000182#endif
Greg Clayton4272cc72011-02-02 02:24:04 +0000183}
184
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185void PluginManager::Terminate() {
186 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
187 PluginTerminateMap &plugin_map = GetPluginMap();
188
189 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
190 for (pos = plugin_map.begin(); pos != end; ++pos) {
Adrian Prantl05097242018-04-30 16:49:04 +0000191 // Call the plug-in "void LLDBPluginTerminate (void)" function if there is
192 // one (if the symbol was not nullptr).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 if (pos->second.library.isValid()) {
194 if (pos->second.plugin_term_callback)
195 pos->second.plugin_term_callback();
Greg Clayton4272cc72011-02-02 02:24:04 +0000196 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 }
198 plugin_map.clear();
Greg Clayton4272cc72011-02-02 02:24:04 +0000199}
200
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201#pragma mark ABI
202
Kate Stoneb9c1b512016-09-06 20:57:50 +0000203struct ABIInstance {
204 ABIInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206 ConstString name;
207 std::string description;
208 ABICreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209};
210
211typedef std::vector<ABIInstance> ABIInstances;
212
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213static std::recursive_mutex &GetABIInstancesMutex() {
214 static std::recursive_mutex g_instances_mutex;
215 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000216}
217
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218static ABIInstances &GetABIInstances() {
219 static ABIInstances g_instances;
220 return g_instances;
Greg Claytonded470d2011-03-19 01:12:21 +0000221}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000222
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223bool PluginManager::RegisterPlugin(const ConstString &name,
224 const char *description,
225 ABICreateInstance create_callback) {
226 if (create_callback) {
227 ABIInstance instance;
228 assert((bool)name);
229 instance.name = name;
230 if (description && description[0])
231 instance.description = description;
232 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000233 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234 GetABIInstances().push_back(instance);
235 return true;
236 }
237 return false;
238}
239
240bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
241 if (create_callback) {
242 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
243 ABIInstances &instances = GetABIInstances();
244
245 ABIInstances::iterator pos, end = instances.end();
246 for (pos = instances.begin(); pos != end; ++pos) {
247 if (pos->create_callback == create_callback) {
248 instances.erase(pos);
249 return true;
250 }
251 }
252 }
253 return false;
254}
255
256ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
257 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
258 ABIInstances &instances = GetABIInstances();
259 if (idx < instances.size())
260 return instances[idx].create_callback;
261 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262}
263
264ABICreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265PluginManager::GetABICreateCallbackForPluginName(const ConstString &name) {
266 if (name) {
267 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
268 ABIInstances &instances = GetABIInstances();
Greg Claytonded470d2011-03-19 01:12:21 +0000269
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270 ABIInstances::iterator pos, end = instances.end();
271 for (pos = instances.begin(); pos != end; ++pos) {
272 if (name == pos->name)
273 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000274 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000275 }
276 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277}
278
Pavel Labath13e37d42017-10-25 21:05:31 +0000279#pragma mark Architecture
280
281struct ArchitectureInstance {
282 ConstString name;
283 std::string description;
284 PluginManager::ArchitectureCreateInstance create_callback;
285};
286
287typedef std::vector<ArchitectureInstance> ArchitectureInstances;
288
289static std::mutex g_architecture_mutex;
290
291static ArchitectureInstances &GetArchitectureInstances() {
292 static ArchitectureInstances g_instances;
293 return g_instances;
294}
295
296void PluginManager::RegisterPlugin(const ConstString &name,
297 llvm::StringRef description,
298 ArchitectureCreateInstance create_callback) {
299 std::lock_guard<std::mutex> guard(g_architecture_mutex);
300 GetArchitectureInstances().push_back({name, description, create_callback});
301}
302
303void PluginManager::UnregisterPlugin(
304 ArchitectureCreateInstance create_callback) {
305 std::lock_guard<std::mutex> guard(g_architecture_mutex);
306 auto &instances = GetArchitectureInstances();
307
308 for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
309 if (pos->create_callback == create_callback) {
310 instances.erase(pos);
311 return;
312 }
313 }
314 llvm_unreachable("Plugin not found");
315}
316
317std::unique_ptr<Architecture>
318PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
319 std::lock_guard<std::mutex> guard(g_architecture_mutex);
320 for (const auto &instances : GetArchitectureInstances()) {
321 if (auto plugin_up = instances.create_callback(arch))
322 return plugin_up;
323 }
324 return nullptr;
325}
326
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327#pragma mark Disassembler
328
Kate Stoneb9c1b512016-09-06 20:57:50 +0000329struct DisassemblerInstance {
330 DisassemblerInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331
Kate Stoneb9c1b512016-09-06 20:57:50 +0000332 ConstString name;
333 std::string description;
334 DisassemblerCreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000335};
336
337typedef std::vector<DisassemblerInstance> DisassemblerInstances;
338
Kate Stoneb9c1b512016-09-06 20:57:50 +0000339static std::recursive_mutex &GetDisassemblerMutex() {
340 static std::recursive_mutex g_instances_mutex;
341 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342}
343
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344static DisassemblerInstances &GetDisassemblerInstances() {
345 static DisassemblerInstances g_instances;
346 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +0000347}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348
Kate Stoneb9c1b512016-09-06 20:57:50 +0000349bool PluginManager::RegisterPlugin(const ConstString &name,
350 const char *description,
351 DisassemblerCreateInstance create_callback) {
352 if (create_callback) {
353 DisassemblerInstance instance;
354 assert((bool)name);
355 instance.name = name;
356 if (description && description[0])
357 instance.description = description;
358 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000359 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360 GetDisassemblerInstances().push_back(instance);
361 return true;
362 }
363 return false;
364}
365
366bool PluginManager::UnregisterPlugin(
367 DisassemblerCreateInstance create_callback) {
368 if (create_callback) {
369 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
370 DisassemblerInstances &instances = GetDisassemblerInstances();
371
372 DisassemblerInstances::iterator pos, end = instances.end();
373 for (pos = instances.begin(); pos != end; ++pos) {
374 if (pos->create_callback == create_callback) {
375 instances.erase(pos);
376 return true;
377 }
378 }
379 }
380 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381}
382
383DisassemblerCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000384PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
385 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
386 DisassemblerInstances &instances = GetDisassemblerInstances();
387 if (idx < instances.size())
388 return instances[idx].create_callback;
389 return nullptr;
390}
391
392DisassemblerCreateInstance
393PluginManager::GetDisassemblerCreateCallbackForPluginName(
394 const ConstString &name) {
395 if (name) {
396 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
397 DisassemblerInstances &instances = GetDisassemblerInstances();
398
399 DisassemblerInstances::iterator pos, end = instances.end();
400 for (pos = instances.begin(); pos != end; ++pos) {
401 if (name == pos->name)
402 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000404 }
405 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406}
407
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000408#pragma mark DynamicLoader
409
Kate Stoneb9c1b512016-09-06 20:57:50 +0000410struct DynamicLoaderInstance {
411 DynamicLoaderInstance()
412 : name(), description(), create_callback(nullptr),
413 debugger_init_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000414
Kate Stoneb9c1b512016-09-06 20:57:50 +0000415 ConstString name;
416 std::string description;
417 DynamicLoaderCreateInstance create_callback;
418 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000419};
420
421typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423static std::recursive_mutex &GetDynamicLoaderMutex() {
424 static std::recursive_mutex g_instances_mutex;
425 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +0000426}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428static DynamicLoaderInstances &GetDynamicLoaderInstances() {
429 static DynamicLoaderInstances g_instances;
430 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431}
432
Kate Stoneb9c1b512016-09-06 20:57:50 +0000433bool PluginManager::RegisterPlugin(
434 const ConstString &name, const char *description,
435 DynamicLoaderCreateInstance create_callback,
436 DebuggerInitializeCallback debugger_init_callback) {
437 if (create_callback) {
438 DynamicLoaderInstance instance;
439 assert((bool)name);
440 instance.name = name;
441 if (description && description[0])
442 instance.description = description;
443 instance.create_callback = create_callback;
444 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000445 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000446 GetDynamicLoaderInstances().push_back(instance);
447 }
448 return false;
449}
450
451bool PluginManager::UnregisterPlugin(
452 DynamicLoaderCreateInstance create_callback) {
453 if (create_callback) {
454 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
455 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
456
457 DynamicLoaderInstances::iterator pos, end = instances.end();
458 for (pos = instances.begin(); pos != end; ++pos) {
459 if (pos->create_callback == create_callback) {
460 instances.erase(pos);
461 return true;
462 }
463 }
464 }
465 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466}
467
468DynamicLoaderCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000469PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
470 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
471 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
472 if (idx < instances.size())
473 return instances[idx].create_callback;
474 return nullptr;
475}
476
477DynamicLoaderCreateInstance
478PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
479 const ConstString &name) {
480 if (name) {
481 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
482 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
483
484 DynamicLoaderInstances::iterator pos, end = instances.end();
485 for (pos = instances.begin(); pos != end; ++pos) {
486 if (name == pos->name)
487 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000489 }
490 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491}
492
Andrew MacPherson17220c12014-03-05 10:12:43 +0000493#pragma mark JITLoader
494
Kate Stoneb9c1b512016-09-06 20:57:50 +0000495struct JITLoaderInstance {
496 JITLoaderInstance()
497 : name(), description(), create_callback(nullptr),
498 debugger_init_callback(nullptr) {}
Andrew MacPherson17220c12014-03-05 10:12:43 +0000499
Kate Stoneb9c1b512016-09-06 20:57:50 +0000500 ConstString name;
501 std::string description;
502 JITLoaderCreateInstance create_callback;
503 DebuggerInitializeCallback debugger_init_callback;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000504};
505
506typedef std::vector<JITLoaderInstance> JITLoaderInstances;
507
Kate Stoneb9c1b512016-09-06 20:57:50 +0000508static std::recursive_mutex &GetJITLoaderMutex() {
509 static std::recursive_mutex g_instances_mutex;
510 return g_instances_mutex;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000511}
512
Kate Stoneb9c1b512016-09-06 20:57:50 +0000513static JITLoaderInstances &GetJITLoaderInstances() {
514 static JITLoaderInstances g_instances;
515 return g_instances;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000516}
517
Kate Stoneb9c1b512016-09-06 20:57:50 +0000518bool PluginManager::RegisterPlugin(
519 const ConstString &name, const char *description,
520 JITLoaderCreateInstance create_callback,
521 DebuggerInitializeCallback debugger_init_callback) {
522 if (create_callback) {
523 JITLoaderInstance instance;
524 assert((bool)name);
525 instance.name = name;
526 if (description && description[0])
527 instance.description = description;
528 instance.create_callback = create_callback;
529 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000530 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000531 GetJITLoaderInstances().push_back(instance);
532 }
533 return false;
534}
535
536bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
537 if (create_callback) {
538 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
539 JITLoaderInstances &instances = GetJITLoaderInstances();
540
541 JITLoaderInstances::iterator pos, end = instances.end();
542 for (pos = instances.begin(); pos != end; ++pos) {
543 if (pos->create_callback == create_callback) {
544 instances.erase(pos);
545 return true;
546 }
547 }
548 }
549 return false;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000550}
551
552JITLoaderCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000553PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
554 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
555 JITLoaderInstances &instances = GetJITLoaderInstances();
556 if (idx < instances.size())
557 return instances[idx].create_callback;
558 return nullptr;
559}
560
561JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName(
562 const ConstString &name) {
563 if (name) {
564 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
565 JITLoaderInstances &instances = GetJITLoaderInstances();
566
567 JITLoaderInstances::iterator pos, end = instances.end();
568 for (pos = instances.begin(); pos != end; ++pos) {
569 if (name == pos->name)
570 return pos->create_callback;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000571 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000572 }
573 return nullptr;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000574}
575
Greg Claytonf03bbe22011-02-01 01:37:45 +0000576#pragma mark EmulateInstruction
577
Kate Stoneb9c1b512016-09-06 20:57:50 +0000578struct EmulateInstructionInstance {
579 EmulateInstructionInstance()
580 : name(), description(), create_callback(nullptr) {}
581
582 ConstString name;
583 std::string description;
584 EmulateInstructionCreateInstance create_callback;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000585};
586
587typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
588
Kate Stoneb9c1b512016-09-06 20:57:50 +0000589static std::recursive_mutex &GetEmulateInstructionMutex() {
590 static std::recursive_mutex g_instances_mutex;
591 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +0000592}
593
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594static EmulateInstructionInstances &GetEmulateInstructionInstances() {
595 static EmulateInstructionInstances g_instances;
596 return g_instances;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000597}
598
Kate Stoneb9c1b512016-09-06 20:57:50 +0000599bool PluginManager::RegisterPlugin(
600 const ConstString &name, const char *description,
601 EmulateInstructionCreateInstance create_callback) {
602 if (create_callback) {
603 EmulateInstructionInstance instance;
604 assert((bool)name);
605 instance.name = name;
606 if (description && description[0])
607 instance.description = description;
608 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000609 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000610 GetEmulateInstructionInstances().push_back(instance);
611 }
612 return false;
613}
614
615bool PluginManager::UnregisterPlugin(
616 EmulateInstructionCreateInstance create_callback) {
617 if (create_callback) {
618 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
619 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
620
621 EmulateInstructionInstances::iterator pos, end = instances.end();
622 for (pos = instances.begin(); pos != end; ++pos) {
623 if (pos->create_callback == create_callback) {
624 instances.erase(pos);
625 return true;
626 }
627 }
628 }
629 return false;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000630}
631
632EmulateInstructionCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000633PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
634 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
635 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
636 if (idx < instances.size())
637 return instances[idx].create_callback;
638 return nullptr;
639}
640
641EmulateInstructionCreateInstance
642PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
643 const ConstString &name) {
644 if (name) {
645 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
646 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
647
648 EmulateInstructionInstances::iterator pos, end = instances.end();
649 for (pos = instances.begin(); pos != end; ++pos) {
650 if (name == pos->name)
651 return pos->create_callback;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000652 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000653 }
654 return nullptr;
Greg Claytonf03bbe22011-02-01 01:37:45 +0000655}
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000656
Eugene Zelenko89183722016-03-11 21:55:47 +0000657#pragma mark OperatingSystem
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000658
Kate Stoneb9c1b512016-09-06 20:57:50 +0000659struct OperatingSystemInstance {
660 OperatingSystemInstance()
661 : name(), description(), create_callback(nullptr),
662 debugger_init_callback(nullptr) {}
663
664 ConstString name;
665 std::string description;
666 OperatingSystemCreateInstance create_callback;
667 DebuggerInitializeCallback debugger_init_callback;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000668};
669
670typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
671
Kate Stoneb9c1b512016-09-06 20:57:50 +0000672static std::recursive_mutex &GetOperatingSystemMutex() {
673 static std::recursive_mutex g_instances_mutex;
674 return g_instances_mutex;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000675}
676
Kate Stoneb9c1b512016-09-06 20:57:50 +0000677static OperatingSystemInstances &GetOperatingSystemInstances() {
678 static OperatingSystemInstances g_instances;
679 return g_instances;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000680}
681
Kate Stoneb9c1b512016-09-06 20:57:50 +0000682bool PluginManager::RegisterPlugin(
683 const ConstString &name, const char *description,
684 OperatingSystemCreateInstance create_callback,
685 DebuggerInitializeCallback debugger_init_callback) {
686 if (create_callback) {
687 OperatingSystemInstance instance;
688 assert((bool)name);
689 instance.name = name;
690 if (description && description[0])
691 instance.description = description;
692 instance.create_callback = create_callback;
693 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000694 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000695 GetOperatingSystemInstances().push_back(instance);
696 }
697 return false;
698}
699
700bool PluginManager::UnregisterPlugin(
701 OperatingSystemCreateInstance create_callback) {
702 if (create_callback) {
703 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
704 OperatingSystemInstances &instances = GetOperatingSystemInstances();
705
706 OperatingSystemInstances::iterator pos, end = instances.end();
707 for (pos = instances.begin(); pos != end; ++pos) {
708 if (pos->create_callback == create_callback) {
709 instances.erase(pos);
710 return true;
711 }
712 }
713 }
714 return false;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000715}
716
717OperatingSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000718PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
719 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
720 OperatingSystemInstances &instances = GetOperatingSystemInstances();
721 if (idx < instances.size())
722 return instances[idx].create_callback;
723 return nullptr;
724}
725
726OperatingSystemCreateInstance
727PluginManager::GetOperatingSystemCreateCallbackForPluginName(
728 const ConstString &name) {
729 if (name) {
730 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
731 OperatingSystemInstances &instances = GetOperatingSystemInstances();
732
733 OperatingSystemInstances::iterator pos, end = instances.end();
734 for (pos = instances.begin(); pos != end; ++pos) {
735 if (name == pos->name)
736 return pos->create_callback;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000737 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000738 }
739 return nullptr;
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000740}
Greg Claytonf03bbe22011-02-01 01:37:45 +0000741
Enrico Granata5f9d3102015-08-27 21:33:50 +0000742#pragma mark Language
743
Kate Stoneb9c1b512016-09-06 20:57:50 +0000744struct LanguageInstance {
745 LanguageInstance() : name(), description(), create_callback(nullptr) {}
746
747 ConstString name;
748 std::string description;
749 LanguageCreateInstance create_callback;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000750};
751
752typedef std::vector<LanguageInstance> LanguageInstances;
753
Kate Stoneb9c1b512016-09-06 20:57:50 +0000754static std::recursive_mutex &GetLanguageMutex() {
755 static std::recursive_mutex g_instances_mutex;
756 return g_instances_mutex;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000757}
758
Kate Stoneb9c1b512016-09-06 20:57:50 +0000759static LanguageInstances &GetLanguageInstances() {
760 static LanguageInstances g_instances;
761 return g_instances;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000762}
763
Kate Stoneb9c1b512016-09-06 20:57:50 +0000764bool PluginManager::RegisterPlugin(const ConstString &name,
765 const char *description,
766 LanguageCreateInstance create_callback) {
767 if (create_callback) {
768 LanguageInstance instance;
769 assert((bool)name);
770 instance.name = name;
771 if (description && description[0])
772 instance.description = description;
773 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000774 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 GetLanguageInstances().push_back(instance);
776 }
777 return false;
778}
779
780bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
781 if (create_callback) {
782 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
783 LanguageInstances &instances = GetLanguageInstances();
784
785 LanguageInstances::iterator pos, end = instances.end();
786 for (pos = instances.begin(); pos != end; ++pos) {
787 if (pos->create_callback == create_callback) {
788 instances.erase(pos);
789 return true;
790 }
791 }
792 }
793 return false;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000794}
795
796LanguageCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000797PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
798 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
799 LanguageInstances &instances = GetLanguageInstances();
800 if (idx < instances.size())
801 return instances[idx].create_callback;
802 return nullptr;
803}
804
805LanguageCreateInstance
806PluginManager::GetLanguageCreateCallbackForPluginName(const ConstString &name) {
807 if (name) {
808 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
809 LanguageInstances &instances = GetLanguageInstances();
810
811 LanguageInstances::iterator pos, end = instances.end();
812 for (pos = instances.begin(); pos != end; ++pos) {
813 if (name == pos->name)
814 return pos->create_callback;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000815 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000816 }
817 return nullptr;
Enrico Granata5f9d3102015-08-27 21:33:50 +0000818}
819
Jim Ingham22777012010-09-23 02:01:19 +0000820#pragma mark LanguageRuntime
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000821
Kate Stoneb9c1b512016-09-06 20:57:50 +0000822struct LanguageRuntimeInstance {
823 LanguageRuntimeInstance() : name(), description(), create_callback(nullptr) {}
Jim Ingham22777012010-09-23 02:01:19 +0000824
Kate Stoneb9c1b512016-09-06 20:57:50 +0000825 ConstString name;
826 std::string description;
827 LanguageRuntimeCreateInstance create_callback;
828 LanguageRuntimeGetCommandObject command_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000829};
830
831typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
832
Kate Stoneb9c1b512016-09-06 20:57:50 +0000833static std::recursive_mutex &GetLanguageRuntimeMutex() {
834 static std::recursive_mutex g_instances_mutex;
835 return g_instances_mutex;
Jim Ingham22777012010-09-23 02:01:19 +0000836}
837
Kate Stoneb9c1b512016-09-06 20:57:50 +0000838static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
839 static LanguageRuntimeInstances g_instances;
840 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +0000841}
Jim Ingham22777012010-09-23 02:01:19 +0000842
Kate Stoneb9c1b512016-09-06 20:57:50 +0000843bool PluginManager::RegisterPlugin(
844 const ConstString &name, const char *description,
845 LanguageRuntimeCreateInstance create_callback,
846 LanguageRuntimeGetCommandObject command_callback) {
847 if (create_callback) {
848 LanguageRuntimeInstance instance;
849 assert((bool)name);
850 instance.name = name;
851 if (description && description[0])
852 instance.description = description;
853 instance.create_callback = create_callback;
854 instance.command_callback = command_callback;
855 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
856 GetLanguageRuntimeInstances().push_back(instance);
857 }
858 return false;
859}
860
861bool PluginManager::UnregisterPlugin(
862 LanguageRuntimeCreateInstance create_callback) {
863 if (create_callback) {
864 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
865 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
866
867 LanguageRuntimeInstances::iterator pos, end = instances.end();
868 for (pos = instances.begin(); pos != end; ++pos) {
869 if (pos->create_callback == create_callback) {
870 instances.erase(pos);
871 return true;
872 }
Jim Ingham22777012010-09-23 02:01:19 +0000873 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000874 }
875 return false;
Jim Ingham22777012010-09-23 02:01:19 +0000876}
877
878LanguageRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000879PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
880 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
881 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
882 if (idx < instances.size())
883 return instances[idx].create_callback;
884 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000885}
886
Colin Rileyc9c55a22015-05-04 18:39:38 +0000887LanguageRuntimeGetCommandObject
Kate Stoneb9c1b512016-09-06 20:57:50 +0000888PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
889 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
890 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
891 if (idx < instances.size())
892 return instances[idx].command_callback;
893 return nullptr;
Colin Rileyc9c55a22015-05-04 18:39:38 +0000894}
895
Jim Ingham22777012010-09-23 02:01:19 +0000896LanguageRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000897PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
898 const ConstString &name) {
899 if (name) {
900 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
901 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
902
903 LanguageRuntimeInstances::iterator pos, end = instances.end();
904 for (pos = instances.begin(); pos != end; ++pos) {
905 if (name == pos->name)
906 return pos->create_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000907 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000908 }
909 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000910}
911
Jason Molendaeef51062013-11-05 03:57:19 +0000912#pragma mark SystemRuntime
913
Kate Stoneb9c1b512016-09-06 20:57:50 +0000914struct SystemRuntimeInstance {
915 SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {}
Jason Molendaeef51062013-11-05 03:57:19 +0000916
Kate Stoneb9c1b512016-09-06 20:57:50 +0000917 ConstString name;
918 std::string description;
919 SystemRuntimeCreateInstance create_callback;
Jason Molendaeef51062013-11-05 03:57:19 +0000920};
921
922typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
923
Kate Stoneb9c1b512016-09-06 20:57:50 +0000924static std::recursive_mutex &GetSystemRuntimeMutex() {
925 static std::recursive_mutex g_instances_mutex;
926 return g_instances_mutex;
Jason Molendaeef51062013-11-05 03:57:19 +0000927}
928
Kate Stoneb9c1b512016-09-06 20:57:50 +0000929static SystemRuntimeInstances &GetSystemRuntimeInstances() {
930 static SystemRuntimeInstances g_instances;
931 return g_instances;
Jason Molendaeef51062013-11-05 03:57:19 +0000932}
933
Kate Stoneb9c1b512016-09-06 20:57:50 +0000934bool PluginManager::RegisterPlugin(
935 const ConstString &name, const char *description,
936 SystemRuntimeCreateInstance create_callback) {
937 if (create_callback) {
938 SystemRuntimeInstance instance;
939 assert((bool)name);
940 instance.name = name;
941 if (description && description[0])
942 instance.description = description;
943 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000944 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000945 GetSystemRuntimeInstances().push_back(instance);
946 }
947 return false;
948}
949
950bool PluginManager::UnregisterPlugin(
951 SystemRuntimeCreateInstance create_callback) {
952 if (create_callback) {
953 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
954 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
955
956 SystemRuntimeInstances::iterator pos, end = instances.end();
957 for (pos = instances.begin(); pos != end; ++pos) {
958 if (pos->create_callback == create_callback) {
959 instances.erase(pos);
960 return true;
961 }
962 }
963 }
964 return false;
Jason Molendaeef51062013-11-05 03:57:19 +0000965}
966
967SystemRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +0000968PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
969 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
970 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
971 if (idx < instances.size())
972 return instances[idx].create_callback;
973 return nullptr;
974}
975
976SystemRuntimeCreateInstance
977PluginManager::GetSystemRuntimeCreateCallbackForPluginName(
978 const ConstString &name) {
979 if (name) {
980 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
981 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
982
983 SystemRuntimeInstances::iterator pos, end = instances.end();
984 for (pos = instances.begin(); pos != end; ++pos) {
985 if (name == pos->name)
986 return pos->create_callback;
Jason Molendaeef51062013-11-05 03:57:19 +0000987 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000988 }
989 return nullptr;
Jason Molendaeef51062013-11-05 03:57:19 +0000990}
991
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000992#pragma mark ObjectFile
993
Kate Stoneb9c1b512016-09-06 20:57:50 +0000994struct ObjectFileInstance {
995 ObjectFileInstance()
996 : name(), description(), create_callback(nullptr),
997 create_memory_callback(nullptr), get_module_specifications(nullptr),
998 save_core(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000999
Kate Stoneb9c1b512016-09-06 20:57:50 +00001000 ConstString name;
1001 std::string description;
1002 ObjectFileCreateInstance create_callback;
1003 ObjectFileCreateMemoryInstance create_memory_callback;
1004 ObjectFileGetModuleSpecifications get_module_specifications;
1005 ObjectFileSaveCore save_core;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001006};
1007
1008typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1009
Kate Stoneb9c1b512016-09-06 20:57:50 +00001010static std::recursive_mutex &GetObjectFileMutex() {
1011 static std::recursive_mutex g_instances_mutex;
1012 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001013}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015static ObjectFileInstances &GetObjectFileInstances() {
1016 static ObjectFileInstances g_instances;
1017 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001018}
1019
Kate Stoneb9c1b512016-09-06 20:57:50 +00001020bool PluginManager::RegisterPlugin(
1021 const ConstString &name, const char *description,
1022 ObjectFileCreateInstance create_callback,
1023 ObjectFileCreateMemoryInstance create_memory_callback,
1024 ObjectFileGetModuleSpecifications get_module_specifications,
1025 ObjectFileSaveCore save_core) {
1026 if (create_callback) {
1027 ObjectFileInstance instance;
1028 assert((bool)name);
1029 instance.name = name;
1030 if (description && description[0])
1031 instance.description = description;
1032 instance.create_callback = create_callback;
1033 instance.create_memory_callback = create_memory_callback;
1034 instance.save_core = save_core;
1035 instance.get_module_specifications = get_module_specifications;
1036 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1037 GetObjectFileInstances().push_back(instance);
1038 }
1039 return false;
1040}
1041
1042bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
1043 if (create_callback) {
1044 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1045 ObjectFileInstances &instances = GetObjectFileInstances();
1046
1047 ObjectFileInstances::iterator pos, end = instances.end();
1048 for (pos = instances.begin(); pos != end; ++pos) {
1049 if (pos->create_callback == create_callback) {
1050 instances.erase(pos);
1051 return true;
1052 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001053 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001054 }
1055 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001056}
1057
1058ObjectFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001059PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
1060 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1061 ObjectFileInstances &instances = GetObjectFileInstances();
1062 if (idx < instances.size())
1063 return instances[idx].create_callback;
1064 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001065}
Greg Claytonab65b342011-04-13 22:47:15 +00001066
Greg Claytonc9660542012-02-05 02:38:54 +00001067ObjectFileCreateMemoryInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
1069 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1070 ObjectFileInstances &instances = GetObjectFileInstances();
1071 if (idx < instances.size())
1072 return instances[idx].create_memory_callback;
1073 return nullptr;
Greg Claytonc9660542012-02-05 02:38:54 +00001074}
1075
Greg Claytonf4d6de62013-04-24 22:29:28 +00001076ObjectFileGetModuleSpecifications
Kate Stoneb9c1b512016-09-06 20:57:50 +00001077PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
1078 uint32_t idx) {
1079 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1080 ObjectFileInstances &instances = GetObjectFileInstances();
1081 if (idx < instances.size())
1082 return instances[idx].get_module_specifications;
1083 return nullptr;
Greg Claytonf4d6de62013-04-24 22:29:28 +00001084}
1085
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001086ObjectFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001087PluginManager::GetObjectFileCreateCallbackForPluginName(
1088 const ConstString &name) {
1089 if (name) {
1090 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1091 ObjectFileInstances &instances = GetObjectFileInstances();
1092
1093 ObjectFileInstances::iterator pos, end = instances.end();
1094 for (pos = instances.begin(); pos != end; ++pos) {
1095 if (name == pos->name)
1096 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001098 }
1099 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001100}
1101
Greg Claytonc9660542012-02-05 02:38:54 +00001102ObjectFileCreateMemoryInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001103PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
1104 const ConstString &name) {
1105 if (name) {
1106 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1107 ObjectFileInstances &instances = GetObjectFileInstances();
1108
1109 ObjectFileInstances::iterator pos, end = instances.end();
1110 for (pos = instances.begin(); pos != end; ++pos) {
1111 if (name == pos->name)
1112 return pos->create_memory_callback;
Greg Claytonc9660542012-02-05 02:38:54 +00001113 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001114 }
1115 return nullptr;
Greg Claytonc9660542012-02-05 02:38:54 +00001116}
1117
Zachary Turner97206d52017-05-12 04:51:55 +00001118Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
1119 const FileSpec &outfile) {
1120 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001121 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1122 ObjectFileInstances &instances = GetObjectFileInstances();
1123
1124 ObjectFileInstances::iterator pos, end = instances.end();
1125 for (pos = instances.begin(); pos != end; ++pos) {
1126 if (pos->save_core && pos->save_core(process_sp, outfile, error))
1127 return error;
1128 }
1129 error.SetErrorString(
1130 "no ObjectFile plugins were able to save a core for this process");
1131 return error;
Greg Claytona2715cf2014-06-13 00:54:12 +00001132}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133
1134#pragma mark ObjectContainer
1135
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136struct ObjectContainerInstance {
1137 ObjectContainerInstance()
1138 : name(), description(), create_callback(nullptr),
1139 get_module_specifications(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001140
Kate Stoneb9c1b512016-09-06 20:57:50 +00001141 ConstString name;
1142 std::string description;
1143 ObjectContainerCreateInstance create_callback;
1144 ObjectFileGetModuleSpecifications get_module_specifications;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145};
1146
1147typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1148
Kate Stoneb9c1b512016-09-06 20:57:50 +00001149static std::recursive_mutex &GetObjectContainerMutex() {
1150 static std::recursive_mutex g_instances_mutex;
1151 return g_instances_mutex;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001152}
1153
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154static ObjectContainerInstances &GetObjectContainerInstances() {
1155 static ObjectContainerInstances g_instances;
1156 return g_instances;
Greg Claytonab65b342011-04-13 22:47:15 +00001157}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001158
Kate Stoneb9c1b512016-09-06 20:57:50 +00001159bool PluginManager::RegisterPlugin(
1160 const ConstString &name, const char *description,
1161 ObjectContainerCreateInstance create_callback,
1162 ObjectFileGetModuleSpecifications get_module_specifications) {
1163 if (create_callback) {
1164 ObjectContainerInstance instance;
1165 assert((bool)name);
1166 instance.name = name;
1167 if (description && description[0])
1168 instance.description = description;
1169 instance.create_callback = create_callback;
1170 instance.get_module_specifications = get_module_specifications;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001171 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001172 GetObjectContainerInstances().push_back(instance);
1173 }
1174 return false;
1175}
1176
1177bool PluginManager::UnregisterPlugin(
1178 ObjectContainerCreateInstance create_callback) {
1179 if (create_callback) {
1180 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1181 ObjectContainerInstances &instances = GetObjectContainerInstances();
1182
1183 ObjectContainerInstances::iterator pos, end = instances.end();
1184 for (pos = instances.begin(); pos != end; ++pos) {
1185 if (pos->create_callback == create_callback) {
1186 instances.erase(pos);
1187 return true;
1188 }
1189 }
1190 }
1191 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192}
Greg Claytonab65b342011-04-13 22:47:15 +00001193
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001194ObjectContainerCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001195PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
1196 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1197 ObjectContainerInstances &instances = GetObjectContainerInstances();
1198 if (idx < instances.size())
1199 return instances[idx].create_callback;
1200 return nullptr;
1201}
1202
1203ObjectContainerCreateInstance
1204PluginManager::GetObjectContainerCreateCallbackForPluginName(
1205 const ConstString &name) {
1206 if (name) {
1207 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1208 ObjectContainerInstances &instances = GetObjectContainerInstances();
1209
1210 ObjectContainerInstances::iterator pos, end = instances.end();
1211 for (pos = instances.begin(); pos != end; ++pos) {
1212 if (name == pos->name)
1213 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001214 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001215 }
1216 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001217}
1218
Greg Claytonf4d6de62013-04-24 22:29:28 +00001219ObjectFileGetModuleSpecifications
Kate Stoneb9c1b512016-09-06 20:57:50 +00001220PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
1221 uint32_t idx) {
1222 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1223 ObjectContainerInstances &instances = GetObjectContainerInstances();
1224 if (idx < instances.size())
1225 return instances[idx].get_module_specifications;
1226 return nullptr;
Greg Claytonf4d6de62013-04-24 22:29:28 +00001227}
1228
Greg Claytone996fd32011-03-08 22:40:15 +00001229#pragma mark Platform
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001230
Kate Stoneb9c1b512016-09-06 20:57:50 +00001231struct PlatformInstance {
1232 PlatformInstance()
1233 : name(), description(), create_callback(nullptr),
1234 debugger_init_callback(nullptr) {}
1235
1236 ConstString name;
1237 std::string description;
1238 PlatformCreateInstance create_callback;
1239 DebuggerInitializeCallback debugger_init_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001240};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001241
Greg Claytone996fd32011-03-08 22:40:15 +00001242typedef std::vector<PlatformInstance> PlatformInstances;
1243
Kate Stoneb9c1b512016-09-06 20:57:50 +00001244static std::recursive_mutex &GetPlatformInstancesMutex() {
1245 static std::recursive_mutex g_platform_instances_mutex;
1246 return g_platform_instances_mutex;
Greg Claytone996fd32011-03-08 22:40:15 +00001247}
1248
Kate Stoneb9c1b512016-09-06 20:57:50 +00001249static PlatformInstances &GetPlatformInstances() {
1250 static PlatformInstances g_platform_instances;
1251 return g_platform_instances;
Greg Claytonded470d2011-03-19 01:12:21 +00001252}
Greg Claytone996fd32011-03-08 22:40:15 +00001253
Kate Stoneb9c1b512016-09-06 20:57:50 +00001254bool PluginManager::RegisterPlugin(
1255 const ConstString &name, const char *description,
1256 PlatformCreateInstance create_callback,
1257 DebuggerInitializeCallback debugger_init_callback) {
1258 if (create_callback) {
1259 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001260
Kate Stoneb9c1b512016-09-06 20:57:50 +00001261 PlatformInstance instance;
1262 assert((bool)name);
1263 instance.name = name;
1264 if (description && description[0])
1265 instance.description = description;
1266 instance.create_callback = create_callback;
1267 instance.debugger_init_callback = debugger_init_callback;
1268 GetPlatformInstances().push_back(instance);
1269 return true;
1270 }
1271 return false;
1272}
1273
1274const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
1275 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1276 PlatformInstances &instances = GetPlatformInstances();
1277 if (idx < instances.size())
1278 return instances[idx].name.GetCString();
1279 return nullptr;
1280}
1281
1282const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
1283 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1284 PlatformInstances &instances = GetPlatformInstances();
1285 if (idx < instances.size())
1286 return instances[idx].description.c_str();
1287 return nullptr;
1288}
1289
1290bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
1291 if (create_callback) {
1292 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1293 PlatformInstances &instances = GetPlatformInstances();
1294
1295 PlatformInstances::iterator pos, end = instances.end();
1296 for (pos = instances.begin(); pos != end; ++pos) {
1297 if (pos->create_callback == create_callback) {
1298 instances.erase(pos);
Greg Claytonded470d2011-03-19 01:12:21 +00001299 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001300 }
Greg Claytone996fd32011-03-08 22:40:15 +00001301 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001302 }
1303 return false;
Greg Claytone996fd32011-03-08 22:40:15 +00001304}
1305
1306PlatformCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001307PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
1308 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1309 PlatformInstances &instances = GetPlatformInstances();
1310 if (idx < instances.size())
1311 return instances[idx].create_callback;
1312 return nullptr;
Greg Claytone996fd32011-03-08 22:40:15 +00001313}
1314
1315PlatformCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001316PluginManager::GetPlatformCreateCallbackForPluginName(const ConstString &name) {
1317 if (name) {
1318 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1319 PlatformInstances &instances = GetPlatformInstances();
Greg Claytonded470d2011-03-19 01:12:21 +00001320
Kate Stoneb9c1b512016-09-06 20:57:50 +00001321 PlatformInstances::iterator pos, end = instances.end();
1322 for (pos = instances.begin(); pos != end; ++pos) {
1323 if (name == pos->name)
1324 return pos->create_callback;
Greg Claytone996fd32011-03-08 22:40:15 +00001325 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001326 }
1327 return nullptr;
Greg Claytone996fd32011-03-08 22:40:15 +00001328}
1329
Zachary Turner4aa87532016-11-17 01:37:42 +00001330size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001331 StringList &matches) {
Zachary Turner4aa87532016-11-17 01:37:42 +00001332 if (name.empty())
1333 return matches.GetSize();
Greg Claytonab65b342011-04-13 22:47:15 +00001334
Zachary Turner4aa87532016-11-17 01:37:42 +00001335 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1336 PlatformInstances &instances = GetPlatformInstances();
1337 llvm::StringRef name_sref(name);
1338
1339 PlatformInstances::iterator pos, end = instances.end();
1340 for (pos = instances.begin(); pos != end; ++pos) {
1341 llvm::StringRef plugin_name(pos->name.GetCString());
1342 if (plugin_name.startswith(name_sref))
1343 matches.AppendString(plugin_name.data());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001344 }
1345 return matches.GetSize();
Greg Claytonab65b342011-04-13 22:47:15 +00001346}
Eugene Zelenko89183722016-03-11 21:55:47 +00001347
Greg Claytone996fd32011-03-08 22:40:15 +00001348#pragma mark Process
1349
Kate Stoneb9c1b512016-09-06 20:57:50 +00001350struct ProcessInstance {
1351 ProcessInstance()
1352 : name(), description(), create_callback(nullptr),
1353 debugger_init_callback(nullptr) {}
1354
1355 ConstString name;
1356 std::string description;
1357 ProcessCreateInstance create_callback;
1358 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001359};
1360
1361typedef std::vector<ProcessInstance> ProcessInstances;
1362
Kate Stoneb9c1b512016-09-06 20:57:50 +00001363static std::recursive_mutex &GetProcessMutex() {
1364 static std::recursive_mutex g_instances_mutex;
1365 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001366}
1367
Kate Stoneb9c1b512016-09-06 20:57:50 +00001368static ProcessInstances &GetProcessInstances() {
1369 static ProcessInstances g_instances;
1370 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001371}
1372
Kate Stoneb9c1b512016-09-06 20:57:50 +00001373bool PluginManager::RegisterPlugin(
1374 const ConstString &name, const char *description,
1375 ProcessCreateInstance create_callback,
1376 DebuggerInitializeCallback debugger_init_callback) {
1377 if (create_callback) {
1378 ProcessInstance instance;
1379 assert((bool)name);
1380 instance.name = name;
1381 if (description && description[0])
1382 instance.description = description;
1383 instance.create_callback = create_callback;
1384 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001385 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001386 GetProcessInstances().push_back(instance);
1387 }
1388 return false;
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001389}
1390
Kate Stoneb9c1b512016-09-06 20:57:50 +00001391const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
1392 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1393 ProcessInstances &instances = GetProcessInstances();
1394 if (idx < instances.size())
1395 return instances[idx].name.GetCString();
1396 return nullptr;
1397}
1398
1399const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
1400 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1401 ProcessInstances &instances = GetProcessInstances();
1402 if (idx < instances.size())
1403 return instances[idx].description.c_str();
1404 return nullptr;
1405}
1406
1407bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
1408 if (create_callback) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001409 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001410 ProcessInstances &instances = GetProcessInstances();
Greg Claytonbfe5f3b2011-02-18 01:44:25 +00001411
Kate Stoneb9c1b512016-09-06 20:57:50 +00001412 ProcessInstances::iterator pos, end = instances.end();
1413 for (pos = instances.begin(); pos != end; ++pos) {
1414 if (pos->create_callback == create_callback) {
1415 instances.erase(pos);
1416 return true;
1417 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001418 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001419 }
1420 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001421}
1422
1423ProcessCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001424PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
1425 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1426 ProcessInstances &instances = GetProcessInstances();
1427 if (idx < instances.size())
1428 return instances[idx].create_callback;
1429 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001430}
1431
1432ProcessCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001433PluginManager::GetProcessCreateCallbackForPluginName(const ConstString &name) {
1434 if (name) {
1435 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1436 ProcessInstances &instances = GetProcessInstances();
1437
1438 ProcessInstances::iterator pos, end = instances.end();
1439 for (pos = instances.begin(); pos != end; ++pos) {
1440 if (name == pos->name)
1441 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001442 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001443 }
1444 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001445}
1446
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001447#pragma mark ScriptInterpreter
1448
Kate Stoneb9c1b512016-09-06 20:57:50 +00001449struct ScriptInterpreterInstance {
1450 ScriptInterpreterInstance()
1451 : name(), language(lldb::eScriptLanguageNone), description(),
1452 create_callback(nullptr) {}
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001453
Kate Stoneb9c1b512016-09-06 20:57:50 +00001454 ConstString name;
1455 lldb::ScriptLanguage language;
1456 std::string description;
1457 ScriptInterpreterCreateInstance create_callback;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001458};
1459
1460typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
1461
Kate Stoneb9c1b512016-09-06 20:57:50 +00001462static std::recursive_mutex &GetScriptInterpreterMutex() {
1463 static std::recursive_mutex g_instances_mutex;
1464 return g_instances_mutex;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001465}
1466
Kate Stoneb9c1b512016-09-06 20:57:50 +00001467static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
1468 static ScriptInterpreterInstances g_instances;
1469 return g_instances;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001470}
1471
Kate Stoneb9c1b512016-09-06 20:57:50 +00001472bool PluginManager::RegisterPlugin(
1473 const ConstString &name, const char *description,
1474 lldb::ScriptLanguage script_language,
1475 ScriptInterpreterCreateInstance create_callback) {
1476 if (!create_callback)
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001477 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001478 ScriptInterpreterInstance instance;
1479 assert((bool)name);
1480 instance.name = name;
1481 if (description && description[0])
1482 instance.description = description;
1483 instance.create_callback = create_callback;
1484 instance.language = script_language;
1485 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1486 GetScriptInterpreterInstances().push_back(instance);
1487 return false;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001488}
1489
Kate Stoneb9c1b512016-09-06 20:57:50 +00001490bool PluginManager::UnregisterPlugin(
1491 ScriptInterpreterCreateInstance create_callback) {
1492 if (!create_callback)
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001493 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001494 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1495 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1496
1497 ScriptInterpreterInstances::iterator pos, end = instances.end();
1498 for (pos = instances.begin(); pos != end; ++pos) {
1499 if (pos->create_callback != create_callback)
1500 continue;
1501
1502 instances.erase(pos);
1503 return true;
1504 }
1505 return false;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001506}
1507
1508ScriptInterpreterCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001509PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
1510 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1511 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1512 if (idx < instances.size())
1513 return instances[idx].create_callback;
1514 return nullptr;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001515}
1516
Kate Stoneb9c1b512016-09-06 20:57:50 +00001517lldb::ScriptInterpreterSP PluginManager::GetScriptInterpreterForLanguage(
1518 lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter) {
1519 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1520 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001521
Kate Stoneb9c1b512016-09-06 20:57:50 +00001522 ScriptInterpreterInstances::iterator pos, end = instances.end();
1523 ScriptInterpreterCreateInstance none_instance = nullptr;
1524 for (pos = instances.begin(); pos != end; ++pos) {
1525 if (pos->language == lldb::eScriptLanguageNone)
1526 none_instance = pos->create_callback;
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001527
Kate Stoneb9c1b512016-09-06 20:57:50 +00001528 if (script_lang == pos->language)
1529 return pos->create_callback(interpreter);
1530 }
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001531
Kate Stoneb9c1b512016-09-06 20:57:50 +00001532 // If we didn't find one, return the ScriptInterpreter for the null language.
1533 assert(none_instance != nullptr);
1534 return none_instance(interpreter);
Zachary Turner2c1f46d2015-07-30 20:28:07 +00001535}
1536
Todd Fiala75930012016-08-19 04:21:48 +00001537#pragma mark -
1538#pragma mark StructuredDataPlugin
1539
1540// -----------------------------------------------------------------------------
1541// StructuredDataPlugin
1542// -----------------------------------------------------------------------------
1543
Kate Stoneb9c1b512016-09-06 20:57:50 +00001544struct StructuredDataPluginInstance {
1545 StructuredDataPluginInstance()
1546 : name(), description(), create_callback(nullptr),
1547 debugger_init_callback(nullptr), filter_callback(nullptr) {}
Todd Fiala75930012016-08-19 04:21:48 +00001548
Kate Stoneb9c1b512016-09-06 20:57:50 +00001549 ConstString name;
1550 std::string description;
1551 StructuredDataPluginCreateInstance create_callback;
1552 DebuggerInitializeCallback debugger_init_callback;
1553 StructuredDataFilterLaunchInfo filter_callback;
Todd Fiala75930012016-08-19 04:21:48 +00001554};
1555
1556typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;
1557
Kate Stoneb9c1b512016-09-06 20:57:50 +00001558static std::recursive_mutex &GetStructuredDataPluginMutex() {
1559 static std::recursive_mutex g_instances_mutex;
1560 return g_instances_mutex;
Todd Fiala75930012016-08-19 04:21:48 +00001561}
1562
Kate Stoneb9c1b512016-09-06 20:57:50 +00001563static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
1564 static StructuredDataPluginInstances g_instances;
1565 return g_instances;
Todd Fiala75930012016-08-19 04:21:48 +00001566}
1567
Kate Stoneb9c1b512016-09-06 20:57:50 +00001568bool PluginManager::RegisterPlugin(
1569 const ConstString &name, const char *description,
1570 StructuredDataPluginCreateInstance create_callback,
1571 DebuggerInitializeCallback debugger_init_callback,
1572 StructuredDataFilterLaunchInfo filter_callback) {
1573 if (create_callback) {
1574 StructuredDataPluginInstance instance;
1575 assert((bool)name);
1576 instance.name = name;
1577 if (description && description[0])
1578 instance.description = description;
1579 instance.create_callback = create_callback;
1580 instance.debugger_init_callback = debugger_init_callback;
1581 instance.filter_callback = filter_callback;
1582 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1583 GetStructuredDataPluginInstances().push_back(instance);
1584 }
1585 return false;
Todd Fiala75930012016-08-19 04:21:48 +00001586}
1587
Kate Stoneb9c1b512016-09-06 20:57:50 +00001588bool PluginManager::UnregisterPlugin(
1589 StructuredDataPluginCreateInstance create_callback) {
1590 if (create_callback) {
Todd Fiala75930012016-08-19 04:21:48 +00001591 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1592 StructuredDataPluginInstances &instances =
1593 GetStructuredDataPluginInstances();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001594
1595 StructuredDataPluginInstances::iterator pos, end = instances.end();
1596 for (pos = instances.begin(); pos != end; ++pos) {
1597 if (pos->create_callback == create_callback) {
1598 instances.erase(pos);
1599 return true;
1600 }
1601 }
1602 }
1603 return false;
1604}
1605
1606StructuredDataPluginCreateInstance
1607PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
1608 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1609 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
1610 if (idx < instances.size())
1611 return instances[idx].create_callback;
1612 return nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00001613}
1614
1615StructuredDataPluginCreateInstance
1616PluginManager::GetStructuredDataPluginCreateCallbackForPluginName(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001617 const ConstString &name) {
1618 if (name) {
Todd Fiala75930012016-08-19 04:21:48 +00001619 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1620 StructuredDataPluginInstances &instances =
1621 GetStructuredDataPluginInstances();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001622
1623 StructuredDataPluginInstances::iterator pos, end = instances.end();
1624 for (pos = instances.begin(); pos != end; ++pos) {
1625 if (name == pos->name)
1626 return pos->create_callback;
Todd Fiala75930012016-08-19 04:21:48 +00001627 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001628 }
1629 return nullptr;
1630}
1631
1632StructuredDataFilterLaunchInfo
1633PluginManager::GetStructuredDataFilterCallbackAtIndex(
1634 uint32_t idx, bool &iteration_complete) {
1635 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1636 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
1637 if (idx < instances.size()) {
1638 iteration_complete = false;
1639 return instances[idx].filter_callback;
1640 } else {
1641 iteration_complete = true;
1642 }
1643 return nullptr;
Todd Fiala75930012016-08-19 04:21:48 +00001644}
1645
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001646#pragma mark SymbolFile
1647
Kate Stoneb9c1b512016-09-06 20:57:50 +00001648struct SymbolFileInstance {
1649 SymbolFileInstance()
1650 : name(), description(), create_callback(nullptr),
1651 debugger_init_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001652
Kate Stoneb9c1b512016-09-06 20:57:50 +00001653 ConstString name;
1654 std::string description;
1655 SymbolFileCreateInstance create_callback;
1656 DebuggerInitializeCallback debugger_init_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001657};
1658
1659typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1660
Kate Stoneb9c1b512016-09-06 20:57:50 +00001661static std::recursive_mutex &GetSymbolFileMutex() {
1662 static std::recursive_mutex g_instances_mutex;
1663 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001664}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001665
Kate Stoneb9c1b512016-09-06 20:57:50 +00001666static SymbolFileInstances &GetSymbolFileInstances() {
1667 static SymbolFileInstances g_instances;
1668 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001669}
1670
Kate Stoneb9c1b512016-09-06 20:57:50 +00001671bool PluginManager::RegisterPlugin(
1672 const ConstString &name, const char *description,
1673 SymbolFileCreateInstance create_callback,
1674 DebuggerInitializeCallback debugger_init_callback) {
1675 if (create_callback) {
1676 SymbolFileInstance instance;
1677 assert((bool)name);
1678 instance.name = name;
1679 if (description && description[0])
1680 instance.description = description;
1681 instance.create_callback = create_callback;
1682 instance.debugger_init_callback = debugger_init_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001683 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001684 GetSymbolFileInstances().push_back(instance);
1685 }
1686 return false;
1687}
1688
1689bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
1690 if (create_callback) {
1691 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1692 SymbolFileInstances &instances = GetSymbolFileInstances();
1693
1694 SymbolFileInstances::iterator pos, end = instances.end();
1695 for (pos = instances.begin(); pos != end; ++pos) {
1696 if (pos->create_callback == create_callback) {
1697 instances.erase(pos);
1698 return true;
1699 }
1700 }
1701 }
1702 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001703}
Greg Claytonab65b342011-04-13 22:47:15 +00001704
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001705SymbolFileCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001706PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1707 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1708 SymbolFileInstances &instances = GetSymbolFileInstances();
1709 if (idx < instances.size())
1710 return instances[idx].create_callback;
1711 return nullptr;
1712}
1713
1714SymbolFileCreateInstance
1715PluginManager::GetSymbolFileCreateCallbackForPluginName(
1716 const ConstString &name) {
1717 if (name) {
1718 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1719 SymbolFileInstances &instances = GetSymbolFileInstances();
1720
1721 SymbolFileInstances::iterator pos, end = instances.end();
1722 for (pos = instances.begin(); pos != end; ++pos) {
1723 if (name == pos->name)
1724 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001725 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001726 }
1727 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001728}
1729
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001730#pragma mark SymbolVendor
1731
Kate Stoneb9c1b512016-09-06 20:57:50 +00001732struct SymbolVendorInstance {
1733 SymbolVendorInstance() : name(), description(), create_callback(nullptr) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001734
Kate Stoneb9c1b512016-09-06 20:57:50 +00001735 ConstString name;
1736 std::string description;
1737 SymbolVendorCreateInstance create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001738};
1739
1740typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1741
Kate Stoneb9c1b512016-09-06 20:57:50 +00001742static std::recursive_mutex &GetSymbolVendorMutex() {
1743 static std::recursive_mutex g_instances_mutex;
1744 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001745}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001746
Kate Stoneb9c1b512016-09-06 20:57:50 +00001747static SymbolVendorInstances &GetSymbolVendorInstances() {
1748 static SymbolVendorInstances g_instances;
1749 return g_instances;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001750}
1751
Kate Stoneb9c1b512016-09-06 20:57:50 +00001752bool PluginManager::RegisterPlugin(const ConstString &name,
1753 const char *description,
1754 SymbolVendorCreateInstance create_callback) {
1755 if (create_callback) {
1756 SymbolVendorInstance instance;
1757 assert((bool)name);
1758 instance.name = name;
1759 if (description && description[0])
1760 instance.description = description;
1761 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001762 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001763 GetSymbolVendorInstances().push_back(instance);
1764 }
1765 return false;
1766}
1767
1768bool PluginManager::UnregisterPlugin(
1769 SymbolVendorCreateInstance create_callback) {
1770 if (create_callback) {
1771 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1772 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1773
1774 SymbolVendorInstances::iterator pos, end = instances.end();
1775 for (pos = instances.begin(); pos != end; ++pos) {
1776 if (pos->create_callback == create_callback) {
1777 instances.erase(pos);
1778 return true;
1779 }
1780 }
1781 }
1782 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001783}
1784
1785SymbolVendorCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001786PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1787 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1788 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1789 if (idx < instances.size())
1790 return instances[idx].create_callback;
1791 return nullptr;
1792}
1793
1794SymbolVendorCreateInstance
1795PluginManager::GetSymbolVendorCreateCallbackForPluginName(
1796 const ConstString &name) {
1797 if (name) {
1798 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1799 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1800
1801 SymbolVendorInstances::iterator pos, end = instances.end();
1802 for (pos = instances.begin(); pos != end; ++pos) {
1803 if (name == pos->name)
1804 return pos->create_callback;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001805 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001806 }
1807 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001808}
1809
Greg Clayton7be25422011-04-25 21:14:26 +00001810#pragma mark UnwindAssembly
Jason Molendafbcb7f22010-09-10 07:49:16 +00001811
Kate Stoneb9c1b512016-09-06 20:57:50 +00001812struct UnwindAssemblyInstance {
1813 UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001814
Kate Stoneb9c1b512016-09-06 20:57:50 +00001815 ConstString name;
1816 std::string description;
1817 UnwindAssemblyCreateInstance create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001818};
1819
Greg Clayton7be25422011-04-25 21:14:26 +00001820typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001821
Kate Stoneb9c1b512016-09-06 20:57:50 +00001822static std::recursive_mutex &GetUnwindAssemblyMutex() {
1823 static std::recursive_mutex g_instances_mutex;
1824 return g_instances_mutex;
Greg Claytonab65b342011-04-13 22:47:15 +00001825}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001826
Kate Stoneb9c1b512016-09-06 20:57:50 +00001827static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1828 static UnwindAssemblyInstances g_instances;
1829 return g_instances;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001830}
1831
Kate Stoneb9c1b512016-09-06 20:57:50 +00001832bool PluginManager::RegisterPlugin(
1833 const ConstString &name, const char *description,
1834 UnwindAssemblyCreateInstance create_callback) {
1835 if (create_callback) {
1836 UnwindAssemblyInstance instance;
1837 assert((bool)name);
1838 instance.name = name;
1839 if (description && description[0])
1840 instance.description = description;
1841 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001842 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001843 GetUnwindAssemblyInstances().push_back(instance);
1844 }
1845 return false;
1846}
1847
1848bool PluginManager::UnregisterPlugin(
1849 UnwindAssemblyCreateInstance create_callback) {
1850 if (create_callback) {
1851 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1852 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1853
1854 UnwindAssemblyInstances::iterator pos, end = instances.end();
1855 for (pos = instances.begin(); pos != end; ++pos) {
1856 if (pos->create_callback == create_callback) {
1857 instances.erase(pos);
1858 return true;
1859 }
1860 }
1861 }
1862 return false;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001863}
1864
Greg Clayton7be25422011-04-25 21:14:26 +00001865UnwindAssemblyCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001866PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1867 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1868 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1869 if (idx < instances.size())
1870 return instances[idx].create_callback;
1871 return nullptr;
1872}
1873
1874UnwindAssemblyCreateInstance
1875PluginManager::GetUnwindAssemblyCreateCallbackForPluginName(
1876 const ConstString &name) {
1877 if (name) {
1878 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1879 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1880
1881 UnwindAssemblyInstances::iterator pos, end = instances.end();
1882 for (pos = instances.begin(); pos != end; ++pos) {
1883 if (name == pos->name)
1884 return pos->create_callback;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001885 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001886 }
1887 return nullptr;
Jason Molendafbcb7f22010-09-10 07:49:16 +00001888}
1889
Kuba Breckabeed8212014-09-04 01:03:18 +00001890#pragma mark MemoryHistory
1891
Kate Stoneb9c1b512016-09-06 20:57:50 +00001892struct MemoryHistoryInstance {
1893 MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {}
1894
1895 ConstString name;
1896 std::string description;
1897 MemoryHistoryCreateInstance create_callback;
Kuba Breckabeed8212014-09-04 01:03:18 +00001898};
1899
1900typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
1901
Kate Stoneb9c1b512016-09-06 20:57:50 +00001902static std::recursive_mutex &GetMemoryHistoryMutex() {
1903 static std::recursive_mutex g_instances_mutex;
1904 return g_instances_mutex;
Kuba Breckabeed8212014-09-04 01:03:18 +00001905}
1906
Kate Stoneb9c1b512016-09-06 20:57:50 +00001907static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1908 static MemoryHistoryInstances g_instances;
1909 return g_instances;
Kuba Breckabeed8212014-09-04 01:03:18 +00001910}
1911
Kate Stoneb9c1b512016-09-06 20:57:50 +00001912bool PluginManager::RegisterPlugin(
1913 const ConstString &name, const char *description,
1914 MemoryHistoryCreateInstance create_callback) {
1915 if (create_callback) {
1916 MemoryHistoryInstance instance;
1917 assert((bool)name);
1918 instance.name = name;
1919 if (description && description[0])
1920 instance.description = description;
1921 instance.create_callback = create_callback;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001922 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001923 GetMemoryHistoryInstances().push_back(instance);
1924 }
1925 return false;
1926}
1927
1928bool PluginManager::UnregisterPlugin(
1929 MemoryHistoryCreateInstance create_callback) {
1930 if (create_callback) {
1931 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1932 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1933
1934 MemoryHistoryInstances::iterator pos, end = instances.end();
1935 for (pos = instances.begin(); pos != end; ++pos) {
1936 if (pos->create_callback == create_callback) {
1937 instances.erase(pos);
1938 return true;
1939 }
1940 }
1941 }
1942 return false;
Kuba Breckabeed8212014-09-04 01:03:18 +00001943}
1944
Kuba Breckabeed8212014-09-04 01:03:18 +00001945MemoryHistoryCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00001946PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1947 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1948 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1949 if (idx < instances.size())
1950 return instances[idx].create_callback;
1951 return nullptr;
1952}
1953
1954MemoryHistoryCreateInstance
1955PluginManager::GetMemoryHistoryCreateCallbackForPluginName(
1956 const ConstString &name) {
1957 if (name) {
1958 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1959 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1960
1961 MemoryHistoryInstances::iterator pos, end = instances.end();
1962 for (pos = instances.begin(); pos != end; ++pos) {
1963 if (name == pos->name)
1964 return pos->create_callback;
Kuba Breckabeed8212014-09-04 01:03:18 +00001965 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001966 }
1967 return nullptr;
Kuba Breckabeed8212014-09-04 01:03:18 +00001968}
1969
Kuba Breckaafdf8422014-10-10 23:43:03 +00001970#pragma mark InstrumentationRuntime
1971
Kate Stoneb9c1b512016-09-06 20:57:50 +00001972struct InstrumentationRuntimeInstance {
1973 InstrumentationRuntimeInstance()
1974 : name(), description(), create_callback(nullptr) {}
1975
1976 ConstString name;
1977 std::string description;
1978 InstrumentationRuntimeCreateInstance create_callback;
1979 InstrumentationRuntimeGetType get_type_callback;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001980};
1981
Kate Stoneb9c1b512016-09-06 20:57:50 +00001982typedef std::vector<InstrumentationRuntimeInstance>
1983 InstrumentationRuntimeInstances;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001984
Kate Stoneb9c1b512016-09-06 20:57:50 +00001985static std::recursive_mutex &GetInstrumentationRuntimeMutex() {
1986 static std::recursive_mutex g_instances_mutex;
1987 return g_instances_mutex;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001988}
1989
Kate Stoneb9c1b512016-09-06 20:57:50 +00001990static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1991 static InstrumentationRuntimeInstances g_instances;
1992 return g_instances;
Kuba Breckaafdf8422014-10-10 23:43:03 +00001993}
1994
Kate Stoneb9c1b512016-09-06 20:57:50 +00001995bool PluginManager::RegisterPlugin(
1996 const ConstString &name, const char *description,
1997 InstrumentationRuntimeCreateInstance create_callback,
1998 InstrumentationRuntimeGetType get_type_callback) {
1999 if (create_callback) {
2000 InstrumentationRuntimeInstance instance;
2001 assert((bool)name);
2002 instance.name = name;
2003 if (description && description[0])
2004 instance.description = description;
2005 instance.create_callback = create_callback;
2006 instance.get_type_callback = get_type_callback;
2007 std::lock_guard<std::recursive_mutex> guard(
2008 GetInstrumentationRuntimeMutex());
2009 GetInstrumentationRuntimeInstances().push_back(instance);
2010 }
2011 return false;
2012}
2013
2014bool PluginManager::UnregisterPlugin(
2015 InstrumentationRuntimeCreateInstance create_callback) {
2016 if (create_callback) {
2017 std::lock_guard<std::recursive_mutex> guard(
2018 GetInstrumentationRuntimeMutex());
2019 InstrumentationRuntimeInstances &instances =
2020 GetInstrumentationRuntimeInstances();
2021
2022 InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2023 for (pos = instances.begin(); pos != end; ++pos) {
2024 if (pos->create_callback == create_callback) {
2025 instances.erase(pos);
2026 return true;
2027 }
Kuba Breckaafdf8422014-10-10 23:43:03 +00002028 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002029 }
2030 return false;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002031}
2032
2033InstrumentationRuntimeGetType
Kate Stoneb9c1b512016-09-06 20:57:50 +00002034PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
2035 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
2036 InstrumentationRuntimeInstances &instances =
2037 GetInstrumentationRuntimeInstances();
2038 if (idx < instances.size())
2039 return instances[idx].get_type_callback;
2040 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002041}
2042
2043InstrumentationRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002044PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
2045 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
2046 InstrumentationRuntimeInstances &instances =
2047 GetInstrumentationRuntimeInstances();
2048 if (idx < instances.size())
2049 return instances[idx].create_callback;
2050 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002051}
2052
Kuba Breckaafdf8422014-10-10 23:43:03 +00002053InstrumentationRuntimeCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002054PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName(
2055 const ConstString &name) {
2056 if (name) {
2057 std::lock_guard<std::recursive_mutex> guard(
2058 GetInstrumentationRuntimeMutex());
2059 InstrumentationRuntimeInstances &instances =
2060 GetInstrumentationRuntimeInstances();
2061
2062 InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2063 for (pos = instances.begin(); pos != end; ++pos) {
2064 if (name == pos->name)
2065 return pos->create_callback;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002066 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002067 }
2068 return nullptr;
Kuba Breckaafdf8422014-10-10 23:43:03 +00002069}
2070
Greg Clayton56939cb2015-09-17 22:23:34 +00002071#pragma mark TypeSystem
2072
Kate Stoneb9c1b512016-09-06 20:57:50 +00002073struct TypeSystemInstance {
2074 TypeSystemInstance() : name(), description(), create_callback(nullptr) {}
Greg Clayton56939cb2015-09-17 22:23:34 +00002075
Kate Stoneb9c1b512016-09-06 20:57:50 +00002076 ConstString name;
2077 std::string description;
2078 TypeSystemCreateInstance create_callback;
2079 TypeSystemEnumerateSupportedLanguages enumerate_callback;
Greg Clayton56939cb2015-09-17 22:23:34 +00002080};
2081
2082typedef std::vector<TypeSystemInstance> TypeSystemInstances;
2083
Kate Stoneb9c1b512016-09-06 20:57:50 +00002084static std::recursive_mutex &GetTypeSystemMutex() {
2085 static std::recursive_mutex g_instances_mutex;
2086 return g_instances_mutex;
Greg Clayton56939cb2015-09-17 22:23:34 +00002087}
2088
Kate Stoneb9c1b512016-09-06 20:57:50 +00002089static TypeSystemInstances &GetTypeSystemInstances() {
2090 static TypeSystemInstances g_instances;
2091 return g_instances;
Greg Clayton56939cb2015-09-17 22:23:34 +00002092}
2093
Kate Stoneb9c1b512016-09-06 20:57:50 +00002094bool PluginManager::RegisterPlugin(const ConstString &name,
2095 const char *description,
2096 TypeSystemCreateInstance create_callback,
2097 TypeSystemEnumerateSupportedLanguages
2098 enumerate_supported_languages_callback) {
2099 if (create_callback) {
2100 TypeSystemInstance instance;
2101 assert((bool)name);
2102 instance.name = name;
2103 if (description && description[0])
2104 instance.description = description;
2105 instance.create_callback = create_callback;
2106 instance.enumerate_callback = enumerate_supported_languages_callback;
2107 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2108 GetTypeSystemInstances().push_back(instance);
2109 }
2110 return false;
2111}
2112
2113bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
2114 if (create_callback) {
2115 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2116 TypeSystemInstances &instances = GetTypeSystemInstances();
2117
2118 TypeSystemInstances::iterator pos, end = instances.end();
2119 for (pos = instances.begin(); pos != end; ++pos) {
2120 if (pos->create_callback == create_callback) {
2121 instances.erase(pos);
2122 return true;
2123 }
Greg Clayton56939cb2015-09-17 22:23:34 +00002124 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002125 }
2126 return false;
Greg Clayton56939cb2015-09-17 22:23:34 +00002127}
2128
2129TypeSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002130PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
2131 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2132 TypeSystemInstances &instances = GetTypeSystemInstances();
2133 if (idx < instances.size())
2134 return instances[idx].create_callback;
2135 return nullptr;
Greg Clayton56939cb2015-09-17 22:23:34 +00002136}
2137
2138TypeSystemCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002139PluginManager::GetTypeSystemCreateCallbackForPluginName(
2140 const ConstString &name) {
2141 if (name) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00002142 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002143 TypeSystemInstances &instances = GetTypeSystemInstances();
2144
2145 TypeSystemInstances::iterator pos, end = instances.end();
2146 for (pos = instances.begin(); pos != end; ++pos) {
2147 if (name == pos->name)
2148 return pos->create_callback;
2149 }
2150 }
2151 return nullptr;
Sean Callananfe38c852015-10-08 23:07:53 +00002152}
2153
2154TypeSystemEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002155PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(
2156 uint32_t idx) {
2157 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2158 TypeSystemInstances &instances = GetTypeSystemInstances();
2159 if (idx < instances.size())
2160 return instances[idx].enumerate_callback;
2161 return nullptr;
2162}
2163
2164TypeSystemEnumerateSupportedLanguages
2165PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
2166 const ConstString &name) {
2167 if (name) {
2168 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2169 TypeSystemInstances &instances = GetTypeSystemInstances();
2170
2171 TypeSystemInstances::iterator pos, end = instances.end();
2172 for (pos = instances.begin(); pos != end; ++pos) {
2173 if (name == pos->name)
2174 return pos->enumerate_callback;
Sean Callananfe38c852015-10-08 23:07:53 +00002175 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002176 }
2177 return nullptr;
Sean Callananfe38c852015-10-08 23:07:53 +00002178}
Greg Clayton56939cb2015-09-17 22:23:34 +00002179
Sean Callanan66810412015-10-19 23:11:07 +00002180#pragma mark REPL
2181
Kate Stoneb9c1b512016-09-06 20:57:50 +00002182struct REPLInstance {
2183 REPLInstance() : name(), description(), create_callback(nullptr) {}
2184
2185 ConstString name;
2186 std::string description;
2187 REPLCreateInstance create_callback;
2188 REPLEnumerateSupportedLanguages enumerate_languages_callback;
Sean Callanan66810412015-10-19 23:11:07 +00002189};
2190
2191typedef std::vector<REPLInstance> REPLInstances;
2192
Kate Stoneb9c1b512016-09-06 20:57:50 +00002193static std::recursive_mutex &GetREPLMutex() {
2194 static std::recursive_mutex g_instances_mutex;
2195 return g_instances_mutex;
Sean Callanan66810412015-10-19 23:11:07 +00002196}
2197
Kate Stoneb9c1b512016-09-06 20:57:50 +00002198static REPLInstances &GetREPLInstances() {
2199 static REPLInstances g_instances;
2200 return g_instances;
Sean Callanan66810412015-10-19 23:11:07 +00002201}
2202
Kate Stoneb9c1b512016-09-06 20:57:50 +00002203bool PluginManager::RegisterPlugin(
2204 const ConstString &name, const char *description,
2205 REPLCreateInstance create_callback,
2206 REPLEnumerateSupportedLanguages enumerate_languages_callback) {
2207 if (create_callback) {
2208 REPLInstance instance;
2209 assert((bool)name);
2210 instance.name = name;
2211 if (description && description[0])
2212 instance.description = description;
2213 instance.create_callback = create_callback;
2214 instance.enumerate_languages_callback = enumerate_languages_callback;
2215 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2216 GetREPLInstances().push_back(instance);
2217 }
2218 return false;
2219}
2220
2221bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
2222 if (create_callback) {
2223 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2224 REPLInstances &instances = GetREPLInstances();
2225
2226 REPLInstances::iterator pos, end = instances.end();
2227 for (pos = instances.begin(); pos != end; ++pos) {
2228 if (pos->create_callback == create_callback) {
2229 instances.erase(pos);
2230 return true;
2231 }
Sean Callanan66810412015-10-19 23:11:07 +00002232 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002233 }
2234 return false;
Sean Callanan66810412015-10-19 23:11:07 +00002235}
2236
Kate Stoneb9c1b512016-09-06 20:57:50 +00002237REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
2238 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2239 REPLInstances &instances = GetREPLInstances();
2240 if (idx < instances.size())
2241 return instances[idx].create_callback;
2242 return nullptr;
Sean Callanan66810412015-10-19 23:11:07 +00002243}
2244
2245REPLCreateInstance
Kate Stoneb9c1b512016-09-06 20:57:50 +00002246PluginManager::GetREPLCreateCallbackForPluginName(const ConstString &name) {
2247 if (name) {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00002248 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002249 REPLInstances &instances = GetREPLInstances();
Sean Callanan66810412015-10-19 23:11:07 +00002250
Kate Stoneb9c1b512016-09-06 20:57:50 +00002251 REPLInstances::iterator pos, end = instances.end();
2252 for (pos = instances.begin(); pos != end; ++pos) {
2253 if (name == pos->name)
2254 return pos->create_callback;
Sean Callanan66810412015-10-19 23:11:07 +00002255 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002256 }
2257 return nullptr;
Sean Callanan66810412015-10-19 23:11:07 +00002258}
2259
Sean Callanan93c0b002015-10-21 19:14:33 +00002260REPLEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002261PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) {
2262 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2263 REPLInstances &instances = GetREPLInstances();
2264 if (idx < instances.size())
2265 return instances[idx].enumerate_languages_callback;
2266 return nullptr;
Sean Callanan93c0b002015-10-21 19:14:33 +00002267}
2268
Sean Callanan93c0b002015-10-21 19:14:33 +00002269REPLEnumerateSupportedLanguages
Kate Stoneb9c1b512016-09-06 20:57:50 +00002270PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
2271 const ConstString &name) {
2272 if (name) {
2273 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2274 REPLInstances &instances = GetREPLInstances();
2275
2276 REPLInstances::iterator pos, end = instances.end();
2277 for (pos = instances.begin(); pos != end; ++pos) {
2278 if (name == pos->name)
2279 return pos->enumerate_languages_callback;
Sean Callanan93c0b002015-10-21 19:14:33 +00002280 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002281 }
2282 return nullptr;
Sean Callanan93c0b002015-10-21 19:14:33 +00002283}
2284
Kuba Breckaafdf8422014-10-10 23:43:03 +00002285#pragma mark PluginManager
2286
Kate Stoneb9c1b512016-09-06 20:57:50 +00002287void PluginManager::DebuggerInitialize(Debugger &debugger) {
2288 // Initialize the DynamicLoader plugins
2289 {
2290 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
2291 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
Jason Molenda9b837a12013-04-05 05:06:39 +00002292
Kate Stoneb9c1b512016-09-06 20:57:50 +00002293 DynamicLoaderInstances::iterator pos, end = instances.end();
2294 for (pos = instances.begin(); pos != end; ++pos) {
2295 if (pos->debugger_init_callback)
2296 pos->debugger_init_callback(debugger);
Andrew MacPherson17220c12014-03-05 10:12:43 +00002297 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002298 }
Andrew MacPherson17220c12014-03-05 10:12:43 +00002299
Kate Stoneb9c1b512016-09-06 20:57:50 +00002300 // Initialize the JITLoader plugins
2301 {
2302 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
2303 JITLoaderInstances &instances = GetJITLoaderInstances();
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002304
Kate Stoneb9c1b512016-09-06 20:57:50 +00002305 JITLoaderInstances::iterator pos, end = instances.end();
2306 for (pos = instances.begin(); pos != end; ++pos) {
2307 if (pos->debugger_init_callback)
2308 pos->debugger_init_callback(debugger);
Greg Clayton7f982402013-07-15 22:54:20 +00002309 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002310 }
Greg Clayton7f982402013-07-15 22:54:20 +00002311
Kate Stoneb9c1b512016-09-06 20:57:50 +00002312 // Initialize the Platform plugins
2313 {
2314 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
2315 PlatformInstances &instances = GetPlatformInstances();
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002316
Kate Stoneb9c1b512016-09-06 20:57:50 +00002317 PlatformInstances::iterator pos, end = instances.end();
2318 for (pos = instances.begin(); pos != end; ++pos) {
2319 if (pos->debugger_init_callback)
2320 pos->debugger_init_callback(debugger);
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002321 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002322 }
Todd Fiala75930012016-08-19 04:21:48 +00002323
Kate Stoneb9c1b512016-09-06 20:57:50 +00002324 // Initialize the Process plugins
2325 {
2326 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
2327 ProcessInstances &instances = GetProcessInstances();
2328
2329 ProcessInstances::iterator pos, end = instances.end();
2330 for (pos = instances.begin(); pos != end; ++pos) {
2331 if (pos->debugger_init_callback)
2332 pos->debugger_init_callback(debugger);
Todd Fiala75930012016-08-19 04:21:48 +00002333 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002334 }
2335
2336 // Initialize the SymbolFile plugins
2337 {
2338 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
2339 for (auto &sym_file : GetSymbolFileInstances()) {
2340 if (sym_file.debugger_init_callback)
2341 sym_file.debugger_init_callback(debugger);
2342 }
2343 }
2344
2345 // Initialize the OperatingSystem plugins
2346 {
2347 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
2348 for (auto &os : GetOperatingSystemInstances()) {
2349 if (os.debugger_init_callback)
2350 os.debugger_init_callback(debugger);
2351 }
2352 }
2353
2354 // Initialize the StructuredDataPlugin plugins
2355 {
2356 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
2357 for (auto &plugin : GetStructuredDataPluginInstances()) {
2358 if (plugin.debugger_init_callback)
2359 plugin.debugger_init_callback(debugger);
2360 }
2361 }
Greg Claytone8cd0c92012-10-19 18:02:49 +00002362}
2363
Greg Clayton7f982402013-07-15 22:54:20 +00002364// This is the preferred new way to register plugin specific settings. e.g.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002365// This will put a plugin's settings under e.g.
2366// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2367static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins(
2368 Debugger &debugger, const ConstString &plugin_type_name,
2369 const ConstString &plugin_type_desc, bool can_create) {
2370 lldb::OptionValuePropertiesSP parent_properties_sp(
2371 debugger.GetValueProperties());
2372 if (parent_properties_sp) {
2373 static ConstString g_property_name("plugin");
2374
2375 OptionValuePropertiesSP plugin_properties_sp =
2376 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
2377 if (!plugin_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002378 plugin_properties_sp =
2379 std::make_shared<OptionValueProperties>(g_property_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002380 parent_properties_sp->AppendProperty(
2381 g_property_name, ConstString("Settings specify to plugins."), true,
2382 plugin_properties_sp);
Greg Claytone8cd0c92012-10-19 18:02:49 +00002383 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002384
2385 if (plugin_properties_sp) {
2386 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2387 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2388 if (!plugin_type_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002389 plugin_type_properties_sp =
2390 std::make_shared<OptionValueProperties>(plugin_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002391 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2392 true, plugin_type_properties_sp);
2393 }
2394 return plugin_type_properties_sp;
2395 }
2396 }
2397 return lldb::OptionValuePropertiesSP();
Greg Claytone8cd0c92012-10-19 18:02:49 +00002398}
2399
Greg Clayton7f982402013-07-15 22:54:20 +00002400// This is deprecated way to register plugin specific settings. e.g.
Adrian Prantl05097242018-04-30 16:49:04 +00002401// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
2402// generic settings would be under "platform.SETTINGNAME".
Kate Stoneb9c1b512016-09-06 20:57:50 +00002403static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
2404 Debugger &debugger, const ConstString &plugin_type_name,
2405 const ConstString &plugin_type_desc, bool can_create) {
2406 static ConstString g_property_name("plugin");
2407 lldb::OptionValuePropertiesSP parent_properties_sp(
2408 debugger.GetValueProperties());
2409 if (parent_properties_sp) {
2410 OptionValuePropertiesSP plugin_properties_sp =
2411 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2412 if (!plugin_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002413 plugin_properties_sp =
2414 std::make_shared<OptionValueProperties>(plugin_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002415 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2416 true, plugin_properties_sp);
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002417 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002418
2419 if (plugin_properties_sp) {
2420 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2421 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
2422 if (!plugin_type_properties_sp && can_create) {
Zachary Turner2f3df612017-04-06 21:28:29 +00002423 plugin_type_properties_sp =
2424 std::make_shared<OptionValueProperties>(g_property_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002425 plugin_properties_sp->AppendProperty(
2426 g_property_name, ConstString("Settings specific to plugins"), true,
2427 plugin_type_properties_sp);
2428 }
2429 return plugin_type_properties_sp;
2430 }
2431 }
2432 return lldb::OptionValuePropertiesSP();
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002433}
2434
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002435namespace {
2436
2437typedef lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002438GetDebuggerPropertyForPluginsPtr(Debugger &, const ConstString &,
2439 const ConstString &, bool can_create);
Jason Molenda3b59f5c2013-04-05 22:40:42 +00002440
Greg Claytone8cd0c92012-10-19 18:02:49 +00002441lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002442GetSettingForPlugin(Debugger &debugger, const ConstString &setting_name,
2443 const ConstString &plugin_type_name,
2444 GetDebuggerPropertyForPluginsPtr get_debugger_property =
2445 GetDebuggerPropertyForPlugins) {
2446 lldb::OptionValuePropertiesSP properties_sp;
2447 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
2448 debugger, plugin_type_name,
2449 ConstString(), // not creating to so we don't need the description
2450 false));
2451 if (plugin_type_properties_sp)
2452 properties_sp =
2453 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2454 return properties_sp;
Greg Claytone8cd0c92012-10-19 18:02:49 +00002455}
2456
Kate Stoneb9c1b512016-09-06 20:57:50 +00002457bool CreateSettingForPlugin(
2458 Debugger &debugger, const ConstString &plugin_type_name,
2459 const ConstString &plugin_type_desc,
2460 const lldb::OptionValuePropertiesSP &properties_sp,
2461 const ConstString &description, bool is_global_property,
2462 GetDebuggerPropertyForPluginsPtr get_debugger_property =
2463 GetDebuggerPropertyForPlugins) {
2464 if (properties_sp) {
2465 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2466 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
2467 true));
2468 if (plugin_type_properties_sp) {
2469 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2470 description, is_global_property,
2471 properties_sp);
2472 return true;
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002473 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002474 }
2475 return false;
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002476}
2477
Kate Stoneb9c1b512016-09-06 20:57:50 +00002478const char *kDynamicLoaderPluginName("dynamic-loader");
2479const char *kPlatformPluginName("platform");
2480const char *kProcessPluginName("process");
2481const char *kSymbolFilePluginName("symbol-file");
2482const char *kJITLoaderPluginName("jit-loader");
2483const char *kStructuredDataPluginName("structured-data");
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002484
Eugene Zelenko89183722016-03-11 21:55:47 +00002485} // anonymous namespace
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002486
Kate Stoneb9c1b512016-09-06 20:57:50 +00002487lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(
2488 Debugger &debugger, const ConstString &setting_name) {
2489 return GetSettingForPlugin(debugger, setting_name,
2490 ConstString(kDynamicLoaderPluginName));
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002491}
2492
Kate Stoneb9c1b512016-09-06 20:57:50 +00002493bool PluginManager::CreateSettingForDynamicLoaderPlugin(
2494 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2495 const ConstString &description, bool is_global_property) {
2496 return CreateSettingForPlugin(
2497 debugger, ConstString(kDynamicLoaderPluginName),
2498 ConstString("Settings for dynamic loader plug-ins"), properties_sp,
2499 description, is_global_property);
Greg Claytone8cd0c92012-10-19 18:02:49 +00002500}
2501
Jason Molenda9b837a12013-04-05 05:06:39 +00002502lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002503PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
2504 const ConstString &setting_name) {
2505 return GetSettingForPlugin(debugger, setting_name,
2506 ConstString(kPlatformPluginName),
2507 GetDebuggerPropertyForPluginsOldStyle);
Jason Molenda9b837a12013-04-05 05:06:39 +00002508}
2509
Kate Stoneb9c1b512016-09-06 20:57:50 +00002510bool PluginManager::CreateSettingForPlatformPlugin(
2511 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2512 const ConstString &description, bool is_global_property) {
2513 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
2514 ConstString("Settings for platform plug-ins"),
2515 properties_sp, description, is_global_property,
2516 GetDebuggerPropertyForPluginsOldStyle);
Greg Clayton7f982402013-07-15 22:54:20 +00002517}
2518
Greg Clayton7f982402013-07-15 22:54:20 +00002519lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002520PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
2521 const ConstString &setting_name) {
2522 return GetSettingForPlugin(debugger, setting_name,
2523 ConstString(kProcessPluginName));
Greg Clayton7f982402013-07-15 22:54:20 +00002524}
2525
Kate Stoneb9c1b512016-09-06 20:57:50 +00002526bool PluginManager::CreateSettingForProcessPlugin(
2527 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2528 const ConstString &description, bool is_global_property) {
2529 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
2530 ConstString("Settings for process plug-ins"),
2531 properties_sp, description, is_global_property);
Jason Molenda9b837a12013-04-05 05:06:39 +00002532}
2533
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002534lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002535PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
2536 const ConstString &setting_name) {
2537 return GetSettingForPlugin(debugger, setting_name,
2538 ConstString(kSymbolFilePluginName));
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002539}
2540
Kate Stoneb9c1b512016-09-06 20:57:50 +00002541bool PluginManager::CreateSettingForSymbolFilePlugin(
2542 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2543 const ConstString &description, bool is_global_property) {
2544 return CreateSettingForPlugin(
2545 debugger, ConstString(kSymbolFilePluginName),
2546 ConstString("Settings for symbol file plug-ins"), properties_sp,
2547 description, is_global_property);
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002548}
2549
2550lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00002551PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
2552 const ConstString &setting_name) {
2553 return GetSettingForPlugin(debugger, setting_name,
2554 ConstString(kJITLoaderPluginName));
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +00002555}
2556
Kate Stoneb9c1b512016-09-06 20:57:50 +00002557bool PluginManager::CreateSettingForJITLoaderPlugin(
2558 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2559 const ConstString &description, bool is_global_property) {
2560 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
2561 ConstString("Settings for JIT loader plug-ins"),
2562 properties_sp, description, is_global_property);
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +00002563}
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002564
2565static const char *kOperatingSystemPluginName("os");
2566
Kate Stoneb9c1b512016-09-06 20:57:50 +00002567lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin(
2568 Debugger &debugger, const ConstString &setting_name) {
2569 lldb::OptionValuePropertiesSP properties_sp;
2570 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2571 GetDebuggerPropertyForPlugins(
2572 debugger, ConstString(kOperatingSystemPluginName),
2573 ConstString(), // not creating to so we don't need the description
2574 false));
2575 if (plugin_type_properties_sp)
2576 properties_sp =
2577 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2578 return properties_sp;
2579}
2580
2581bool PluginManager::CreateSettingForOperatingSystemPlugin(
2582 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2583 const ConstString &description, bool is_global_property) {
2584 if (properties_sp) {
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002585 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002586 GetDebuggerPropertyForPlugins(
2587 debugger, ConstString(kOperatingSystemPluginName),
2588 ConstString("Settings for operating system plug-ins"), true));
2589 if (plugin_type_properties_sp) {
2590 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2591 description, is_global_property,
2592 properties_sp);
2593 return true;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002594 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002595 }
2596 return false;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00002597}
Todd Fiala75930012016-08-19 04:21:48 +00002598
Kate Stoneb9c1b512016-09-06 20:57:50 +00002599lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin(
2600 Debugger &debugger, const ConstString &setting_name) {
2601 return GetSettingForPlugin(debugger, setting_name,
2602 ConstString(kStructuredDataPluginName));
Todd Fiala75930012016-08-19 04:21:48 +00002603}
2604
Kate Stoneb9c1b512016-09-06 20:57:50 +00002605bool PluginManager::CreateSettingForStructuredDataPlugin(
2606 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2607 const ConstString &description, bool is_global_property) {
2608 return CreateSettingForPlugin(
2609 debugger, ConstString(kStructuredDataPluginName),
2610 ConstString("Settings for structured data plug-ins"), properties_sp,
2611 description, is_global_property);
Todd Fiala75930012016-08-19 04:21:48 +00002612}