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