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