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