xref: /freebsd/contrib/llvm-project/lldb/source/Core/PluginManager.cpp (revision e9e8876a4d6afc1ad5315faaa191b25121a813d7)
1 //===-- PluginManager.cpp -------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Core/PluginManager.h"
10 
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Host/FileSystem.h"
13 #include "lldb/Host/HostInfo.h"
14 #include "lldb/Interpreter/OptionValueProperties.h"
15 #include "lldb/Utility/ConstString.h"
16 #include "lldb/Utility/FileSpec.h"
17 #include "lldb/Utility/Status.h"
18 #include "lldb/Utility/StringList.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Support/DynamicLibrary.h"
21 #include "llvm/Support/FileSystem.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <cassert>
24 #include <map>
25 #include <memory>
26 #include <mutex>
27 #include <string>
28 #include <utility>
29 #include <vector>
30 #if defined(_WIN32)
31 #include "lldb/Host/windows/PosixApi.h"
32 #endif
33 
34 using namespace lldb;
35 using namespace lldb_private;
36 
37 typedef bool (*PluginInitCallback)();
38 typedef void (*PluginTermCallback)();
39 
40 struct PluginInfo {
41   PluginInfo() = default;
42 
43   llvm::sys::DynamicLibrary library;
44   PluginInitCallback plugin_init_callback = nullptr;
45   PluginTermCallback plugin_term_callback = nullptr;
46 };
47 
48 typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
49 
50 static std::recursive_mutex &GetPluginMapMutex() {
51   static std::recursive_mutex g_plugin_map_mutex;
52   return g_plugin_map_mutex;
53 }
54 
55 static PluginTerminateMap &GetPluginMap() {
56   static PluginTerminateMap g_plugin_map;
57   return g_plugin_map;
58 }
59 
60 static bool PluginIsLoaded(const FileSpec &plugin_file_spec) {
61   std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
62   PluginTerminateMap &plugin_map = GetPluginMap();
63   return plugin_map.find(plugin_file_spec) != plugin_map.end();
64 }
65 
66 static void SetPluginInfo(const FileSpec &plugin_file_spec,
67                           const PluginInfo &plugin_info) {
68   std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
69   PluginTerminateMap &plugin_map = GetPluginMap();
70   assert(plugin_map.find(plugin_file_spec) == plugin_map.end());
71   plugin_map[plugin_file_spec] = plugin_info;
72 }
73 
74 template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
75   return reinterpret_cast<FPtrTy>(VPtr);
76 }
77 
78 static FileSystem::EnumerateDirectoryResult
79 LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
80                    llvm::StringRef path) {
81   Status error;
82 
83   namespace fs = llvm::sys::fs;
84   // If we have a regular file, a symbolic link or unknown file type, try and
85   // process the file. We must handle unknown as sometimes the directory
86   // enumeration might be enumerating a file system that doesn't have correct
87   // file type information.
88   if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
89       ft == fs::file_type::type_unknown) {
90     FileSpec plugin_file_spec(path);
91     FileSystem::Instance().Resolve(plugin_file_spec);
92 
93     if (PluginIsLoaded(plugin_file_spec))
94       return FileSystem::eEnumerateDirectoryResultNext;
95     else {
96       PluginInfo plugin_info;
97 
98       std::string pluginLoadError;
99       plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary(
100           plugin_file_spec.GetPath().c_str(), &pluginLoadError);
101       if (plugin_info.library.isValid()) {
102         bool success = false;
103         plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>(
104             plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
105         if (plugin_info.plugin_init_callback) {
106           // Call the plug-in "bool LLDBPluginInitialize(void)" function
107           success = plugin_info.plugin_init_callback();
108         }
109 
110         if (success) {
111           // It is ok for the "LLDBPluginTerminate" symbol to be nullptr
112           plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>(
113               plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
114         } else {
115           // The initialize function returned FALSE which means the plug-in
116           // might not be compatible, or might be too new or too old, or might
117           // not want to run on this machine.  Set it to a default-constructed
118           // instance to invalidate it.
119           plugin_info = PluginInfo();
120         }
121 
122         // Regardless of success or failure, cache the plug-in load in our
123         // plug-in info so we don't try to load it again and again.
124         SetPluginInfo(plugin_file_spec, plugin_info);
125 
126         return FileSystem::eEnumerateDirectoryResultNext;
127       }
128     }
129   }
130 
131   if (ft == fs::file_type::directory_file ||
132       ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
133     // Try and recurse into anything that a directory or symbolic link. We must
134     // also do this for unknown as sometimes the directory enumeration might be
135     // enumerating a file system that doesn't have correct file type
136     // information.
137     return FileSystem::eEnumerateDirectoryResultEnter;
138   }
139 
140   return FileSystem::eEnumerateDirectoryResultNext;
141 }
142 
143 void PluginManager::Initialize() {
144   const bool find_directories = true;
145   const bool find_files = true;
146   const bool find_other = true;
147   char dir_path[PATH_MAX];
148   if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
149     if (FileSystem::Instance().Exists(dir_spec) &&
150         dir_spec.GetPath(dir_path, sizeof(dir_path))) {
151       FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
152                                                 find_files, find_other,
153                                                 LoadPluginCallback, nullptr);
154     }
155   }
156 
157   if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
158     if (FileSystem::Instance().Exists(dir_spec) &&
159         dir_spec.GetPath(dir_path, sizeof(dir_path))) {
160       FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
161                                                 find_files, find_other,
162                                                 LoadPluginCallback, nullptr);
163     }
164   }
165 }
166 
167 void PluginManager::Terminate() {
168   std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
169   PluginTerminateMap &plugin_map = GetPluginMap();
170 
171   PluginTerminateMap::const_iterator pos, end = plugin_map.end();
172   for (pos = plugin_map.begin(); pos != end; ++pos) {
173     // Call the plug-in "void LLDBPluginTerminate (void)" function if there is
174     // one (if the symbol was not nullptr).
175     if (pos->second.library.isValid()) {
176       if (pos->second.plugin_term_callback)
177         pos->second.plugin_term_callback();
178     }
179   }
180   plugin_map.clear();
181 }
182 
183 template <typename Callback> struct PluginInstance {
184   typedef Callback CallbackType;
185 
186   PluginInstance() = default;
187   PluginInstance(ConstString name, std::string description,
188                  Callback create_callback = nullptr,
189                  DebuggerInitializeCallback debugger_init_callback = nullptr)
190       : name(name), description(std::move(description)),
191         create_callback(create_callback),
192         debugger_init_callback(debugger_init_callback) {}
193 
194   ConstString name;
195   std::string description;
196   Callback create_callback;
197   DebuggerInitializeCallback debugger_init_callback;
198 };
199 
200 template <typename Instance> class PluginInstances {
201 public:
202   template <typename... Args>
203   bool RegisterPlugin(ConstString name, const char *description,
204                       typename Instance::CallbackType callback,
205                       Args &&... args) {
206     if (!callback)
207       return false;
208     assert((bool)name);
209     Instance instance =
210         Instance(name, description, callback, std::forward<Args>(args)...);
211     m_instances.push_back(instance);
212     return false;
213   }
214 
215   bool UnregisterPlugin(typename Instance::CallbackType callback) {
216     if (!callback)
217       return false;
218     auto pos = m_instances.begin();
219     auto end = m_instances.end();
220     for (; pos != end; ++pos) {
221       if (pos->create_callback == callback) {
222         m_instances.erase(pos);
223         return true;
224       }
225     }
226     return false;
227   }
228 
229   typename Instance::CallbackType GetCallbackAtIndex(uint32_t idx) {
230     if (Instance *instance = GetInstanceAtIndex(idx))
231       return instance->create_callback;
232     return nullptr;
233   }
234 
235   const char *GetDescriptionAtIndex(uint32_t idx) {
236     if (Instance *instance = GetInstanceAtIndex(idx))
237       return instance->description.c_str();
238     return nullptr;
239   }
240 
241   const char *GetNameAtIndex(uint32_t idx) {
242     if (Instance *instance = GetInstanceAtIndex(idx))
243       return instance->name.GetCString();
244     return nullptr;
245   }
246 
247   typename Instance::CallbackType GetCallbackForName(ConstString name) {
248     if (!name)
249       return nullptr;
250     for (auto &instance : m_instances) {
251       if (name == instance.name)
252         return instance.create_callback;
253     }
254     return nullptr;
255   }
256 
257   void PerformDebuggerCallback(Debugger &debugger) {
258     for (auto &instance : m_instances) {
259       if (instance.debugger_init_callback)
260         instance.debugger_init_callback(debugger);
261     }
262   }
263 
264   const std::vector<Instance> &GetInstances() const { return m_instances; }
265   std::vector<Instance> &GetInstances() { return m_instances; }
266 
267   Instance *GetInstanceAtIndex(uint32_t idx) {
268     if (idx < m_instances.size())
269       return &m_instances[idx];
270     return nullptr;
271   }
272 
273 private:
274   std::vector<Instance> m_instances;
275 };
276 
277 #pragma mark ABI
278 
279 typedef PluginInstance<ABICreateInstance> ABIInstance;
280 typedef PluginInstances<ABIInstance> ABIInstances;
281 
282 static ABIInstances &GetABIInstances() {
283   static ABIInstances g_instances;
284   return g_instances;
285 }
286 
287 bool PluginManager::RegisterPlugin(ConstString name, const char *description,
288                                    ABICreateInstance create_callback) {
289   return GetABIInstances().RegisterPlugin(name, description, create_callback);
290 }
291 
292 bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
293   return GetABIInstances().UnregisterPlugin(create_callback);
294 }
295 
296 ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
297   return GetABIInstances().GetCallbackAtIndex(idx);
298 }
299 
300 #pragma mark Architecture
301 
302 typedef PluginInstance<ArchitectureCreateInstance> ArchitectureInstance;
303 typedef std::vector<ArchitectureInstance> ArchitectureInstances;
304 
305 static ArchitectureInstances &GetArchitectureInstances() {
306   static ArchitectureInstances g_instances;
307   return g_instances;
308 }
309 
310 void PluginManager::RegisterPlugin(ConstString name,
311                                    llvm::StringRef description,
312                                    ArchitectureCreateInstance create_callback) {
313   GetArchitectureInstances().push_back(
314       {name, std::string(description), create_callback});
315 }
316 
317 void PluginManager::UnregisterPlugin(
318     ArchitectureCreateInstance create_callback) {
319   auto &instances = GetArchitectureInstances();
320 
321   for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
322     if (pos->create_callback == create_callback) {
323       instances.erase(pos);
324       return;
325     }
326   }
327   llvm_unreachable("Plugin not found");
328 }
329 
330 std::unique_ptr<Architecture>
331 PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
332   for (const auto &instances : GetArchitectureInstances()) {
333     if (auto plugin_up = instances.create_callback(arch))
334       return plugin_up;
335   }
336   return nullptr;
337 }
338 
339 #pragma mark Disassembler
340 
341 typedef PluginInstance<DisassemblerCreateInstance> DisassemblerInstance;
342 typedef PluginInstances<DisassemblerInstance> DisassemblerInstances;
343 
344 static DisassemblerInstances &GetDisassemblerInstances() {
345   static DisassemblerInstances g_instances;
346   return g_instances;
347 }
348 
349 bool PluginManager::RegisterPlugin(ConstString name, const char *description,
350                                    DisassemblerCreateInstance create_callback) {
351   return GetDisassemblerInstances().RegisterPlugin(name, description,
352                                                    create_callback);
353 }
354 
355 bool PluginManager::UnregisterPlugin(
356     DisassemblerCreateInstance create_callback) {
357   return GetDisassemblerInstances().UnregisterPlugin(create_callback);
358 }
359 
360 DisassemblerCreateInstance
361 PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
362   return GetDisassemblerInstances().GetCallbackAtIndex(idx);
363 }
364 
365 DisassemblerCreateInstance
366 PluginManager::GetDisassemblerCreateCallbackForPluginName(ConstString name) {
367   return GetDisassemblerInstances().GetCallbackForName(name);
368 }
369 
370 #pragma mark DynamicLoader
371 
372 typedef PluginInstance<DynamicLoaderCreateInstance> DynamicLoaderInstance;
373 typedef PluginInstances<DynamicLoaderInstance> DynamicLoaderInstances;
374 
375 static DynamicLoaderInstances &GetDynamicLoaderInstances() {
376   static DynamicLoaderInstances g_instances;
377   return g_instances;
378 }
379 
380 bool PluginManager::RegisterPlugin(
381     ConstString name, const char *description,
382     DynamicLoaderCreateInstance create_callback,
383     DebuggerInitializeCallback debugger_init_callback) {
384   return GetDynamicLoaderInstances().RegisterPlugin(
385       name, description, create_callback, debugger_init_callback);
386 }
387 
388 bool PluginManager::UnregisterPlugin(
389     DynamicLoaderCreateInstance create_callback) {
390   return GetDynamicLoaderInstances().UnregisterPlugin(create_callback);
391 }
392 
393 DynamicLoaderCreateInstance
394 PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
395   return GetDynamicLoaderInstances().GetCallbackAtIndex(idx);
396 }
397 
398 DynamicLoaderCreateInstance
399 PluginManager::GetDynamicLoaderCreateCallbackForPluginName(ConstString name) {
400   return GetDynamicLoaderInstances().GetCallbackForName(name);
401 }
402 
403 #pragma mark JITLoader
404 
405 typedef PluginInstance<JITLoaderCreateInstance> JITLoaderInstance;
406 typedef PluginInstances<JITLoaderInstance> JITLoaderInstances;
407 
408 static JITLoaderInstances &GetJITLoaderInstances() {
409   static JITLoaderInstances g_instances;
410   return g_instances;
411 }
412 
413 bool PluginManager::RegisterPlugin(
414     ConstString name, const char *description,
415     JITLoaderCreateInstance create_callback,
416     DebuggerInitializeCallback debugger_init_callback) {
417   return GetJITLoaderInstances().RegisterPlugin(
418       name, description, create_callback, debugger_init_callback);
419 }
420 
421 bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
422   return GetJITLoaderInstances().UnregisterPlugin(create_callback);
423 }
424 
425 JITLoaderCreateInstance
426 PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
427   return GetJITLoaderInstances().GetCallbackAtIndex(idx);
428 }
429 
430 #pragma mark EmulateInstruction
431 
432 typedef PluginInstance<EmulateInstructionCreateInstance>
433     EmulateInstructionInstance;
434 typedef PluginInstances<EmulateInstructionInstance> EmulateInstructionInstances;
435 
436 static EmulateInstructionInstances &GetEmulateInstructionInstances() {
437   static EmulateInstructionInstances g_instances;
438   return g_instances;
439 }
440 
441 bool PluginManager::RegisterPlugin(
442     ConstString name, const char *description,
443     EmulateInstructionCreateInstance create_callback) {
444   return GetEmulateInstructionInstances().RegisterPlugin(name, description,
445                                                          create_callback);
446 }
447 
448 bool PluginManager::UnregisterPlugin(
449     EmulateInstructionCreateInstance create_callback) {
450   return GetEmulateInstructionInstances().UnregisterPlugin(create_callback);
451 }
452 
453 EmulateInstructionCreateInstance
454 PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
455   return GetEmulateInstructionInstances().GetCallbackAtIndex(idx);
456 }
457 
458 EmulateInstructionCreateInstance
459 PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
460     ConstString name) {
461   return GetEmulateInstructionInstances().GetCallbackForName(name);
462 }
463 
464 #pragma mark OperatingSystem
465 
466 typedef PluginInstance<OperatingSystemCreateInstance> OperatingSystemInstance;
467 typedef PluginInstances<OperatingSystemInstance> OperatingSystemInstances;
468 
469 static OperatingSystemInstances &GetOperatingSystemInstances() {
470   static OperatingSystemInstances g_instances;
471   return g_instances;
472 }
473 
474 bool PluginManager::RegisterPlugin(
475     ConstString name, const char *description,
476     OperatingSystemCreateInstance create_callback,
477     DebuggerInitializeCallback debugger_init_callback) {
478   return GetOperatingSystemInstances().RegisterPlugin(
479       name, description, create_callback, debugger_init_callback);
480 }
481 
482 bool PluginManager::UnregisterPlugin(
483     OperatingSystemCreateInstance create_callback) {
484   return GetOperatingSystemInstances().UnregisterPlugin(create_callback);
485 }
486 
487 OperatingSystemCreateInstance
488 PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
489   return GetOperatingSystemInstances().GetCallbackAtIndex(idx);
490 }
491 
492 OperatingSystemCreateInstance
493 PluginManager::GetOperatingSystemCreateCallbackForPluginName(ConstString name) {
494   return GetOperatingSystemInstances().GetCallbackForName(name);
495 }
496 
497 #pragma mark Language
498 
499 typedef PluginInstance<LanguageCreateInstance> LanguageInstance;
500 typedef PluginInstances<LanguageInstance> LanguageInstances;
501 
502 static LanguageInstances &GetLanguageInstances() {
503   static LanguageInstances g_instances;
504   return g_instances;
505 }
506 
507 bool PluginManager::RegisterPlugin(ConstString name, const char *description,
508                                    LanguageCreateInstance create_callback) {
509   return GetLanguageInstances().RegisterPlugin(name, description,
510                                                create_callback);
511 }
512 
513 bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
514   return GetLanguageInstances().UnregisterPlugin(create_callback);
515 }
516 
517 LanguageCreateInstance
518 PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
519   return GetLanguageInstances().GetCallbackAtIndex(idx);
520 }
521 
522 #pragma mark LanguageRuntime
523 
524 struct LanguageRuntimeInstance
525     : public PluginInstance<LanguageRuntimeCreateInstance> {
526   LanguageRuntimeInstance(
527       ConstString name, std::string description, CallbackType create_callback,
528       DebuggerInitializeCallback debugger_init_callback,
529       LanguageRuntimeGetCommandObject command_callback,
530       LanguageRuntimeGetExceptionPrecondition precondition_callback)
531       : PluginInstance<LanguageRuntimeCreateInstance>(
532             name, std::move(description), create_callback,
533             debugger_init_callback),
534         command_callback(command_callback),
535         precondition_callback(precondition_callback) {}
536 
537   LanguageRuntimeGetCommandObject command_callback;
538   LanguageRuntimeGetExceptionPrecondition precondition_callback;
539 };
540 
541 typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances;
542 
543 static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
544   static LanguageRuntimeInstances g_instances;
545   return g_instances;
546 }
547 
548 bool PluginManager::RegisterPlugin(
549     ConstString name, const char *description,
550     LanguageRuntimeCreateInstance create_callback,
551     LanguageRuntimeGetCommandObject command_callback,
552     LanguageRuntimeGetExceptionPrecondition precondition_callback) {
553   return GetLanguageRuntimeInstances().RegisterPlugin(
554       name, description, create_callback, nullptr, command_callback,
555       precondition_callback);
556 }
557 
558 bool PluginManager::UnregisterPlugin(
559     LanguageRuntimeCreateInstance create_callback) {
560   return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback);
561 }
562 
563 LanguageRuntimeCreateInstance
564 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
565   return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx);
566 }
567 
568 LanguageRuntimeGetCommandObject
569 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
570   const auto &instances = GetLanguageRuntimeInstances().GetInstances();
571   if (idx < instances.size())
572     return instances[idx].command_callback;
573   return nullptr;
574 }
575 
576 LanguageRuntimeGetExceptionPrecondition
577 PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
578   const auto &instances = GetLanguageRuntimeInstances().GetInstances();
579   if (idx < instances.size())
580     return instances[idx].precondition_callback;
581   return nullptr;
582 }
583 
584 #pragma mark SystemRuntime
585 
586 typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance;
587 typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances;
588 
589 static SystemRuntimeInstances &GetSystemRuntimeInstances() {
590   static SystemRuntimeInstances g_instances;
591   return g_instances;
592 }
593 
594 bool PluginManager::RegisterPlugin(
595     ConstString name, const char *description,
596     SystemRuntimeCreateInstance create_callback) {
597   return GetSystemRuntimeInstances().RegisterPlugin(name, description,
598                                                     create_callback);
599 }
600 
601 bool PluginManager::UnregisterPlugin(
602     SystemRuntimeCreateInstance create_callback) {
603   return GetSystemRuntimeInstances().UnregisterPlugin(create_callback);
604 }
605 
606 SystemRuntimeCreateInstance
607 PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
608   return GetSystemRuntimeInstances().GetCallbackAtIndex(idx);
609 }
610 
611 #pragma mark ObjectFile
612 
613 struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> {
614   ObjectFileInstance(
615       ConstString name, std::string description, CallbackType create_callback,
616       ObjectFileCreateMemoryInstance create_memory_callback,
617       ObjectFileGetModuleSpecifications get_module_specifications,
618       ObjectFileSaveCore save_core)
619       : PluginInstance<ObjectFileCreateInstance>(name, std::move(description),
620                                                  create_callback),
621         create_memory_callback(create_memory_callback),
622         get_module_specifications(get_module_specifications),
623         save_core(save_core) {}
624 
625   ObjectFileCreateMemoryInstance create_memory_callback;
626   ObjectFileGetModuleSpecifications get_module_specifications;
627   ObjectFileSaveCore save_core;
628 };
629 typedef PluginInstances<ObjectFileInstance> ObjectFileInstances;
630 
631 static ObjectFileInstances &GetObjectFileInstances() {
632   static ObjectFileInstances g_instances;
633   return g_instances;
634 }
635 
636 bool PluginManager::RegisterPlugin(
637     ConstString name, const char *description,
638     ObjectFileCreateInstance create_callback,
639     ObjectFileCreateMemoryInstance create_memory_callback,
640     ObjectFileGetModuleSpecifications get_module_specifications,
641     ObjectFileSaveCore save_core) {
642   return GetObjectFileInstances().RegisterPlugin(
643       name, description, create_callback, create_memory_callback,
644       get_module_specifications, save_core);
645 }
646 
647 bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
648   return GetObjectFileInstances().UnregisterPlugin(create_callback);
649 }
650 
651 ObjectFileCreateInstance
652 PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
653   return GetObjectFileInstances().GetCallbackAtIndex(idx);
654 }
655 
656 ObjectFileCreateMemoryInstance
657 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
658   const auto &instances = GetObjectFileInstances().GetInstances();
659   if (idx < instances.size())
660     return instances[idx].create_memory_callback;
661   return nullptr;
662 }
663 
664 ObjectFileGetModuleSpecifications
665 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
666     uint32_t idx) {
667   const auto &instances = GetObjectFileInstances().GetInstances();
668   if (idx < instances.size())
669     return instances[idx].get_module_specifications;
670   return nullptr;
671 }
672 
673 ObjectFileCreateMemoryInstance
674 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
675     ConstString name) {
676   if (!name)
677     return nullptr;
678   const auto &instances = GetObjectFileInstances().GetInstances();
679   for (auto &instance : instances) {
680     if (instance.name == name)
681       return instance.create_memory_callback;
682   }
683   return nullptr;
684 }
685 
686 Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
687                                const FileSpec &outfile,
688                                lldb::SaveCoreStyle &core_style) {
689   Status error;
690   auto &instances = GetObjectFileInstances().GetInstances();
691   for (auto &instance : instances) {
692     if (instance.save_core &&
693         instance.save_core(process_sp, outfile, core_style, error))
694       return error;
695   }
696   error.SetErrorString(
697       "no ObjectFile plugins were able to save a core for this process");
698   return error;
699 }
700 
701 #pragma mark ObjectContainer
702 
703 struct ObjectContainerInstance
704     : public PluginInstance<ObjectContainerCreateInstance> {
705   ObjectContainerInstance(
706       ConstString name, std::string description, CallbackType create_callback,
707       ObjectFileGetModuleSpecifications get_module_specifications)
708       : PluginInstance<ObjectContainerCreateInstance>(
709             name, std::move(description), create_callback),
710         get_module_specifications(get_module_specifications) {}
711 
712   ObjectFileGetModuleSpecifications get_module_specifications;
713 };
714 typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;
715 
716 static ObjectContainerInstances &GetObjectContainerInstances() {
717   static ObjectContainerInstances g_instances;
718   return g_instances;
719 }
720 
721 bool PluginManager::RegisterPlugin(
722     ConstString name, const char *description,
723     ObjectContainerCreateInstance create_callback,
724     ObjectFileGetModuleSpecifications get_module_specifications) {
725   return GetObjectContainerInstances().RegisterPlugin(
726       name, description, create_callback, get_module_specifications);
727 }
728 
729 bool PluginManager::UnregisterPlugin(
730     ObjectContainerCreateInstance create_callback) {
731   return GetObjectContainerInstances().UnregisterPlugin(create_callback);
732 }
733 
734 ObjectContainerCreateInstance
735 PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
736   return GetObjectContainerInstances().GetCallbackAtIndex(idx);
737 }
738 
739 ObjectFileGetModuleSpecifications
740 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
741     uint32_t idx) {
742   const auto &instances = GetObjectContainerInstances().GetInstances();
743   if (idx < instances.size())
744     return instances[idx].get_module_specifications;
745   return nullptr;
746 }
747 
748 #pragma mark Platform
749 
750 typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
751 typedef PluginInstances<PlatformInstance> PlatformInstances;
752 
753 static PlatformInstances &GetPlatformInstances() {
754   static PlatformInstances g_platform_instances;
755   return g_platform_instances;
756 }
757 
758 bool PluginManager::RegisterPlugin(
759     ConstString name, const char *description,
760     PlatformCreateInstance create_callback,
761     DebuggerInitializeCallback debugger_init_callback) {
762   return GetPlatformInstances().RegisterPlugin(
763       name, description, create_callback, debugger_init_callback);
764 }
765 
766 bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
767   return GetPlatformInstances().UnregisterPlugin(create_callback);
768 }
769 
770 const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
771   return GetPlatformInstances().GetNameAtIndex(idx);
772 }
773 
774 const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
775   return GetPlatformInstances().GetDescriptionAtIndex(idx);
776 }
777 
778 PlatformCreateInstance
779 PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
780   return GetPlatformInstances().GetCallbackAtIndex(idx);
781 }
782 
783 PlatformCreateInstance
784 PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) {
785   return GetPlatformInstances().GetCallbackForName(name);
786 }
787 
788 void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
789                                              CompletionRequest &request) {
790   for (const auto &instance : GetPlatformInstances().GetInstances()) {
791     if (instance.name.GetStringRef().startswith(name))
792       request.AddCompletion(instance.name.GetCString());
793   }
794 }
795 
796 #pragma mark Process
797 
798 typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
799 typedef PluginInstances<ProcessInstance> ProcessInstances;
800 
801 static ProcessInstances &GetProcessInstances() {
802   static ProcessInstances g_instances;
803   return g_instances;
804 }
805 
806 bool PluginManager::RegisterPlugin(
807     ConstString name, const char *description,
808     ProcessCreateInstance create_callback,
809     DebuggerInitializeCallback debugger_init_callback) {
810   return GetProcessInstances().RegisterPlugin(
811       name, description, create_callback, debugger_init_callback);
812 }
813 
814 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
815   return GetProcessInstances().UnregisterPlugin(create_callback);
816 }
817 
818 const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
819   return GetProcessInstances().GetNameAtIndex(idx);
820 }
821 
822 const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
823   return GetProcessInstances().GetDescriptionAtIndex(idx);
824 }
825 
826 ProcessCreateInstance
827 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
828   return GetProcessInstances().GetCallbackAtIndex(idx);
829 }
830 
831 ProcessCreateInstance
832 PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) {
833   return GetProcessInstances().GetCallbackForName(name);
834 }
835 
836 void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
837                                             CompletionRequest &request) {
838   for (const auto &instance : GetProcessInstances().GetInstances()) {
839     if (instance.name.GetStringRef().startswith(name))
840       request.AddCompletion(instance.name.GetCString(), instance.description);
841   }
842 }
843 
844 #pragma mark ScriptInterpreter
845 
846 struct ScriptInterpreterInstance
847     : public PluginInstance<ScriptInterpreterCreateInstance> {
848   ScriptInterpreterInstance(ConstString name, std::string description,
849                             CallbackType create_callback,
850                             lldb::ScriptLanguage language)
851       : PluginInstance<ScriptInterpreterCreateInstance>(
852             name, std::move(description), create_callback),
853         language(language) {}
854 
855   lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
856 };
857 
858 typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;
859 
860 static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
861   static ScriptInterpreterInstances g_instances;
862   return g_instances;
863 }
864 
865 bool PluginManager::RegisterPlugin(
866     ConstString name, const char *description,
867     lldb::ScriptLanguage script_language,
868     ScriptInterpreterCreateInstance create_callback) {
869   return GetScriptInterpreterInstances().RegisterPlugin(
870       name, description, create_callback, script_language);
871 }
872 
873 bool PluginManager::UnregisterPlugin(
874     ScriptInterpreterCreateInstance create_callback) {
875   return GetScriptInterpreterInstances().UnregisterPlugin(create_callback);
876 }
877 
878 ScriptInterpreterCreateInstance
879 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
880   return GetScriptInterpreterInstances().GetCallbackAtIndex(idx);
881 }
882 
883 lldb::ScriptInterpreterSP
884 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
885                                                Debugger &debugger) {
886   const auto &instances = GetScriptInterpreterInstances().GetInstances();
887   ScriptInterpreterCreateInstance none_instance = nullptr;
888   for (const auto &instance : instances) {
889     if (instance.language == lldb::eScriptLanguageNone)
890       none_instance = instance.create_callback;
891 
892     if (script_lang == instance.language)
893       return instance.create_callback(debugger);
894   }
895 
896   // If we didn't find one, return the ScriptInterpreter for the null language.
897   assert(none_instance != nullptr);
898   return none_instance(debugger);
899 }
900 
901 #pragma mark StructuredDataPlugin
902 
903 struct StructuredDataPluginInstance
904     : public PluginInstance<StructuredDataPluginCreateInstance> {
905   StructuredDataPluginInstance(
906       ConstString name, std::string description, CallbackType create_callback,
907       DebuggerInitializeCallback debugger_init_callback,
908       StructuredDataFilterLaunchInfo filter_callback)
909       : PluginInstance<StructuredDataPluginCreateInstance>(
910             name, std::move(description), create_callback,
911             debugger_init_callback),
912         filter_callback(filter_callback) {}
913 
914   StructuredDataFilterLaunchInfo filter_callback = nullptr;
915 };
916 
917 typedef PluginInstances<StructuredDataPluginInstance>
918     StructuredDataPluginInstances;
919 
920 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
921   static StructuredDataPluginInstances g_instances;
922   return g_instances;
923 }
924 
925 bool PluginManager::RegisterPlugin(
926     ConstString name, const char *description,
927     StructuredDataPluginCreateInstance create_callback,
928     DebuggerInitializeCallback debugger_init_callback,
929     StructuredDataFilterLaunchInfo filter_callback) {
930   return GetStructuredDataPluginInstances().RegisterPlugin(
931       name, description, create_callback, debugger_init_callback,
932       filter_callback);
933 }
934 
935 bool PluginManager::UnregisterPlugin(
936     StructuredDataPluginCreateInstance create_callback) {
937   return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback);
938 }
939 
940 StructuredDataPluginCreateInstance
941 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
942   return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx);
943 }
944 
945 StructuredDataFilterLaunchInfo
946 PluginManager::GetStructuredDataFilterCallbackAtIndex(
947     uint32_t idx, bool &iteration_complete) {
948   const auto &instances = GetStructuredDataPluginInstances().GetInstances();
949   if (idx < instances.size()) {
950     iteration_complete = false;
951     return instances[idx].filter_callback;
952   } else {
953     iteration_complete = true;
954   }
955   return nullptr;
956 }
957 
958 #pragma mark SymbolFile
959 
960 typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
961 typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;
962 
963 static SymbolFileInstances &GetSymbolFileInstances() {
964   static SymbolFileInstances g_instances;
965   return g_instances;
966 }
967 
968 bool PluginManager::RegisterPlugin(
969     ConstString name, const char *description,
970     SymbolFileCreateInstance create_callback,
971     DebuggerInitializeCallback debugger_init_callback) {
972   return GetSymbolFileInstances().RegisterPlugin(
973       name, description, create_callback, debugger_init_callback);
974 }
975 
976 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
977   return GetSymbolFileInstances().UnregisterPlugin(create_callback);
978 }
979 
980 SymbolFileCreateInstance
981 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
982   return GetSymbolFileInstances().GetCallbackAtIndex(idx);
983 }
984 
985 #pragma mark SymbolVendor
986 
987 typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
988 typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;
989 
990 static SymbolVendorInstances &GetSymbolVendorInstances() {
991   static SymbolVendorInstances g_instances;
992   return g_instances;
993 }
994 
995 bool PluginManager::RegisterPlugin(ConstString name, const char *description,
996                                    SymbolVendorCreateInstance create_callback) {
997   return GetSymbolVendorInstances().RegisterPlugin(name, description,
998                                                    create_callback);
999 }
1000 
1001 bool PluginManager::UnregisterPlugin(
1002     SymbolVendorCreateInstance create_callback) {
1003   return GetSymbolVendorInstances().UnregisterPlugin(create_callback);
1004 }
1005 
1006 SymbolVendorCreateInstance
1007 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1008   return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
1009 }
1010 
1011 #pragma mark Trace
1012 
1013 struct TraceInstance
1014     : public PluginInstance<TraceCreateInstanceForSessionFile> {
1015   TraceInstance(
1016       ConstString name, std::string description,
1017       CallbackType create_callback_for_session_file,
1018       TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1019       llvm::StringRef schema)
1020       : PluginInstance<TraceCreateInstanceForSessionFile>(
1021             name, std::move(description), create_callback_for_session_file),
1022         schema(schema),
1023         create_callback_for_live_process(create_callback_for_live_process) {}
1024 
1025   llvm::StringRef schema;
1026   TraceCreateInstanceForLiveProcess create_callback_for_live_process;
1027 };
1028 
1029 typedef PluginInstances<TraceInstance> TraceInstances;
1030 
1031 static TraceInstances &GetTracePluginInstances() {
1032   static TraceInstances g_instances;
1033   return g_instances;
1034 }
1035 
1036 bool PluginManager::RegisterPlugin(
1037     ConstString name, const char *description,
1038     TraceCreateInstanceForSessionFile create_callback_for_session_file,
1039     TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1040     llvm::StringRef schema) {
1041   return GetTracePluginInstances().RegisterPlugin(
1042       name, description, create_callback_for_session_file,
1043       create_callback_for_live_process, schema);
1044 }
1045 
1046 bool PluginManager::UnregisterPlugin(
1047     TraceCreateInstanceForSessionFile create_callback_for_session_file) {
1048   return GetTracePluginInstances().UnregisterPlugin(
1049       create_callback_for_session_file);
1050 }
1051 
1052 TraceCreateInstanceForSessionFile
1053 PluginManager::GetTraceCreateCallback(ConstString plugin_name) {
1054   return GetTracePluginInstances().GetCallbackForName(plugin_name);
1055 }
1056 
1057 TraceCreateInstanceForLiveProcess
1058 PluginManager::GetTraceCreateCallbackForLiveProcess(ConstString plugin_name) {
1059   for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1060     if (instance.name == plugin_name)
1061       return instance.create_callback_for_live_process;
1062   return nullptr;
1063 }
1064 
1065 llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) {
1066   for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1067     if (instance.name == plugin_name)
1068       return instance.schema;
1069   return llvm::StringRef();
1070 }
1071 
1072 llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
1073   if (TraceInstance *instance =
1074           GetTracePluginInstances().GetInstanceAtIndex(index))
1075     return instance->schema;
1076   return llvm::StringRef();
1077 }
1078 
1079 #pragma mark TraceExporter
1080 
1081 struct TraceExporterInstance
1082     : public PluginInstance<TraceExporterCreateInstance> {
1083   TraceExporterInstance(
1084       ConstString name, std::string description,
1085       TraceExporterCreateInstance create_instance,
1086       ThreadTraceExportCommandCreator create_thread_trace_export_command)
1087       : PluginInstance<TraceExporterCreateInstance>(
1088             name, std::move(description), create_instance),
1089         create_thread_trace_export_command(create_thread_trace_export_command) {
1090   }
1091 
1092   ThreadTraceExportCommandCreator create_thread_trace_export_command;
1093 };
1094 
1095 typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;
1096 
1097 static TraceExporterInstances &GetTraceExporterInstances() {
1098   static TraceExporterInstances g_instances;
1099   return g_instances;
1100 }
1101 
1102 bool PluginManager::RegisterPlugin(
1103     ConstString name, const char *description,
1104     TraceExporterCreateInstance create_callback,
1105     ThreadTraceExportCommandCreator create_thread_trace_export_command) {
1106   return GetTraceExporterInstances().RegisterPlugin(
1107       name, description, create_callback, create_thread_trace_export_command);
1108 }
1109 
1110 TraceExporterCreateInstance
1111 PluginManager::GetTraceExporterCreateCallback(ConstString plugin_name) {
1112   return GetTraceExporterInstances().GetCallbackForName(plugin_name);
1113 }
1114 
1115 bool PluginManager::UnregisterPlugin(
1116     TraceExporterCreateInstance create_callback) {
1117   return GetTraceExporterInstances().UnregisterPlugin(create_callback);
1118 }
1119 
1120 ThreadTraceExportCommandCreator
1121 PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
1122   if (TraceExporterInstance *instance =
1123           GetTraceExporterInstances().GetInstanceAtIndex(index))
1124     return instance->create_thread_trace_export_command;
1125   return nullptr;
1126 }
1127 
1128 const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
1129   return GetTraceExporterInstances().GetNameAtIndex(index);
1130 }
1131 
1132 #pragma mark UnwindAssembly
1133 
1134 typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
1135 typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;
1136 
1137 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1138   static UnwindAssemblyInstances g_instances;
1139   return g_instances;
1140 }
1141 
1142 bool PluginManager::RegisterPlugin(
1143     ConstString name, const char *description,
1144     UnwindAssemblyCreateInstance create_callback) {
1145   return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
1146                                                      create_callback);
1147 }
1148 
1149 bool PluginManager::UnregisterPlugin(
1150     UnwindAssemblyCreateInstance create_callback) {
1151   return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback);
1152 }
1153 
1154 UnwindAssemblyCreateInstance
1155 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1156   return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx);
1157 }
1158 
1159 #pragma mark MemoryHistory
1160 
1161 typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
1162 typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;
1163 
1164 static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1165   static MemoryHistoryInstances g_instances;
1166   return g_instances;
1167 }
1168 
1169 bool PluginManager::RegisterPlugin(
1170     ConstString name, const char *description,
1171     MemoryHistoryCreateInstance create_callback) {
1172   return GetMemoryHistoryInstances().RegisterPlugin(name, description,
1173                                                     create_callback);
1174 }
1175 
1176 bool PluginManager::UnregisterPlugin(
1177     MemoryHistoryCreateInstance create_callback) {
1178   return GetMemoryHistoryInstances().UnregisterPlugin(create_callback);
1179 }
1180 
1181 MemoryHistoryCreateInstance
1182 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1183   return GetMemoryHistoryInstances().GetCallbackAtIndex(idx);
1184 }
1185 
1186 #pragma mark InstrumentationRuntime
1187 
1188 struct InstrumentationRuntimeInstance
1189     : public PluginInstance<InstrumentationRuntimeCreateInstance> {
1190   InstrumentationRuntimeInstance(
1191       ConstString name, std::string description, CallbackType create_callback,
1192       InstrumentationRuntimeGetType get_type_callback)
1193       : PluginInstance<InstrumentationRuntimeCreateInstance>(
1194             name, std::move(description), create_callback),
1195         get_type_callback(get_type_callback) {}
1196 
1197   InstrumentationRuntimeGetType get_type_callback = nullptr;
1198 };
1199 
1200 typedef PluginInstances<InstrumentationRuntimeInstance>
1201     InstrumentationRuntimeInstances;
1202 
1203 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1204   static InstrumentationRuntimeInstances g_instances;
1205   return g_instances;
1206 }
1207 
1208 bool PluginManager::RegisterPlugin(
1209     ConstString name, const char *description,
1210     InstrumentationRuntimeCreateInstance create_callback,
1211     InstrumentationRuntimeGetType get_type_callback) {
1212   return GetInstrumentationRuntimeInstances().RegisterPlugin(
1213       name, description, create_callback, get_type_callback);
1214 }
1215 
1216 bool PluginManager::UnregisterPlugin(
1217     InstrumentationRuntimeCreateInstance create_callback) {
1218   return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback);
1219 }
1220 
1221 InstrumentationRuntimeGetType
1222 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
1223   const auto &instances = GetInstrumentationRuntimeInstances().GetInstances();
1224   if (idx < instances.size())
1225     return instances[idx].get_type_callback;
1226   return nullptr;
1227 }
1228 
1229 InstrumentationRuntimeCreateInstance
1230 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
1231   return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx);
1232 }
1233 
1234 #pragma mark TypeSystem
1235 
1236 struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
1237   TypeSystemInstance(ConstString name, std::string description,
1238                      CallbackType create_callback,
1239                      LanguageSet supported_languages_for_types,
1240                      LanguageSet supported_languages_for_expressions)
1241       : PluginInstance<TypeSystemCreateInstance>(name, std::move(description),
1242                                                  create_callback),
1243         supported_languages_for_types(supported_languages_for_types),
1244         supported_languages_for_expressions(
1245             supported_languages_for_expressions) {}
1246 
1247   LanguageSet supported_languages_for_types;
1248   LanguageSet supported_languages_for_expressions;
1249 };
1250 
1251 typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;
1252 
1253 static TypeSystemInstances &GetTypeSystemInstances() {
1254   static TypeSystemInstances g_instances;
1255   return g_instances;
1256 }
1257 
1258 bool PluginManager::RegisterPlugin(
1259     ConstString name, const char *description,
1260     TypeSystemCreateInstance create_callback,
1261     LanguageSet supported_languages_for_types,
1262     LanguageSet supported_languages_for_expressions) {
1263   return GetTypeSystemInstances().RegisterPlugin(
1264       name, description, create_callback, supported_languages_for_types,
1265       supported_languages_for_expressions);
1266 }
1267 
1268 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
1269   return GetTypeSystemInstances().UnregisterPlugin(create_callback);
1270 }
1271 
1272 TypeSystemCreateInstance
1273 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
1274   return GetTypeSystemInstances().GetCallbackAtIndex(idx);
1275 }
1276 
1277 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
1278   const auto &instances = GetTypeSystemInstances().GetInstances();
1279   LanguageSet all;
1280   for (unsigned i = 0; i < instances.size(); ++i)
1281     all.bitvector |= instances[i].supported_languages_for_types.bitvector;
1282   return all;
1283 }
1284 
1285 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
1286   const auto &instances = GetTypeSystemInstances().GetInstances();
1287   LanguageSet all;
1288   for (unsigned i = 0; i < instances.size(); ++i)
1289     all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
1290   return all;
1291 }
1292 
1293 #pragma mark REPL
1294 
1295 struct REPLInstance : public PluginInstance<REPLCreateInstance> {
1296   REPLInstance(ConstString name, std::string description,
1297                CallbackType create_callback, LanguageSet supported_languages)
1298       : PluginInstance<REPLCreateInstance>(name, std::move(description),
1299                                            create_callback),
1300         supported_languages(supported_languages) {}
1301 
1302   LanguageSet supported_languages;
1303 };
1304 
1305 typedef PluginInstances<REPLInstance> REPLInstances;
1306 
1307 static REPLInstances &GetREPLInstances() {
1308   static REPLInstances g_instances;
1309   return g_instances;
1310 }
1311 
1312 bool PluginManager::RegisterPlugin(ConstString name, const char *description,
1313                                    REPLCreateInstance create_callback,
1314                                    LanguageSet supported_languages) {
1315   return GetREPLInstances().RegisterPlugin(name, description, create_callback,
1316                                            supported_languages);
1317 }
1318 
1319 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
1320   return GetREPLInstances().UnregisterPlugin(create_callback);
1321 }
1322 
1323 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
1324   return GetREPLInstances().GetCallbackAtIndex(idx);
1325 }
1326 
1327 LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
1328   const auto &instances = GetREPLInstances().GetInstances();
1329   LanguageSet all;
1330   for (unsigned i = 0; i < instances.size(); ++i)
1331     all.bitvector |= instances[i].supported_languages.bitvector;
1332   return all;
1333 }
1334 
1335 #pragma mark PluginManager
1336 
1337 void PluginManager::DebuggerInitialize(Debugger &debugger) {
1338   GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
1339   GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1340   GetPlatformInstances().PerformDebuggerCallback(debugger);
1341   GetProcessInstances().PerformDebuggerCallback(debugger);
1342   GetSymbolFileInstances().PerformDebuggerCallback(debugger);
1343   GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
1344   GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
1345   GetTracePluginInstances().PerformDebuggerCallback(debugger);
1346 }
1347 
1348 // This is the preferred new way to register plugin specific settings.  e.g.
1349 // This will put a plugin's settings under e.g.
1350 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1351 static lldb::OptionValuePropertiesSP
1352 GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name,
1353                               ConstString plugin_type_desc, bool can_create) {
1354   lldb::OptionValuePropertiesSP parent_properties_sp(
1355       debugger.GetValueProperties());
1356   if (parent_properties_sp) {
1357     static ConstString g_property_name("plugin");
1358 
1359     OptionValuePropertiesSP plugin_properties_sp =
1360         parent_properties_sp->GetSubProperty(nullptr, g_property_name);
1361     if (!plugin_properties_sp && can_create) {
1362       plugin_properties_sp =
1363           std::make_shared<OptionValueProperties>(g_property_name);
1364       parent_properties_sp->AppendProperty(
1365           g_property_name, ConstString("Settings specify to plugins."), true,
1366           plugin_properties_sp);
1367     }
1368 
1369     if (plugin_properties_sp) {
1370       lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1371           plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1372       if (!plugin_type_properties_sp && can_create) {
1373         plugin_type_properties_sp =
1374             std::make_shared<OptionValueProperties>(plugin_type_name);
1375         plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1376                                              true, plugin_type_properties_sp);
1377       }
1378       return plugin_type_properties_sp;
1379     }
1380   }
1381   return lldb::OptionValuePropertiesSP();
1382 }
1383 
1384 // This is deprecated way to register plugin specific settings.  e.g.
1385 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
1386 // generic settings would be under "platform.SETTINGNAME".
1387 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
1388     Debugger &debugger, ConstString plugin_type_name,
1389     ConstString plugin_type_desc, bool can_create) {
1390   static ConstString g_property_name("plugin");
1391   lldb::OptionValuePropertiesSP parent_properties_sp(
1392       debugger.GetValueProperties());
1393   if (parent_properties_sp) {
1394     OptionValuePropertiesSP plugin_properties_sp =
1395         parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1396     if (!plugin_properties_sp && can_create) {
1397       plugin_properties_sp =
1398           std::make_shared<OptionValueProperties>(plugin_type_name);
1399       parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1400                                            true, plugin_properties_sp);
1401     }
1402 
1403     if (plugin_properties_sp) {
1404       lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1405           plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
1406       if (!plugin_type_properties_sp && can_create) {
1407         plugin_type_properties_sp =
1408             std::make_shared<OptionValueProperties>(g_property_name);
1409         plugin_properties_sp->AppendProperty(
1410             g_property_name, ConstString("Settings specific to plugins"), true,
1411             plugin_type_properties_sp);
1412       }
1413       return plugin_type_properties_sp;
1414     }
1415   }
1416   return lldb::OptionValuePropertiesSP();
1417 }
1418 
1419 namespace {
1420 
1421 typedef lldb::OptionValuePropertiesSP
1422 GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString,
1423                                  bool can_create);
1424 
1425 lldb::OptionValuePropertiesSP
1426 GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
1427                     ConstString plugin_type_name,
1428                     GetDebuggerPropertyForPluginsPtr get_debugger_property =
1429                         GetDebuggerPropertyForPlugins) {
1430   lldb::OptionValuePropertiesSP properties_sp;
1431   lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
1432       debugger, plugin_type_name,
1433       ConstString(), // not creating to so we don't need the description
1434       false));
1435   if (plugin_type_properties_sp)
1436     properties_sp =
1437         plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1438   return properties_sp;
1439 }
1440 
1441 bool CreateSettingForPlugin(
1442     Debugger &debugger, ConstString plugin_type_name,
1443     ConstString plugin_type_desc,
1444     const lldb::OptionValuePropertiesSP &properties_sp, ConstString description,
1445     bool is_global_property,
1446     GetDebuggerPropertyForPluginsPtr get_debugger_property =
1447         GetDebuggerPropertyForPlugins) {
1448   if (properties_sp) {
1449     lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1450         get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
1451                               true));
1452     if (plugin_type_properties_sp) {
1453       plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1454                                                 description, is_global_property,
1455                                                 properties_sp);
1456       return true;
1457     }
1458   }
1459   return false;
1460 }
1461 
1462 const char *kDynamicLoaderPluginName("dynamic-loader");
1463 const char *kPlatformPluginName("platform");
1464 const char *kProcessPluginName("process");
1465 const char *kSymbolFilePluginName("symbol-file");
1466 const char *kJITLoaderPluginName("jit-loader");
1467 const char *kStructuredDataPluginName("structured-data");
1468 
1469 } // anonymous namespace
1470 
1471 lldb::OptionValuePropertiesSP
1472 PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
1473                                                 ConstString setting_name) {
1474   return GetSettingForPlugin(debugger, setting_name,
1475                              ConstString(kDynamicLoaderPluginName));
1476 }
1477 
1478 bool PluginManager::CreateSettingForDynamicLoaderPlugin(
1479     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1480     ConstString description, bool is_global_property) {
1481   return CreateSettingForPlugin(
1482       debugger, ConstString(kDynamicLoaderPluginName),
1483       ConstString("Settings for dynamic loader plug-ins"), properties_sp,
1484       description, is_global_property);
1485 }
1486 
1487 lldb::OptionValuePropertiesSP
1488 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
1489                                            ConstString setting_name) {
1490   return GetSettingForPlugin(debugger, setting_name,
1491                              ConstString(kPlatformPluginName),
1492                              GetDebuggerPropertyForPluginsOldStyle);
1493 }
1494 
1495 bool PluginManager::CreateSettingForPlatformPlugin(
1496     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1497     ConstString description, bool is_global_property) {
1498   return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
1499                                 ConstString("Settings for platform plug-ins"),
1500                                 properties_sp, description, is_global_property,
1501                                 GetDebuggerPropertyForPluginsOldStyle);
1502 }
1503 
1504 lldb::OptionValuePropertiesSP
1505 PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
1506                                           ConstString setting_name) {
1507   return GetSettingForPlugin(debugger, setting_name,
1508                              ConstString(kProcessPluginName));
1509 }
1510 
1511 bool PluginManager::CreateSettingForProcessPlugin(
1512     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1513     ConstString description, bool is_global_property) {
1514   return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
1515                                 ConstString("Settings for process plug-ins"),
1516                                 properties_sp, description, is_global_property);
1517 }
1518 
1519 lldb::OptionValuePropertiesSP
1520 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
1521                                              ConstString setting_name) {
1522   return GetSettingForPlugin(debugger, setting_name,
1523                              ConstString(kSymbolFilePluginName));
1524 }
1525 
1526 bool PluginManager::CreateSettingForSymbolFilePlugin(
1527     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1528     ConstString description, bool is_global_property) {
1529   return CreateSettingForPlugin(
1530       debugger, ConstString(kSymbolFilePluginName),
1531       ConstString("Settings for symbol file plug-ins"), properties_sp,
1532       description, is_global_property);
1533 }
1534 
1535 lldb::OptionValuePropertiesSP
1536 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
1537                                             ConstString setting_name) {
1538   return GetSettingForPlugin(debugger, setting_name,
1539                              ConstString(kJITLoaderPluginName));
1540 }
1541 
1542 bool PluginManager::CreateSettingForJITLoaderPlugin(
1543     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1544     ConstString description, bool is_global_property) {
1545   return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
1546                                 ConstString("Settings for JIT loader plug-ins"),
1547                                 properties_sp, description, is_global_property);
1548 }
1549 
1550 static const char *kOperatingSystemPluginName("os");
1551 
1552 lldb::OptionValuePropertiesSP
1553 PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger,
1554                                                   ConstString setting_name) {
1555   lldb::OptionValuePropertiesSP properties_sp;
1556   lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1557       GetDebuggerPropertyForPlugins(
1558           debugger, ConstString(kOperatingSystemPluginName),
1559           ConstString(), // not creating to so we don't need the description
1560           false));
1561   if (plugin_type_properties_sp)
1562     properties_sp =
1563         plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1564   return properties_sp;
1565 }
1566 
1567 bool PluginManager::CreateSettingForOperatingSystemPlugin(
1568     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1569     ConstString description, bool is_global_property) {
1570   if (properties_sp) {
1571     lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1572         GetDebuggerPropertyForPlugins(
1573             debugger, ConstString(kOperatingSystemPluginName),
1574             ConstString("Settings for operating system plug-ins"), true));
1575     if (plugin_type_properties_sp) {
1576       plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1577                                                 description, is_global_property,
1578                                                 properties_sp);
1579       return true;
1580     }
1581   }
1582   return false;
1583 }
1584 
1585 lldb::OptionValuePropertiesSP
1586 PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
1587                                                  ConstString setting_name) {
1588   return GetSettingForPlugin(debugger, setting_name,
1589                              ConstString(kStructuredDataPluginName));
1590 }
1591 
1592 bool PluginManager::CreateSettingForStructuredDataPlugin(
1593     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1594     ConstString description, bool is_global_property) {
1595   return CreateSettingForPlugin(
1596       debugger, ConstString(kStructuredDataPluginName),
1597       ConstString("Settings for structured data plug-ins"), properties_sp,
1598       description, is_global_property);
1599 }
1600