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