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(ConstString name, const char *description,
518                                    LanguageCreateInstance create_callback) {
519   return GetLanguageInstances().RegisterPlugin(name, description,
520                                                create_callback);
521 }
522 
523 bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
524   return GetLanguageInstances().UnregisterPlugin(create_callback);
525 }
526 
527 LanguageCreateInstance
528 PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
529   return GetLanguageInstances().GetCallbackAtIndex(idx);
530 }
531 
532 #pragma mark LanguageRuntime
533 
534 struct LanguageRuntimeInstance
535     : public PluginInstance<LanguageRuntimeCreateInstance> {
536   LanguageRuntimeInstance(
537       ConstString name, std::string description, CallbackType create_callback,
538       DebuggerInitializeCallback debugger_init_callback,
539       LanguageRuntimeGetCommandObject command_callback,
540       LanguageRuntimeGetExceptionPrecondition precondition_callback)
541       : PluginInstance<LanguageRuntimeCreateInstance>(
542             name, std::move(description), create_callback,
543             debugger_init_callback),
544         command_callback(command_callback),
545         precondition_callback(precondition_callback) {}
546 
547   LanguageRuntimeGetCommandObject command_callback;
548   LanguageRuntimeGetExceptionPrecondition precondition_callback;
549 };
550 
551 typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances;
552 
553 static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
554   static LanguageRuntimeInstances g_instances;
555   return g_instances;
556 }
557 
558 bool PluginManager::RegisterPlugin(
559     ConstString name, const char *description,
560     LanguageRuntimeCreateInstance create_callback,
561     LanguageRuntimeGetCommandObject command_callback,
562     LanguageRuntimeGetExceptionPrecondition precondition_callback) {
563   return GetLanguageRuntimeInstances().RegisterPlugin(
564       name, description, create_callback, nullptr, command_callback,
565       precondition_callback);
566 }
567 
568 bool PluginManager::UnregisterPlugin(
569     LanguageRuntimeCreateInstance create_callback) {
570   return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback);
571 }
572 
573 LanguageRuntimeCreateInstance
574 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
575   return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx);
576 }
577 
578 LanguageRuntimeGetCommandObject
579 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
580   const auto &instances = GetLanguageRuntimeInstances().GetInstances();
581   if (idx < instances.size())
582     return instances[idx].command_callback;
583   return nullptr;
584 }
585 
586 LanguageRuntimeGetExceptionPrecondition
587 PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
588   const auto &instances = GetLanguageRuntimeInstances().GetInstances();
589   if (idx < instances.size())
590     return instances[idx].precondition_callback;
591   return nullptr;
592 }
593 
594 #pragma mark SystemRuntime
595 
596 typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance;
597 typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances;
598 
599 static SystemRuntimeInstances &GetSystemRuntimeInstances() {
600   static SystemRuntimeInstances g_instances;
601   return g_instances;
602 }
603 
604 bool PluginManager::RegisterPlugin(
605     ConstString name, const char *description,
606     SystemRuntimeCreateInstance create_callback) {
607   return GetSystemRuntimeInstances().RegisterPlugin(name, description,
608                                                     create_callback);
609 }
610 
611 bool PluginManager::UnregisterPlugin(
612     SystemRuntimeCreateInstance create_callback) {
613   return GetSystemRuntimeInstances().UnregisterPlugin(create_callback);
614 }
615 
616 SystemRuntimeCreateInstance
617 PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
618   return GetSystemRuntimeInstances().GetCallbackAtIndex(idx);
619 }
620 
621 #pragma mark ObjectFile
622 
623 struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> {
624   ObjectFileInstance(
625       ConstString name, std::string description, CallbackType create_callback,
626       ObjectFileCreateMemoryInstance create_memory_callback,
627       ObjectFileGetModuleSpecifications get_module_specifications,
628       ObjectFileSaveCore save_core)
629       : PluginInstance<ObjectFileCreateInstance>(name, std::move(description),
630                                                  create_callback),
631         create_memory_callback(create_memory_callback),
632         get_module_specifications(get_module_specifications),
633         save_core(save_core) {}
634 
635   ObjectFileCreateMemoryInstance create_memory_callback;
636   ObjectFileGetModuleSpecifications get_module_specifications;
637   ObjectFileSaveCore save_core;
638 };
639 typedef PluginInstances<ObjectFileInstance> ObjectFileInstances;
640 
641 static ObjectFileInstances &GetObjectFileInstances() {
642   static ObjectFileInstances g_instances;
643   return g_instances;
644 }
645 
646 bool PluginManager::RegisterPlugin(
647     llvm::StringRef name, llvm::StringRef description,
648     ObjectFileCreateInstance create_callback,
649     ObjectFileCreateMemoryInstance create_memory_callback,
650     ObjectFileGetModuleSpecifications get_module_specifications,
651     ObjectFileSaveCore save_core) {
652   return GetObjectFileInstances().RegisterPlugin(
653       ConstString(name), description.str().c_str(), create_callback,
654       create_memory_callback, get_module_specifications, save_core);
655 }
656 
657 bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
658   return GetObjectFileInstances().UnregisterPlugin(create_callback);
659 }
660 
661 ObjectFileCreateInstance
662 PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
663   return GetObjectFileInstances().GetCallbackAtIndex(idx);
664 }
665 
666 ObjectFileCreateMemoryInstance
667 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
668   const auto &instances = GetObjectFileInstances().GetInstances();
669   if (idx < instances.size())
670     return instances[idx].create_memory_callback;
671   return nullptr;
672 }
673 
674 ObjectFileGetModuleSpecifications
675 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
676     uint32_t idx) {
677   const auto &instances = GetObjectFileInstances().GetInstances();
678   if (idx < instances.size())
679     return instances[idx].get_module_specifications;
680   return nullptr;
681 }
682 
683 ObjectFileCreateMemoryInstance
684 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
685     llvm::StringRef name) {
686   const auto &instances = GetObjectFileInstances().GetInstances();
687   for (auto &instance : instances) {
688     if (instance.name.GetStringRef() == name)
689       return instance.create_memory_callback;
690   }
691   return nullptr;
692 }
693 
694 Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
695                                const FileSpec &outfile,
696                                lldb::SaveCoreStyle &core_style,
697                                llvm::StringRef plugin_name) {
698   if (plugin_name.empty()) {
699     // Try saving core directly from the process plugin first.
700     llvm::Expected<bool> ret = process_sp->SaveCore(outfile.GetPath());
701     if (!ret)
702       return Status(ret.takeError());
703     if (ret.get())
704       return Status();
705   }
706 
707   // Fall back to object plugins.
708   Status error;
709   auto &instances = GetObjectFileInstances().GetInstances();
710   for (auto &instance : instances) {
711     if (plugin_name.empty() || instance.name.GetStringRef() == plugin_name) {
712       if (instance.save_core &&
713           instance.save_core(process_sp, outfile, core_style, error))
714         return error;
715     }
716   }
717   error.SetErrorString(
718       "no ObjectFile plugins were able to save a core for this process");
719   return error;
720 }
721 
722 #pragma mark ObjectContainer
723 
724 struct ObjectContainerInstance
725     : public PluginInstance<ObjectContainerCreateInstance> {
726   ObjectContainerInstance(
727       ConstString name, std::string description, CallbackType create_callback,
728       ObjectFileGetModuleSpecifications get_module_specifications)
729       : PluginInstance<ObjectContainerCreateInstance>(
730             name, std::move(description), create_callback),
731         get_module_specifications(get_module_specifications) {}
732 
733   ObjectFileGetModuleSpecifications get_module_specifications;
734 };
735 typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;
736 
737 static ObjectContainerInstances &GetObjectContainerInstances() {
738   static ObjectContainerInstances g_instances;
739   return g_instances;
740 }
741 
742 bool PluginManager::RegisterPlugin(
743     llvm::StringRef name, llvm::StringRef description,
744     ObjectContainerCreateInstance create_callback,
745     ObjectFileGetModuleSpecifications get_module_specifications) {
746   return GetObjectContainerInstances().RegisterPlugin(
747       ConstString(name), description.str().c_str(), create_callback,
748       get_module_specifications);
749 }
750 
751 bool PluginManager::UnregisterPlugin(
752     ObjectContainerCreateInstance create_callback) {
753   return GetObjectContainerInstances().UnregisterPlugin(create_callback);
754 }
755 
756 ObjectContainerCreateInstance
757 PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
758   return GetObjectContainerInstances().GetCallbackAtIndex(idx);
759 }
760 
761 ObjectFileGetModuleSpecifications
762 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
763     uint32_t idx) {
764   const auto &instances = GetObjectContainerInstances().GetInstances();
765   if (idx < instances.size())
766     return instances[idx].get_module_specifications;
767   return nullptr;
768 }
769 
770 #pragma mark Platform
771 
772 typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
773 typedef PluginInstances<PlatformInstance> PlatformInstances;
774 
775 static PlatformInstances &GetPlatformInstances() {
776   static PlatformInstances g_platform_instances;
777   return g_platform_instances;
778 }
779 
780 bool PluginManager::RegisterPlugin(
781     llvm::StringRef name, llvm::StringRef description,
782     PlatformCreateInstance create_callback,
783     DebuggerInitializeCallback debugger_init_callback) {
784   return GetPlatformInstances().RegisterPlugin(
785       ConstString(name), description.str().c_str(), create_callback,
786       debugger_init_callback);
787 }
788 
789 bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
790   return GetPlatformInstances().UnregisterPlugin(create_callback);
791 }
792 
793 llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
794   return GetPlatformInstances().GetNameAtIndex(idx);
795 }
796 
797 llvm::StringRef
798 PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
799   return GetPlatformInstances().GetDescriptionAtIndex(idx);
800 }
801 
802 PlatformCreateInstance
803 PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
804   return GetPlatformInstances().GetCallbackAtIndex(idx);
805 }
806 
807 PlatformCreateInstance
808 PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) {
809   return GetPlatformInstances().GetCallbackForName(ConstString(name));
810 }
811 
812 void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
813                                              CompletionRequest &request) {
814   for (const auto &instance : GetPlatformInstances().GetInstances()) {
815     if (instance.name.GetStringRef().startswith(name))
816       request.AddCompletion(instance.name.GetCString());
817   }
818 }
819 
820 #pragma mark Process
821 
822 typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
823 typedef PluginInstances<ProcessInstance> ProcessInstances;
824 
825 static ProcessInstances &GetProcessInstances() {
826   static ProcessInstances g_instances;
827   return g_instances;
828 }
829 
830 bool PluginManager::RegisterPlugin(
831     ConstString name, const char *description,
832     ProcessCreateInstance create_callback,
833     DebuggerInitializeCallback debugger_init_callback) {
834   return GetProcessInstances().RegisterPlugin(
835       name, description, create_callback, debugger_init_callback);
836 }
837 
838 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
839   return GetProcessInstances().UnregisterPlugin(create_callback);
840 }
841 
842 const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
843   return GetProcessInstances().GetNameAtIndex(idx);
844 }
845 
846 const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
847   return GetProcessInstances().GetDescriptionAtIndex(idx);
848 }
849 
850 ProcessCreateInstance
851 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
852   return GetProcessInstances().GetCallbackAtIndex(idx);
853 }
854 
855 ProcessCreateInstance
856 PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) {
857   return GetProcessInstances().GetCallbackForName(name);
858 }
859 
860 void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
861                                             CompletionRequest &request) {
862   for (const auto &instance : GetProcessInstances().GetInstances()) {
863     if (instance.name.GetStringRef().startswith(name))
864       request.AddCompletion(instance.name.GetCString(), instance.description);
865   }
866 }
867 
868 #pragma mark ScriptInterpreter
869 
870 struct ScriptInterpreterInstance
871     : public PluginInstance<ScriptInterpreterCreateInstance> {
872   ScriptInterpreterInstance(ConstString name, std::string description,
873                             CallbackType create_callback,
874                             lldb::ScriptLanguage language)
875       : PluginInstance<ScriptInterpreterCreateInstance>(
876             name, std::move(description), create_callback),
877         language(language) {}
878 
879   lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
880 };
881 
882 typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;
883 
884 static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
885   static ScriptInterpreterInstances g_instances;
886   return g_instances;
887 }
888 
889 bool PluginManager::RegisterPlugin(
890     ConstString name, const char *description,
891     lldb::ScriptLanguage script_language,
892     ScriptInterpreterCreateInstance create_callback) {
893   return GetScriptInterpreterInstances().RegisterPlugin(
894       name, description, create_callback, script_language);
895 }
896 
897 bool PluginManager::UnregisterPlugin(
898     ScriptInterpreterCreateInstance create_callback) {
899   return GetScriptInterpreterInstances().UnregisterPlugin(create_callback);
900 }
901 
902 ScriptInterpreterCreateInstance
903 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
904   return GetScriptInterpreterInstances().GetCallbackAtIndex(idx);
905 }
906 
907 lldb::ScriptInterpreterSP
908 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
909                                                Debugger &debugger) {
910   const auto &instances = GetScriptInterpreterInstances().GetInstances();
911   ScriptInterpreterCreateInstance none_instance = nullptr;
912   for (const auto &instance : instances) {
913     if (instance.language == lldb::eScriptLanguageNone)
914       none_instance = instance.create_callback;
915 
916     if (script_lang == instance.language)
917       return instance.create_callback(debugger);
918   }
919 
920   // If we didn't find one, return the ScriptInterpreter for the null language.
921   assert(none_instance != nullptr);
922   return none_instance(debugger);
923 }
924 
925 #pragma mark StructuredDataPlugin
926 
927 struct StructuredDataPluginInstance
928     : public PluginInstance<StructuredDataPluginCreateInstance> {
929   StructuredDataPluginInstance(
930       ConstString name, std::string description, CallbackType create_callback,
931       DebuggerInitializeCallback debugger_init_callback,
932       StructuredDataFilterLaunchInfo filter_callback)
933       : PluginInstance<StructuredDataPluginCreateInstance>(
934             name, std::move(description), create_callback,
935             debugger_init_callback),
936         filter_callback(filter_callback) {}
937 
938   StructuredDataFilterLaunchInfo filter_callback = nullptr;
939 };
940 
941 typedef PluginInstances<StructuredDataPluginInstance>
942     StructuredDataPluginInstances;
943 
944 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
945   static StructuredDataPluginInstances g_instances;
946   return g_instances;
947 }
948 
949 bool PluginManager::RegisterPlugin(
950     ConstString name, const char *description,
951     StructuredDataPluginCreateInstance create_callback,
952     DebuggerInitializeCallback debugger_init_callback,
953     StructuredDataFilterLaunchInfo filter_callback) {
954   return GetStructuredDataPluginInstances().RegisterPlugin(
955       name, description, create_callback, debugger_init_callback,
956       filter_callback);
957 }
958 
959 bool PluginManager::UnregisterPlugin(
960     StructuredDataPluginCreateInstance create_callback) {
961   return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback);
962 }
963 
964 StructuredDataPluginCreateInstance
965 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
966   return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx);
967 }
968 
969 StructuredDataFilterLaunchInfo
970 PluginManager::GetStructuredDataFilterCallbackAtIndex(
971     uint32_t idx, bool &iteration_complete) {
972   const auto &instances = GetStructuredDataPluginInstances().GetInstances();
973   if (idx < instances.size()) {
974     iteration_complete = false;
975     return instances[idx].filter_callback;
976   } else {
977     iteration_complete = true;
978   }
979   return nullptr;
980 }
981 
982 #pragma mark SymbolFile
983 
984 typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
985 typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;
986 
987 static SymbolFileInstances &GetSymbolFileInstances() {
988   static SymbolFileInstances g_instances;
989   return g_instances;
990 }
991 
992 bool PluginManager::RegisterPlugin(
993     ConstString name, const char *description,
994     SymbolFileCreateInstance create_callback,
995     DebuggerInitializeCallback debugger_init_callback) {
996   return GetSymbolFileInstances().RegisterPlugin(
997       name, description, create_callback, debugger_init_callback);
998 }
999 
1000 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
1001   return GetSymbolFileInstances().UnregisterPlugin(create_callback);
1002 }
1003 
1004 SymbolFileCreateInstance
1005 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1006   return GetSymbolFileInstances().GetCallbackAtIndex(idx);
1007 }
1008 
1009 #pragma mark SymbolVendor
1010 
1011 typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
1012 typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;
1013 
1014 static SymbolVendorInstances &GetSymbolVendorInstances() {
1015   static SymbolVendorInstances g_instances;
1016   return g_instances;
1017 }
1018 
1019 bool PluginManager::RegisterPlugin(ConstString name, const char *description,
1020                                    SymbolVendorCreateInstance create_callback) {
1021   return GetSymbolVendorInstances().RegisterPlugin(name, description,
1022                                                    create_callback);
1023 }
1024 
1025 bool PluginManager::UnregisterPlugin(
1026     SymbolVendorCreateInstance create_callback) {
1027   return GetSymbolVendorInstances().UnregisterPlugin(create_callback);
1028 }
1029 
1030 SymbolVendorCreateInstance
1031 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1032   return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
1033 }
1034 
1035 #pragma mark Trace
1036 
1037 struct TraceInstance
1038     : public PluginInstance<TraceCreateInstanceForSessionFile> {
1039   TraceInstance(
1040       ConstString name, std::string description,
1041       CallbackType create_callback_for_session_file,
1042       TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1043       llvm::StringRef schema)
1044       : PluginInstance<TraceCreateInstanceForSessionFile>(
1045             name, std::move(description), create_callback_for_session_file),
1046         schema(schema),
1047         create_callback_for_live_process(create_callback_for_live_process) {}
1048 
1049   llvm::StringRef schema;
1050   TraceCreateInstanceForLiveProcess create_callback_for_live_process;
1051 };
1052 
1053 typedef PluginInstances<TraceInstance> TraceInstances;
1054 
1055 static TraceInstances &GetTracePluginInstances() {
1056   static TraceInstances g_instances;
1057   return g_instances;
1058 }
1059 
1060 bool PluginManager::RegisterPlugin(
1061     ConstString name, const char *description,
1062     TraceCreateInstanceForSessionFile create_callback_for_session_file,
1063     TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1064     llvm::StringRef schema) {
1065   return GetTracePluginInstances().RegisterPlugin(
1066       name, description, create_callback_for_session_file,
1067       create_callback_for_live_process, schema);
1068 }
1069 
1070 bool PluginManager::UnregisterPlugin(
1071     TraceCreateInstanceForSessionFile create_callback_for_session_file) {
1072   return GetTracePluginInstances().UnregisterPlugin(
1073       create_callback_for_session_file);
1074 }
1075 
1076 TraceCreateInstanceForSessionFile
1077 PluginManager::GetTraceCreateCallback(ConstString plugin_name) {
1078   return GetTracePluginInstances().GetCallbackForName(plugin_name);
1079 }
1080 
1081 TraceCreateInstanceForLiveProcess
1082 PluginManager::GetTraceCreateCallbackForLiveProcess(ConstString plugin_name) {
1083   for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1084     if (instance.name == plugin_name)
1085       return instance.create_callback_for_live_process;
1086   return nullptr;
1087 }
1088 
1089 llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) {
1090   for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1091     if (instance.name == plugin_name)
1092       return instance.schema;
1093   return llvm::StringRef();
1094 }
1095 
1096 llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
1097   if (TraceInstance *instance =
1098           GetTracePluginInstances().GetInstanceAtIndex(index))
1099     return instance->schema;
1100   return llvm::StringRef();
1101 }
1102 
1103 #pragma mark TraceExporter
1104 
1105 struct TraceExporterInstance
1106     : public PluginInstance<TraceExporterCreateInstance> {
1107   TraceExporterInstance(
1108       ConstString name, std::string description,
1109       TraceExporterCreateInstance create_instance,
1110       ThreadTraceExportCommandCreator create_thread_trace_export_command)
1111       : PluginInstance<TraceExporterCreateInstance>(
1112             name, std::move(description), create_instance),
1113         create_thread_trace_export_command(create_thread_trace_export_command) {
1114   }
1115 
1116   ThreadTraceExportCommandCreator create_thread_trace_export_command;
1117 };
1118 
1119 typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;
1120 
1121 static TraceExporterInstances &GetTraceExporterInstances() {
1122   static TraceExporterInstances g_instances;
1123   return g_instances;
1124 }
1125 
1126 bool PluginManager::RegisterPlugin(
1127     ConstString name, const char *description,
1128     TraceExporterCreateInstance create_callback,
1129     ThreadTraceExportCommandCreator create_thread_trace_export_command) {
1130   return GetTraceExporterInstances().RegisterPlugin(
1131       name, description, create_callback, create_thread_trace_export_command);
1132 }
1133 
1134 TraceExporterCreateInstance
1135 PluginManager::GetTraceExporterCreateCallback(ConstString plugin_name) {
1136   return GetTraceExporterInstances().GetCallbackForName(plugin_name);
1137 }
1138 
1139 bool PluginManager::UnregisterPlugin(
1140     TraceExporterCreateInstance create_callback) {
1141   return GetTraceExporterInstances().UnregisterPlugin(create_callback);
1142 }
1143 
1144 ThreadTraceExportCommandCreator
1145 PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
1146   if (TraceExporterInstance *instance =
1147           GetTraceExporterInstances().GetInstanceAtIndex(index))
1148     return instance->create_thread_trace_export_command;
1149   return nullptr;
1150 }
1151 
1152 const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
1153   return GetTraceExporterInstances().GetNameAtIndex(index);
1154 }
1155 
1156 #pragma mark UnwindAssembly
1157 
1158 typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
1159 typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;
1160 
1161 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1162   static UnwindAssemblyInstances g_instances;
1163   return g_instances;
1164 }
1165 
1166 bool PluginManager::RegisterPlugin(
1167     ConstString name, const char *description,
1168     UnwindAssemblyCreateInstance create_callback) {
1169   return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
1170                                                      create_callback);
1171 }
1172 
1173 bool PluginManager::UnregisterPlugin(
1174     UnwindAssemblyCreateInstance create_callback) {
1175   return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback);
1176 }
1177 
1178 UnwindAssemblyCreateInstance
1179 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1180   return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx);
1181 }
1182 
1183 #pragma mark MemoryHistory
1184 
1185 typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
1186 typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;
1187 
1188 static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1189   static MemoryHistoryInstances g_instances;
1190   return g_instances;
1191 }
1192 
1193 bool PluginManager::RegisterPlugin(
1194     ConstString name, const char *description,
1195     MemoryHistoryCreateInstance create_callback) {
1196   return GetMemoryHistoryInstances().RegisterPlugin(name, description,
1197                                                     create_callback);
1198 }
1199 
1200 bool PluginManager::UnregisterPlugin(
1201     MemoryHistoryCreateInstance create_callback) {
1202   return GetMemoryHistoryInstances().UnregisterPlugin(create_callback);
1203 }
1204 
1205 MemoryHistoryCreateInstance
1206 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1207   return GetMemoryHistoryInstances().GetCallbackAtIndex(idx);
1208 }
1209 
1210 #pragma mark InstrumentationRuntime
1211 
1212 struct InstrumentationRuntimeInstance
1213     : public PluginInstance<InstrumentationRuntimeCreateInstance> {
1214   InstrumentationRuntimeInstance(
1215       ConstString name, std::string description, CallbackType create_callback,
1216       InstrumentationRuntimeGetType get_type_callback)
1217       : PluginInstance<InstrumentationRuntimeCreateInstance>(
1218             name, std::move(description), create_callback),
1219         get_type_callback(get_type_callback) {}
1220 
1221   InstrumentationRuntimeGetType get_type_callback = nullptr;
1222 };
1223 
1224 typedef PluginInstances<InstrumentationRuntimeInstance>
1225     InstrumentationRuntimeInstances;
1226 
1227 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1228   static InstrumentationRuntimeInstances g_instances;
1229   return g_instances;
1230 }
1231 
1232 bool PluginManager::RegisterPlugin(
1233     ConstString name, const char *description,
1234     InstrumentationRuntimeCreateInstance create_callback,
1235     InstrumentationRuntimeGetType get_type_callback) {
1236   return GetInstrumentationRuntimeInstances().RegisterPlugin(
1237       name, description, create_callback, get_type_callback);
1238 }
1239 
1240 bool PluginManager::UnregisterPlugin(
1241     InstrumentationRuntimeCreateInstance create_callback) {
1242   return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback);
1243 }
1244 
1245 InstrumentationRuntimeGetType
1246 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
1247   const auto &instances = GetInstrumentationRuntimeInstances().GetInstances();
1248   if (idx < instances.size())
1249     return instances[idx].get_type_callback;
1250   return nullptr;
1251 }
1252 
1253 InstrumentationRuntimeCreateInstance
1254 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
1255   return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx);
1256 }
1257 
1258 #pragma mark TypeSystem
1259 
1260 struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
1261   TypeSystemInstance(ConstString name, std::string description,
1262                      CallbackType create_callback,
1263                      LanguageSet supported_languages_for_types,
1264                      LanguageSet supported_languages_for_expressions)
1265       : PluginInstance<TypeSystemCreateInstance>(name, std::move(description),
1266                                                  create_callback),
1267         supported_languages_for_types(supported_languages_for_types),
1268         supported_languages_for_expressions(
1269             supported_languages_for_expressions) {}
1270 
1271   LanguageSet supported_languages_for_types;
1272   LanguageSet supported_languages_for_expressions;
1273 };
1274 
1275 typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;
1276 
1277 static TypeSystemInstances &GetTypeSystemInstances() {
1278   static TypeSystemInstances g_instances;
1279   return g_instances;
1280 }
1281 
1282 bool PluginManager::RegisterPlugin(
1283     ConstString name, const char *description,
1284     TypeSystemCreateInstance create_callback,
1285     LanguageSet supported_languages_for_types,
1286     LanguageSet supported_languages_for_expressions) {
1287   return GetTypeSystemInstances().RegisterPlugin(
1288       name, description, create_callback, supported_languages_for_types,
1289       supported_languages_for_expressions);
1290 }
1291 
1292 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
1293   return GetTypeSystemInstances().UnregisterPlugin(create_callback);
1294 }
1295 
1296 TypeSystemCreateInstance
1297 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
1298   return GetTypeSystemInstances().GetCallbackAtIndex(idx);
1299 }
1300 
1301 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
1302   const auto &instances = GetTypeSystemInstances().GetInstances();
1303   LanguageSet all;
1304   for (unsigned i = 0; i < instances.size(); ++i)
1305     all.bitvector |= instances[i].supported_languages_for_types.bitvector;
1306   return all;
1307 }
1308 
1309 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
1310   const auto &instances = GetTypeSystemInstances().GetInstances();
1311   LanguageSet all;
1312   for (unsigned i = 0; i < instances.size(); ++i)
1313     all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
1314   return all;
1315 }
1316 
1317 #pragma mark REPL
1318 
1319 struct REPLInstance : public PluginInstance<REPLCreateInstance> {
1320   REPLInstance(ConstString name, std::string description,
1321                CallbackType create_callback, LanguageSet supported_languages)
1322       : PluginInstance<REPLCreateInstance>(name, std::move(description),
1323                                            create_callback),
1324         supported_languages(supported_languages) {}
1325 
1326   LanguageSet supported_languages;
1327 };
1328 
1329 typedef PluginInstances<REPLInstance> REPLInstances;
1330 
1331 static REPLInstances &GetREPLInstances() {
1332   static REPLInstances g_instances;
1333   return g_instances;
1334 }
1335 
1336 bool PluginManager::RegisterPlugin(ConstString name, const char *description,
1337                                    REPLCreateInstance create_callback,
1338                                    LanguageSet supported_languages) {
1339   return GetREPLInstances().RegisterPlugin(name, description, create_callback,
1340                                            supported_languages);
1341 }
1342 
1343 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
1344   return GetREPLInstances().UnregisterPlugin(create_callback);
1345 }
1346 
1347 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
1348   return GetREPLInstances().GetCallbackAtIndex(idx);
1349 }
1350 
1351 LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
1352   const auto &instances = GetREPLInstances().GetInstances();
1353   LanguageSet all;
1354   for (unsigned i = 0; i < instances.size(); ++i)
1355     all.bitvector |= instances[i].supported_languages.bitvector;
1356   return all;
1357 }
1358 
1359 #pragma mark PluginManager
1360 
1361 void PluginManager::DebuggerInitialize(Debugger &debugger) {
1362   GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
1363   GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1364   GetPlatformInstances().PerformDebuggerCallback(debugger);
1365   GetProcessInstances().PerformDebuggerCallback(debugger);
1366   GetSymbolFileInstances().PerformDebuggerCallback(debugger);
1367   GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
1368   GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
1369   GetTracePluginInstances().PerformDebuggerCallback(debugger);
1370 }
1371 
1372 // This is the preferred new way to register plugin specific settings.  e.g.
1373 // This will put a plugin's settings under e.g.
1374 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1375 static lldb::OptionValuePropertiesSP
1376 GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name,
1377                               ConstString plugin_type_desc, bool can_create) {
1378   lldb::OptionValuePropertiesSP parent_properties_sp(
1379       debugger.GetValueProperties());
1380   if (parent_properties_sp) {
1381     static ConstString g_property_name("plugin");
1382 
1383     OptionValuePropertiesSP plugin_properties_sp =
1384         parent_properties_sp->GetSubProperty(nullptr, g_property_name);
1385     if (!plugin_properties_sp && can_create) {
1386       plugin_properties_sp =
1387           std::make_shared<OptionValueProperties>(g_property_name);
1388       parent_properties_sp->AppendProperty(
1389           g_property_name, ConstString("Settings specify to plugins."), true,
1390           plugin_properties_sp);
1391     }
1392 
1393     if (plugin_properties_sp) {
1394       lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1395           plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1396       if (!plugin_type_properties_sp && can_create) {
1397         plugin_type_properties_sp =
1398             std::make_shared<OptionValueProperties>(plugin_type_name);
1399         plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1400                                              true, plugin_type_properties_sp);
1401       }
1402       return plugin_type_properties_sp;
1403     }
1404   }
1405   return lldb::OptionValuePropertiesSP();
1406 }
1407 
1408 // This is deprecated way to register plugin specific settings.  e.g.
1409 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
1410 // generic settings would be under "platform.SETTINGNAME".
1411 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
1412     Debugger &debugger, ConstString plugin_type_name,
1413     ConstString plugin_type_desc, bool can_create) {
1414   static ConstString g_property_name("plugin");
1415   lldb::OptionValuePropertiesSP parent_properties_sp(
1416       debugger.GetValueProperties());
1417   if (parent_properties_sp) {
1418     OptionValuePropertiesSP plugin_properties_sp =
1419         parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1420     if (!plugin_properties_sp && can_create) {
1421       plugin_properties_sp =
1422           std::make_shared<OptionValueProperties>(plugin_type_name);
1423       parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1424                                            true, plugin_properties_sp);
1425     }
1426 
1427     if (plugin_properties_sp) {
1428       lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1429           plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
1430       if (!plugin_type_properties_sp && can_create) {
1431         plugin_type_properties_sp =
1432             std::make_shared<OptionValueProperties>(g_property_name);
1433         plugin_properties_sp->AppendProperty(
1434             g_property_name, ConstString("Settings specific to plugins"), true,
1435             plugin_type_properties_sp);
1436       }
1437       return plugin_type_properties_sp;
1438     }
1439   }
1440   return lldb::OptionValuePropertiesSP();
1441 }
1442 
1443 namespace {
1444 
1445 typedef lldb::OptionValuePropertiesSP
1446 GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString,
1447                                  bool can_create);
1448 }
1449 
1450 static lldb::OptionValuePropertiesSP
1451 GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
1452                     ConstString plugin_type_name,
1453                     GetDebuggerPropertyForPluginsPtr get_debugger_property =
1454                         GetDebuggerPropertyForPlugins) {
1455   lldb::OptionValuePropertiesSP properties_sp;
1456   lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
1457       debugger, plugin_type_name,
1458       ConstString(), // not creating to so we don't need the description
1459       false));
1460   if (plugin_type_properties_sp)
1461     properties_sp =
1462         plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1463   return properties_sp;
1464 }
1465 
1466 static bool
1467 CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name,
1468                        ConstString plugin_type_desc,
1469                        const lldb::OptionValuePropertiesSP &properties_sp,
1470                        ConstString description, bool is_global_property,
1471                        GetDebuggerPropertyForPluginsPtr get_debugger_property =
1472                            GetDebuggerPropertyForPlugins) {
1473   if (properties_sp) {
1474     lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1475         get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
1476                               true));
1477     if (plugin_type_properties_sp) {
1478       plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1479                                                 description, is_global_property,
1480                                                 properties_sp);
1481       return true;
1482     }
1483   }
1484   return false;
1485 }
1486 
1487 static const char *kDynamicLoaderPluginName("dynamic-loader");
1488 static const char *kPlatformPluginName("platform");
1489 static const char *kProcessPluginName("process");
1490 static const char *kSymbolFilePluginName("symbol-file");
1491 static const char *kJITLoaderPluginName("jit-loader");
1492 static const char *kStructuredDataPluginName("structured-data");
1493 
1494 lldb::OptionValuePropertiesSP
1495 PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
1496                                                 ConstString setting_name) {
1497   return GetSettingForPlugin(debugger, setting_name,
1498                              ConstString(kDynamicLoaderPluginName));
1499 }
1500 
1501 bool PluginManager::CreateSettingForDynamicLoaderPlugin(
1502     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1503     ConstString description, bool is_global_property) {
1504   return CreateSettingForPlugin(
1505       debugger, ConstString(kDynamicLoaderPluginName),
1506       ConstString("Settings for dynamic loader plug-ins"), properties_sp,
1507       description, is_global_property);
1508 }
1509 
1510 lldb::OptionValuePropertiesSP
1511 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
1512                                            ConstString setting_name) {
1513   return GetSettingForPlugin(debugger, setting_name,
1514                              ConstString(kPlatformPluginName),
1515                              GetDebuggerPropertyForPluginsOldStyle);
1516 }
1517 
1518 bool PluginManager::CreateSettingForPlatformPlugin(
1519     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1520     ConstString description, bool is_global_property) {
1521   return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
1522                                 ConstString("Settings for platform plug-ins"),
1523                                 properties_sp, description, is_global_property,
1524                                 GetDebuggerPropertyForPluginsOldStyle);
1525 }
1526 
1527 lldb::OptionValuePropertiesSP
1528 PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
1529                                           ConstString setting_name) {
1530   return GetSettingForPlugin(debugger, setting_name,
1531                              ConstString(kProcessPluginName));
1532 }
1533 
1534 bool PluginManager::CreateSettingForProcessPlugin(
1535     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1536     ConstString description, bool is_global_property) {
1537   return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
1538                                 ConstString("Settings for process plug-ins"),
1539                                 properties_sp, description, is_global_property);
1540 }
1541 
1542 lldb::OptionValuePropertiesSP
1543 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
1544                                              ConstString setting_name) {
1545   return GetSettingForPlugin(debugger, setting_name,
1546                              ConstString(kSymbolFilePluginName));
1547 }
1548 
1549 bool PluginManager::CreateSettingForSymbolFilePlugin(
1550     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1551     ConstString description, bool is_global_property) {
1552   return CreateSettingForPlugin(
1553       debugger, ConstString(kSymbolFilePluginName),
1554       ConstString("Settings for symbol file plug-ins"), properties_sp,
1555       description, is_global_property);
1556 }
1557 
1558 lldb::OptionValuePropertiesSP
1559 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
1560                                             ConstString setting_name) {
1561   return GetSettingForPlugin(debugger, setting_name,
1562                              ConstString(kJITLoaderPluginName));
1563 }
1564 
1565 bool PluginManager::CreateSettingForJITLoaderPlugin(
1566     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1567     ConstString description, bool is_global_property) {
1568   return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
1569                                 ConstString("Settings for JIT loader plug-ins"),
1570                                 properties_sp, description, is_global_property);
1571 }
1572 
1573 static const char *kOperatingSystemPluginName("os");
1574 
1575 lldb::OptionValuePropertiesSP
1576 PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger,
1577                                                   ConstString setting_name) {
1578   lldb::OptionValuePropertiesSP properties_sp;
1579   lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1580       GetDebuggerPropertyForPlugins(
1581           debugger, ConstString(kOperatingSystemPluginName),
1582           ConstString(), // not creating to so we don't need the description
1583           false));
1584   if (plugin_type_properties_sp)
1585     properties_sp =
1586         plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1587   return properties_sp;
1588 }
1589 
1590 bool PluginManager::CreateSettingForOperatingSystemPlugin(
1591     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1592     ConstString description, bool is_global_property) {
1593   if (properties_sp) {
1594     lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1595         GetDebuggerPropertyForPlugins(
1596             debugger, ConstString(kOperatingSystemPluginName),
1597             ConstString("Settings for operating system plug-ins"), true));
1598     if (plugin_type_properties_sp) {
1599       plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1600                                                 description, is_global_property,
1601                                                 properties_sp);
1602       return true;
1603     }
1604   }
1605   return false;
1606 }
1607 
1608 lldb::OptionValuePropertiesSP
1609 PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
1610                                                  ConstString setting_name) {
1611   return GetSettingForPlugin(debugger, setting_name,
1612                              ConstString(kStructuredDataPluginName));
1613 }
1614 
1615 bool PluginManager::CreateSettingForStructuredDataPlugin(
1616     Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1617     ConstString description, bool is_global_property) {
1618   return CreateSettingForPlugin(
1619       debugger, ConstString(kStructuredDataPluginName),
1620       ConstString("Settings for structured data plug-ins"), properties_sp,
1621       description, is_global_property);
1622 }
1623