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