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