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
34using namespace lldb;
35using namespace lldb_private;
36
37typedef bool (*PluginInitCallback)();
38typedef void (*PluginTermCallback)();
39
40struct PluginInfo {
41  PluginInfo() = default;
42
43  llvm::sys::DynamicLibrary library;
44  PluginInitCallback plugin_init_callback = nullptr;
45  PluginTermCallback plugin_term_callback = nullptr;
46};
47
48typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
49
50static std::recursive_mutex &GetPluginMapMutex() {
51  static std::recursive_mutex g_plugin_map_mutex;
52  return g_plugin_map_mutex;
53}
54
55static PluginTerminateMap &GetPluginMap() {
56  static PluginTerminateMap g_plugin_map;
57  return g_plugin_map;
58}
59
60static 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
66static 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
74template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
75  return reinterpret_cast<FPtrTy>(VPtr);
76}
77
78static FileSystem::EnumerateDirectoryResult
79LoadPluginCallback(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
143void 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
167void 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
183template <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
199template <typename Instance> class PluginInstances {
200public:
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
272private:
273  std::vector<Instance> m_instances;
274};
275
276#pragma mark ABI
277
278typedef PluginInstance<ABICreateInstance> ABIInstance;
279typedef PluginInstances<ABIInstance> ABIInstances;
280
281static ABIInstances &GetABIInstances() {
282  static ABIInstances g_instances;
283  return g_instances;
284}
285
286bool PluginManager::RegisterPlugin(llvm::StringRef name,
287                                   llvm::StringRef description,
288                                   ABICreateInstance create_callback) {
289  return GetABIInstances().RegisterPlugin(name, description, create_callback);
290}
291
292bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
293  return GetABIInstances().UnregisterPlugin(create_callback);
294}
295
296ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
297  return GetABIInstances().GetCallbackAtIndex(idx);
298}
299
300#pragma mark Architecture
301
302typedef PluginInstance<ArchitectureCreateInstance> ArchitectureInstance;
303typedef std::vector<ArchitectureInstance> ArchitectureInstances;
304
305static ArchitectureInstances &GetArchitectureInstances() {
306  static ArchitectureInstances g_instances;
307  return g_instances;
308}
309
310void PluginManager::RegisterPlugin(llvm::StringRef name,
311                                   llvm::StringRef description,
312                                   ArchitectureCreateInstance create_callback) {
313  GetArchitectureInstances().push_back({name, description, create_callback});
314}
315
316void 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
329std::unique_ptr<Architecture>
330PluginManager::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
340typedef PluginInstance<DisassemblerCreateInstance> DisassemblerInstance;
341typedef PluginInstances<DisassemblerInstance> DisassemblerInstances;
342
343static DisassemblerInstances &GetDisassemblerInstances() {
344  static DisassemblerInstances g_instances;
345  return g_instances;
346}
347
348bool PluginManager::RegisterPlugin(llvm::StringRef name,
349                                   llvm::StringRef description,
350                                   DisassemblerCreateInstance create_callback) {
351  return GetDisassemblerInstances().RegisterPlugin(name, description,
352                                                   create_callback);
353}
354
355bool PluginManager::UnregisterPlugin(
356    DisassemblerCreateInstance create_callback) {
357  return GetDisassemblerInstances().UnregisterPlugin(create_callback);
358}
359
360DisassemblerCreateInstance
361PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
362  return GetDisassemblerInstances().GetCallbackAtIndex(idx);
363}
364
365DisassemblerCreateInstance
366PluginManager::GetDisassemblerCreateCallbackForPluginName(
367    llvm::StringRef name) {
368  return GetDisassemblerInstances().GetCallbackForName(name);
369}
370
371#pragma mark DynamicLoader
372
373typedef PluginInstance<DynamicLoaderCreateInstance> DynamicLoaderInstance;
374typedef PluginInstances<DynamicLoaderInstance> DynamicLoaderInstances;
375
376static DynamicLoaderInstances &GetDynamicLoaderInstances() {
377  static DynamicLoaderInstances g_instances;
378  return g_instances;
379}
380
381bool 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
389bool PluginManager::UnregisterPlugin(
390    DynamicLoaderCreateInstance create_callback) {
391  return GetDynamicLoaderInstances().UnregisterPlugin(create_callback);
392}
393
394DynamicLoaderCreateInstance
395PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
396  return GetDynamicLoaderInstances().GetCallbackAtIndex(idx);
397}
398
399DynamicLoaderCreateInstance
400PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
401    llvm::StringRef name) {
402  return GetDynamicLoaderInstances().GetCallbackForName(name);
403}
404
405#pragma mark JITLoader
406
407typedef PluginInstance<JITLoaderCreateInstance> JITLoaderInstance;
408typedef PluginInstances<JITLoaderInstance> JITLoaderInstances;
409
410static JITLoaderInstances &GetJITLoaderInstances() {
411  static JITLoaderInstances g_instances;
412  return g_instances;
413}
414
415bool 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
423bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
424  return GetJITLoaderInstances().UnregisterPlugin(create_callback);
425}
426
427JITLoaderCreateInstance
428PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
429  return GetJITLoaderInstances().GetCallbackAtIndex(idx);
430}
431
432#pragma mark EmulateInstruction
433
434typedef PluginInstance<EmulateInstructionCreateInstance>
435    EmulateInstructionInstance;
436typedef PluginInstances<EmulateInstructionInstance> EmulateInstructionInstances;
437
438static EmulateInstructionInstances &GetEmulateInstructionInstances() {
439  static EmulateInstructionInstances g_instances;
440  return g_instances;
441}
442
443bool PluginManager::RegisterPlugin(
444    llvm::StringRef name, llvm::StringRef description,
445    EmulateInstructionCreateInstance create_callback) {
446  return GetEmulateInstructionInstances().RegisterPlugin(name, description,
447                                                         create_callback);
448}
449
450bool PluginManager::UnregisterPlugin(
451    EmulateInstructionCreateInstance create_callback) {
452  return GetEmulateInstructionInstances().UnregisterPlugin(create_callback);
453}
454
455EmulateInstructionCreateInstance
456PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
457  return GetEmulateInstructionInstances().GetCallbackAtIndex(idx);
458}
459
460EmulateInstructionCreateInstance
461PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
462    llvm::StringRef name) {
463  return GetEmulateInstructionInstances().GetCallbackForName(name);
464}
465
466#pragma mark OperatingSystem
467
468typedef PluginInstance<OperatingSystemCreateInstance> OperatingSystemInstance;
469typedef PluginInstances<OperatingSystemInstance> OperatingSystemInstances;
470
471static OperatingSystemInstances &GetOperatingSystemInstances() {
472  static OperatingSystemInstances g_instances;
473  return g_instances;
474}
475
476bool 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
484bool PluginManager::UnregisterPlugin(
485    OperatingSystemCreateInstance create_callback) {
486  return GetOperatingSystemInstances().UnregisterPlugin(create_callback);
487}
488
489OperatingSystemCreateInstance
490PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
491  return GetOperatingSystemInstances().GetCallbackAtIndex(idx);
492}
493
494OperatingSystemCreateInstance
495PluginManager::GetOperatingSystemCreateCallbackForPluginName(
496    llvm::StringRef name) {
497  return GetOperatingSystemInstances().GetCallbackForName(name);
498}
499
500#pragma mark Language
501
502typedef PluginInstance<LanguageCreateInstance> LanguageInstance;
503typedef PluginInstances<LanguageInstance> LanguageInstances;
504
505static LanguageInstances &GetLanguageInstances() {
506  static LanguageInstances g_instances;
507  return g_instances;
508}
509
510bool PluginManager::RegisterPlugin(llvm::StringRef name,
511                                   llvm::StringRef description,
512                                   LanguageCreateInstance create_callback) {
513  return GetLanguageInstances().RegisterPlugin(name, description,
514                                               create_callback);
515}
516
517bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
518  return GetLanguageInstances().UnregisterPlugin(create_callback);
519}
520
521LanguageCreateInstance
522PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
523  return GetLanguageInstances().GetCallbackAtIndex(idx);
524}
525
526#pragma mark LanguageRuntime
527
528struct 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
545typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances;
546
547static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
548  static LanguageRuntimeInstances g_instances;
549  return g_instances;
550}
551
552bool 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
562bool PluginManager::UnregisterPlugin(
563    LanguageRuntimeCreateInstance create_callback) {
564  return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback);
565}
566
567LanguageRuntimeCreateInstance
568PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
569  return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx);
570}
571
572LanguageRuntimeGetCommandObject
573PluginManager::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
580LanguageRuntimeGetExceptionPrecondition
581PluginManager::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
590typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance;
591typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances;
592
593static SystemRuntimeInstances &GetSystemRuntimeInstances() {
594  static SystemRuntimeInstances g_instances;
595  return g_instances;
596}
597
598bool PluginManager::RegisterPlugin(
599    llvm::StringRef name, llvm::StringRef description,
600    SystemRuntimeCreateInstance create_callback) {
601  return GetSystemRuntimeInstances().RegisterPlugin(name, description,
602                                                    create_callback);
603}
604
605bool PluginManager::UnregisterPlugin(
606    SystemRuntimeCreateInstance create_callback) {
607  return GetSystemRuntimeInstances().UnregisterPlugin(create_callback);
608}
609
610SystemRuntimeCreateInstance
611PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
612  return GetSystemRuntimeInstances().GetCallbackAtIndex(idx);
613}
614
615#pragma mark ObjectFile
616
617struct 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};
635typedef PluginInstances<ObjectFileInstance> ObjectFileInstances;
636
637static ObjectFileInstances &GetObjectFileInstances() {
638  static ObjectFileInstances g_instances;
639  return g_instances;
640}
641
642bool 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
654bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
655  return GetObjectFileInstances().UnregisterPlugin(create_callback);
656}
657
658ObjectFileCreateInstance
659PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
660  return GetObjectFileInstances().GetCallbackAtIndex(idx);
661}
662
663ObjectFileCreateMemoryInstance
664PluginManager::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
671ObjectFileGetModuleSpecifications
672PluginManager::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
680ObjectFileCreateMemoryInstance
681PluginManager::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
691Status 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
721struct 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};
736typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;
737
738static ObjectContainerInstances &GetObjectContainerInstances() {
739  static ObjectContainerInstances g_instances;
740  return g_instances;
741}
742
743bool 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
753bool PluginManager::UnregisterPlugin(
754    ObjectContainerCreateInstance create_callback) {
755  return GetObjectContainerInstances().UnregisterPlugin(create_callback);
756}
757
758ObjectContainerCreateInstance
759PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
760  return GetObjectContainerInstances().GetCallbackAtIndex(idx);
761}
762
763ObjectContainerCreateMemoryInstance
764PluginManager::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
771ObjectFileGetModuleSpecifications
772PluginManager::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
782typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
783typedef PluginInstances<PlatformInstance> PlatformInstances;
784
785static PlatformInstances &GetPlatformInstances() {
786  static PlatformInstances g_platform_instances;
787  return g_platform_instances;
788}
789
790bool 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
798bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
799  return GetPlatformInstances().UnregisterPlugin(create_callback);
800}
801
802llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
803  return GetPlatformInstances().GetNameAtIndex(idx);
804}
805
806llvm::StringRef
807PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
808  return GetPlatformInstances().GetDescriptionAtIndex(idx);
809}
810
811PlatformCreateInstance
812PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
813  return GetPlatformInstances().GetCallbackAtIndex(idx);
814}
815
816PlatformCreateInstance
817PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) {
818  return GetPlatformInstances().GetCallbackForName(name);
819}
820
821void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
822                                             CompletionRequest &request) {
823  for (const auto &instance : GetPlatformInstances().GetInstances()) {
824    if (instance.name.starts_with(name))
825      request.AddCompletion(instance.name);
826  }
827}
828
829#pragma mark Process
830
831typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
832typedef PluginInstances<ProcessInstance> ProcessInstances;
833
834static ProcessInstances &GetProcessInstances() {
835  static ProcessInstances g_instances;
836  return g_instances;
837}
838
839bool 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
847bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
848  return GetProcessInstances().UnregisterPlugin(create_callback);
849}
850
851llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
852  return GetProcessInstances().GetNameAtIndex(idx);
853}
854
855llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
856  return GetProcessInstances().GetDescriptionAtIndex(idx);
857}
858
859ProcessCreateInstance
860PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
861  return GetProcessInstances().GetCallbackAtIndex(idx);
862}
863
864ProcessCreateInstance
865PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) {
866  return GetProcessInstances().GetCallbackForName(name);
867}
868
869void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
870                                            CompletionRequest &request) {
871  for (const auto &instance : GetProcessInstances().GetInstances()) {
872    if (instance.name.starts_with(name))
873      request.AddCompletion(instance.name, instance.description);
874  }
875}
876
877#pragma mark RegisterTypeBuilder
878
879struct 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
887typedef PluginInstances<RegisterTypeBuilderInstance>
888    RegisterTypeBuilderInstances;
889
890static RegisterTypeBuilderInstances &GetRegisterTypeBuilderInstances() {
891  static RegisterTypeBuilderInstances g_instances;
892  return g_instances;
893}
894
895bool PluginManager::RegisterPlugin(
896    llvm::StringRef name, llvm::StringRef description,
897    RegisterTypeBuilderCreateInstance create_callback) {
898  return GetRegisterTypeBuilderInstances().RegisterPlugin(name, description,
899                                                          create_callback);
900}
901
902bool PluginManager::UnregisterPlugin(
903    RegisterTypeBuilderCreateInstance create_callback) {
904  return GetRegisterTypeBuilderInstances().UnregisterPlugin(create_callback);
905}
906
907lldb::RegisterTypeBuilderSP
908PluginManager::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
918struct 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
930typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;
931
932static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
933  static ScriptInterpreterInstances g_instances;
934  return g_instances;
935}
936
937bool 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
945bool PluginManager::UnregisterPlugin(
946    ScriptInterpreterCreateInstance create_callback) {
947  return GetScriptInterpreterInstances().UnregisterPlugin(create_callback);
948}
949
950ScriptInterpreterCreateInstance
951PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
952  return GetScriptInterpreterInstances().GetCallbackAtIndex(idx);
953}
954
955lldb::ScriptInterpreterSP
956PluginManager::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
975struct 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
989typedef PluginInstances<StructuredDataPluginInstance>
990    StructuredDataPluginInstances;
991
992static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
993  static StructuredDataPluginInstances g_instances;
994  return g_instances;
995}
996
997bool 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
1007bool PluginManager::UnregisterPlugin(
1008    StructuredDataPluginCreateInstance create_callback) {
1009  return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback);
1010}
1011
1012StructuredDataPluginCreateInstance
1013PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
1014  return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx);
1015}
1016
1017StructuredDataFilterLaunchInfo
1018PluginManager::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
1032typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
1033typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;
1034
1035static SymbolFileInstances &GetSymbolFileInstances() {
1036  static SymbolFileInstances g_instances;
1037  return g_instances;
1038}
1039
1040bool 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
1048bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
1049  return GetSymbolFileInstances().UnregisterPlugin(create_callback);
1050}
1051
1052SymbolFileCreateInstance
1053PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1054  return GetSymbolFileInstances().GetCallbackAtIndex(idx);
1055}
1056
1057#pragma mark SymbolVendor
1058
1059typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
1060typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;
1061
1062static SymbolVendorInstances &GetSymbolVendorInstances() {
1063  static SymbolVendorInstances g_instances;
1064  return g_instances;
1065}
1066
1067bool PluginManager::RegisterPlugin(llvm::StringRef name,
1068                                   llvm::StringRef description,
1069                                   SymbolVendorCreateInstance create_callback) {
1070  return GetSymbolVendorInstances().RegisterPlugin(name, description,
1071                                                   create_callback);
1072}
1073
1074bool PluginManager::UnregisterPlugin(
1075    SymbolVendorCreateInstance create_callback) {
1076  return GetSymbolVendorInstances().UnregisterPlugin(create_callback);
1077}
1078
1079SymbolVendorCreateInstance
1080PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1081  return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
1082}
1083
1084#pragma mark SymbolLocator
1085
1086struct 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      SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
1094      SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
1095      DebuggerInitializeCallback debugger_init_callback)
1096      : PluginInstance<SymbolLocatorCreateInstance>(
1097            name, description, create_callback, debugger_init_callback),
1098        locate_executable_object_file(locate_executable_object_file),
1099        locate_executable_symbol_file(locate_executable_symbol_file),
1100        download_object_symbol_file(download_object_symbol_file),
1101        find_symbol_file_in_bundle(find_symbol_file_in_bundle) {}
1102
1103  SymbolLocatorLocateExecutableObjectFile locate_executable_object_file;
1104  SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file;
1105  SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file;
1106  SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle;
1107};
1108typedef PluginInstances<SymbolLocatorInstance> SymbolLocatorInstances;
1109
1110static SymbolLocatorInstances &GetSymbolLocatorInstances() {
1111  static SymbolLocatorInstances g_instances;
1112  return g_instances;
1113}
1114
1115bool PluginManager::RegisterPlugin(
1116    llvm::StringRef name, llvm::StringRef description,
1117    SymbolLocatorCreateInstance create_callback,
1118    SymbolLocatorLocateExecutableObjectFile locate_executable_object_file,
1119    SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
1120    SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
1121    SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
1122    DebuggerInitializeCallback debugger_init_callback) {
1123  return GetSymbolLocatorInstances().RegisterPlugin(
1124      name, description, create_callback, locate_executable_object_file,
1125      locate_executable_symbol_file, download_object_symbol_file,
1126      find_symbol_file_in_bundle, debugger_init_callback);
1127}
1128
1129bool PluginManager::UnregisterPlugin(
1130    SymbolLocatorCreateInstance create_callback) {
1131  return GetSymbolLocatorInstances().UnregisterPlugin(create_callback);
1132}
1133
1134SymbolLocatorCreateInstance
1135PluginManager::GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx) {
1136  return GetSymbolLocatorInstances().GetCallbackAtIndex(idx);
1137}
1138
1139ModuleSpec
1140PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
1141  auto &instances = GetSymbolLocatorInstances().GetInstances();
1142  for (auto &instance : instances) {
1143    if (instance.locate_executable_object_file) {
1144      std::optional<ModuleSpec> result =
1145          instance.locate_executable_object_file(module_spec);
1146      if (result)
1147        return *result;
1148    }
1149  }
1150  return {};
1151}
1152
1153FileSpec PluginManager::LocateExecutableSymbolFile(
1154    const ModuleSpec &module_spec, const FileSpecList &default_search_paths) {
1155  auto &instances = GetSymbolLocatorInstances().GetInstances();
1156  for (auto &instance : instances) {
1157    if (instance.locate_executable_symbol_file) {
1158      std::optional<FileSpec> result = instance.locate_executable_symbol_file(
1159          module_spec, default_search_paths);
1160      if (result)
1161        return *result;
1162    }
1163  }
1164  return {};
1165}
1166
1167bool PluginManager::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
1168                                                Status &error,
1169                                                bool force_lookup,
1170                                                bool copy_executable) {
1171  auto &instances = GetSymbolLocatorInstances().GetInstances();
1172  for (auto &instance : instances) {
1173    if (instance.download_object_symbol_file) {
1174      if (instance.download_object_symbol_file(module_spec, error, force_lookup,
1175                                               copy_executable))
1176        return true;
1177    }
1178  }
1179  return false;
1180}
1181
1182FileSpec PluginManager::FindSymbolFileInBundle(const FileSpec &symfile_bundle,
1183                                               const UUID *uuid,
1184                                               const ArchSpec *arch) {
1185  auto &instances = GetSymbolLocatorInstances().GetInstances();
1186  for (auto &instance : instances) {
1187    if (instance.find_symbol_file_in_bundle) {
1188      std::optional<FileSpec> result =
1189          instance.find_symbol_file_in_bundle(symfile_bundle, uuid, arch);
1190      if (result)
1191        return *result;
1192    }
1193  }
1194  return {};
1195}
1196
1197#pragma mark Trace
1198
1199struct TraceInstance
1200    : public PluginInstance<TraceCreateInstanceFromBundle> {
1201  TraceInstance(
1202      llvm::StringRef name, llvm::StringRef description,
1203      CallbackType create_callback_from_bundle,
1204      TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1205      llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback)
1206      : PluginInstance<TraceCreateInstanceFromBundle>(
1207            name, description, create_callback_from_bundle,
1208            debugger_init_callback),
1209        schema(schema),
1210        create_callback_for_live_process(create_callback_for_live_process) {}
1211
1212  llvm::StringRef schema;
1213  TraceCreateInstanceForLiveProcess create_callback_for_live_process;
1214};
1215
1216typedef PluginInstances<TraceInstance> TraceInstances;
1217
1218static TraceInstances &GetTracePluginInstances() {
1219  static TraceInstances g_instances;
1220  return g_instances;
1221}
1222
1223bool PluginManager::RegisterPlugin(
1224    llvm::StringRef name, llvm::StringRef description,
1225    TraceCreateInstanceFromBundle create_callback_from_bundle,
1226    TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1227    llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback) {
1228  return GetTracePluginInstances().RegisterPlugin(
1229      name, description, create_callback_from_bundle,
1230      create_callback_for_live_process, schema, debugger_init_callback);
1231}
1232
1233bool PluginManager::UnregisterPlugin(
1234    TraceCreateInstanceFromBundle create_callback_from_bundle) {
1235  return GetTracePluginInstances().UnregisterPlugin(
1236      create_callback_from_bundle);
1237}
1238
1239TraceCreateInstanceFromBundle
1240PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) {
1241  return GetTracePluginInstances().GetCallbackForName(plugin_name);
1242}
1243
1244TraceCreateInstanceForLiveProcess
1245PluginManager::GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name) {
1246  for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1247    if (instance.name == plugin_name)
1248      return instance.create_callback_for_live_process;
1249  return nullptr;
1250}
1251
1252llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) {
1253  for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1254    if (instance.name == plugin_name)
1255      return instance.schema;
1256  return llvm::StringRef();
1257}
1258
1259llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
1260  if (TraceInstance *instance =
1261          GetTracePluginInstances().GetInstanceAtIndex(index))
1262    return instance->schema;
1263  return llvm::StringRef();
1264}
1265
1266#pragma mark TraceExporter
1267
1268struct TraceExporterInstance
1269    : public PluginInstance<TraceExporterCreateInstance> {
1270  TraceExporterInstance(
1271      llvm::StringRef name, llvm::StringRef description,
1272      TraceExporterCreateInstance create_instance,
1273      ThreadTraceExportCommandCreator create_thread_trace_export_command)
1274      : PluginInstance<TraceExporterCreateInstance>(name, description,
1275                                                    create_instance),
1276        create_thread_trace_export_command(create_thread_trace_export_command) {
1277  }
1278
1279  ThreadTraceExportCommandCreator create_thread_trace_export_command;
1280};
1281
1282typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;
1283
1284static TraceExporterInstances &GetTraceExporterInstances() {
1285  static TraceExporterInstances g_instances;
1286  return g_instances;
1287}
1288
1289bool PluginManager::RegisterPlugin(
1290    llvm::StringRef name, llvm::StringRef description,
1291    TraceExporterCreateInstance create_callback,
1292    ThreadTraceExportCommandCreator create_thread_trace_export_command) {
1293  return GetTraceExporterInstances().RegisterPlugin(
1294      name, description, create_callback, create_thread_trace_export_command);
1295}
1296
1297TraceExporterCreateInstance
1298PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) {
1299  return GetTraceExporterInstances().GetCallbackForName(plugin_name);
1300}
1301
1302bool PluginManager::UnregisterPlugin(
1303    TraceExporterCreateInstance create_callback) {
1304  return GetTraceExporterInstances().UnregisterPlugin(create_callback);
1305}
1306
1307ThreadTraceExportCommandCreator
1308PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
1309  if (TraceExporterInstance *instance =
1310          GetTraceExporterInstances().GetInstanceAtIndex(index))
1311    return instance->create_thread_trace_export_command;
1312  return nullptr;
1313}
1314
1315llvm::StringRef
1316PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
1317  return GetTraceExporterInstances().GetNameAtIndex(index);
1318}
1319
1320#pragma mark UnwindAssembly
1321
1322typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
1323typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;
1324
1325static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1326  static UnwindAssemblyInstances g_instances;
1327  return g_instances;
1328}
1329
1330bool PluginManager::RegisterPlugin(
1331    llvm::StringRef name, llvm::StringRef description,
1332    UnwindAssemblyCreateInstance create_callback) {
1333  return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
1334                                                     create_callback);
1335}
1336
1337bool PluginManager::UnregisterPlugin(
1338    UnwindAssemblyCreateInstance create_callback) {
1339  return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback);
1340}
1341
1342UnwindAssemblyCreateInstance
1343PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1344  return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx);
1345}
1346
1347#pragma mark MemoryHistory
1348
1349typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
1350typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;
1351
1352static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1353  static MemoryHistoryInstances g_instances;
1354  return g_instances;
1355}
1356
1357bool PluginManager::RegisterPlugin(
1358    llvm::StringRef name, llvm::StringRef description,
1359    MemoryHistoryCreateInstance create_callback) {
1360  return GetMemoryHistoryInstances().RegisterPlugin(name, description,
1361                                                    create_callback);
1362}
1363
1364bool PluginManager::UnregisterPlugin(
1365    MemoryHistoryCreateInstance create_callback) {
1366  return GetMemoryHistoryInstances().UnregisterPlugin(create_callback);
1367}
1368
1369MemoryHistoryCreateInstance
1370PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1371  return GetMemoryHistoryInstances().GetCallbackAtIndex(idx);
1372}
1373
1374#pragma mark InstrumentationRuntime
1375
1376struct InstrumentationRuntimeInstance
1377    : public PluginInstance<InstrumentationRuntimeCreateInstance> {
1378  InstrumentationRuntimeInstance(
1379      llvm::StringRef name, llvm::StringRef description,
1380      CallbackType create_callback,
1381      InstrumentationRuntimeGetType get_type_callback)
1382      : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description,
1383                                                             create_callback),
1384        get_type_callback(get_type_callback) {}
1385
1386  InstrumentationRuntimeGetType get_type_callback = nullptr;
1387};
1388
1389typedef PluginInstances<InstrumentationRuntimeInstance>
1390    InstrumentationRuntimeInstances;
1391
1392static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1393  static InstrumentationRuntimeInstances g_instances;
1394  return g_instances;
1395}
1396
1397bool PluginManager::RegisterPlugin(
1398    llvm::StringRef name, llvm::StringRef description,
1399    InstrumentationRuntimeCreateInstance create_callback,
1400    InstrumentationRuntimeGetType get_type_callback) {
1401  return GetInstrumentationRuntimeInstances().RegisterPlugin(
1402      name, description, create_callback, get_type_callback);
1403}
1404
1405bool PluginManager::UnregisterPlugin(
1406    InstrumentationRuntimeCreateInstance create_callback) {
1407  return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback);
1408}
1409
1410InstrumentationRuntimeGetType
1411PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
1412  const auto &instances = GetInstrumentationRuntimeInstances().GetInstances();
1413  if (idx < instances.size())
1414    return instances[idx].get_type_callback;
1415  return nullptr;
1416}
1417
1418InstrumentationRuntimeCreateInstance
1419PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
1420  return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx);
1421}
1422
1423#pragma mark TypeSystem
1424
1425struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
1426  TypeSystemInstance(llvm::StringRef name, llvm::StringRef description,
1427                     CallbackType create_callback,
1428                     LanguageSet supported_languages_for_types,
1429                     LanguageSet supported_languages_for_expressions)
1430      : PluginInstance<TypeSystemCreateInstance>(name, description,
1431                                                 create_callback),
1432        supported_languages_for_types(supported_languages_for_types),
1433        supported_languages_for_expressions(
1434            supported_languages_for_expressions) {}
1435
1436  LanguageSet supported_languages_for_types;
1437  LanguageSet supported_languages_for_expressions;
1438};
1439
1440typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;
1441
1442static TypeSystemInstances &GetTypeSystemInstances() {
1443  static TypeSystemInstances g_instances;
1444  return g_instances;
1445}
1446
1447bool PluginManager::RegisterPlugin(
1448    llvm::StringRef name, llvm::StringRef description,
1449    TypeSystemCreateInstance create_callback,
1450    LanguageSet supported_languages_for_types,
1451    LanguageSet supported_languages_for_expressions) {
1452  return GetTypeSystemInstances().RegisterPlugin(
1453      name, description, create_callback, supported_languages_for_types,
1454      supported_languages_for_expressions);
1455}
1456
1457bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
1458  return GetTypeSystemInstances().UnregisterPlugin(create_callback);
1459}
1460
1461TypeSystemCreateInstance
1462PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
1463  return GetTypeSystemInstances().GetCallbackAtIndex(idx);
1464}
1465
1466LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
1467  const auto &instances = GetTypeSystemInstances().GetInstances();
1468  LanguageSet all;
1469  for (unsigned i = 0; i < instances.size(); ++i)
1470    all.bitvector |= instances[i].supported_languages_for_types.bitvector;
1471  return all;
1472}
1473
1474LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
1475  const auto &instances = GetTypeSystemInstances().GetInstances();
1476  LanguageSet all;
1477  for (unsigned i = 0; i < instances.size(); ++i)
1478    all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
1479  return all;
1480}
1481
1482#pragma mark REPL
1483
1484struct REPLInstance : public PluginInstance<REPLCreateInstance> {
1485  REPLInstance(llvm::StringRef name, llvm::StringRef description,
1486               CallbackType create_callback, LanguageSet supported_languages)
1487      : PluginInstance<REPLCreateInstance>(name, description, create_callback),
1488        supported_languages(supported_languages) {}
1489
1490  LanguageSet supported_languages;
1491};
1492
1493typedef PluginInstances<REPLInstance> REPLInstances;
1494
1495static REPLInstances &GetREPLInstances() {
1496  static REPLInstances g_instances;
1497  return g_instances;
1498}
1499
1500bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
1501                                   REPLCreateInstance create_callback,
1502                                   LanguageSet supported_languages) {
1503  return GetREPLInstances().RegisterPlugin(name, description, create_callback,
1504                                           supported_languages);
1505}
1506
1507bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
1508  return GetREPLInstances().UnregisterPlugin(create_callback);
1509}
1510
1511REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
1512  return GetREPLInstances().GetCallbackAtIndex(idx);
1513}
1514
1515LanguageSet PluginManager::GetREPLSupportedLanguagesAtIndex(uint32_t idx) {
1516  const auto &instances = GetREPLInstances().GetInstances();
1517  return idx < instances.size() ? instances[idx].supported_languages
1518                                : LanguageSet();
1519}
1520
1521LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
1522  const auto &instances = GetREPLInstances().GetInstances();
1523  LanguageSet all;
1524  for (unsigned i = 0; i < instances.size(); ++i)
1525    all.bitvector |= instances[i].supported_languages.bitvector;
1526  return all;
1527}
1528
1529#pragma mark PluginManager
1530
1531void PluginManager::DebuggerInitialize(Debugger &debugger) {
1532  GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
1533  GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1534  GetObjectFileInstances().PerformDebuggerCallback(debugger);
1535  GetPlatformInstances().PerformDebuggerCallback(debugger);
1536  GetProcessInstances().PerformDebuggerCallback(debugger);
1537  GetSymbolFileInstances().PerformDebuggerCallback(debugger);
1538  GetSymbolLocatorInstances().PerformDebuggerCallback(debugger);
1539  GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
1540  GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
1541  GetTracePluginInstances().PerformDebuggerCallback(debugger);
1542}
1543
1544// This is the preferred new way to register plugin specific settings.  e.g.
1545// This will put a plugin's settings under e.g.
1546// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1547static lldb::OptionValuePropertiesSP
1548GetDebuggerPropertyForPlugins(Debugger &debugger, llvm::StringRef plugin_type_name,
1549                              llvm::StringRef plugin_type_desc,
1550                              bool can_create) {
1551  lldb::OptionValuePropertiesSP parent_properties_sp(
1552      debugger.GetValueProperties());
1553  if (parent_properties_sp) {
1554    static constexpr llvm::StringLiteral g_property_name("plugin");
1555
1556    OptionValuePropertiesSP plugin_properties_sp =
1557        parent_properties_sp->GetSubProperty(nullptr, g_property_name);
1558    if (!plugin_properties_sp && can_create) {
1559      plugin_properties_sp =
1560          std::make_shared<OptionValueProperties>(g_property_name);
1561      parent_properties_sp->AppendProperty(g_property_name,
1562                                           "Settings specify to plugins.", true,
1563                                           plugin_properties_sp);
1564    }
1565
1566    if (plugin_properties_sp) {
1567      lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1568          plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1569      if (!plugin_type_properties_sp && can_create) {
1570        plugin_type_properties_sp =
1571            std::make_shared<OptionValueProperties>(plugin_type_name);
1572        plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1573                                             true, plugin_type_properties_sp);
1574      }
1575      return plugin_type_properties_sp;
1576    }
1577  }
1578  return lldb::OptionValuePropertiesSP();
1579}
1580
1581// This is deprecated way to register plugin specific settings.  e.g.
1582// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
1583// generic settings would be under "platform.SETTINGNAME".
1584static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
1585    Debugger &debugger, llvm::StringRef plugin_type_name,
1586    llvm::StringRef plugin_type_desc, bool can_create) {
1587  static constexpr llvm::StringLiteral g_property_name("plugin");
1588  lldb::OptionValuePropertiesSP parent_properties_sp(
1589      debugger.GetValueProperties());
1590  if (parent_properties_sp) {
1591    OptionValuePropertiesSP plugin_properties_sp =
1592        parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1593    if (!plugin_properties_sp && can_create) {
1594      plugin_properties_sp =
1595          std::make_shared<OptionValueProperties>(plugin_type_name);
1596      parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1597                                           true, plugin_properties_sp);
1598    }
1599
1600    if (plugin_properties_sp) {
1601      lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1602          plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
1603      if (!plugin_type_properties_sp && can_create) {
1604        plugin_type_properties_sp =
1605            std::make_shared<OptionValueProperties>(g_property_name);
1606        plugin_properties_sp->AppendProperty(g_property_name,
1607                                             "Settings specific to plugins",
1608                                             true, plugin_type_properties_sp);
1609      }
1610      return plugin_type_properties_sp;
1611    }
1612  }
1613  return lldb::OptionValuePropertiesSP();
1614}
1615
1616namespace {
1617
1618typedef lldb::OptionValuePropertiesSP
1619GetDebuggerPropertyForPluginsPtr(Debugger &, llvm::StringRef, llvm::StringRef,
1620                                 bool can_create);
1621}
1622
1623static lldb::OptionValuePropertiesSP
1624GetSettingForPlugin(Debugger &debugger, llvm::StringRef setting_name,
1625                    llvm::StringRef plugin_type_name,
1626                    GetDebuggerPropertyForPluginsPtr get_debugger_property =
1627                        GetDebuggerPropertyForPlugins) {
1628  lldb::OptionValuePropertiesSP properties_sp;
1629  lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
1630      debugger, plugin_type_name,
1631      "", // not creating to so we don't need the description
1632      false));
1633  if (plugin_type_properties_sp)
1634    properties_sp =
1635        plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1636  return properties_sp;
1637}
1638
1639static bool
1640CreateSettingForPlugin(Debugger &debugger, llvm::StringRef plugin_type_name,
1641                       llvm::StringRef plugin_type_desc,
1642                       const lldb::OptionValuePropertiesSP &properties_sp,
1643                       llvm::StringRef description, bool is_global_property,
1644                       GetDebuggerPropertyForPluginsPtr get_debugger_property =
1645                           GetDebuggerPropertyForPlugins) {
1646  if (properties_sp) {
1647    lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1648        get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
1649                              true));
1650    if (plugin_type_properties_sp) {
1651      plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1652                                                description, is_global_property,
1653                                                properties_sp);
1654      return true;
1655    }
1656  }
1657  return false;
1658}
1659
1660static constexpr llvm::StringLiteral kDynamicLoaderPluginName("dynamic-loader");
1661static constexpr llvm::StringLiteral kPlatformPluginName("platform");
1662static constexpr llvm::StringLiteral kProcessPluginName("process");
1663static constexpr llvm::StringLiteral kTracePluginName("trace");
1664static constexpr llvm::StringLiteral kObjectFilePluginName("object-file");
1665static constexpr llvm::StringLiteral kSymbolFilePluginName("symbol-file");
1666static constexpr llvm::StringLiteral kSymbolLocatorPluginName("symbol-locator");
1667static constexpr llvm::StringLiteral kJITLoaderPluginName("jit-loader");
1668static constexpr llvm::StringLiteral
1669    kStructuredDataPluginName("structured-data");
1670
1671lldb::OptionValuePropertiesSP
1672PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
1673                                                llvm::StringRef setting_name) {
1674  return GetSettingForPlugin(debugger, setting_name, kDynamicLoaderPluginName);
1675}
1676
1677bool PluginManager::CreateSettingForDynamicLoaderPlugin(
1678    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1679    llvm::StringRef description, bool is_global_property) {
1680  return CreateSettingForPlugin(debugger, kDynamicLoaderPluginName,
1681                                "Settings for dynamic loader plug-ins",
1682                                properties_sp, description, is_global_property);
1683}
1684
1685lldb::OptionValuePropertiesSP
1686PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
1687                                           llvm::StringRef setting_name) {
1688  return GetSettingForPlugin(debugger, setting_name, kPlatformPluginName,
1689                             GetDebuggerPropertyForPluginsOldStyle);
1690}
1691
1692bool PluginManager::CreateSettingForPlatformPlugin(
1693    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1694    llvm::StringRef description, bool is_global_property) {
1695  return CreateSettingForPlugin(debugger, kPlatformPluginName,
1696                                "Settings for platform plug-ins", properties_sp,
1697                                description, is_global_property,
1698                                GetDebuggerPropertyForPluginsOldStyle);
1699}
1700
1701lldb::OptionValuePropertiesSP
1702PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
1703                                          llvm::StringRef setting_name) {
1704  return GetSettingForPlugin(debugger, setting_name, kProcessPluginName);
1705}
1706
1707bool PluginManager::CreateSettingForProcessPlugin(
1708    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1709    llvm::StringRef description, bool is_global_property) {
1710  return CreateSettingForPlugin(debugger, kProcessPluginName,
1711                                "Settings for process plug-ins", properties_sp,
1712                                description, is_global_property);
1713}
1714
1715lldb::OptionValuePropertiesSP
1716PluginManager::GetSettingForSymbolLocatorPlugin(Debugger &debugger,
1717                                                llvm::StringRef setting_name) {
1718  return GetSettingForPlugin(debugger, setting_name, kSymbolLocatorPluginName);
1719}
1720
1721bool PluginManager::CreateSettingForSymbolLocatorPlugin(
1722    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1723    llvm::StringRef description, bool is_global_property) {
1724  return CreateSettingForPlugin(debugger, kSymbolLocatorPluginName,
1725                                "Settings for symbol locator plug-ins",
1726                                properties_sp, description, is_global_property);
1727}
1728
1729bool PluginManager::CreateSettingForTracePlugin(
1730    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1731    llvm::StringRef description, bool is_global_property) {
1732  return CreateSettingForPlugin(debugger, kTracePluginName,
1733                                "Settings for trace plug-ins", properties_sp,
1734                                description, is_global_property);
1735}
1736
1737lldb::OptionValuePropertiesSP
1738PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger,
1739                                             llvm::StringRef setting_name) {
1740  return GetSettingForPlugin(debugger, setting_name, kObjectFilePluginName);
1741}
1742
1743bool PluginManager::CreateSettingForObjectFilePlugin(
1744    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1745    llvm::StringRef description, bool is_global_property) {
1746  return CreateSettingForPlugin(debugger, kObjectFilePluginName,
1747                                "Settings for object file plug-ins",
1748                                properties_sp, description, is_global_property);
1749}
1750
1751lldb::OptionValuePropertiesSP
1752PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
1753                                             llvm::StringRef setting_name) {
1754  return GetSettingForPlugin(debugger, setting_name, kSymbolFilePluginName);
1755}
1756
1757bool PluginManager::CreateSettingForSymbolFilePlugin(
1758    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1759    llvm::StringRef description, bool is_global_property) {
1760  return CreateSettingForPlugin(debugger, kSymbolFilePluginName,
1761                                "Settings for symbol file plug-ins",
1762                                properties_sp, description, is_global_property);
1763}
1764
1765lldb::OptionValuePropertiesSP
1766PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
1767                                            llvm::StringRef setting_name) {
1768  return GetSettingForPlugin(debugger, setting_name, kJITLoaderPluginName);
1769}
1770
1771bool PluginManager::CreateSettingForJITLoaderPlugin(
1772    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1773    llvm::StringRef description, bool is_global_property) {
1774  return CreateSettingForPlugin(debugger, kJITLoaderPluginName,
1775                                "Settings for JIT loader plug-ins",
1776                                properties_sp, description, is_global_property);
1777}
1778
1779static const char *kOperatingSystemPluginName("os");
1780
1781lldb::OptionValuePropertiesSP
1782PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger,
1783                                                  llvm::StringRef setting_name) {
1784  lldb::OptionValuePropertiesSP properties_sp;
1785  lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1786      GetDebuggerPropertyForPlugins(
1787          debugger, kOperatingSystemPluginName,
1788          "", // not creating to so we don't need the description
1789          false));
1790  if (plugin_type_properties_sp)
1791    properties_sp =
1792        plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1793  return properties_sp;
1794}
1795
1796bool PluginManager::CreateSettingForOperatingSystemPlugin(
1797    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1798    llvm::StringRef description, bool is_global_property) {
1799  if (properties_sp) {
1800    lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1801        GetDebuggerPropertyForPlugins(debugger, kOperatingSystemPluginName,
1802                                      "Settings for operating system plug-ins",
1803                                      true));
1804    if (plugin_type_properties_sp) {
1805      plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1806                                                description, is_global_property,
1807                                                properties_sp);
1808      return true;
1809    }
1810  }
1811  return false;
1812}
1813
1814lldb::OptionValuePropertiesSP
1815PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
1816                                                 llvm::StringRef setting_name) {
1817  return GetSettingForPlugin(debugger, setting_name, kStructuredDataPluginName);
1818}
1819
1820bool PluginManager::CreateSettingForStructuredDataPlugin(
1821    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1822    llvm::StringRef description, bool is_global_property) {
1823  return CreateSettingForPlugin(debugger, kStructuredDataPluginName,
1824                                "Settings for structured data plug-ins",
1825                                properties_sp, description, is_global_property);
1826}
1827