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