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