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