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