1 //===-- PluginManager.cpp -------------------------------------------------===//
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>(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(
303       {name, std::string(description), create_callback});
304 }
305 
306 void PluginManager::UnregisterPlugin(
307     ArchitectureCreateInstance create_callback) {
308   std::lock_guard<std::mutex> guard(GetArchitectureMutex());
309   auto &instances = GetArchitectureInstances();
310 
311   for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
312     if (pos->create_callback == create_callback) {
313       instances.erase(pos);
314       return;
315     }
316   }
317   llvm_unreachable("Plugin not found");
318 }
319 
320 std::unique_ptr<Architecture>
321 PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
322   std::lock_guard<std::mutex> guard(GetArchitectureMutex());
323   for (const auto &instances : GetArchitectureInstances()) {
324     if (auto plugin_up = instances.create_callback(arch))
325       return plugin_up;
326   }
327   return nullptr;
328 }
329 
330 #pragma mark Disassembler
331 
332 struct DisassemblerInstance {
333   DisassemblerInstance() : name(), description(), create_callback(nullptr) {}
334 
335   ConstString name;
336   std::string description;
337   DisassemblerCreateInstance create_callback;
338 };
339 
340 typedef std::vector<DisassemblerInstance> DisassemblerInstances;
341 
342 static std::recursive_mutex &GetDisassemblerMutex() {
343   static std::recursive_mutex g_instances_mutex;
344   return g_instances_mutex;
345 }
346 
347 static DisassemblerInstances &GetDisassemblerInstances() {
348   static DisassemblerInstances g_instances;
349   return g_instances;
350 }
351 
352 bool PluginManager::RegisterPlugin(ConstString name,
353                                    const char *description,
354                                    DisassemblerCreateInstance create_callback) {
355   if (create_callback) {
356     DisassemblerInstance instance;
357     assert((bool)name);
358     instance.name = name;
359     if (description && description[0])
360       instance.description = description;
361     instance.create_callback = create_callback;
362     std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
363     GetDisassemblerInstances().push_back(instance);
364     return true;
365   }
366   return false;
367 }
368 
369 bool PluginManager::UnregisterPlugin(
370     DisassemblerCreateInstance create_callback) {
371   if (create_callback) {
372     std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
373     DisassemblerInstances &instances = GetDisassemblerInstances();
374 
375     DisassemblerInstances::iterator pos, end = instances.end();
376     for (pos = instances.begin(); pos != end; ++pos) {
377       if (pos->create_callback == create_callback) {
378         instances.erase(pos);
379         return true;
380       }
381     }
382   }
383   return false;
384 }
385 
386 DisassemblerCreateInstance
387 PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
388   std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
389   DisassemblerInstances &instances = GetDisassemblerInstances();
390   if (idx < instances.size())
391     return instances[idx].create_callback;
392   return nullptr;
393 }
394 
395 DisassemblerCreateInstance
396 PluginManager::GetDisassemblerCreateCallbackForPluginName(
397     ConstString name) {
398   if (name) {
399     std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
400     DisassemblerInstances &instances = GetDisassemblerInstances();
401 
402     DisassemblerInstances::iterator pos, end = instances.end();
403     for (pos = instances.begin(); pos != end; ++pos) {
404       if (name == pos->name)
405         return pos->create_callback;
406     }
407   }
408   return nullptr;
409 }
410 
411 #pragma mark DynamicLoader
412 
413 struct DynamicLoaderInstance {
414   DynamicLoaderInstance()
415       : name(), description(), create_callback(nullptr),
416         debugger_init_callback(nullptr) {}
417 
418   ConstString name;
419   std::string description;
420   DynamicLoaderCreateInstance create_callback;
421   DebuggerInitializeCallback debugger_init_callback;
422 };
423 
424 typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
425 
426 static std::recursive_mutex &GetDynamicLoaderMutex() {
427   static std::recursive_mutex g_instances_mutex;
428   return g_instances_mutex;
429 }
430 
431 static DynamicLoaderInstances &GetDynamicLoaderInstances() {
432   static DynamicLoaderInstances g_instances;
433   return g_instances;
434 }
435 
436 bool PluginManager::RegisterPlugin(
437     ConstString name, const char *description,
438     DynamicLoaderCreateInstance create_callback,
439     DebuggerInitializeCallback debugger_init_callback) {
440   if (create_callback) {
441     DynamicLoaderInstance instance;
442     assert((bool)name);
443     instance.name = name;
444     if (description && description[0])
445       instance.description = description;
446     instance.create_callback = create_callback;
447     instance.debugger_init_callback = debugger_init_callback;
448     std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
449     GetDynamicLoaderInstances().push_back(instance);
450   }
451   return false;
452 }
453 
454 bool PluginManager::UnregisterPlugin(
455     DynamicLoaderCreateInstance create_callback) {
456   if (create_callback) {
457     std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
458     DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
459 
460     DynamicLoaderInstances::iterator pos, end = instances.end();
461     for (pos = instances.begin(); pos != end; ++pos) {
462       if (pos->create_callback == create_callback) {
463         instances.erase(pos);
464         return true;
465       }
466     }
467   }
468   return false;
469 }
470 
471 DynamicLoaderCreateInstance
472 PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
473   std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
474   DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
475   if (idx < instances.size())
476     return instances[idx].create_callback;
477   return nullptr;
478 }
479 
480 DynamicLoaderCreateInstance
481 PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
482     ConstString name) {
483   if (name) {
484     std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
485     DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
486 
487     DynamicLoaderInstances::iterator pos, end = instances.end();
488     for (pos = instances.begin(); pos != end; ++pos) {
489       if (name == pos->name)
490         return pos->create_callback;
491     }
492   }
493   return nullptr;
494 }
495 
496 #pragma mark JITLoader
497 
498 struct JITLoaderInstance {
499   JITLoaderInstance()
500       : name(), description(), create_callback(nullptr),
501         debugger_init_callback(nullptr) {}
502 
503   ConstString name;
504   std::string description;
505   JITLoaderCreateInstance create_callback;
506   DebuggerInitializeCallback debugger_init_callback;
507 };
508 
509 typedef std::vector<JITLoaderInstance> JITLoaderInstances;
510 
511 static std::recursive_mutex &GetJITLoaderMutex() {
512   static std::recursive_mutex g_instances_mutex;
513   return g_instances_mutex;
514 }
515 
516 static JITLoaderInstances &GetJITLoaderInstances() {
517   static JITLoaderInstances g_instances;
518   return g_instances;
519 }
520 
521 bool PluginManager::RegisterPlugin(
522     ConstString name, const char *description,
523     JITLoaderCreateInstance create_callback,
524     DebuggerInitializeCallback debugger_init_callback) {
525   if (create_callback) {
526     JITLoaderInstance instance;
527     assert((bool)name);
528     instance.name = name;
529     if (description && description[0])
530       instance.description = description;
531     instance.create_callback = create_callback;
532     instance.debugger_init_callback = debugger_init_callback;
533     std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
534     GetJITLoaderInstances().push_back(instance);
535   }
536   return false;
537 }
538 
539 bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
540   if (create_callback) {
541     std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
542     JITLoaderInstances &instances = GetJITLoaderInstances();
543 
544     JITLoaderInstances::iterator pos, end = instances.end();
545     for (pos = instances.begin(); pos != end; ++pos) {
546       if (pos->create_callback == create_callback) {
547         instances.erase(pos);
548         return true;
549       }
550     }
551   }
552   return false;
553 }
554 
555 JITLoaderCreateInstance
556 PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
557   std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
558   JITLoaderInstances &instances = GetJITLoaderInstances();
559   if (idx < instances.size())
560     return instances[idx].create_callback;
561   return nullptr;
562 }
563 
564 JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName(
565     ConstString name) {
566   if (name) {
567     std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
568     JITLoaderInstances &instances = GetJITLoaderInstances();
569 
570     JITLoaderInstances::iterator pos, end = instances.end();
571     for (pos = instances.begin(); pos != end; ++pos) {
572       if (name == pos->name)
573         return pos->create_callback;
574     }
575   }
576   return nullptr;
577 }
578 
579 #pragma mark EmulateInstruction
580 
581 struct EmulateInstructionInstance {
582   EmulateInstructionInstance()
583       : name(), description(), create_callback(nullptr) {}
584 
585   ConstString name;
586   std::string description;
587   EmulateInstructionCreateInstance create_callback;
588 };
589 
590 typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
591 
592 static std::recursive_mutex &GetEmulateInstructionMutex() {
593   static std::recursive_mutex g_instances_mutex;
594   return g_instances_mutex;
595 }
596 
597 static EmulateInstructionInstances &GetEmulateInstructionInstances() {
598   static EmulateInstructionInstances g_instances;
599   return g_instances;
600 }
601 
602 bool PluginManager::RegisterPlugin(
603     ConstString name, const char *description,
604     EmulateInstructionCreateInstance create_callback) {
605   if (create_callback) {
606     EmulateInstructionInstance instance;
607     assert((bool)name);
608     instance.name = name;
609     if (description && description[0])
610       instance.description = description;
611     instance.create_callback = create_callback;
612     std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
613     GetEmulateInstructionInstances().push_back(instance);
614   }
615   return false;
616 }
617 
618 bool PluginManager::UnregisterPlugin(
619     EmulateInstructionCreateInstance create_callback) {
620   if (create_callback) {
621     std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
622     EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
623 
624     EmulateInstructionInstances::iterator pos, end = instances.end();
625     for (pos = instances.begin(); pos != end; ++pos) {
626       if (pos->create_callback == create_callback) {
627         instances.erase(pos);
628         return true;
629       }
630     }
631   }
632   return false;
633 }
634 
635 EmulateInstructionCreateInstance
636 PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
637   std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
638   EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
639   if (idx < instances.size())
640     return instances[idx].create_callback;
641   return nullptr;
642 }
643 
644 EmulateInstructionCreateInstance
645 PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
646     ConstString name) {
647   if (name) {
648     std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
649     EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
650 
651     EmulateInstructionInstances::iterator pos, end = instances.end();
652     for (pos = instances.begin(); pos != end; ++pos) {
653       if (name == pos->name)
654         return pos->create_callback;
655     }
656   }
657   return nullptr;
658 }
659 
660 #pragma mark OperatingSystem
661 
662 struct OperatingSystemInstance {
663   OperatingSystemInstance()
664       : name(), description(), create_callback(nullptr),
665         debugger_init_callback(nullptr) {}
666 
667   ConstString name;
668   std::string description;
669   OperatingSystemCreateInstance create_callback;
670   DebuggerInitializeCallback debugger_init_callback;
671 };
672 
673 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
674 
675 static std::recursive_mutex &GetOperatingSystemMutex() {
676   static std::recursive_mutex g_instances_mutex;
677   return g_instances_mutex;
678 }
679 
680 static OperatingSystemInstances &GetOperatingSystemInstances() {
681   static OperatingSystemInstances g_instances;
682   return g_instances;
683 }
684 
685 bool PluginManager::RegisterPlugin(
686     ConstString name, const char *description,
687     OperatingSystemCreateInstance create_callback,
688     DebuggerInitializeCallback debugger_init_callback) {
689   if (create_callback) {
690     OperatingSystemInstance instance;
691     assert((bool)name);
692     instance.name = name;
693     if (description && description[0])
694       instance.description = description;
695     instance.create_callback = create_callback;
696     instance.debugger_init_callback = debugger_init_callback;
697     std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
698     GetOperatingSystemInstances().push_back(instance);
699   }
700   return false;
701 }
702 
703 bool PluginManager::UnregisterPlugin(
704     OperatingSystemCreateInstance create_callback) {
705   if (create_callback) {
706     std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
707     OperatingSystemInstances &instances = GetOperatingSystemInstances();
708 
709     OperatingSystemInstances::iterator pos, end = instances.end();
710     for (pos = instances.begin(); pos != end; ++pos) {
711       if (pos->create_callback == create_callback) {
712         instances.erase(pos);
713         return true;
714       }
715     }
716   }
717   return false;
718 }
719 
720 OperatingSystemCreateInstance
721 PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
722   std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
723   OperatingSystemInstances &instances = GetOperatingSystemInstances();
724   if (idx < instances.size())
725     return instances[idx].create_callback;
726   return nullptr;
727 }
728 
729 OperatingSystemCreateInstance
730 PluginManager::GetOperatingSystemCreateCallbackForPluginName(
731     ConstString name) {
732   if (name) {
733     std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
734     OperatingSystemInstances &instances = GetOperatingSystemInstances();
735 
736     OperatingSystemInstances::iterator pos, end = instances.end();
737     for (pos = instances.begin(); pos != end; ++pos) {
738       if (name == pos->name)
739         return pos->create_callback;
740     }
741   }
742   return nullptr;
743 }
744 
745 #pragma mark Language
746 
747 struct LanguageInstance {
748   LanguageInstance() : name(), description(), create_callback(nullptr) {}
749 
750   ConstString name;
751   std::string description;
752   LanguageCreateInstance create_callback;
753 };
754 
755 typedef std::vector<LanguageInstance> LanguageInstances;
756 
757 static std::recursive_mutex &GetLanguageMutex() {
758   static std::recursive_mutex g_instances_mutex;
759   return g_instances_mutex;
760 }
761 
762 static LanguageInstances &GetLanguageInstances() {
763   static LanguageInstances g_instances;
764   return g_instances;
765 }
766 
767 bool PluginManager::RegisterPlugin(ConstString name,
768                                    const char *description,
769                                    LanguageCreateInstance create_callback) {
770   if (create_callback) {
771     LanguageInstance instance;
772     assert((bool)name);
773     instance.name = name;
774     if (description && description[0])
775       instance.description = description;
776     instance.create_callback = create_callback;
777     std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
778     GetLanguageInstances().push_back(instance);
779   }
780   return false;
781 }
782 
783 bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
784   if (create_callback) {
785     std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
786     LanguageInstances &instances = GetLanguageInstances();
787 
788     LanguageInstances::iterator pos, end = instances.end();
789     for (pos = instances.begin(); pos != end; ++pos) {
790       if (pos->create_callback == create_callback) {
791         instances.erase(pos);
792         return true;
793       }
794     }
795   }
796   return false;
797 }
798 
799 LanguageCreateInstance
800 PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
801   std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
802   LanguageInstances &instances = GetLanguageInstances();
803   if (idx < instances.size())
804     return instances[idx].create_callback;
805   return nullptr;
806 }
807 
808 LanguageCreateInstance
809 PluginManager::GetLanguageCreateCallbackForPluginName(ConstString name) {
810   if (name) {
811     std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
812     LanguageInstances &instances = GetLanguageInstances();
813 
814     LanguageInstances::iterator pos, end = instances.end();
815     for (pos = instances.begin(); pos != end; ++pos) {
816       if (name == pos->name)
817         return pos->create_callback;
818     }
819   }
820   return nullptr;
821 }
822 
823 #pragma mark LanguageRuntime
824 
825 struct LanguageRuntimeInstance {
826   LanguageRuntimeInstance() : name(), description(), create_callback(nullptr) {}
827 
828   ConstString name;
829   std::string description;
830   LanguageRuntimeCreateInstance create_callback;
831   LanguageRuntimeGetCommandObject command_callback;
832   LanguageRuntimeGetExceptionPrecondition precondition_callback;
833 };
834 
835 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
836 
837 static std::recursive_mutex &GetLanguageRuntimeMutex() {
838   static std::recursive_mutex g_instances_mutex;
839   return g_instances_mutex;
840 }
841 
842 static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
843   static LanguageRuntimeInstances g_instances;
844   return g_instances;
845 }
846 
847 bool PluginManager::RegisterPlugin(
848     ConstString name, const char *description,
849     LanguageRuntimeCreateInstance create_callback,
850     LanguageRuntimeGetCommandObject command_callback,
851     LanguageRuntimeGetExceptionPrecondition precondition_callback) {
852   if (create_callback) {
853     LanguageRuntimeInstance instance;
854     assert((bool)name);
855     instance.name = name;
856     if (description && description[0])
857       instance.description = description;
858     instance.create_callback = create_callback;
859     instance.command_callback = command_callback;
860     instance.precondition_callback = precondition_callback;
861     std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
862     GetLanguageRuntimeInstances().push_back(instance);
863   }
864   return false;
865 }
866 
867 bool PluginManager::UnregisterPlugin(
868     LanguageRuntimeCreateInstance create_callback) {
869   if (create_callback) {
870     std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
871     LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
872 
873     LanguageRuntimeInstances::iterator pos, end = instances.end();
874     for (pos = instances.begin(); pos != end; ++pos) {
875       if (pos->create_callback == create_callback) {
876         instances.erase(pos);
877         return true;
878       }
879     }
880   }
881   return false;
882 }
883 
884 LanguageRuntimeCreateInstance
885 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
886   std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
887   LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
888   if (idx < instances.size())
889     return instances[idx].create_callback;
890   return nullptr;
891 }
892 
893 LanguageRuntimeGetCommandObject
894 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
895   std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
896   LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
897   if (idx < instances.size())
898     return instances[idx].command_callback;
899   return nullptr;
900 }
901 
902 LanguageRuntimeGetExceptionPrecondition
903 PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
904   std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
905   LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
906   if (idx < instances.size())
907     return instances[idx].precondition_callback;
908   return nullptr;
909 }
910 
911 LanguageRuntimeCreateInstance
912 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
913     ConstString name) {
914   if (name) {
915     std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
916     LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
917 
918     LanguageRuntimeInstances::iterator pos, end = instances.end();
919     for (pos = instances.begin(); pos != end; ++pos) {
920       if (name == pos->name)
921         return pos->create_callback;
922     }
923   }
924   return nullptr;
925 }
926 
927 #pragma mark SystemRuntime
928 
929 struct SystemRuntimeInstance {
930   SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {}
931 
932   ConstString name;
933   std::string description;
934   SystemRuntimeCreateInstance create_callback;
935 };
936 
937 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
938 
939 static std::recursive_mutex &GetSystemRuntimeMutex() {
940   static std::recursive_mutex g_instances_mutex;
941   return g_instances_mutex;
942 }
943 
944 static SystemRuntimeInstances &GetSystemRuntimeInstances() {
945   static SystemRuntimeInstances g_instances;
946   return g_instances;
947 }
948 
949 bool PluginManager::RegisterPlugin(
950     ConstString name, const char *description,
951     SystemRuntimeCreateInstance create_callback) {
952   if (create_callback) {
953     SystemRuntimeInstance instance;
954     assert((bool)name);
955     instance.name = name;
956     if (description && description[0])
957       instance.description = description;
958     instance.create_callback = create_callback;
959     std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
960     GetSystemRuntimeInstances().push_back(instance);
961   }
962   return false;
963 }
964 
965 bool PluginManager::UnregisterPlugin(
966     SystemRuntimeCreateInstance create_callback) {
967   if (create_callback) {
968     std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
969     SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
970 
971     SystemRuntimeInstances::iterator pos, end = instances.end();
972     for (pos = instances.begin(); pos != end; ++pos) {
973       if (pos->create_callback == create_callback) {
974         instances.erase(pos);
975         return true;
976       }
977     }
978   }
979   return false;
980 }
981 
982 SystemRuntimeCreateInstance
983 PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
984   std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
985   SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
986   if (idx < instances.size())
987     return instances[idx].create_callback;
988   return nullptr;
989 }
990 
991 SystemRuntimeCreateInstance
992 PluginManager::GetSystemRuntimeCreateCallbackForPluginName(
993     ConstString name) {
994   if (name) {
995     std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
996     SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
997 
998     SystemRuntimeInstances::iterator pos, end = instances.end();
999     for (pos = instances.begin(); pos != end; ++pos) {
1000       if (name == pos->name)
1001         return pos->create_callback;
1002     }
1003   }
1004   return nullptr;
1005 }
1006 
1007 #pragma mark ObjectFile
1008 
1009 struct ObjectFileInstance {
1010   ObjectFileInstance()
1011       : name(), description(), create_callback(nullptr),
1012         create_memory_callback(nullptr), get_module_specifications(nullptr),
1013         save_core(nullptr) {}
1014 
1015   ConstString name;
1016   std::string description;
1017   ObjectFileCreateInstance create_callback;
1018   ObjectFileCreateMemoryInstance create_memory_callback;
1019   ObjectFileGetModuleSpecifications get_module_specifications;
1020   ObjectFileSaveCore save_core;
1021 };
1022 
1023 typedef std::vector<ObjectFileInstance> ObjectFileInstances;
1024 
1025 static std::recursive_mutex &GetObjectFileMutex() {
1026   static std::recursive_mutex g_instances_mutex;
1027   return g_instances_mutex;
1028 }
1029 
1030 static ObjectFileInstances &GetObjectFileInstances() {
1031   static ObjectFileInstances g_instances;
1032   return g_instances;
1033 }
1034 
1035 bool PluginManager::RegisterPlugin(
1036     ConstString name, const char *description,
1037     ObjectFileCreateInstance create_callback,
1038     ObjectFileCreateMemoryInstance create_memory_callback,
1039     ObjectFileGetModuleSpecifications get_module_specifications,
1040     ObjectFileSaveCore save_core) {
1041   if (create_callback) {
1042     ObjectFileInstance instance;
1043     assert((bool)name);
1044     instance.name = name;
1045     if (description && description[0])
1046       instance.description = description;
1047     instance.create_callback = create_callback;
1048     instance.create_memory_callback = create_memory_callback;
1049     instance.save_core = save_core;
1050     instance.get_module_specifications = get_module_specifications;
1051     std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1052     GetObjectFileInstances().push_back(instance);
1053   }
1054   return false;
1055 }
1056 
1057 bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
1058   if (create_callback) {
1059     std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1060     ObjectFileInstances &instances = GetObjectFileInstances();
1061 
1062     ObjectFileInstances::iterator pos, end = instances.end();
1063     for (pos = instances.begin(); pos != end; ++pos) {
1064       if (pos->create_callback == create_callback) {
1065         instances.erase(pos);
1066         return true;
1067       }
1068     }
1069   }
1070   return false;
1071 }
1072 
1073 ObjectFileCreateInstance
1074 PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
1075   std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1076   ObjectFileInstances &instances = GetObjectFileInstances();
1077   if (idx < instances.size())
1078     return instances[idx].create_callback;
1079   return nullptr;
1080 }
1081 
1082 ObjectFileCreateMemoryInstance
1083 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
1084   std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1085   ObjectFileInstances &instances = GetObjectFileInstances();
1086   if (idx < instances.size())
1087     return instances[idx].create_memory_callback;
1088   return nullptr;
1089 }
1090 
1091 ObjectFileGetModuleSpecifications
1092 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
1093     uint32_t idx) {
1094   std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1095   ObjectFileInstances &instances = GetObjectFileInstances();
1096   if (idx < instances.size())
1097     return instances[idx].get_module_specifications;
1098   return nullptr;
1099 }
1100 
1101 ObjectFileCreateInstance
1102 PluginManager::GetObjectFileCreateCallbackForPluginName(
1103     ConstString name) {
1104   if (name) {
1105     std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1106     ObjectFileInstances &instances = GetObjectFileInstances();
1107 
1108     ObjectFileInstances::iterator pos, end = instances.end();
1109     for (pos = instances.begin(); pos != end; ++pos) {
1110       if (name == pos->name)
1111         return pos->create_callback;
1112     }
1113   }
1114   return nullptr;
1115 }
1116 
1117 ObjectFileCreateMemoryInstance
1118 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
1119     ConstString name) {
1120   if (name) {
1121     std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1122     ObjectFileInstances &instances = GetObjectFileInstances();
1123 
1124     ObjectFileInstances::iterator pos, end = instances.end();
1125     for (pos = instances.begin(); pos != end; ++pos) {
1126       if (name == pos->name)
1127         return pos->create_memory_callback;
1128     }
1129   }
1130   return nullptr;
1131 }
1132 
1133 Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
1134                                const FileSpec &outfile) {
1135   Status error;
1136   std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
1137   ObjectFileInstances &instances = GetObjectFileInstances();
1138 
1139   ObjectFileInstances::iterator pos, end = instances.end();
1140   for (pos = instances.begin(); pos != end; ++pos) {
1141     if (pos->save_core && pos->save_core(process_sp, outfile, error))
1142       return error;
1143   }
1144   error.SetErrorString(
1145       "no ObjectFile plugins were able to save a core for this process");
1146   return error;
1147 }
1148 
1149 #pragma mark ObjectContainer
1150 
1151 struct ObjectContainerInstance {
1152   ObjectContainerInstance()
1153       : name(), description(), create_callback(nullptr),
1154         get_module_specifications(nullptr) {}
1155 
1156   ConstString name;
1157   std::string description;
1158   ObjectContainerCreateInstance create_callback;
1159   ObjectFileGetModuleSpecifications get_module_specifications;
1160 };
1161 
1162 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1163 
1164 static std::recursive_mutex &GetObjectContainerMutex() {
1165   static std::recursive_mutex g_instances_mutex;
1166   return g_instances_mutex;
1167 }
1168 
1169 static ObjectContainerInstances &GetObjectContainerInstances() {
1170   static ObjectContainerInstances g_instances;
1171   return g_instances;
1172 }
1173 
1174 bool PluginManager::RegisterPlugin(
1175     ConstString name, const char *description,
1176     ObjectContainerCreateInstance create_callback,
1177     ObjectFileGetModuleSpecifications get_module_specifications) {
1178   if (create_callback) {
1179     ObjectContainerInstance instance;
1180     assert((bool)name);
1181     instance.name = name;
1182     if (description && description[0])
1183       instance.description = description;
1184     instance.create_callback = create_callback;
1185     instance.get_module_specifications = get_module_specifications;
1186     std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1187     GetObjectContainerInstances().push_back(instance);
1188   }
1189   return false;
1190 }
1191 
1192 bool PluginManager::UnregisterPlugin(
1193     ObjectContainerCreateInstance create_callback) {
1194   if (create_callback) {
1195     std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1196     ObjectContainerInstances &instances = GetObjectContainerInstances();
1197 
1198     ObjectContainerInstances::iterator pos, end = instances.end();
1199     for (pos = instances.begin(); pos != end; ++pos) {
1200       if (pos->create_callback == create_callback) {
1201         instances.erase(pos);
1202         return true;
1203       }
1204     }
1205   }
1206   return false;
1207 }
1208 
1209 ObjectContainerCreateInstance
1210 PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
1211   std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1212   ObjectContainerInstances &instances = GetObjectContainerInstances();
1213   if (idx < instances.size())
1214     return instances[idx].create_callback;
1215   return nullptr;
1216 }
1217 
1218 ObjectContainerCreateInstance
1219 PluginManager::GetObjectContainerCreateCallbackForPluginName(
1220     ConstString name) {
1221   if (name) {
1222     std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1223     ObjectContainerInstances &instances = GetObjectContainerInstances();
1224 
1225     ObjectContainerInstances::iterator pos, end = instances.end();
1226     for (pos = instances.begin(); pos != end; ++pos) {
1227       if (name == pos->name)
1228         return pos->create_callback;
1229     }
1230   }
1231   return nullptr;
1232 }
1233 
1234 ObjectFileGetModuleSpecifications
1235 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
1236     uint32_t idx) {
1237   std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
1238   ObjectContainerInstances &instances = GetObjectContainerInstances();
1239   if (idx < instances.size())
1240     return instances[idx].get_module_specifications;
1241   return nullptr;
1242 }
1243 
1244 #pragma mark Platform
1245 
1246 struct PlatformInstance {
1247   PlatformInstance()
1248       : name(), description(), create_callback(nullptr),
1249         debugger_init_callback(nullptr) {}
1250 
1251   ConstString name;
1252   std::string description;
1253   PlatformCreateInstance create_callback;
1254   DebuggerInitializeCallback debugger_init_callback;
1255 };
1256 
1257 typedef std::vector<PlatformInstance> PlatformInstances;
1258 
1259 static std::recursive_mutex &GetPlatformInstancesMutex() {
1260   static std::recursive_mutex g_platform_instances_mutex;
1261   return g_platform_instances_mutex;
1262 }
1263 
1264 static PlatformInstances &GetPlatformInstances() {
1265   static PlatformInstances g_platform_instances;
1266   return g_platform_instances;
1267 }
1268 
1269 bool PluginManager::RegisterPlugin(
1270     ConstString name, const char *description,
1271     PlatformCreateInstance create_callback,
1272     DebuggerInitializeCallback debugger_init_callback) {
1273   if (create_callback) {
1274     std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1275 
1276     PlatformInstance instance;
1277     assert((bool)name);
1278     instance.name = name;
1279     if (description && description[0])
1280       instance.description = description;
1281     instance.create_callback = create_callback;
1282     instance.debugger_init_callback = debugger_init_callback;
1283     GetPlatformInstances().push_back(instance);
1284     return true;
1285   }
1286   return false;
1287 }
1288 
1289 const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
1290   std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1291   PlatformInstances &instances = GetPlatformInstances();
1292   if (idx < instances.size())
1293     return instances[idx].name.GetCString();
1294   return nullptr;
1295 }
1296 
1297 const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
1298   std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1299   PlatformInstances &instances = GetPlatformInstances();
1300   if (idx < instances.size())
1301     return instances[idx].description.c_str();
1302   return nullptr;
1303 }
1304 
1305 bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
1306   if (create_callback) {
1307     std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1308     PlatformInstances &instances = GetPlatformInstances();
1309 
1310     PlatformInstances::iterator pos, end = instances.end();
1311     for (pos = instances.begin(); pos != end; ++pos) {
1312       if (pos->create_callback == create_callback) {
1313         instances.erase(pos);
1314         return true;
1315       }
1316     }
1317   }
1318   return false;
1319 }
1320 
1321 PlatformCreateInstance
1322 PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
1323   std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1324   PlatformInstances &instances = GetPlatformInstances();
1325   if (idx < instances.size())
1326     return instances[idx].create_callback;
1327   return nullptr;
1328 }
1329 
1330 PlatformCreateInstance
1331 PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) {
1332   if (name) {
1333     std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1334     PlatformInstances &instances = GetPlatformInstances();
1335 
1336     PlatformInstances::iterator pos, end = instances.end();
1337     for (pos = instances.begin(); pos != end; ++pos) {
1338       if (name == pos->name)
1339         return pos->create_callback;
1340     }
1341   }
1342   return nullptr;
1343 }
1344 
1345 void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
1346                                              CompletionRequest &request) {
1347   if (name.empty())
1348     return;
1349 
1350   std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
1351   PlatformInstances &instances = GetPlatformInstances();
1352   llvm::StringRef name_sref(name);
1353 
1354   PlatformInstances::iterator pos, end = instances.end();
1355   for (pos = instances.begin(); pos != end; ++pos) {
1356     llvm::StringRef plugin_name(pos->name.GetCString());
1357     if (plugin_name.startswith(name_sref))
1358       request.AddCompletion(plugin_name.data());
1359   }
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   ConstString name;
2088   std::string description;
2089   TypeSystemCreateInstance create_callback;
2090   LanguageSet supported_languages_for_types;
2091   LanguageSet supported_languages_for_expressions;
2092 };
2093 
2094 typedef std::vector<TypeSystemInstance> TypeSystemInstances;
2095 
2096 static std::recursive_mutex &GetTypeSystemMutex() {
2097   static std::recursive_mutex g_instances_mutex;
2098   return g_instances_mutex;
2099 }
2100 
2101 static TypeSystemInstances &GetTypeSystemInstances() {
2102   static TypeSystemInstances g_instances;
2103   return g_instances;
2104 }
2105 
2106 bool PluginManager::RegisterPlugin(
2107     ConstString name, const char *description,
2108     TypeSystemCreateInstance create_callback,
2109     LanguageSet supported_languages_for_types,
2110     LanguageSet supported_languages_for_expressions) {
2111   if (create_callback) {
2112     TypeSystemInstance instance;
2113     assert((bool)name);
2114     instance.name = name;
2115     if (description && description[0])
2116       instance.description = description;
2117     instance.create_callback = create_callback;
2118     instance.supported_languages_for_types = supported_languages_for_types;
2119     instance.supported_languages_for_expressions = supported_languages_for_expressions;
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 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
2168   std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2169   LanguageSet all;
2170   TypeSystemInstances &instances = GetTypeSystemInstances();
2171   for (unsigned i = 0; i < instances.size(); ++i)
2172     all.bitvector |= instances[i].supported_languages_for_types.bitvector;
2173   return all;
2174 }
2175 
2176 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
2177   std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
2178   LanguageSet all;
2179   TypeSystemInstances &instances = GetTypeSystemInstances();
2180   for (unsigned i = 0; i < instances.size(); ++i)
2181     all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
2182   return all;
2183 }
2184 
2185 #pragma mark REPL
2186 
2187 struct REPLInstance {
2188   REPLInstance() : name(), description(), create_callback(nullptr) {}
2189 
2190   ConstString name;
2191   std::string description;
2192   REPLCreateInstance create_callback;
2193   LanguageSet supported_languages;
2194 };
2195 
2196 typedef std::vector<REPLInstance> REPLInstances;
2197 
2198 static std::recursive_mutex &GetREPLMutex() {
2199   static std::recursive_mutex g_instances_mutex;
2200   return g_instances_mutex;
2201 }
2202 
2203 static REPLInstances &GetREPLInstances() {
2204   static REPLInstances g_instances;
2205   return g_instances;
2206 }
2207 
2208 bool PluginManager::RegisterPlugin(ConstString name, const char *description,
2209                                    REPLCreateInstance create_callback,
2210                                    LanguageSet supported_languages) {
2211   if (create_callback) {
2212     REPLInstance instance;
2213     assert((bool)name);
2214     instance.name = name;
2215     if (description && description[0])
2216       instance.description = description;
2217     instance.create_callback = create_callback;
2218     instance.supported_languages = supported_languages;
2219     std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2220     GetREPLInstances().push_back(instance);
2221   }
2222   return false;
2223 }
2224 
2225 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
2226   if (create_callback) {
2227     std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2228     REPLInstances &instances = GetREPLInstances();
2229 
2230     REPLInstances::iterator pos, end = instances.end();
2231     for (pos = instances.begin(); pos != end; ++pos) {
2232       if (pos->create_callback == create_callback) {
2233         instances.erase(pos);
2234         return true;
2235       }
2236     }
2237   }
2238   return false;
2239 }
2240 
2241 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
2242   std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2243   REPLInstances &instances = GetREPLInstances();
2244   if (idx < instances.size())
2245     return instances[idx].create_callback;
2246   return nullptr;
2247 }
2248 
2249 REPLCreateInstance
2250 PluginManager::GetREPLCreateCallbackForPluginName(ConstString name) {
2251   if (name) {
2252     std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2253     REPLInstances &instances = GetREPLInstances();
2254 
2255     REPLInstances::iterator pos, end = instances.end();
2256     for (pos = instances.begin(); pos != end; ++pos) {
2257       if (name == pos->name)
2258         return pos->create_callback;
2259     }
2260   }
2261   return nullptr;
2262 }
2263 
2264 LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
2265   std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
2266   LanguageSet all;
2267   REPLInstances &instances = GetREPLInstances();
2268   for (unsigned i = 0; i < instances.size(); ++i)
2269     all.bitvector |= instances[i].supported_languages.bitvector;
2270   return all;
2271 }
2272 
2273 #pragma mark PluginManager
2274 
2275 void PluginManager::DebuggerInitialize(Debugger &debugger) {
2276   // Initialize the DynamicLoader plugins
2277   {
2278     std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
2279     DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
2280 
2281     DynamicLoaderInstances::iterator pos, end = instances.end();
2282     for (pos = instances.begin(); pos != end; ++pos) {
2283       if (pos->debugger_init_callback)
2284         pos->debugger_init_callback(debugger);
2285     }
2286   }
2287 
2288   // Initialize the JITLoader plugins
2289   {
2290     std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
2291     JITLoaderInstances &instances = GetJITLoaderInstances();
2292 
2293     JITLoaderInstances::iterator pos, end = instances.end();
2294     for (pos = instances.begin(); pos != end; ++pos) {
2295       if (pos->debugger_init_callback)
2296         pos->debugger_init_callback(debugger);
2297     }
2298   }
2299 
2300   // Initialize the Platform plugins
2301   {
2302     std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
2303     PlatformInstances &instances = GetPlatformInstances();
2304 
2305     PlatformInstances::iterator pos, end = instances.end();
2306     for (pos = instances.begin(); pos != end; ++pos) {
2307       if (pos->debugger_init_callback)
2308         pos->debugger_init_callback(debugger);
2309     }
2310   }
2311 
2312   // Initialize the Process plugins
2313   {
2314     std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
2315     ProcessInstances &instances = GetProcessInstances();
2316 
2317     ProcessInstances::iterator pos, end = instances.end();
2318     for (pos = instances.begin(); pos != end; ++pos) {
2319       if (pos->debugger_init_callback)
2320         pos->debugger_init_callback(debugger);
2321     }
2322   }
2323 
2324   // Initialize the SymbolFile plugins
2325   {
2326     std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
2327     for (auto &sym_file : GetSymbolFileInstances()) {
2328       if (sym_file.debugger_init_callback)
2329         sym_file.debugger_init_callback(debugger);
2330     }
2331   }
2332 
2333   // Initialize the OperatingSystem plugins
2334   {
2335     std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
2336     for (auto &os : GetOperatingSystemInstances()) {
2337       if (os.debugger_init_callback)
2338         os.debugger_init_callback(debugger);
2339     }
2340   }
2341 
2342   // Initialize the StructuredDataPlugin plugins
2343   {
2344     std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
2345     for (auto &plugin : GetStructuredDataPluginInstances()) {
2346       if (plugin.debugger_init_callback)
2347         plugin.debugger_init_callback(debugger);
2348     }
2349   }
2350 }
2351 
2352 // This is the preferred new way to register plugin specific settings.  e.g.
2353 // This will put a plugin's settings under e.g.
2354 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
2355 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins(
2356     Debugger &debugger, ConstString plugin_type_name,
2357     ConstString plugin_type_desc, bool can_create) {
2358   lldb::OptionValuePropertiesSP parent_properties_sp(
2359       debugger.GetValueProperties());
2360   if (parent_properties_sp) {
2361     static ConstString g_property_name("plugin");
2362 
2363     OptionValuePropertiesSP plugin_properties_sp =
2364         parent_properties_sp->GetSubProperty(nullptr, g_property_name);
2365     if (!plugin_properties_sp && can_create) {
2366       plugin_properties_sp =
2367           std::make_shared<OptionValueProperties>(g_property_name);
2368       parent_properties_sp->AppendProperty(
2369           g_property_name, ConstString("Settings specify to plugins."), true,
2370           plugin_properties_sp);
2371     }
2372 
2373     if (plugin_properties_sp) {
2374       lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2375           plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2376       if (!plugin_type_properties_sp && can_create) {
2377         plugin_type_properties_sp =
2378             std::make_shared<OptionValueProperties>(plugin_type_name);
2379         plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2380                                              true, plugin_type_properties_sp);
2381       }
2382       return plugin_type_properties_sp;
2383     }
2384   }
2385   return lldb::OptionValuePropertiesSP();
2386 }
2387 
2388 // This is deprecated way to register plugin specific settings.  e.g.
2389 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
2390 // generic settings would be under "platform.SETTINGNAME".
2391 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
2392     Debugger &debugger, ConstString plugin_type_name,
2393     ConstString plugin_type_desc, bool can_create) {
2394   static ConstString g_property_name("plugin");
2395   lldb::OptionValuePropertiesSP parent_properties_sp(
2396       debugger.GetValueProperties());
2397   if (parent_properties_sp) {
2398     OptionValuePropertiesSP plugin_properties_sp =
2399         parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
2400     if (!plugin_properties_sp && can_create) {
2401       plugin_properties_sp =
2402           std::make_shared<OptionValueProperties>(plugin_type_name);
2403       parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
2404                                            true, plugin_properties_sp);
2405     }
2406 
2407     if (plugin_properties_sp) {
2408       lldb::OptionValuePropertiesSP plugin_type_properties_sp =
2409           plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
2410       if (!plugin_type_properties_sp && can_create) {
2411         plugin_type_properties_sp =
2412             std::make_shared<OptionValueProperties>(g_property_name);
2413         plugin_properties_sp->AppendProperty(
2414             g_property_name, ConstString("Settings specific to plugins"), true,
2415             plugin_type_properties_sp);
2416       }
2417       return plugin_type_properties_sp;
2418     }
2419   }
2420   return lldb::OptionValuePropertiesSP();
2421 }
2422 
2423 namespace {
2424 
2425 typedef lldb::OptionValuePropertiesSP
2426 GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString ,
2427                                  ConstString , bool can_create);
2428 
2429 lldb::OptionValuePropertiesSP
2430 GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
2431                     ConstString plugin_type_name,
2432                     GetDebuggerPropertyForPluginsPtr get_debugger_property =
2433                         GetDebuggerPropertyForPlugins) {
2434   lldb::OptionValuePropertiesSP properties_sp;
2435   lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
2436       debugger, plugin_type_name,
2437       ConstString(), // not creating to so we don't need the description
2438       false));
2439   if (plugin_type_properties_sp)
2440     properties_sp =
2441         plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2442   return properties_sp;
2443 }
2444 
2445 bool CreateSettingForPlugin(
2446     Debugger &debugger, ConstString plugin_type_name,
2447     ConstString plugin_type_desc,
2448     const lldb::OptionValuePropertiesSP &properties_sp,
2449     ConstString description, bool is_global_property,
2450     GetDebuggerPropertyForPluginsPtr get_debugger_property =
2451         GetDebuggerPropertyForPlugins) {
2452   if (properties_sp) {
2453     lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2454         get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
2455                               true));
2456     if (plugin_type_properties_sp) {
2457       plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2458                                                 description, is_global_property,
2459                                                 properties_sp);
2460       return true;
2461     }
2462   }
2463   return false;
2464 }
2465 
2466 const char *kDynamicLoaderPluginName("dynamic-loader");
2467 const char *kPlatformPluginName("platform");
2468 const char *kProcessPluginName("process");
2469 const char *kSymbolFilePluginName("symbol-file");
2470 const char *kJITLoaderPluginName("jit-loader");
2471 const char *kStructuredDataPluginName("structured-data");
2472 
2473 } // anonymous namespace
2474 
2475 lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(
2476     Debugger &debugger, ConstString setting_name) {
2477   return GetSettingForPlugin(debugger, setting_name,
2478                              ConstString(kDynamicLoaderPluginName));
2479 }
2480 
2481 bool PluginManager::CreateSettingForDynamicLoaderPlugin(
2482     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2483     ConstString description, bool is_global_property) {
2484   return CreateSettingForPlugin(
2485       debugger, ConstString(kDynamicLoaderPluginName),
2486       ConstString("Settings for dynamic loader plug-ins"), properties_sp,
2487       description, is_global_property);
2488 }
2489 
2490 lldb::OptionValuePropertiesSP
2491 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
2492                                            ConstString setting_name) {
2493   return GetSettingForPlugin(debugger, setting_name,
2494                              ConstString(kPlatformPluginName),
2495                              GetDebuggerPropertyForPluginsOldStyle);
2496 }
2497 
2498 bool PluginManager::CreateSettingForPlatformPlugin(
2499     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2500     ConstString description, bool is_global_property) {
2501   return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
2502                                 ConstString("Settings for platform plug-ins"),
2503                                 properties_sp, description, is_global_property,
2504                                 GetDebuggerPropertyForPluginsOldStyle);
2505 }
2506 
2507 lldb::OptionValuePropertiesSP
2508 PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
2509                                           ConstString setting_name) {
2510   return GetSettingForPlugin(debugger, setting_name,
2511                              ConstString(kProcessPluginName));
2512 }
2513 
2514 bool PluginManager::CreateSettingForProcessPlugin(
2515     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2516     ConstString description, bool is_global_property) {
2517   return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
2518                                 ConstString("Settings for process plug-ins"),
2519                                 properties_sp, description, is_global_property);
2520 }
2521 
2522 lldb::OptionValuePropertiesSP
2523 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
2524                                              ConstString setting_name) {
2525   return GetSettingForPlugin(debugger, setting_name,
2526                              ConstString(kSymbolFilePluginName));
2527 }
2528 
2529 bool PluginManager::CreateSettingForSymbolFilePlugin(
2530     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2531     ConstString description, bool is_global_property) {
2532   return CreateSettingForPlugin(
2533       debugger, ConstString(kSymbolFilePluginName),
2534       ConstString("Settings for symbol file plug-ins"), properties_sp,
2535       description, is_global_property);
2536 }
2537 
2538 lldb::OptionValuePropertiesSP
2539 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
2540                                             ConstString setting_name) {
2541   return GetSettingForPlugin(debugger, setting_name,
2542                              ConstString(kJITLoaderPluginName));
2543 }
2544 
2545 bool PluginManager::CreateSettingForJITLoaderPlugin(
2546     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2547     ConstString description, bool is_global_property) {
2548   return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
2549                                 ConstString("Settings for JIT loader plug-ins"),
2550                                 properties_sp, description, is_global_property);
2551 }
2552 
2553 static const char *kOperatingSystemPluginName("os");
2554 
2555 lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin(
2556     Debugger &debugger, ConstString setting_name) {
2557   lldb::OptionValuePropertiesSP properties_sp;
2558   lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2559       GetDebuggerPropertyForPlugins(
2560           debugger, ConstString(kOperatingSystemPluginName),
2561           ConstString(), // not creating to so we don't need the description
2562           false));
2563   if (plugin_type_properties_sp)
2564     properties_sp =
2565         plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
2566   return properties_sp;
2567 }
2568 
2569 bool PluginManager::CreateSettingForOperatingSystemPlugin(
2570     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2571     ConstString description, bool is_global_property) {
2572   if (properties_sp) {
2573     lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2574         GetDebuggerPropertyForPlugins(
2575             debugger, ConstString(kOperatingSystemPluginName),
2576             ConstString("Settings for operating system plug-ins"), true));
2577     if (plugin_type_properties_sp) {
2578       plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
2579                                                 description, is_global_property,
2580                                                 properties_sp);
2581       return true;
2582     }
2583   }
2584   return false;
2585 }
2586 
2587 lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin(
2588     Debugger &debugger, ConstString setting_name) {
2589   return GetSettingForPlugin(debugger, setting_name,
2590                              ConstString(kStructuredDataPluginName));
2591 }
2592 
2593 bool PluginManager::CreateSettingForStructuredDataPlugin(
2594     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2595     ConstString description, bool is_global_property) {
2596   return CreateSettingForPlugin(
2597       debugger, ConstString(kStructuredDataPluginName),
2598       ConstString("Settings for structured data plug-ins"), properties_sp,
2599       description, is_global_property);
2600 }
2601