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