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