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