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