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