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