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