1 //===-- 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
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Host/FileSystem.h"
14 #include "lldb/Host/HostInfo.h"
15 #include "lldb/Interpreter/OptionValueProperties.h"
16 #include "lldb/Utility/ConstString.h"
17 #include "lldb/Utility/FileSpec.h"
18 #include "lldb/Utility/Status.h"
19 #include "lldb/Utility/StringList.h"
20
21 #if defined(_WIN32)
22 #include "lldb/Host/windows/PosixApi.h"
23 #endif
24
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/Support/DynamicLibrary.h"
27 #include "llvm/Support/FileSystem.h"
28 #include "llvm/Support/raw_ostream.h"
29
30 #include <map>
31 #include <memory>
32 #include <mutex>
33 #include <string>
34 #include <utility>
35 #include <vector>
36
37 #include <assert.h>
38
39 namespace lldb_private {
40 class CommandInterpreter;
41 }
42
43 using namespace lldb;
44 using namespace lldb_private;
45
46 enum PluginAction {
47 ePluginRegisterInstance,
48 ePluginUnregisterInstance,
49 ePluginGetInstanceAtIndex
50 };
51
52 typedef bool (*PluginInitCallback)();
53 typedef void (*PluginTermCallback)();
54
55 struct PluginInfo {
PluginInfoPluginInfo56 PluginInfo() : plugin_init_callback(nullptr), plugin_term_callback(nullptr) {}
57
58 llvm::sys::DynamicLibrary library;
59 PluginInitCallback plugin_init_callback;
60 PluginTermCallback plugin_term_callback;
61 };
62
63 typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
64
GetPluginMapMutex()65 static std::recursive_mutex &GetPluginMapMutex() {
66 static std::recursive_mutex g_plugin_map_mutex;
67 return g_plugin_map_mutex;
68 }
69
GetPluginMap()70 static PluginTerminateMap &GetPluginMap() {
71 static PluginTerminateMap g_plugin_map;
72 return g_plugin_map;
73 }
74
PluginIsLoaded(const FileSpec & plugin_file_spec)75 static 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();
79 }
80
SetPluginInfo(const FileSpec & plugin_file_spec,const PluginInfo & plugin_info)81 static 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;
87 }
88
CastToFPtr(void * VPtr)89 template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
90 return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
91 }
92
93 static FileSystem::EnumerateDirectoryResult
LoadPluginCallback(void * baton,llvm::sys::fs::file_type ft,llvm::StringRef path)94 LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
95 llvm::StringRef path) {
96 // PluginManager *plugin_manager = (PluginManager *)baton;
97 Status error;
98
99 namespace fs = llvm::sys::fs;
100 // 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
102 // enumeration might be enumerating a file system that doesn't have correct
103 // file type information.
104 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
105 ft == fs::file_type::type_unknown) {
106 FileSpec plugin_file_spec(path);
107 FileSystem::Instance().Resolve(plugin_file_spec);
108
109 if (PluginIsLoaded(plugin_file_spec))
110 return FileSystem::eEnumerateDirectoryResultNext;
111 else {
112 PluginInfo plugin_info;
113
114 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();
124 }
125
126 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
132 // 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.
135 plugin_info = PluginInfo();
136 }
137
138 // 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.
140 SetPluginInfo(plugin_file_spec, plugin_info);
141
142 return FileSystem::eEnumerateDirectoryResultNext;
143 }
144 }
145 }
146
147 if (ft == fs::file_type::directory_file ||
148 ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
149 // 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
152 // information.
153 return FileSystem::eEnumerateDirectoryResultEnter;
154 }
155
156 return FileSystem::eEnumerateDirectoryResultNext;
157 }
158
Initialize()159 void PluginManager::Initialize() {
160 #if 1
161 const bool find_directories = true;
162 const bool find_files = true;
163 const bool find_other = true;
164 char dir_path[PATH_MAX];
165 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
166 if (FileSystem::Instance().Exists(dir_spec) &&
167 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
168 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
169 find_files, find_other,
170 LoadPluginCallback, nullptr);
171 }
172 }
173
174 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
175 if (FileSystem::Instance().Exists(dir_spec) &&
176 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
177 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
178 find_files, find_other,
179 LoadPluginCallback, nullptr);
180 }
181 }
182 #endif
183 }
184
Terminate()185 void 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) {
191 // Call the plug-in "void LLDBPluginTerminate (void)" function if there is
192 // one (if the symbol was not nullptr).
193 if (pos->second.library.isValid()) {
194 if (pos->second.plugin_term_callback)
195 pos->second.plugin_term_callback();
196 }
197 }
198 plugin_map.clear();
199 }
200
201 #pragma mark ABI
202
203 struct ABIInstance {
ABIInstanceABIInstance204 ABIInstance() : name(), description(), create_callback(nullptr) {}
205
206 ConstString name;
207 std::string description;
208 ABICreateInstance create_callback;
209 };
210
211 typedef std::vector<ABIInstance> ABIInstances;
212
GetABIInstancesMutex()213 static std::recursive_mutex &GetABIInstancesMutex() {
214 static std::recursive_mutex g_instances_mutex;
215 return g_instances_mutex;
216 }
217
GetABIInstances()218 static ABIInstances &GetABIInstances() {
219 static ABIInstances g_instances;
220 return g_instances;
221 }
222
RegisterPlugin(const ConstString & name,const char * description,ABICreateInstance create_callback)223 bool 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;
233 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
234 GetABIInstances().push_back(instance);
235 return true;
236 }
237 return false;
238 }
239
UnregisterPlugin(ABICreateInstance create_callback)240 bool 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
GetABICreateCallbackAtIndex(uint32_t idx)256 ABICreateInstance 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;
262 }
263
264 ABICreateInstance
GetABICreateCallbackForPluginName(const ConstString & name)265 PluginManager::GetABICreateCallbackForPluginName(const ConstString &name) {
266 if (name) {
267 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
268 ABIInstances &instances = GetABIInstances();
269
270 ABIInstances::iterator pos, end = instances.end();
271 for (pos = instances.begin(); pos != end; ++pos) {
272 if (name == pos->name)
273 return pos->create_callback;
274 }
275 }
276 return nullptr;
277 }
278
279 #pragma mark Architecture
280
281 struct ArchitectureInstance {
282 ConstString name;
283 std::string description;
284 PluginManager::ArchitectureCreateInstance create_callback;
285 };
286
287 typedef std::vector<ArchitectureInstance> ArchitectureInstances;
288
GetArchitectureMutex()289 static std::mutex &GetArchitectureMutex() {
290 static std::mutex g_architecture_mutex;
291 return g_architecture_mutex;
292 }
293
GetArchitectureInstances()294 static ArchitectureInstances &GetArchitectureInstances() {
295 static ArchitectureInstances g_instances;
296 return g_instances;
297 }
298
RegisterPlugin(const ConstString & name,llvm::StringRef description,ArchitectureCreateInstance create_callback)299 void PluginManager::RegisterPlugin(const ConstString &name,
300 llvm::StringRef description,
301 ArchitectureCreateInstance create_callback) {
302 std::lock_guard<std::mutex> guard(GetArchitectureMutex());
303 GetArchitectureInstances().push_back({name, description, create_callback});
304 }
305
UnregisterPlugin(ArchitectureCreateInstance create_callback)306 void PluginManager::UnregisterPlugin(
307 ArchitectureCreateInstance create_callback) {
308 std::lock_guard<std::mutex> guard(GetArchitectureMutex());
309 auto &instances = GetArchitectureInstances();
310
311 for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
312 if (pos->create_callback == create_callback) {
313 instances.erase(pos);
314 return;
315 }
316 }
317 llvm_unreachable("Plugin not found");
318 }
319
320 std::unique_ptr<Architecture>
CreateArchitectureInstance(const ArchSpec & arch)321 PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
322 std::lock_guard<std::mutex> guard(GetArchitectureMutex());
323 for (const auto &instances : GetArchitectureInstances()) {
324 if (auto plugin_up = instances.create_callback(arch))
325 return plugin_up;
326 }
327 return nullptr;
328 }
329
330 #pragma mark Disassembler
331
332 struct DisassemblerInstance {
DisassemblerInstanceDisassemblerInstance333 DisassemblerInstance() : name(), description(), create_callback(nullptr) {}
334
335 ConstString name;
336 std::string description;
337 DisassemblerCreateInstance create_callback;
338 };
339
340 typedef std::vector<DisassemblerInstance> DisassemblerInstances;
341
GetDisassemblerMutex()342 static std::recursive_mutex &GetDisassemblerMutex() {
343 static std::recursive_mutex g_instances_mutex;
344 return g_instances_mutex;
345 }
346
GetDisassemblerInstances()347 static DisassemblerInstances &GetDisassemblerInstances() {
348 static DisassemblerInstances g_instances;
349 return g_instances;
350 }
351
RegisterPlugin(const ConstString & name,const char * description,DisassemblerCreateInstance create_callback)352 bool PluginManager::RegisterPlugin(const ConstString &name,
353 const char *description,
354 DisassemblerCreateInstance create_callback) {
355 if (create_callback) {
356 DisassemblerInstance instance;
357 assert((bool)name);
358 instance.name = name;
359 if (description && description[0])
360 instance.description = description;
361 instance.create_callback = create_callback;
362 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
363 GetDisassemblerInstances().push_back(instance);
364 return true;
365 }
366 return false;
367 }
368
UnregisterPlugin(DisassemblerCreateInstance create_callback)369 bool PluginManager::UnregisterPlugin(
370 DisassemblerCreateInstance create_callback) {
371 if (create_callback) {
372 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
373 DisassemblerInstances &instances = GetDisassemblerInstances();
374
375 DisassemblerInstances::iterator pos, end = instances.end();
376 for (pos = instances.begin(); pos != end; ++pos) {
377 if (pos->create_callback == create_callback) {
378 instances.erase(pos);
379 return true;
380 }
381 }
382 }
383 return false;
384 }
385
386 DisassemblerCreateInstance
GetDisassemblerCreateCallbackAtIndex(uint32_t idx)387 PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
388 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
389 DisassemblerInstances &instances = GetDisassemblerInstances();
390 if (idx < instances.size())
391 return instances[idx].create_callback;
392 return nullptr;
393 }
394
395 DisassemblerCreateInstance
GetDisassemblerCreateCallbackForPluginName(const ConstString & name)396 PluginManager::GetDisassemblerCreateCallbackForPluginName(
397 const ConstString &name) {
398 if (name) {
399 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
400 DisassemblerInstances &instances = GetDisassemblerInstances();
401
402 DisassemblerInstances::iterator pos, end = instances.end();
403 for (pos = instances.begin(); pos != end; ++pos) {
404 if (name == pos->name)
405 return pos->create_callback;
406 }
407 }
408 return nullptr;
409 }
410
411 #pragma mark DynamicLoader
412
413 struct DynamicLoaderInstance {
DynamicLoaderInstanceDynamicLoaderInstance414 DynamicLoaderInstance()
415 : name(), description(), create_callback(nullptr),
416 debugger_init_callback(nullptr) {}
417
418 ConstString name;
419 std::string description;
420 DynamicLoaderCreateInstance create_callback;
421 DebuggerInitializeCallback debugger_init_callback;
422 };
423
424 typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
425
GetDynamicLoaderMutex()426 static std::recursive_mutex &GetDynamicLoaderMutex() {
427 static std::recursive_mutex g_instances_mutex;
428 return g_instances_mutex;
429 }
430
GetDynamicLoaderInstances()431 static DynamicLoaderInstances &GetDynamicLoaderInstances() {
432 static DynamicLoaderInstances g_instances;
433 return g_instances;
434 }
435
RegisterPlugin(const ConstString & name,const char * description,DynamicLoaderCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)436 bool PluginManager::RegisterPlugin(
437 const ConstString &name, const char *description,
438 DynamicLoaderCreateInstance create_callback,
439 DebuggerInitializeCallback debugger_init_callback) {
440 if (create_callback) {
441 DynamicLoaderInstance instance;
442 assert((bool)name);
443 instance.name = name;
444 if (description && description[0])
445 instance.description = description;
446 instance.create_callback = create_callback;
447 instance.debugger_init_callback = debugger_init_callback;
448 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
449 GetDynamicLoaderInstances().push_back(instance);
450 }
451 return false;
452 }
453
UnregisterPlugin(DynamicLoaderCreateInstance create_callback)454 bool PluginManager::UnregisterPlugin(
455 DynamicLoaderCreateInstance create_callback) {
456 if (create_callback) {
457 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
458 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
459
460 DynamicLoaderInstances::iterator pos, end = instances.end();
461 for (pos = instances.begin(); pos != end; ++pos) {
462 if (pos->create_callback == create_callback) {
463 instances.erase(pos);
464 return true;
465 }
466 }
467 }
468 return false;
469 }
470
471 DynamicLoaderCreateInstance
GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx)472 PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
473 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
474 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
475 if (idx < instances.size())
476 return instances[idx].create_callback;
477 return nullptr;
478 }
479
480 DynamicLoaderCreateInstance
GetDynamicLoaderCreateCallbackForPluginName(const ConstString & name)481 PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
482 const ConstString &name) {
483 if (name) {
484 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
485 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
486
487 DynamicLoaderInstances::iterator pos, end = instances.end();
488 for (pos = instances.begin(); pos != end; ++pos) {
489 if (name == pos->name)
490 return pos->create_callback;
491 }
492 }
493 return nullptr;
494 }
495
496 #pragma mark JITLoader
497
498 struct JITLoaderInstance {
JITLoaderInstanceJITLoaderInstance499 JITLoaderInstance()
500 : name(), description(), create_callback(nullptr),
501 debugger_init_callback(nullptr) {}
502
503 ConstString name;
504 std::string description;
505 JITLoaderCreateInstance create_callback;
506 DebuggerInitializeCallback debugger_init_callback;
507 };
508
509 typedef std::vector<JITLoaderInstance> JITLoaderInstances;
510
GetJITLoaderMutex()511 static std::recursive_mutex &GetJITLoaderMutex() {
512 static std::recursive_mutex g_instances_mutex;
513 return g_instances_mutex;
514 }
515
GetJITLoaderInstances()516 static JITLoaderInstances &GetJITLoaderInstances() {
517 static JITLoaderInstances g_instances;
518 return g_instances;
519 }
520
RegisterPlugin(const ConstString & name,const char * description,JITLoaderCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)521 bool PluginManager::RegisterPlugin(
522 const ConstString &name, const char *description,
523 JITLoaderCreateInstance create_callback,
524 DebuggerInitializeCallback debugger_init_callback) {
525 if (create_callback) {
526 JITLoaderInstance instance;
527 assert((bool)name);
528 instance.name = name;
529 if (description && description[0])
530 instance.description = description;
531 instance.create_callback = create_callback;
532 instance.debugger_init_callback = debugger_init_callback;
533 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
534 GetJITLoaderInstances().push_back(instance);
535 }
536 return false;
537 }
538
UnregisterPlugin(JITLoaderCreateInstance create_callback)539 bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
540 if (create_callback) {
541 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
542 JITLoaderInstances &instances = GetJITLoaderInstances();
543
544 JITLoaderInstances::iterator pos, end = instances.end();
545 for (pos = instances.begin(); pos != end; ++pos) {
546 if (pos->create_callback == create_callback) {
547 instances.erase(pos);
548 return true;
549 }
550 }
551 }
552 return false;
553 }
554
555 JITLoaderCreateInstance
GetJITLoaderCreateCallbackAtIndex(uint32_t idx)556 PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
557 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
558 JITLoaderInstances &instances = GetJITLoaderInstances();
559 if (idx < instances.size())
560 return instances[idx].create_callback;
561 return nullptr;
562 }
563
GetJITLoaderCreateCallbackForPluginName(const ConstString & name)564 JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName(
565 const ConstString &name) {
566 if (name) {
567 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
568 JITLoaderInstances &instances = GetJITLoaderInstances();
569
570 JITLoaderInstances::iterator pos, end = instances.end();
571 for (pos = instances.begin(); pos != end; ++pos) {
572 if (name == pos->name)
573 return pos->create_callback;
574 }
575 }
576 return nullptr;
577 }
578
579 #pragma mark EmulateInstruction
580
581 struct EmulateInstructionInstance {
EmulateInstructionInstanceEmulateInstructionInstance582 EmulateInstructionInstance()
583 : name(), description(), create_callback(nullptr) {}
584
585 ConstString name;
586 std::string description;
587 EmulateInstructionCreateInstance create_callback;
588 };
589
590 typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
591
GetEmulateInstructionMutex()592 static std::recursive_mutex &GetEmulateInstructionMutex() {
593 static std::recursive_mutex g_instances_mutex;
594 return g_instances_mutex;
595 }
596
GetEmulateInstructionInstances()597 static EmulateInstructionInstances &GetEmulateInstructionInstances() {
598 static EmulateInstructionInstances g_instances;
599 return g_instances;
600 }
601
RegisterPlugin(const ConstString & name,const char * description,EmulateInstructionCreateInstance create_callback)602 bool PluginManager::RegisterPlugin(
603 const ConstString &name, const char *description,
604 EmulateInstructionCreateInstance create_callback) {
605 if (create_callback) {
606 EmulateInstructionInstance instance;
607 assert((bool)name);
608 instance.name = name;
609 if (description && description[0])
610 instance.description = description;
611 instance.create_callback = create_callback;
612 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
613 GetEmulateInstructionInstances().push_back(instance);
614 }
615 return false;
616 }
617
UnregisterPlugin(EmulateInstructionCreateInstance create_callback)618 bool PluginManager::UnregisterPlugin(
619 EmulateInstructionCreateInstance create_callback) {
620 if (create_callback) {
621 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
622 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
623
624 EmulateInstructionInstances::iterator pos, end = instances.end();
625 for (pos = instances.begin(); pos != end; ++pos) {
626 if (pos->create_callback == create_callback) {
627 instances.erase(pos);
628 return true;
629 }
630 }
631 }
632 return false;
633 }
634
635 EmulateInstructionCreateInstance
GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx)636 PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
637 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
638 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
639 if (idx < instances.size())
640 return instances[idx].create_callback;
641 return nullptr;
642 }
643
644 EmulateInstructionCreateInstance
GetEmulateInstructionCreateCallbackForPluginName(const ConstString & name)645 PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
646 const ConstString &name) {
647 if (name) {
648 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
649 EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
650
651 EmulateInstructionInstances::iterator pos, end = instances.end();
652 for (pos = instances.begin(); pos != end; ++pos) {
653 if (name == pos->name)
654 return pos->create_callback;
655 }
656 }
657 return nullptr;
658 }
659
660 #pragma mark OperatingSystem
661
662 struct OperatingSystemInstance {
OperatingSystemInstanceOperatingSystemInstance663 OperatingSystemInstance()
664 : name(), description(), create_callback(nullptr),
665 debugger_init_callback(nullptr) {}
666
667 ConstString name;
668 std::string description;
669 OperatingSystemCreateInstance create_callback;
670 DebuggerInitializeCallback debugger_init_callback;
671 };
672
673 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
674
GetOperatingSystemMutex()675 static std::recursive_mutex &GetOperatingSystemMutex() {
676 static std::recursive_mutex g_instances_mutex;
677 return g_instances_mutex;
678 }
679
GetOperatingSystemInstances()680 static OperatingSystemInstances &GetOperatingSystemInstances() {
681 static OperatingSystemInstances g_instances;
682 return g_instances;
683 }
684
RegisterPlugin(const ConstString & name,const char * description,OperatingSystemCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)685 bool PluginManager::RegisterPlugin(
686 const ConstString &name, const char *description,
687 OperatingSystemCreateInstance create_callback,
688 DebuggerInitializeCallback debugger_init_callback) {
689 if (create_callback) {
690 OperatingSystemInstance instance;
691 assert((bool)name);
692 instance.name = name;
693 if (description && description[0])
694 instance.description = description;
695 instance.create_callback = create_callback;
696 instance.debugger_init_callback = debugger_init_callback;
697 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
698 GetOperatingSystemInstances().push_back(instance);
699 }
700 return false;
701 }
702
UnregisterPlugin(OperatingSystemCreateInstance create_callback)703 bool PluginManager::UnregisterPlugin(
704 OperatingSystemCreateInstance create_callback) {
705 if (create_callback) {
706 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
707 OperatingSystemInstances &instances = GetOperatingSystemInstances();
708
709 OperatingSystemInstances::iterator pos, end = instances.end();
710 for (pos = instances.begin(); pos != end; ++pos) {
711 if (pos->create_callback == create_callback) {
712 instances.erase(pos);
713 return true;
714 }
715 }
716 }
717 return false;
718 }
719
720 OperatingSystemCreateInstance
GetOperatingSystemCreateCallbackAtIndex(uint32_t idx)721 PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
722 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
723 OperatingSystemInstances &instances = GetOperatingSystemInstances();
724 if (idx < instances.size())
725 return instances[idx].create_callback;
726 return nullptr;
727 }
728
729 OperatingSystemCreateInstance
GetOperatingSystemCreateCallbackForPluginName(const ConstString & name)730 PluginManager::GetOperatingSystemCreateCallbackForPluginName(
731 const ConstString &name) {
732 if (name) {
733 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
734 OperatingSystemInstances &instances = GetOperatingSystemInstances();
735
736 OperatingSystemInstances::iterator pos, end = instances.end();
737 for (pos = instances.begin(); pos != end; ++pos) {
738 if (name == pos->name)
739 return pos->create_callback;
740 }
741 }
742 return nullptr;
743 }
744
745 #pragma mark Language
746
747 struct LanguageInstance {
LanguageInstanceLanguageInstance748 LanguageInstance() : name(), description(), create_callback(nullptr) {}
749
750 ConstString name;
751 std::string description;
752 LanguageCreateInstance create_callback;
753 };
754
755 typedef std::vector<LanguageInstance> LanguageInstances;
756
GetLanguageMutex()757 static std::recursive_mutex &GetLanguageMutex() {
758 static std::recursive_mutex g_instances_mutex;
759 return g_instances_mutex;
760 }
761
GetLanguageInstances()762 static LanguageInstances &GetLanguageInstances() {
763 static LanguageInstances g_instances;
764 return g_instances;
765 }
766
RegisterPlugin(const ConstString & name,const char * description,LanguageCreateInstance create_callback)767 bool PluginManager::RegisterPlugin(const ConstString &name,
768 const char *description,
769 LanguageCreateInstance create_callback) {
770 if (create_callback) {
771 LanguageInstance instance;
772 assert((bool)name);
773 instance.name = name;
774 if (description && description[0])
775 instance.description = description;
776 instance.create_callback = create_callback;
777 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
778 GetLanguageInstances().push_back(instance);
779 }
780 return false;
781 }
782
UnregisterPlugin(LanguageCreateInstance create_callback)783 bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
784 if (create_callback) {
785 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
786 LanguageInstances &instances = GetLanguageInstances();
787
788 LanguageInstances::iterator pos, end = instances.end();
789 for (pos = instances.begin(); pos != end; ++pos) {
790 if (pos->create_callback == create_callback) {
791 instances.erase(pos);
792 return true;
793 }
794 }
795 }
796 return false;
797 }
798
799 LanguageCreateInstance
GetLanguageCreateCallbackAtIndex(uint32_t idx)800 PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
801 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
802 LanguageInstances &instances = GetLanguageInstances();
803 if (idx < instances.size())
804 return instances[idx].create_callback;
805 return nullptr;
806 }
807
808 LanguageCreateInstance
GetLanguageCreateCallbackForPluginName(const ConstString & name)809 PluginManager::GetLanguageCreateCallbackForPluginName(const ConstString &name) {
810 if (name) {
811 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
812 LanguageInstances &instances = GetLanguageInstances();
813
814 LanguageInstances::iterator pos, end = instances.end();
815 for (pos = instances.begin(); pos != end; ++pos) {
816 if (name == pos->name)
817 return pos->create_callback;
818 }
819 }
820 return nullptr;
821 }
822
823 #pragma mark LanguageRuntime
824
825 struct LanguageRuntimeInstance {
LanguageRuntimeInstanceLanguageRuntimeInstance826 LanguageRuntimeInstance() : name(), description(), create_callback(nullptr) {}
827
828 ConstString name;
829 std::string description;
830 LanguageRuntimeCreateInstance create_callback;
831 LanguageRuntimeGetCommandObject command_callback;
832 };
833
834 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
835
GetLanguageRuntimeMutex()836 static std::recursive_mutex &GetLanguageRuntimeMutex() {
837 static std::recursive_mutex g_instances_mutex;
838 return g_instances_mutex;
839 }
840
GetLanguageRuntimeInstances()841 static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
842 static LanguageRuntimeInstances g_instances;
843 return g_instances;
844 }
845
RegisterPlugin(const ConstString & name,const char * description,LanguageRuntimeCreateInstance create_callback,LanguageRuntimeGetCommandObject command_callback)846 bool PluginManager::RegisterPlugin(
847 const ConstString &name, const char *description,
848 LanguageRuntimeCreateInstance create_callback,
849 LanguageRuntimeGetCommandObject command_callback) {
850 if (create_callback) {
851 LanguageRuntimeInstance instance;
852 assert((bool)name);
853 instance.name = name;
854 if (description && description[0])
855 instance.description = description;
856 instance.create_callback = create_callback;
857 instance.command_callback = command_callback;
858 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
859 GetLanguageRuntimeInstances().push_back(instance);
860 }
861 return false;
862 }
863
UnregisterPlugin(LanguageRuntimeCreateInstance create_callback)864 bool PluginManager::UnregisterPlugin(
865 LanguageRuntimeCreateInstance create_callback) {
866 if (create_callback) {
867 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
868 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
869
870 LanguageRuntimeInstances::iterator pos, end = instances.end();
871 for (pos = instances.begin(); pos != end; ++pos) {
872 if (pos->create_callback == create_callback) {
873 instances.erase(pos);
874 return true;
875 }
876 }
877 }
878 return false;
879 }
880
881 LanguageRuntimeCreateInstance
GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx)882 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
883 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
884 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
885 if (idx < instances.size())
886 return instances[idx].create_callback;
887 return nullptr;
888 }
889
890 LanguageRuntimeGetCommandObject
GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx)891 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
892 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
893 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
894 if (idx < instances.size())
895 return instances[idx].command_callback;
896 return nullptr;
897 }
898
899 LanguageRuntimeCreateInstance
GetLanguageRuntimeCreateCallbackForPluginName(const ConstString & name)900 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
901 const ConstString &name) {
902 if (name) {
903 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
904 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
905
906 LanguageRuntimeInstances::iterator pos, end = instances.end();
907 for (pos = instances.begin(); pos != end; ++pos) {
908 if (name == pos->name)
909 return pos->create_callback;
910 }
911 }
912 return nullptr;
913 }
914
915 #pragma mark SystemRuntime
916
917 struct SystemRuntimeInstance {
SystemRuntimeInstanceSystemRuntimeInstance918 SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {}
919
920 ConstString name;
921 std::string description;
922 SystemRuntimeCreateInstance create_callback;
923 };
924
925 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
926
GetSystemRuntimeMutex()927 static std::recursive_mutex &GetSystemRuntimeMutex() {
928 static std::recursive_mutex g_instances_mutex;
929 return g_instances_mutex;
930 }
931
GetSystemRuntimeInstances()932 static SystemRuntimeInstances &GetSystemRuntimeInstances() {
933 static SystemRuntimeInstances g_instances;
934 return g_instances;
935 }
936
RegisterPlugin(const ConstString & name,const char * description,SystemRuntimeCreateInstance create_callback)937 bool PluginManager::RegisterPlugin(
938 const ConstString &name, const char *description,
939 SystemRuntimeCreateInstance create_callback) {
940 if (create_callback) {
941 SystemRuntimeInstance instance;
942 assert((bool)name);
943 instance.name = name;
944 if (description && description[0])
945 instance.description = description;
946 instance.create_callback = create_callback;
947 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
948 GetSystemRuntimeInstances().push_back(instance);
949 }
950 return false;
951 }
952
UnregisterPlugin(SystemRuntimeCreateInstance create_callback)953 bool PluginManager::UnregisterPlugin(
954 SystemRuntimeCreateInstance create_callback) {
955 if (create_callback) {
956 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
957 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
958
959 SystemRuntimeInstances::iterator pos, end = instances.end();
960 for (pos = instances.begin(); pos != end; ++pos) {
961 if (pos->create_callback == create_callback) {
962 instances.erase(pos);
963 return true;
964 }
965 }
966 }
967 return false;
968 }
969
970 SystemRuntimeCreateInstance
GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx)971 PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
972 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
973 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
974 if (idx < instances.size())
975 return instances[idx].create_callback;
976 return nullptr;
977 }
978
979 SystemRuntimeCreateInstance
GetSystemRuntimeCreateCallbackForPluginName(const ConstString & name)980 PluginManager::GetSystemRuntimeCreateCallbackForPluginName(
981 const ConstString &name) {
982 if (name) {
983 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
984 SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
985
986 SystemRuntimeInstances::iterator pos, end = instances.end();
987 for (pos = instances.begin(); pos != end; ++pos) {
988 if (name == pos->name)
989 return pos->create_callback;
990 }
991 }
992 return nullptr;
993 }
994
995 #pragma mark ObjectFile
996
997 struct ObjectFileInstance {
ObjectFileInstanceObjectFileInstance998 ObjectFileInstance()
999 : name(), description(), create_callback(nullptr),
1000 create_memory_callback(nullptr), get_module_specifications(nullptr),
1001 save_core(nullptr) {}
1002
1003 ConstString name;
1004 std::string description;
1005 ObjectFileCreateInstance create_callback;
1006 ObjectFileCreateMemoryInstance create_memory_callback;
1007 ObjectFileGetModuleSpecifications get_module_specifications;
1008 ObjectFileSaveCore save_core;
1009 };
1010
1011 typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1012
GetObjectFileMutex()1013 static std::recursive_mutex &GetObjectFileMutex() {
1014 static std::recursive_mutex g_instances_mutex;
1015 return g_instances_mutex;
1016 }
1017
GetObjectFileInstances()1018 static ObjectFileInstances &GetObjectFileInstances() {
1019 static ObjectFileInstances g_instances;
1020 return g_instances;
1021 }
1022
RegisterPlugin(const ConstString & name,const char * description,ObjectFileCreateInstance create_callback,ObjectFileCreateMemoryInstance create_memory_callback,ObjectFileGetModuleSpecifications get_module_specifications,ObjectFileSaveCore save_core)1023 bool PluginManager::RegisterPlugin(
1024 const ConstString &name, const char *description,
1025 ObjectFileCreateInstance create_callback,
1026 ObjectFileCreateMemoryInstance create_memory_callback,
1027 ObjectFileGetModuleSpecifications get_module_specifications,
1028 ObjectFileSaveCore save_core) {
1029 if (create_callback) {
1030 ObjectFileInstance instance;
1031 assert((bool)name);
1032 instance.name = name;
1033 if (description && description[0])
1034 instance.description = description;
1035 instance.create_callback = create_callback;
1036 instance.create_memory_callback = create_memory_callback;
1037 instance.save_core = save_core;
1038 instance.get_module_specifications = get_module_specifications;
1039 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1040 GetObjectFileInstances().push_back(instance);
1041 }
1042 return false;
1043 }
1044
UnregisterPlugin(ObjectFileCreateInstance create_callback)1045 bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
1046 if (create_callback) {
1047 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1048 ObjectFileInstances &instances = GetObjectFileInstances();
1049
1050 ObjectFileInstances::iterator pos, end = instances.end();
1051 for (pos = instances.begin(); pos != end; ++pos) {
1052 if (pos->create_callback == create_callback) {
1053 instances.erase(pos);
1054 return true;
1055 }
1056 }
1057 }
1058 return false;
1059 }
1060
1061 ObjectFileCreateInstance
GetObjectFileCreateCallbackAtIndex(uint32_t idx)1062 PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
1063 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1064 ObjectFileInstances &instances = GetObjectFileInstances();
1065 if (idx < instances.size())
1066 return instances[idx].create_callback;
1067 return nullptr;
1068 }
1069
1070 ObjectFileCreateMemoryInstance
GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx)1071 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
1072 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1073 ObjectFileInstances &instances = GetObjectFileInstances();
1074 if (idx < instances.size())
1075 return instances[idx].create_memory_callback;
1076 return nullptr;
1077 }
1078
1079 ObjectFileGetModuleSpecifications
GetObjectFileGetModuleSpecificationsCallbackAtIndex(uint32_t idx)1080 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
1081 uint32_t idx) {
1082 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1083 ObjectFileInstances &instances = GetObjectFileInstances();
1084 if (idx < instances.size())
1085 return instances[idx].get_module_specifications;
1086 return nullptr;
1087 }
1088
1089 ObjectFileCreateInstance
GetObjectFileCreateCallbackForPluginName(const ConstString & name)1090 PluginManager::GetObjectFileCreateCallbackForPluginName(
1091 const ConstString &name) {
1092 if (name) {
1093 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1094 ObjectFileInstances &instances = GetObjectFileInstances();
1095
1096 ObjectFileInstances::iterator pos, end = instances.end();
1097 for (pos = instances.begin(); pos != end; ++pos) {
1098 if (name == pos->name)
1099 return pos->create_callback;
1100 }
1101 }
1102 return nullptr;
1103 }
1104
1105 ObjectFileCreateMemoryInstance
GetObjectFileCreateMemoryCallbackForPluginName(const ConstString & name)1106 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
1107 const ConstString &name) {
1108 if (name) {
1109 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1110 ObjectFileInstances &instances = GetObjectFileInstances();
1111
1112 ObjectFileInstances::iterator pos, end = instances.end();
1113 for (pos = instances.begin(); pos != end; ++pos) {
1114 if (name == pos->name)
1115 return pos->create_memory_callback;
1116 }
1117 }
1118 return nullptr;
1119 }
1120
SaveCore(const lldb::ProcessSP & process_sp,const FileSpec & outfile)1121 Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
1122 const FileSpec &outfile) {
1123 Status error;
1124 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1125 ObjectFileInstances &instances = GetObjectFileInstances();
1126
1127 ObjectFileInstances::iterator pos, end = instances.end();
1128 for (pos = instances.begin(); pos != end; ++pos) {
1129 if (pos->save_core && pos->save_core(process_sp, outfile, error))
1130 return error;
1131 }
1132 error.SetErrorString(
1133 "no ObjectFile plugins were able to save a core for this process");
1134 return error;
1135 }
1136
1137 #pragma mark ObjectContainer
1138
1139 struct ObjectContainerInstance {
ObjectContainerInstanceObjectContainerInstance1140 ObjectContainerInstance()
1141 : name(), description(), create_callback(nullptr),
1142 get_module_specifications(nullptr) {}
1143
1144 ConstString name;
1145 std::string description;
1146 ObjectContainerCreateInstance create_callback;
1147 ObjectFileGetModuleSpecifications get_module_specifications;
1148 };
1149
1150 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1151
GetObjectContainerMutex()1152 static std::recursive_mutex &GetObjectContainerMutex() {
1153 static std::recursive_mutex g_instances_mutex;
1154 return g_instances_mutex;
1155 }
1156
GetObjectContainerInstances()1157 static ObjectContainerInstances &GetObjectContainerInstances() {
1158 static ObjectContainerInstances g_instances;
1159 return g_instances;
1160 }
1161
RegisterPlugin(const ConstString & name,const char * description,ObjectContainerCreateInstance create_callback,ObjectFileGetModuleSpecifications get_module_specifications)1162 bool PluginManager::RegisterPlugin(
1163 const ConstString &name, const char *description,
1164 ObjectContainerCreateInstance create_callback,
1165 ObjectFileGetModuleSpecifications get_module_specifications) {
1166 if (create_callback) {
1167 ObjectContainerInstance instance;
1168 assert((bool)name);
1169 instance.name = name;
1170 if (description && description[0])
1171 instance.description = description;
1172 instance.create_callback = create_callback;
1173 instance.get_module_specifications = get_module_specifications;
1174 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1175 GetObjectContainerInstances().push_back(instance);
1176 }
1177 return false;
1178 }
1179
UnregisterPlugin(ObjectContainerCreateInstance create_callback)1180 bool PluginManager::UnregisterPlugin(
1181 ObjectContainerCreateInstance create_callback) {
1182 if (create_callback) {
1183 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1184 ObjectContainerInstances &instances = GetObjectContainerInstances();
1185
1186 ObjectContainerInstances::iterator pos, end = instances.end();
1187 for (pos = instances.begin(); pos != end; ++pos) {
1188 if (pos->create_callback == create_callback) {
1189 instances.erase(pos);
1190 return true;
1191 }
1192 }
1193 }
1194 return false;
1195 }
1196
1197 ObjectContainerCreateInstance
GetObjectContainerCreateCallbackAtIndex(uint32_t idx)1198 PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
1199 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1200 ObjectContainerInstances &instances = GetObjectContainerInstances();
1201 if (idx < instances.size())
1202 return instances[idx].create_callback;
1203 return nullptr;
1204 }
1205
1206 ObjectContainerCreateInstance
GetObjectContainerCreateCallbackForPluginName(const ConstString & name)1207 PluginManager::GetObjectContainerCreateCallbackForPluginName(
1208 const ConstString &name) {
1209 if (name) {
1210 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1211 ObjectContainerInstances &instances = GetObjectContainerInstances();
1212
1213 ObjectContainerInstances::iterator pos, end = instances.end();
1214 for (pos = instances.begin(); pos != end; ++pos) {
1215 if (name == pos->name)
1216 return pos->create_callback;
1217 }
1218 }
1219 return nullptr;
1220 }
1221
1222 ObjectFileGetModuleSpecifications
GetObjectContainerGetModuleSpecificationsCallbackAtIndex(uint32_t idx)1223 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
1224 uint32_t idx) {
1225 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1226 ObjectContainerInstances &instances = GetObjectContainerInstances();
1227 if (idx < instances.size())
1228 return instances[idx].get_module_specifications;
1229 return nullptr;
1230 }
1231
1232 #pragma mark Platform
1233
1234 struct PlatformInstance {
PlatformInstancePlatformInstance1235 PlatformInstance()
1236 : name(), description(), create_callback(nullptr),
1237 debugger_init_callback(nullptr) {}
1238
1239 ConstString name;
1240 std::string description;
1241 PlatformCreateInstance create_callback;
1242 DebuggerInitializeCallback debugger_init_callback;
1243 };
1244
1245 typedef std::vector<PlatformInstance> PlatformInstances;
1246
GetPlatformInstancesMutex()1247 static std::recursive_mutex &GetPlatformInstancesMutex() {
1248 static std::recursive_mutex g_platform_instances_mutex;
1249 return g_platform_instances_mutex;
1250 }
1251
GetPlatformInstances()1252 static PlatformInstances &GetPlatformInstances() {
1253 static PlatformInstances g_platform_instances;
1254 return g_platform_instances;
1255 }
1256
RegisterPlugin(const ConstString & name,const char * description,PlatformCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)1257 bool PluginManager::RegisterPlugin(
1258 const ConstString &name, const char *description,
1259 PlatformCreateInstance create_callback,
1260 DebuggerInitializeCallback debugger_init_callback) {
1261 if (create_callback) {
1262 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1263
1264 PlatformInstance instance;
1265 assert((bool)name);
1266 instance.name = name;
1267 if (description && description[0])
1268 instance.description = description;
1269 instance.create_callback = create_callback;
1270 instance.debugger_init_callback = debugger_init_callback;
1271 GetPlatformInstances().push_back(instance);
1272 return true;
1273 }
1274 return false;
1275 }
1276
GetPlatformPluginNameAtIndex(uint32_t idx)1277 const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
1278 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1279 PlatformInstances &instances = GetPlatformInstances();
1280 if (idx < instances.size())
1281 return instances[idx].name.GetCString();
1282 return nullptr;
1283 }
1284
GetPlatformPluginDescriptionAtIndex(uint32_t idx)1285 const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
1286 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1287 PlatformInstances &instances = GetPlatformInstances();
1288 if (idx < instances.size())
1289 return instances[idx].description.c_str();
1290 return nullptr;
1291 }
1292
UnregisterPlugin(PlatformCreateInstance create_callback)1293 bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
1294 if (create_callback) {
1295 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1296 PlatformInstances &instances = GetPlatformInstances();
1297
1298 PlatformInstances::iterator pos, end = instances.end();
1299 for (pos = instances.begin(); pos != end; ++pos) {
1300 if (pos->create_callback == create_callback) {
1301 instances.erase(pos);
1302 return true;
1303 }
1304 }
1305 }
1306 return false;
1307 }
1308
1309 PlatformCreateInstance
GetPlatformCreateCallbackAtIndex(uint32_t idx)1310 PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
1311 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1312 PlatformInstances &instances = GetPlatformInstances();
1313 if (idx < instances.size())
1314 return instances[idx].create_callback;
1315 return nullptr;
1316 }
1317
1318 PlatformCreateInstance
GetPlatformCreateCallbackForPluginName(const ConstString & name)1319 PluginManager::GetPlatformCreateCallbackForPluginName(const ConstString &name) {
1320 if (name) {
1321 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1322 PlatformInstances &instances = GetPlatformInstances();
1323
1324 PlatformInstances::iterator pos, end = instances.end();
1325 for (pos = instances.begin(); pos != end; ++pos) {
1326 if (name == pos->name)
1327 return pos->create_callback;
1328 }
1329 }
1330 return nullptr;
1331 }
1332
AutoCompletePlatformName(llvm::StringRef name,StringList & matches)1333 size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
1334 StringList &matches) {
1335 if (name.empty())
1336 return matches.GetSize();
1337
1338 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1339 PlatformInstances &instances = GetPlatformInstances();
1340 llvm::StringRef name_sref(name);
1341
1342 PlatformInstances::iterator pos, end = instances.end();
1343 for (pos = instances.begin(); pos != end; ++pos) {
1344 llvm::StringRef plugin_name(pos->name.GetCString());
1345 if (plugin_name.startswith(name_sref))
1346 matches.AppendString(plugin_name.data());
1347 }
1348 return matches.GetSize();
1349 }
1350
1351 #pragma mark Process
1352
1353 struct ProcessInstance {
ProcessInstanceProcessInstance1354 ProcessInstance()
1355 : name(), description(), create_callback(nullptr),
1356 debugger_init_callback(nullptr) {}
1357
1358 ConstString name;
1359 std::string description;
1360 ProcessCreateInstance create_callback;
1361 DebuggerInitializeCallback debugger_init_callback;
1362 };
1363
1364 typedef std::vector<ProcessInstance> ProcessInstances;
1365
GetProcessMutex()1366 static std::recursive_mutex &GetProcessMutex() {
1367 static std::recursive_mutex g_instances_mutex;
1368 return g_instances_mutex;
1369 }
1370
GetProcessInstances()1371 static ProcessInstances &GetProcessInstances() {
1372 static ProcessInstances g_instances;
1373 return g_instances;
1374 }
1375
RegisterPlugin(const ConstString & name,const char * description,ProcessCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)1376 bool PluginManager::RegisterPlugin(
1377 const ConstString &name, const char *description,
1378 ProcessCreateInstance create_callback,
1379 DebuggerInitializeCallback debugger_init_callback) {
1380 if (create_callback) {
1381 ProcessInstance instance;
1382 assert((bool)name);
1383 instance.name = name;
1384 if (description && description[0])
1385 instance.description = description;
1386 instance.create_callback = create_callback;
1387 instance.debugger_init_callback = debugger_init_callback;
1388 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1389 GetProcessInstances().push_back(instance);
1390 }
1391 return false;
1392 }
1393
GetProcessPluginNameAtIndex(uint32_t idx)1394 const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
1395 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1396 ProcessInstances &instances = GetProcessInstances();
1397 if (idx < instances.size())
1398 return instances[idx].name.GetCString();
1399 return nullptr;
1400 }
1401
GetProcessPluginDescriptionAtIndex(uint32_t idx)1402 const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
1403 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1404 ProcessInstances &instances = GetProcessInstances();
1405 if (idx < instances.size())
1406 return instances[idx].description.c_str();
1407 return nullptr;
1408 }
1409
UnregisterPlugin(ProcessCreateInstance create_callback)1410 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
1411 if (create_callback) {
1412 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1413 ProcessInstances &instances = GetProcessInstances();
1414
1415 ProcessInstances::iterator pos, end = instances.end();
1416 for (pos = instances.begin(); pos != end; ++pos) {
1417 if (pos->create_callback == create_callback) {
1418 instances.erase(pos);
1419 return true;
1420 }
1421 }
1422 }
1423 return false;
1424 }
1425
1426 ProcessCreateInstance
GetProcessCreateCallbackAtIndex(uint32_t idx)1427 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
1428 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1429 ProcessInstances &instances = GetProcessInstances();
1430 if (idx < instances.size())
1431 return instances[idx].create_callback;
1432 return nullptr;
1433 }
1434
1435 ProcessCreateInstance
GetProcessCreateCallbackForPluginName(const ConstString & name)1436 PluginManager::GetProcessCreateCallbackForPluginName(const ConstString &name) {
1437 if (name) {
1438 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
1439 ProcessInstances &instances = GetProcessInstances();
1440
1441 ProcessInstances::iterator pos, end = instances.end();
1442 for (pos = instances.begin(); pos != end; ++pos) {
1443 if (name == pos->name)
1444 return pos->create_callback;
1445 }
1446 }
1447 return nullptr;
1448 }
1449
1450 #pragma mark ScriptInterpreter
1451
1452 struct ScriptInterpreterInstance {
ScriptInterpreterInstanceScriptInterpreterInstance1453 ScriptInterpreterInstance()
1454 : name(), language(lldb::eScriptLanguageNone), description(),
1455 create_callback(nullptr) {}
1456
1457 ConstString name;
1458 lldb::ScriptLanguage language;
1459 std::string description;
1460 ScriptInterpreterCreateInstance create_callback;
1461 };
1462
1463 typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
1464
GetScriptInterpreterMutex()1465 static std::recursive_mutex &GetScriptInterpreterMutex() {
1466 static std::recursive_mutex g_instances_mutex;
1467 return g_instances_mutex;
1468 }
1469
GetScriptInterpreterInstances()1470 static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
1471 static ScriptInterpreterInstances g_instances;
1472 return g_instances;
1473 }
1474
RegisterPlugin(const ConstString & name,const char * description,lldb::ScriptLanguage script_language,ScriptInterpreterCreateInstance create_callback)1475 bool PluginManager::RegisterPlugin(
1476 const ConstString &name, const char *description,
1477 lldb::ScriptLanguage script_language,
1478 ScriptInterpreterCreateInstance create_callback) {
1479 if (!create_callback)
1480 return false;
1481 ScriptInterpreterInstance instance;
1482 assert((bool)name);
1483 instance.name = name;
1484 if (description && description[0])
1485 instance.description = description;
1486 instance.create_callback = create_callback;
1487 instance.language = script_language;
1488 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1489 GetScriptInterpreterInstances().push_back(instance);
1490 return false;
1491 }
1492
UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)1493 bool PluginManager::UnregisterPlugin(
1494 ScriptInterpreterCreateInstance create_callback) {
1495 if (!create_callback)
1496 return false;
1497 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1498 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1499
1500 ScriptInterpreterInstances::iterator pos, end = instances.end();
1501 for (pos = instances.begin(); pos != end; ++pos) {
1502 if (pos->create_callback != create_callback)
1503 continue;
1504
1505 instances.erase(pos);
1506 return true;
1507 }
1508 return false;
1509 }
1510
1511 ScriptInterpreterCreateInstance
GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)1512 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
1513 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1514 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1515 if (idx < instances.size())
1516 return instances[idx].create_callback;
1517 return nullptr;
1518 }
1519
GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,CommandInterpreter & interpreter)1520 lldb::ScriptInterpreterSP PluginManager::GetScriptInterpreterForLanguage(
1521 lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter) {
1522 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
1523 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
1524
1525 ScriptInterpreterInstances::iterator pos, end = instances.end();
1526 ScriptInterpreterCreateInstance none_instance = nullptr;
1527 for (pos = instances.begin(); pos != end; ++pos) {
1528 if (pos->language == lldb::eScriptLanguageNone)
1529 none_instance = pos->create_callback;
1530
1531 if (script_lang == pos->language)
1532 return pos->create_callback(interpreter);
1533 }
1534
1535 // If we didn't find one, return the ScriptInterpreter for the null language.
1536 assert(none_instance != nullptr);
1537 return none_instance(interpreter);
1538 }
1539
1540 #pragma mark -
1541 #pragma mark StructuredDataPlugin
1542
1543 // -----------------------------------------------------------------------------
1544 // StructuredDataPlugin
1545 // -----------------------------------------------------------------------------
1546
1547 struct StructuredDataPluginInstance {
StructuredDataPluginInstanceStructuredDataPluginInstance1548 StructuredDataPluginInstance()
1549 : name(), description(), create_callback(nullptr),
1550 debugger_init_callback(nullptr), filter_callback(nullptr) {}
1551
1552 ConstString name;
1553 std::string description;
1554 StructuredDataPluginCreateInstance create_callback;
1555 DebuggerInitializeCallback debugger_init_callback;
1556 StructuredDataFilterLaunchInfo filter_callback;
1557 };
1558
1559 typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;
1560
GetStructuredDataPluginMutex()1561 static std::recursive_mutex &GetStructuredDataPluginMutex() {
1562 static std::recursive_mutex g_instances_mutex;
1563 return g_instances_mutex;
1564 }
1565
GetStructuredDataPluginInstances()1566 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
1567 static StructuredDataPluginInstances g_instances;
1568 return g_instances;
1569 }
1570
RegisterPlugin(const ConstString & name,const char * description,StructuredDataPluginCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback,StructuredDataFilterLaunchInfo filter_callback)1571 bool PluginManager::RegisterPlugin(
1572 const ConstString &name, const char *description,
1573 StructuredDataPluginCreateInstance create_callback,
1574 DebuggerInitializeCallback debugger_init_callback,
1575 StructuredDataFilterLaunchInfo filter_callback) {
1576 if (create_callback) {
1577 StructuredDataPluginInstance instance;
1578 assert((bool)name);
1579 instance.name = name;
1580 if (description && description[0])
1581 instance.description = description;
1582 instance.create_callback = create_callback;
1583 instance.debugger_init_callback = debugger_init_callback;
1584 instance.filter_callback = filter_callback;
1585 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1586 GetStructuredDataPluginInstances().push_back(instance);
1587 }
1588 return false;
1589 }
1590
UnregisterPlugin(StructuredDataPluginCreateInstance create_callback)1591 bool PluginManager::UnregisterPlugin(
1592 StructuredDataPluginCreateInstance create_callback) {
1593 if (create_callback) {
1594 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1595 StructuredDataPluginInstances &instances =
1596 GetStructuredDataPluginInstances();
1597
1598 StructuredDataPluginInstances::iterator pos, end = instances.end();
1599 for (pos = instances.begin(); pos != end; ++pos) {
1600 if (pos->create_callback == create_callback) {
1601 instances.erase(pos);
1602 return true;
1603 }
1604 }
1605 }
1606 return false;
1607 }
1608
1609 StructuredDataPluginCreateInstance
GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx)1610 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
1611 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1612 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
1613 if (idx < instances.size())
1614 return instances[idx].create_callback;
1615 return nullptr;
1616 }
1617
1618 StructuredDataPluginCreateInstance
GetStructuredDataPluginCreateCallbackForPluginName(const ConstString & name)1619 PluginManager::GetStructuredDataPluginCreateCallbackForPluginName(
1620 const ConstString &name) {
1621 if (name) {
1622 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1623 StructuredDataPluginInstances &instances =
1624 GetStructuredDataPluginInstances();
1625
1626 StructuredDataPluginInstances::iterator pos, end = instances.end();
1627 for (pos = instances.begin(); pos != end; ++pos) {
1628 if (name == pos->name)
1629 return pos->create_callback;
1630 }
1631 }
1632 return nullptr;
1633 }
1634
1635 StructuredDataFilterLaunchInfo
GetStructuredDataFilterCallbackAtIndex(uint32_t idx,bool & iteration_complete)1636 PluginManager::GetStructuredDataFilterCallbackAtIndex(
1637 uint32_t idx, bool &iteration_complete) {
1638 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
1639 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
1640 if (idx < instances.size()) {
1641 iteration_complete = false;
1642 return instances[idx].filter_callback;
1643 } else {
1644 iteration_complete = true;
1645 }
1646 return nullptr;
1647 }
1648
1649 #pragma mark SymbolFile
1650
1651 struct SymbolFileInstance {
SymbolFileInstanceSymbolFileInstance1652 SymbolFileInstance()
1653 : name(), description(), create_callback(nullptr),
1654 debugger_init_callback(nullptr) {}
1655
1656 ConstString name;
1657 std::string description;
1658 SymbolFileCreateInstance create_callback;
1659 DebuggerInitializeCallback debugger_init_callback;
1660 };
1661
1662 typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1663
GetSymbolFileMutex()1664 static std::recursive_mutex &GetSymbolFileMutex() {
1665 static std::recursive_mutex g_instances_mutex;
1666 return g_instances_mutex;
1667 }
1668
GetSymbolFileInstances()1669 static SymbolFileInstances &GetSymbolFileInstances() {
1670 static SymbolFileInstances g_instances;
1671 return g_instances;
1672 }
1673
RegisterPlugin(const ConstString & name,const char * description,SymbolFileCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)1674 bool PluginManager::RegisterPlugin(
1675 const ConstString &name, const char *description,
1676 SymbolFileCreateInstance create_callback,
1677 DebuggerInitializeCallback debugger_init_callback) {
1678 if (create_callback) {
1679 SymbolFileInstance instance;
1680 assert((bool)name);
1681 instance.name = name;
1682 if (description && description[0])
1683 instance.description = description;
1684 instance.create_callback = create_callback;
1685 instance.debugger_init_callback = debugger_init_callback;
1686 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1687 GetSymbolFileInstances().push_back(instance);
1688 }
1689 return false;
1690 }
1691
UnregisterPlugin(SymbolFileCreateInstance create_callback)1692 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
1693 if (create_callback) {
1694 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1695 SymbolFileInstances &instances = GetSymbolFileInstances();
1696
1697 SymbolFileInstances::iterator pos, end = instances.end();
1698 for (pos = instances.begin(); pos != end; ++pos) {
1699 if (pos->create_callback == create_callback) {
1700 instances.erase(pos);
1701 return true;
1702 }
1703 }
1704 }
1705 return false;
1706 }
1707
1708 SymbolFileCreateInstance
GetSymbolFileCreateCallbackAtIndex(uint32_t idx)1709 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1710 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1711 SymbolFileInstances &instances = GetSymbolFileInstances();
1712 if (idx < instances.size())
1713 return instances[idx].create_callback;
1714 return nullptr;
1715 }
1716
1717 SymbolFileCreateInstance
GetSymbolFileCreateCallbackForPluginName(const ConstString & name)1718 PluginManager::GetSymbolFileCreateCallbackForPluginName(
1719 const ConstString &name) {
1720 if (name) {
1721 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
1722 SymbolFileInstances &instances = GetSymbolFileInstances();
1723
1724 SymbolFileInstances::iterator pos, end = instances.end();
1725 for (pos = instances.begin(); pos != end; ++pos) {
1726 if (name == pos->name)
1727 return pos->create_callback;
1728 }
1729 }
1730 return nullptr;
1731 }
1732
1733 #pragma mark SymbolVendor
1734
1735 struct SymbolVendorInstance {
SymbolVendorInstanceSymbolVendorInstance1736 SymbolVendorInstance() : name(), description(), create_callback(nullptr) {}
1737
1738 ConstString name;
1739 std::string description;
1740 SymbolVendorCreateInstance create_callback;
1741 };
1742
1743 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1744
GetSymbolVendorMutex()1745 static std::recursive_mutex &GetSymbolVendorMutex() {
1746 static std::recursive_mutex g_instances_mutex;
1747 return g_instances_mutex;
1748 }
1749
GetSymbolVendorInstances()1750 static SymbolVendorInstances &GetSymbolVendorInstances() {
1751 static SymbolVendorInstances g_instances;
1752 return g_instances;
1753 }
1754
RegisterPlugin(const ConstString & name,const char * description,SymbolVendorCreateInstance create_callback)1755 bool PluginManager::RegisterPlugin(const ConstString &name,
1756 const char *description,
1757 SymbolVendorCreateInstance create_callback) {
1758 if (create_callback) {
1759 SymbolVendorInstance instance;
1760 assert((bool)name);
1761 instance.name = name;
1762 if (description && description[0])
1763 instance.description = description;
1764 instance.create_callback = create_callback;
1765 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1766 GetSymbolVendorInstances().push_back(instance);
1767 }
1768 return false;
1769 }
1770
UnregisterPlugin(SymbolVendorCreateInstance create_callback)1771 bool PluginManager::UnregisterPlugin(
1772 SymbolVendorCreateInstance create_callback) {
1773 if (create_callback) {
1774 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1775 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1776
1777 SymbolVendorInstances::iterator pos, end = instances.end();
1778 for (pos = instances.begin(); pos != end; ++pos) {
1779 if (pos->create_callback == create_callback) {
1780 instances.erase(pos);
1781 return true;
1782 }
1783 }
1784 }
1785 return false;
1786 }
1787
1788 SymbolVendorCreateInstance
GetSymbolVendorCreateCallbackAtIndex(uint32_t idx)1789 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1790 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1791 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1792 if (idx < instances.size())
1793 return instances[idx].create_callback;
1794 return nullptr;
1795 }
1796
1797 SymbolVendorCreateInstance
GetSymbolVendorCreateCallbackForPluginName(const ConstString & name)1798 PluginManager::GetSymbolVendorCreateCallbackForPluginName(
1799 const ConstString &name) {
1800 if (name) {
1801 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
1802 SymbolVendorInstances &instances = GetSymbolVendorInstances();
1803
1804 SymbolVendorInstances::iterator pos, end = instances.end();
1805 for (pos = instances.begin(); pos != end; ++pos) {
1806 if (name == pos->name)
1807 return pos->create_callback;
1808 }
1809 }
1810 return nullptr;
1811 }
1812
1813 #pragma mark UnwindAssembly
1814
1815 struct UnwindAssemblyInstance {
UnwindAssemblyInstanceUnwindAssemblyInstance1816 UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {}
1817
1818 ConstString name;
1819 std::string description;
1820 UnwindAssemblyCreateInstance create_callback;
1821 };
1822
1823 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
1824
GetUnwindAssemblyMutex()1825 static std::recursive_mutex &GetUnwindAssemblyMutex() {
1826 static std::recursive_mutex g_instances_mutex;
1827 return g_instances_mutex;
1828 }
1829
GetUnwindAssemblyInstances()1830 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1831 static UnwindAssemblyInstances g_instances;
1832 return g_instances;
1833 }
1834
RegisterPlugin(const ConstString & name,const char * description,UnwindAssemblyCreateInstance create_callback)1835 bool PluginManager::RegisterPlugin(
1836 const ConstString &name, const char *description,
1837 UnwindAssemblyCreateInstance create_callback) {
1838 if (create_callback) {
1839 UnwindAssemblyInstance instance;
1840 assert((bool)name);
1841 instance.name = name;
1842 if (description && description[0])
1843 instance.description = description;
1844 instance.create_callback = create_callback;
1845 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1846 GetUnwindAssemblyInstances().push_back(instance);
1847 }
1848 return false;
1849 }
1850
UnregisterPlugin(UnwindAssemblyCreateInstance create_callback)1851 bool PluginManager::UnregisterPlugin(
1852 UnwindAssemblyCreateInstance create_callback) {
1853 if (create_callback) {
1854 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1855 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1856
1857 UnwindAssemblyInstances::iterator pos, end = instances.end();
1858 for (pos = instances.begin(); pos != end; ++pos) {
1859 if (pos->create_callback == create_callback) {
1860 instances.erase(pos);
1861 return true;
1862 }
1863 }
1864 }
1865 return false;
1866 }
1867
1868 UnwindAssemblyCreateInstance
GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx)1869 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1870 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1871 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1872 if (idx < instances.size())
1873 return instances[idx].create_callback;
1874 return nullptr;
1875 }
1876
1877 UnwindAssemblyCreateInstance
GetUnwindAssemblyCreateCallbackForPluginName(const ConstString & name)1878 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName(
1879 const ConstString &name) {
1880 if (name) {
1881 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
1882 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
1883
1884 UnwindAssemblyInstances::iterator pos, end = instances.end();
1885 for (pos = instances.begin(); pos != end; ++pos) {
1886 if (name == pos->name)
1887 return pos->create_callback;
1888 }
1889 }
1890 return nullptr;
1891 }
1892
1893 #pragma mark MemoryHistory
1894
1895 struct MemoryHistoryInstance {
MemoryHistoryInstanceMemoryHistoryInstance1896 MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {}
1897
1898 ConstString name;
1899 std::string description;
1900 MemoryHistoryCreateInstance create_callback;
1901 };
1902
1903 typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
1904
GetMemoryHistoryMutex()1905 static std::recursive_mutex &GetMemoryHistoryMutex() {
1906 static std::recursive_mutex g_instances_mutex;
1907 return g_instances_mutex;
1908 }
1909
GetMemoryHistoryInstances()1910 static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1911 static MemoryHistoryInstances g_instances;
1912 return g_instances;
1913 }
1914
RegisterPlugin(const ConstString & name,const char * description,MemoryHistoryCreateInstance create_callback)1915 bool PluginManager::RegisterPlugin(
1916 const ConstString &name, const char *description,
1917 MemoryHistoryCreateInstance create_callback) {
1918 if (create_callback) {
1919 MemoryHistoryInstance instance;
1920 assert((bool)name);
1921 instance.name = name;
1922 if (description && description[0])
1923 instance.description = description;
1924 instance.create_callback = create_callback;
1925 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1926 GetMemoryHistoryInstances().push_back(instance);
1927 }
1928 return false;
1929 }
1930
UnregisterPlugin(MemoryHistoryCreateInstance create_callback)1931 bool PluginManager::UnregisterPlugin(
1932 MemoryHistoryCreateInstance create_callback) {
1933 if (create_callback) {
1934 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1935 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1936
1937 MemoryHistoryInstances::iterator pos, end = instances.end();
1938 for (pos = instances.begin(); pos != end; ++pos) {
1939 if (pos->create_callback == create_callback) {
1940 instances.erase(pos);
1941 return true;
1942 }
1943 }
1944 }
1945 return false;
1946 }
1947
1948 MemoryHistoryCreateInstance
GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx)1949 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1950 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1951 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1952 if (idx < instances.size())
1953 return instances[idx].create_callback;
1954 return nullptr;
1955 }
1956
1957 MemoryHistoryCreateInstance
GetMemoryHistoryCreateCallbackForPluginName(const ConstString & name)1958 PluginManager::GetMemoryHistoryCreateCallbackForPluginName(
1959 const ConstString &name) {
1960 if (name) {
1961 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
1962 MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
1963
1964 MemoryHistoryInstances::iterator pos, end = instances.end();
1965 for (pos = instances.begin(); pos != end; ++pos) {
1966 if (name == pos->name)
1967 return pos->create_callback;
1968 }
1969 }
1970 return nullptr;
1971 }
1972
1973 #pragma mark InstrumentationRuntime
1974
1975 struct InstrumentationRuntimeInstance {
InstrumentationRuntimeInstanceInstrumentationRuntimeInstance1976 InstrumentationRuntimeInstance()
1977 : name(), description(), create_callback(nullptr) {}
1978
1979 ConstString name;
1980 std::string description;
1981 InstrumentationRuntimeCreateInstance create_callback;
1982 InstrumentationRuntimeGetType get_type_callback;
1983 };
1984
1985 typedef std::vector<InstrumentationRuntimeInstance>
1986 InstrumentationRuntimeInstances;
1987
GetInstrumentationRuntimeMutex()1988 static std::recursive_mutex &GetInstrumentationRuntimeMutex() {
1989 static std::recursive_mutex g_instances_mutex;
1990 return g_instances_mutex;
1991 }
1992
GetInstrumentationRuntimeInstances()1993 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1994 static InstrumentationRuntimeInstances g_instances;
1995 return g_instances;
1996 }
1997
RegisterPlugin(const ConstString & name,const char * description,InstrumentationRuntimeCreateInstance create_callback,InstrumentationRuntimeGetType get_type_callback)1998 bool PluginManager::RegisterPlugin(
1999 const ConstString &name, const char *description,
2000 InstrumentationRuntimeCreateInstance create_callback,
2001 InstrumentationRuntimeGetType get_type_callback) {
2002 if (create_callback) {
2003 InstrumentationRuntimeInstance instance;
2004 assert((bool)name);
2005 instance.name = name;
2006 if (description && description[0])
2007 instance.description = description;
2008 instance.create_callback = create_callback;
2009 instance.get_type_callback = get_type_callback;
2010 std::lock_guard<std::recursive_mutex> guard(
2011 GetInstrumentationRuntimeMutex());
2012 GetInstrumentationRuntimeInstances().push_back(instance);
2013 }
2014 return false;
2015 }
2016
UnregisterPlugin(InstrumentationRuntimeCreateInstance create_callback)2017 bool PluginManager::UnregisterPlugin(
2018 InstrumentationRuntimeCreateInstance create_callback) {
2019 if (create_callback) {
2020 std::lock_guard<std::recursive_mutex> guard(
2021 GetInstrumentationRuntimeMutex());
2022 InstrumentationRuntimeInstances &instances =
2023 GetInstrumentationRuntimeInstances();
2024
2025 InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2026 for (pos = instances.begin(); pos != end; ++pos) {
2027 if (pos->create_callback == create_callback) {
2028 instances.erase(pos);
2029 return true;
2030 }
2031 }
2032 }
2033 return false;
2034 }
2035
2036 InstrumentationRuntimeGetType
GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx)2037 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
2038 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
2039 InstrumentationRuntimeInstances &instances =
2040 GetInstrumentationRuntimeInstances();
2041 if (idx < instances.size())
2042 return instances[idx].get_type_callback;
2043 return nullptr;
2044 }
2045
2046 InstrumentationRuntimeCreateInstance
GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx)2047 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
2048 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
2049 InstrumentationRuntimeInstances &instances =
2050 GetInstrumentationRuntimeInstances();
2051 if (idx < instances.size())
2052 return instances[idx].create_callback;
2053 return nullptr;
2054 }
2055
2056 InstrumentationRuntimeCreateInstance
GetInstrumentationRuntimeCreateCallbackForPluginName(const ConstString & name)2057 PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName(
2058 const ConstString &name) {
2059 if (name) {
2060 std::lock_guard<std::recursive_mutex> guard(
2061 GetInstrumentationRuntimeMutex());
2062 InstrumentationRuntimeInstances &instances =
2063 GetInstrumentationRuntimeInstances();
2064
2065 InstrumentationRuntimeInstances::iterator pos, end = instances.end();
2066 for (pos = instances.begin(); pos != end; ++pos) {
2067 if (name == pos->name)
2068 return pos->create_callback;
2069 }
2070 }
2071 return nullptr;
2072 }
2073
2074 #pragma mark TypeSystem
2075
2076 struct TypeSystemInstance {
TypeSystemInstanceTypeSystemInstance2077 TypeSystemInstance() : name(), description(), create_callback(nullptr) {}
2078
2079 ConstString name;
2080 std::string description;
2081 TypeSystemCreateInstance create_callback;
2082 TypeSystemEnumerateSupportedLanguages enumerate_callback;
2083 };
2084
2085 typedef std::vector<TypeSystemInstance> TypeSystemInstances;
2086
GetTypeSystemMutex()2087 static std::recursive_mutex &GetTypeSystemMutex() {
2088 static std::recursive_mutex g_instances_mutex;
2089 return g_instances_mutex;
2090 }
2091
GetTypeSystemInstances()2092 static TypeSystemInstances &GetTypeSystemInstances() {
2093 static TypeSystemInstances g_instances;
2094 return g_instances;
2095 }
2096
RegisterPlugin(const ConstString & name,const char * description,TypeSystemCreateInstance create_callback,TypeSystemEnumerateSupportedLanguages enumerate_supported_languages_callback)2097 bool PluginManager::RegisterPlugin(const ConstString &name,
2098 const char *description,
2099 TypeSystemCreateInstance create_callback,
2100 TypeSystemEnumerateSupportedLanguages
2101 enumerate_supported_languages_callback) {
2102 if (create_callback) {
2103 TypeSystemInstance instance;
2104 assert((bool)name);
2105 instance.name = name;
2106 if (description && description[0])
2107 instance.description = description;
2108 instance.create_callback = create_callback;
2109 instance.enumerate_callback = enumerate_supported_languages_callback;
2110 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2111 GetTypeSystemInstances().push_back(instance);
2112 }
2113 return false;
2114 }
2115
UnregisterPlugin(TypeSystemCreateInstance create_callback)2116 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
2117 if (create_callback) {
2118 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2119 TypeSystemInstances &instances = GetTypeSystemInstances();
2120
2121 TypeSystemInstances::iterator pos, end = instances.end();
2122 for (pos = instances.begin(); pos != end; ++pos) {
2123 if (pos->create_callback == create_callback) {
2124 instances.erase(pos);
2125 return true;
2126 }
2127 }
2128 }
2129 return false;
2130 }
2131
2132 TypeSystemCreateInstance
GetTypeSystemCreateCallbackAtIndex(uint32_t idx)2133 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
2134 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2135 TypeSystemInstances &instances = GetTypeSystemInstances();
2136 if (idx < instances.size())
2137 return instances[idx].create_callback;
2138 return nullptr;
2139 }
2140
2141 TypeSystemCreateInstance
GetTypeSystemCreateCallbackForPluginName(const ConstString & name)2142 PluginManager::GetTypeSystemCreateCallbackForPluginName(
2143 const ConstString &name) {
2144 if (name) {
2145 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2146 TypeSystemInstances &instances = GetTypeSystemInstances();
2147
2148 TypeSystemInstances::iterator pos, end = instances.end();
2149 for (pos = instances.begin(); pos != end; ++pos) {
2150 if (name == pos->name)
2151 return pos->create_callback;
2152 }
2153 }
2154 return nullptr;
2155 }
2156
2157 TypeSystemEnumerateSupportedLanguages
GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx)2158 PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(
2159 uint32_t idx) {
2160 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2161 TypeSystemInstances &instances = GetTypeSystemInstances();
2162 if (idx < instances.size())
2163 return instances[idx].enumerate_callback;
2164 return nullptr;
2165 }
2166
2167 TypeSystemEnumerateSupportedLanguages
GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(const ConstString & name)2168 PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
2169 const ConstString &name) {
2170 if (name) {
2171 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2172 TypeSystemInstances &instances = GetTypeSystemInstances();
2173
2174 TypeSystemInstances::iterator pos, end = instances.end();
2175 for (pos = instances.begin(); pos != end; ++pos) {
2176 if (name == pos->name)
2177 return pos->enumerate_callback;
2178 }
2179 }
2180 return nullptr;
2181 }
2182
2183 #pragma mark REPL
2184
2185 struct REPLInstance {
REPLInstanceREPLInstance2186 REPLInstance() : name(), description(), create_callback(nullptr) {}
2187
2188 ConstString name;
2189 std::string description;
2190 REPLCreateInstance create_callback;
2191 REPLEnumerateSupportedLanguages enumerate_languages_callback;
2192 };
2193
2194 typedef std::vector<REPLInstance> REPLInstances;
2195
GetREPLMutex()2196 static std::recursive_mutex &GetREPLMutex() {
2197 static std::recursive_mutex g_instances_mutex;
2198 return g_instances_mutex;
2199 }
2200
GetREPLInstances()2201 static REPLInstances &GetREPLInstances() {
2202 static REPLInstances g_instances;
2203 return g_instances;
2204 }
2205
RegisterPlugin(const ConstString & name,const char * description,REPLCreateInstance create_callback,REPLEnumerateSupportedLanguages enumerate_languages_callback)2206 bool PluginManager::RegisterPlugin(
2207 const ConstString &name, const char *description,
2208 REPLCreateInstance create_callback,
2209 REPLEnumerateSupportedLanguages enumerate_languages_callback) {
2210 if (create_callback) {
2211 REPLInstance instance;
2212 assert((bool)name);
2213 instance.name = name;
2214 if (description && description[0])
2215 instance.description = description;
2216 instance.create_callback = create_callback;
2217 instance.enumerate_languages_callback = enumerate_languages_callback;
2218 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2219 GetREPLInstances().push_back(instance);
2220 }
2221 return false;
2222 }
2223
UnregisterPlugin(REPLCreateInstance create_callback)2224 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
2225 if (create_callback) {
2226 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2227 REPLInstances &instances = GetREPLInstances();
2228
2229 REPLInstances::iterator pos, end = instances.end();
2230 for (pos = instances.begin(); pos != end; ++pos) {
2231 if (pos->create_callback == create_callback) {
2232 instances.erase(pos);
2233 return true;
2234 }
2235 }
2236 }
2237 return false;
2238 }
2239
GetREPLCreateCallbackAtIndex(uint32_t idx)2240 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
2241 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2242 REPLInstances &instances = GetREPLInstances();
2243 if (idx < instances.size())
2244 return instances[idx].create_callback;
2245 return nullptr;
2246 }
2247
2248 REPLCreateInstance
GetREPLCreateCallbackForPluginName(const ConstString & name)2249 PluginManager::GetREPLCreateCallbackForPluginName(const ConstString &name) {
2250 if (name) {
2251 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2252 REPLInstances &instances = GetREPLInstances();
2253
2254 REPLInstances::iterator pos, end = instances.end();
2255 for (pos = instances.begin(); pos != end; ++pos) {
2256 if (name == pos->name)
2257 return pos->create_callback;
2258 }
2259 }
2260 return nullptr;
2261 }
2262
2263 REPLEnumerateSupportedLanguages
GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx)2264 PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) {
2265 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2266 REPLInstances &instances = GetREPLInstances();
2267 if (idx < instances.size())
2268 return instances[idx].enumerate_languages_callback;
2269 return nullptr;
2270 }
2271
2272 REPLEnumerateSupportedLanguages
GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(const ConstString & name)2273 PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
2274 const ConstString &name) {
2275 if (name) {
2276 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2277 REPLInstances &instances = GetREPLInstances();
2278
2279 REPLInstances::iterator pos, end = instances.end();
2280 for (pos = instances.begin(); pos != end; ++pos) {
2281 if (name == pos->name)
2282 return pos->enumerate_languages_callback;
2283 }
2284 }
2285 return nullptr;
2286 }
2287
2288 #pragma mark PluginManager
2289
DebuggerInitialize(Debugger & debugger)2290 void PluginManager::DebuggerInitialize(Debugger &debugger) {
2291 // Initialize the DynamicLoader plugins
2292 {
2293 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
2294 DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
2295
2296 DynamicLoaderInstances::iterator pos, end = instances.end();
2297 for (pos = instances.begin(); pos != end; ++pos) {
2298 if (pos->debugger_init_callback)
2299 pos->debugger_init_callback(debugger);
2300 }
2301 }
2302
2303 // Initialize the JITLoader plugins
2304 {
2305 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
2306 JITLoaderInstances &instances = GetJITLoaderInstances();
2307
2308 JITLoaderInstances::iterator pos, end = instances.end();
2309 for (pos = instances.begin(); pos != end; ++pos) {
2310 if (pos->debugger_init_callback)
2311 pos->debugger_init_callback(debugger);
2312 }
2313 }
2314
2315 // Initialize the Platform plugins
2316 {
2317 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
2318 PlatformInstances &instances = GetPlatformInstances();
2319
2320 PlatformInstances::iterator pos, end = instances.end();
2321 for (pos = instances.begin(); pos != end; ++pos) {
2322 if (pos->debugger_init_callback)
2323 pos->debugger_init_callback(debugger);
2324 }
2325 }
2326
2327 // Initialize the Process plugins
2328 {
2329 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
2330 ProcessInstances &instances = GetProcessInstances();
2331
2332 ProcessInstances::iterator pos, end = instances.end();
2333 for (pos = instances.begin(); pos != end; ++pos) {
2334 if (pos->debugger_init_callback)
2335 pos->debugger_init_callback(debugger);
2336 }
2337 }
2338
2339 // Initialize the SymbolFile plugins
2340 {
2341 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
2342 for (auto &sym_file : GetSymbolFileInstances()) {
2343 if (sym_file.debugger_init_callback)
2344 sym_file.debugger_init_callback(debugger);
2345 }
2346 }
2347
2348 // Initialize the OperatingSystem plugins
2349 {
2350 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
2351 for (auto &os : GetOperatingSystemInstances()) {
2352 if (os.debugger_init_callback)
2353 os.debugger_init_callback(debugger);
2354 }
2355 }
2356
2357 // Initialize the StructuredDataPlugin plugins
2358 {
2359 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
2360 for (auto &plugin : GetStructuredDataPluginInstances()) {
2361 if (plugin.debugger_init_callback)
2362 plugin.debugger_init_callback(debugger);
2363 }
2364 }
2365 }
2366
2367 // This is the preferred new way to register plugin specific settings. e.g.
2368 // This will put a plugin's settings under e.g.
2369 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
GetDebuggerPropertyForPlugins(Debugger & debugger,const ConstString & plugin_type_name,const ConstString & plugin_type_desc,bool can_create)2370 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins(
2371 Debugger &debugger, const ConstString &plugin_type_name,
2372 const ConstString &plugin_type_desc, bool can_create) {
2373 lldb::OptionValuePropertiesSP parent_properties_sp(
2374 debugger.GetValueProperties());
2375 if (parent_properties_sp) {
2376 static ConstString g_property_name("plugin");
2377
2378 OptionValuePropertiesSP plugin_properties_sp =
2379 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
2380 if (!plugin_properties_sp && can_create) {
2381 plugin_properties_sp =
2382 std::make_shared<OptionValueProperties>(g_property_name);
2383 parent_properties_sp->AppendProperty(
2384 g_property_name, ConstString("Settings specify to plugins."), true,
2385 plugin_properties_sp);
2386 }
2387
2388 if (plugin_properties_sp) {
2389 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2390 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2391 if (!plugin_type_properties_sp && can_create) {
2392 plugin_type_properties_sp =
2393 std::make_shared<OptionValueProperties>(plugin_type_name);
2394 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2395 true, plugin_type_properties_sp);
2396 }
2397 return plugin_type_properties_sp;
2398 }
2399 }
2400 return lldb::OptionValuePropertiesSP();
2401 }
2402
2403 // This is deprecated way to register plugin specific settings. e.g.
2404 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
2405 // generic settings would be under "platform.SETTINGNAME".
GetDebuggerPropertyForPluginsOldStyle(Debugger & debugger,const ConstString & plugin_type_name,const ConstString & plugin_type_desc,bool can_create)2406 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
2407 Debugger &debugger, const ConstString &plugin_type_name,
2408 const ConstString &plugin_type_desc, bool can_create) {
2409 static ConstString g_property_name("plugin");
2410 lldb::OptionValuePropertiesSP parent_properties_sp(
2411 debugger.GetValueProperties());
2412 if (parent_properties_sp) {
2413 OptionValuePropertiesSP plugin_properties_sp =
2414 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2415 if (!plugin_properties_sp && can_create) {
2416 plugin_properties_sp =
2417 std::make_shared<OptionValueProperties>(plugin_type_name);
2418 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2419 true, plugin_properties_sp);
2420 }
2421
2422 if (plugin_properties_sp) {
2423 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2424 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
2425 if (!plugin_type_properties_sp && can_create) {
2426 plugin_type_properties_sp =
2427 std::make_shared<OptionValueProperties>(g_property_name);
2428 plugin_properties_sp->AppendProperty(
2429 g_property_name, ConstString("Settings specific to plugins"), true,
2430 plugin_type_properties_sp);
2431 }
2432 return plugin_type_properties_sp;
2433 }
2434 }
2435 return lldb::OptionValuePropertiesSP();
2436 }
2437
2438 namespace {
2439
2440 typedef lldb::OptionValuePropertiesSP
2441 GetDebuggerPropertyForPluginsPtr(Debugger &, const ConstString &,
2442 const ConstString &, bool can_create);
2443
2444 lldb::OptionValuePropertiesSP
GetSettingForPlugin(Debugger & debugger,const ConstString & setting_name,const ConstString & plugin_type_name,GetDebuggerPropertyForPluginsPtr get_debugger_property=GetDebuggerPropertyForPlugins)2445 GetSettingForPlugin(Debugger &debugger, const ConstString &setting_name,
2446 const ConstString &plugin_type_name,
2447 GetDebuggerPropertyForPluginsPtr get_debugger_property =
2448 GetDebuggerPropertyForPlugins) {
2449 lldb::OptionValuePropertiesSP properties_sp;
2450 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
2451 debugger, plugin_type_name,
2452 ConstString(), // not creating to so we don't need the description
2453 false));
2454 if (plugin_type_properties_sp)
2455 properties_sp =
2456 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2457 return properties_sp;
2458 }
2459
CreateSettingForPlugin(Debugger & debugger,const ConstString & plugin_type_name,const ConstString & plugin_type_desc,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property,GetDebuggerPropertyForPluginsPtr get_debugger_property=GetDebuggerPropertyForPlugins)2460 bool CreateSettingForPlugin(
2461 Debugger &debugger, const ConstString &plugin_type_name,
2462 const ConstString &plugin_type_desc,
2463 const lldb::OptionValuePropertiesSP &properties_sp,
2464 const ConstString &description, bool is_global_property,
2465 GetDebuggerPropertyForPluginsPtr get_debugger_property =
2466 GetDebuggerPropertyForPlugins) {
2467 if (properties_sp) {
2468 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2469 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
2470 true));
2471 if (plugin_type_properties_sp) {
2472 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2473 description, is_global_property,
2474 properties_sp);
2475 return true;
2476 }
2477 }
2478 return false;
2479 }
2480
2481 const char *kDynamicLoaderPluginName("dynamic-loader");
2482 const char *kPlatformPluginName("platform");
2483 const char *kProcessPluginName("process");
2484 const char *kSymbolFilePluginName("symbol-file");
2485 const char *kJITLoaderPluginName("jit-loader");
2486 const char *kStructuredDataPluginName("structured-data");
2487
2488 } // anonymous namespace
2489
GetSettingForDynamicLoaderPlugin(Debugger & debugger,const ConstString & setting_name)2490 lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(
2491 Debugger &debugger, const ConstString &setting_name) {
2492 return GetSettingForPlugin(debugger, setting_name,
2493 ConstString(kDynamicLoaderPluginName));
2494 }
2495
CreateSettingForDynamicLoaderPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property)2496 bool PluginManager::CreateSettingForDynamicLoaderPlugin(
2497 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2498 const ConstString &description, bool is_global_property) {
2499 return CreateSettingForPlugin(
2500 debugger, ConstString(kDynamicLoaderPluginName),
2501 ConstString("Settings for dynamic loader plug-ins"), properties_sp,
2502 description, is_global_property);
2503 }
2504
2505 lldb::OptionValuePropertiesSP
GetSettingForPlatformPlugin(Debugger & debugger,const ConstString & setting_name)2506 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
2507 const ConstString &setting_name) {
2508 return GetSettingForPlugin(debugger, setting_name,
2509 ConstString(kPlatformPluginName),
2510 GetDebuggerPropertyForPluginsOldStyle);
2511 }
2512
CreateSettingForPlatformPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property)2513 bool PluginManager::CreateSettingForPlatformPlugin(
2514 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2515 const ConstString &description, bool is_global_property) {
2516 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
2517 ConstString("Settings for platform plug-ins"),
2518 properties_sp, description, is_global_property,
2519 GetDebuggerPropertyForPluginsOldStyle);
2520 }
2521
2522 lldb::OptionValuePropertiesSP
GetSettingForProcessPlugin(Debugger & debugger,const ConstString & setting_name)2523 PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
2524 const ConstString &setting_name) {
2525 return GetSettingForPlugin(debugger, setting_name,
2526 ConstString(kProcessPluginName));
2527 }
2528
CreateSettingForProcessPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property)2529 bool PluginManager::CreateSettingForProcessPlugin(
2530 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2531 const ConstString &description, bool is_global_property) {
2532 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
2533 ConstString("Settings for process plug-ins"),
2534 properties_sp, description, is_global_property);
2535 }
2536
2537 lldb::OptionValuePropertiesSP
GetSettingForSymbolFilePlugin(Debugger & debugger,const ConstString & setting_name)2538 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
2539 const ConstString &setting_name) {
2540 return GetSettingForPlugin(debugger, setting_name,
2541 ConstString(kSymbolFilePluginName));
2542 }
2543
CreateSettingForSymbolFilePlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property)2544 bool PluginManager::CreateSettingForSymbolFilePlugin(
2545 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2546 const ConstString &description, bool is_global_property) {
2547 return CreateSettingForPlugin(
2548 debugger, ConstString(kSymbolFilePluginName),
2549 ConstString("Settings for symbol file plug-ins"), properties_sp,
2550 description, is_global_property);
2551 }
2552
2553 lldb::OptionValuePropertiesSP
GetSettingForJITLoaderPlugin(Debugger & debugger,const ConstString & setting_name)2554 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
2555 const ConstString &setting_name) {
2556 return GetSettingForPlugin(debugger, setting_name,
2557 ConstString(kJITLoaderPluginName));
2558 }
2559
CreateSettingForJITLoaderPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property)2560 bool PluginManager::CreateSettingForJITLoaderPlugin(
2561 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2562 const ConstString &description, bool is_global_property) {
2563 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
2564 ConstString("Settings for JIT loader plug-ins"),
2565 properties_sp, description, is_global_property);
2566 }
2567
2568 static const char *kOperatingSystemPluginName("os");
2569
GetSettingForOperatingSystemPlugin(Debugger & debugger,const ConstString & setting_name)2570 lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin(
2571 Debugger &debugger, const ConstString &setting_name) {
2572 lldb::OptionValuePropertiesSP properties_sp;
2573 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2574 GetDebuggerPropertyForPlugins(
2575 debugger, ConstString(kOperatingSystemPluginName),
2576 ConstString(), // not creating to so we don't need the description
2577 false));
2578 if (plugin_type_properties_sp)
2579 properties_sp =
2580 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2581 return properties_sp;
2582 }
2583
CreateSettingForOperatingSystemPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property)2584 bool PluginManager::CreateSettingForOperatingSystemPlugin(
2585 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2586 const ConstString &description, bool is_global_property) {
2587 if (properties_sp) {
2588 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2589 GetDebuggerPropertyForPlugins(
2590 debugger, ConstString(kOperatingSystemPluginName),
2591 ConstString("Settings for operating system plug-ins"), true));
2592 if (plugin_type_properties_sp) {
2593 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2594 description, is_global_property,
2595 properties_sp);
2596 return true;
2597 }
2598 }
2599 return false;
2600 }
2601
GetSettingForStructuredDataPlugin(Debugger & debugger,const ConstString & setting_name)2602 lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin(
2603 Debugger &debugger, const ConstString &setting_name) {
2604 return GetSettingForPlugin(debugger, setting_name,
2605 ConstString(kStructuredDataPluginName));
2606 }
2607
CreateSettingForStructuredDataPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property)2608 bool PluginManager::CreateSettingForStructuredDataPlugin(
2609 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2610 const ConstString &description, bool is_global_property) {
2611 return CreateSettingForPlugin(
2612 debugger, ConstString(kStructuredDataPluginName),
2613 ConstString("Settings for structured data plug-ins"), properties_sp,
2614 description, is_global_property);
2615 }
2616