1//===-- PluginManager.cpp -------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Core/PluginManager.h"
10
11#include "lldb/Core/Debugger.h"
12#include "lldb/Host/FileSystem.h"
13#include "lldb/Host/HostInfo.h"
14#include "lldb/Interpreter/OptionValueProperties.h"
15#include "lldb/Target/Process.h"
16#include "lldb/Utility/ConstString.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
35using namespace lldb;
36using namespace lldb_private;
37
38typedef bool (*PluginInitCallback)();
39typedef void (*PluginTermCallback)();
40
41struct PluginInfo {
42 PluginInfo() = default;
43
44 llvm::sys::DynamicLibrary library;
45 PluginInitCallback plugin_init_callback = nullptr;
46 PluginTermCallback plugin_term_callback = nullptr;
47};
48
49typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
50
51static std::recursive_mutex &GetPluginMapMutex() {
52 static std::recursive_mutex g_plugin_map_mutex;
53 return g_plugin_map_mutex;
54}
55
56static PluginTerminateMap &GetPluginMap() {
57 static PluginTerminateMap g_plugin_map;
58 return g_plugin_map;
59}
60
61static 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
67static 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
75template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
76 return reinterpret_cast<FPtrTy>(VPtr);
77}
78
79static FileSystem::EnumerateDirectoryResult
80LoadPluginCallback(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
144void 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
168void 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
184template <typename Callback> struct PluginInstance {
185 typedef Callback CallbackType;
186
187 PluginInstance() = default;
188 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
200template <typename Instance> class PluginInstances {
201public:
202 template <typename... 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
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
229 typename Instance::CallbackType GetCallbackAtIndex(uint32_t idx) {
230 if (Instance *instance = GetInstanceAtIndex(idx))
231 return instance->create_callback;
232 return nullptr;
233 }
234
235 llvm::StringRef GetDescriptionAtIndex(uint32_t idx) {
236 if (Instance *instance = GetInstanceAtIndex(idx))
237 return instance->description;
238 return "";
239 }
240
241 llvm::StringRef GetNameAtIndex(uint32_t idx) {
242 if (Instance *instance = GetInstanceAtIndex(idx))
243 return instance->name;
244 return "";
245 }
246
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
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
264 const std::vector<Instance> &GetInstances() const { return m_instances; }
265 std::vector<Instance> &GetInstances() { return m_instances; }
266
267 Instance *GetInstanceAtIndex(uint32_t idx) {
268 if (idx < m_instances.size())
269 return &m_instances[idx];
270 return nullptr;
271 }
272
273private:
274 std::vector<Instance> m_instances;
275};
276
277#pragma mark ABI
278
279typedef PluginInstance<ABICreateInstance> ABIInstance;
280typedef PluginInstances<ABIInstance> ABIInstances;
281
282static ABIInstances &GetABIInstances() {
283 static ABIInstances g_instances;
284 return g_instances;
285}
286
287bool PluginManager::RegisterPlugin(llvm::StringRef name,
288 llvm::StringRef description,
289 ABICreateInstance create_callback) {
290 return GetABIInstances().RegisterPlugin(name, description, create_callback);
291}
292
293bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
294 return GetABIInstances().UnregisterPlugin(create_callback);
295}
296
297ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
298 return GetABIInstances().GetCallbackAtIndex(idx);
299}
300
301#pragma mark Architecture
302
303typedef PluginInstance<ArchitectureCreateInstance> ArchitectureInstance;
304typedef std::vector<ArchitectureInstance> ArchitectureInstances;
305
306static ArchitectureInstances &GetArchitectureInstances() {
307 static ArchitectureInstances g_instances;
308 return g_instances;
309}
310
311void PluginManager::RegisterPlugin(llvm::StringRef name,
312 llvm::StringRef description,
313 ArchitectureCreateInstance create_callback) {
314 GetArchitectureInstances().push_back({name, description, create_callback});
315}
316
317void 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
330std::unique_ptr<Architecture>
331PluginManager::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
341typedef PluginInstance<DisassemblerCreateInstance> DisassemblerInstance;
342typedef PluginInstances<DisassemblerInstance> DisassemblerInstances;
343
344static DisassemblerInstances &GetDisassemblerInstances() {
345 static DisassemblerInstances g_instances;
346 return g_instances;
347}
348
349bool PluginManager::RegisterPlugin(llvm::StringRef name,
350 llvm::StringRef description,
351 DisassemblerCreateInstance create_callback) {
352 return GetDisassemblerInstances().RegisterPlugin(name, description,
353 create_callback);
354}
355
356bool PluginManager::UnregisterPlugin(
357 DisassemblerCreateInstance create_callback) {
358 return GetDisassemblerInstances().UnregisterPlugin(create_callback);
359}
360
361DisassemblerCreateInstance
362PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
363 return GetDisassemblerInstances().GetCallbackAtIndex(idx);
364}
365
366DisassemblerCreateInstance
367PluginManager::GetDisassemblerCreateCallbackForPluginName(
368 llvm::StringRef name) {
369 return GetDisassemblerInstances().GetCallbackForName(name);
370}
371
372#pragma mark DynamicLoader
373
374typedef PluginInstance<DynamicLoaderCreateInstance> DynamicLoaderInstance;
375typedef PluginInstances<DynamicLoaderInstance> DynamicLoaderInstances;
376
377static DynamicLoaderInstances &GetDynamicLoaderInstances() {
378 static DynamicLoaderInstances g_instances;
379 return g_instances;
380}
381
382bool 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
390bool PluginManager::UnregisterPlugin(
391 DynamicLoaderCreateInstance create_callback) {
392 return GetDynamicLoaderInstances().UnregisterPlugin(create_callback);
393}
394
395DynamicLoaderCreateInstance
396PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
397 return GetDynamicLoaderInstances().GetCallbackAtIndex(idx);
398}
399
400DynamicLoaderCreateInstance
401PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
402 llvm::StringRef name) {
403 return GetDynamicLoaderInstances().GetCallbackForName(name);
404}
405
406#pragma mark JITLoader
407
408typedef PluginInstance<JITLoaderCreateInstance> JITLoaderInstance;
409typedef PluginInstances<JITLoaderInstance> JITLoaderInstances;
410
411static JITLoaderInstances &GetJITLoaderInstances() {
412 static JITLoaderInstances g_instances;
413 return g_instances;
414}
415
416bool 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
424bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
425 return GetJITLoaderInstances().UnregisterPlugin(create_callback);
426}
427
428JITLoaderCreateInstance
429PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
430 return GetJITLoaderInstances().GetCallbackAtIndex(idx);
431}
432
433#pragma mark EmulateInstruction
434
435typedef PluginInstance<EmulateInstructionCreateInstance>
436 EmulateInstructionInstance;
437typedef PluginInstances<EmulateInstructionInstance> EmulateInstructionInstances;
438
439static EmulateInstructionInstances &GetEmulateInstructionInstances() {
440 static EmulateInstructionInstances g_instances;
441 return g_instances;
442}
443
444bool PluginManager::RegisterPlugin(
445 llvm::StringRef name, llvm::StringRef description,
446 EmulateInstructionCreateInstance create_callback) {
447 return GetEmulateInstructionInstances().RegisterPlugin(name, description,
448 create_callback);
449}
450
451bool PluginManager::UnregisterPlugin(
452 EmulateInstructionCreateInstance create_callback) {
453 return GetEmulateInstructionInstances().UnregisterPlugin(create_callback);
454}
455
456EmulateInstructionCreateInstance
457PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
458 return GetEmulateInstructionInstances().GetCallbackAtIndex(idx);
459}
460
461EmulateInstructionCreateInstance
462PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
463 llvm::StringRef name) {
464 return GetEmulateInstructionInstances().GetCallbackForName(name);
465}
466
467#pragma mark OperatingSystem
468
469typedef PluginInstance<OperatingSystemCreateInstance> OperatingSystemInstance;
470typedef PluginInstances<OperatingSystemInstance> OperatingSystemInstances;
471
472static OperatingSystemInstances &GetOperatingSystemInstances() {
473 static OperatingSystemInstances g_instances;
474 return g_instances;
475}
476
477bool 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
485bool PluginManager::UnregisterPlugin(
486 OperatingSystemCreateInstance create_callback) {
487 return GetOperatingSystemInstances().UnregisterPlugin(create_callback);
488}
489
490OperatingSystemCreateInstance
491PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
492 return GetOperatingSystemInstances().GetCallbackAtIndex(idx);
493}
494
495OperatingSystemCreateInstance
496PluginManager::GetOperatingSystemCreateCallbackForPluginName(
497 llvm::StringRef name) {
498 return GetOperatingSystemInstances().GetCallbackForName(name);
499}
500
501#pragma mark Language
502
503typedef PluginInstance<LanguageCreateInstance> LanguageInstance;
504typedef PluginInstances<LanguageInstance> LanguageInstances;
505
506static LanguageInstances &GetLanguageInstances() {
507 static LanguageInstances g_instances;
508 return g_instances;
509}
510
511bool PluginManager::RegisterPlugin(llvm::StringRef name,
512 llvm::StringRef description,
513 LanguageCreateInstance create_callback) {
514 return GetLanguageInstances().RegisterPlugin(name, description,
515 create_callback);
516}
517
518bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
519 return GetLanguageInstances().UnregisterPlugin(create_callback);
520}
521
522LanguageCreateInstance
523PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
524 return GetLanguageInstances().GetCallbackAtIndex(idx);
525}
526
527#pragma mark LanguageRuntime
528
529struct LanguageRuntimeInstance
530 : public PluginInstance<LanguageRuntimeCreateInstance> {
531 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
546typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances;
547
548static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
549 static LanguageRuntimeInstances g_instances;
550 return g_instances;
551}
552
553bool 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
563bool PluginManager::UnregisterPlugin(
564 LanguageRuntimeCreateInstance create_callback) {
565 return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback);
566}
567
568LanguageRuntimeCreateInstance
569PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
570 return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx);
571}
572
573LanguageRuntimeGetCommandObject
574PluginManager::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
581LanguageRuntimeGetExceptionPrecondition
582PluginManager::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
591typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance;
592typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances;
593
594static SystemRuntimeInstances &GetSystemRuntimeInstances() {
595 static SystemRuntimeInstances g_instances;
596 return g_instances;
597}
598
599bool PluginManager::RegisterPlugin(
600 llvm::StringRef name, llvm::StringRef description,
601 SystemRuntimeCreateInstance create_callback) {
602 return GetSystemRuntimeInstances().RegisterPlugin(name, description,
603 create_callback);
604}
605
606bool PluginManager::UnregisterPlugin(
607 SystemRuntimeCreateInstance create_callback) {
608 return GetSystemRuntimeInstances().UnregisterPlugin(create_callback);
609}
610
611SystemRuntimeCreateInstance
612PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
613 return GetSystemRuntimeInstances().GetCallbackAtIndex(idx);
614}
615
616#pragma mark ObjectFile
617
618struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> {
619 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};
636typedef PluginInstances<ObjectFileInstance> ObjectFileInstances;
637
638static ObjectFileInstances &GetObjectFileInstances() {
639 static ObjectFileInstances g_instances;
640 return g_instances;
641}
642
643bool PluginManager::RegisterPlugin(
644 llvm::StringRef name, llvm::StringRef description,
645 ObjectFileCreateInstance create_callback,
646 ObjectFileCreateMemoryInstance create_memory_callback,
647 ObjectFileGetModuleSpecifications get_module_specifications,
648 ObjectFileSaveCore save_core,
649 DebuggerInitializeCallback debugger_init_callback) {
650 return GetObjectFileInstances().RegisterPlugin(
651 name, description, create_callback, create_memory_callback,
652 get_module_specifications, save_core, debugger_init_callback);
653}
654
655bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
656 return GetObjectFileInstances().UnregisterPlugin(create_callback);
657}
658
659ObjectFileCreateInstance
660PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
661 return GetObjectFileInstances().GetCallbackAtIndex(idx);
662}
663
664ObjectFileCreateMemoryInstance
665PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
666 const auto &instances = GetObjectFileInstances().GetInstances();
667 if (idx < instances.size())
668 return instances[idx].create_memory_callback;
669 return nullptr;
670}
671
672ObjectFileGetModuleSpecifications
673PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
674 uint32_t idx) {
675 const auto &instances = GetObjectFileInstances().GetInstances();
676 if (idx < instances.size())
677 return instances[idx].get_module_specifications;
678 return nullptr;
679}
680
681ObjectFileCreateMemoryInstance
682PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
683 llvm::StringRef name) {
684 const auto &instances = GetObjectFileInstances().GetInstances();
685 for (auto &instance : instances) {
686 if (instance.name == name)
687 return instance.create_memory_callback;
688 }
689 return nullptr;
690}
691
692Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
693 const FileSpec &outfile,
694 lldb::SaveCoreStyle &core_style,
695 llvm::StringRef plugin_name) {
696 if (plugin_name.empty()) {
697 // Try saving core directly from the process plugin first.
698 llvm::Expected<bool> ret = process_sp->SaveCore(outfile.GetPath());
699 if (!ret)
700 return Status(ret.takeError());
701 if (ret.get())
702 return Status();
703 }
704
705 // Fall back to object plugins.
706 Status error;
707 auto &instances = GetObjectFileInstances().GetInstances();
708 for (auto &instance : instances) {
709 if (plugin_name.empty() || instance.name == plugin_name) {
710 if (instance.save_core &&
711 instance.save_core(process_sp, outfile, core_style, error))
712 return error;
713 }
714 }
715 error.SetErrorString(
716 "no ObjectFile plugins were able to save a core for this process");
717 return error;
718}
719
720#pragma mark ObjectContainer
721
722struct ObjectContainerInstance
723 : public PluginInstance<ObjectContainerCreateInstance> {
724 ObjectContainerInstance(
725 llvm::StringRef name, llvm::StringRef description,
726 CallbackType create_callback,
727 ObjectFileGetModuleSpecifications get_module_specifications)
728 : PluginInstance<ObjectContainerCreateInstance>(name, description,
729 create_callback),
730 get_module_specifications(get_module_specifications) {}
731
732 ObjectFileGetModuleSpecifications get_module_specifications;
733};
734typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;
735
736static ObjectContainerInstances &GetObjectContainerInstances() {
737 static ObjectContainerInstances g_instances;
738 return g_instances;
739}
740
741bool PluginManager::RegisterPlugin(
742 llvm::StringRef name, llvm::StringRef description,
743 ObjectContainerCreateInstance create_callback,
744 ObjectFileGetModuleSpecifications get_module_specifications) {
745 return GetObjectContainerInstances().RegisterPlugin(
746 name, description, create_callback, get_module_specifications);
747}
748
749bool PluginManager::UnregisterPlugin(
750 ObjectContainerCreateInstance create_callback) {
751 return GetObjectContainerInstances().UnregisterPlugin(create_callback);
752}
753
754ObjectContainerCreateInstance
755PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
756 return GetObjectContainerInstances().GetCallbackAtIndex(idx);
757}
758
759ObjectFileGetModuleSpecifications
760PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
761 uint32_t idx) {
762 const auto &instances = GetObjectContainerInstances().GetInstances();
763 if (idx < instances.size())
764 return instances[idx].get_module_specifications;
765 return nullptr;
766}
767
768#pragma mark Platform
769
770typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
771typedef PluginInstances<PlatformInstance> PlatformInstances;
772
773static PlatformInstances &GetPlatformInstances() {
774 static PlatformInstances g_platform_instances;
775 return g_platform_instances;
776}
777
778bool PluginManager::RegisterPlugin(
779 llvm::StringRef name, llvm::StringRef description,
780 PlatformCreateInstance create_callback,
781 DebuggerInitializeCallback debugger_init_callback) {
782 return GetPlatformInstances().RegisterPlugin(
783 name, description, create_callback, debugger_init_callback);
784}
785
786bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
787 return GetPlatformInstances().UnregisterPlugin(create_callback);
788}
789
790llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
791 return GetPlatformInstances().GetNameAtIndex(idx);
792}
793
794llvm::StringRef
795PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
796 return GetPlatformInstances().GetDescriptionAtIndex(idx);
797}
798
799PlatformCreateInstance
800PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
801 return GetPlatformInstances().GetCallbackAtIndex(idx);
802}
803
804PlatformCreateInstance
805PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) {
806 return GetPlatformInstances().GetCallbackForName(name);
807}
808
809void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
810 CompletionRequest &request) {
811 for (const auto &instance : GetPlatformInstances().GetInstances()) {
812 if (instance.name.startswith(name))
813 request.AddCompletion(instance.name);
814 }
815}
816
817#pragma mark Process
818
819typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
820typedef PluginInstances<ProcessInstance> ProcessInstances;
821
822static ProcessInstances &GetProcessInstances() {
823 static ProcessInstances g_instances;
824 return g_instances;
825}
826
827bool PluginManager::RegisterPlugin(
828 llvm::StringRef name, llvm::StringRef description,
829 ProcessCreateInstance create_callback,
830 DebuggerInitializeCallback debugger_init_callback) {
831 return GetProcessInstances().RegisterPlugin(
832 name, description, create_callback, debugger_init_callback);
833}
834
835bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
836 return GetProcessInstances().UnregisterPlugin(create_callback);
837}
838
839llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
840 return GetProcessInstances().GetNameAtIndex(idx);
841}
842
843llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
844 return GetProcessInstances().GetDescriptionAtIndex(idx);
845}
846
847ProcessCreateInstance
848PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
849 return GetProcessInstances().GetCallbackAtIndex(idx);
850}
851
852ProcessCreateInstance
853PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) {
854 return GetProcessInstances().GetCallbackForName(name);
855}
856
857void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
858 CompletionRequest &request) {
859 for (const auto &instance : GetProcessInstances().GetInstances()) {
860 if (instance.name.startswith(name))
861 request.AddCompletion(instance.name, instance.description);
862 }
863}
864
865#pragma mark ScriptInterpreter
866
867struct ScriptInterpreterInstance
868 : public PluginInstance<ScriptInterpreterCreateInstance> {
869 ScriptInterpreterInstance(llvm::StringRef name, llvm::StringRef description,
870 CallbackType create_callback,
871 lldb::ScriptLanguage language)
872 : PluginInstance<ScriptInterpreterCreateInstance>(name, description,
873 create_callback),
874 language(language) {}
875
876 lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
877};
878
879typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;
880
881static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
882 static ScriptInterpreterInstances g_instances;
883 return g_instances;
884}
885
886bool PluginManager::RegisterPlugin(
887 llvm::StringRef name, llvm::StringRef description,
888 lldb::ScriptLanguage script_language,
889 ScriptInterpreterCreateInstance create_callback) {
890 return GetScriptInterpreterInstances().RegisterPlugin(
891 name, description, create_callback, script_language);
892}
893
894bool PluginManager::UnregisterPlugin(
895 ScriptInterpreterCreateInstance create_callback) {
896 return GetScriptInterpreterInstances().UnregisterPlugin(create_callback);
897}
898
899ScriptInterpreterCreateInstance
900PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
901 return GetScriptInterpreterInstances().GetCallbackAtIndex(idx);
902}
903
904lldb::ScriptInterpreterSP
905PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
906 Debugger &debugger) {
907 const auto &instances = GetScriptInterpreterInstances().GetInstances();
908 ScriptInterpreterCreateInstance none_instance = nullptr;
909 for (const auto &instance : instances) {
910 if (instance.language == lldb::eScriptLanguageNone)
911 none_instance = instance.create_callback;
912
913 if (script_lang == instance.language)
914 return instance.create_callback(debugger);
915 }
916
917 // If we didn't find one, return the ScriptInterpreter for the null language.
918 assert(none_instance != nullptr);
919 return none_instance(debugger);
920}
921
922#pragma mark StructuredDataPlugin
923
924struct StructuredDataPluginInstance
925 : public PluginInstance<StructuredDataPluginCreateInstance> {
926 StructuredDataPluginInstance(
927 llvm::StringRef name, llvm::StringRef description,
928 CallbackType create_callback,
929 DebuggerInitializeCallback debugger_init_callback,
930 StructuredDataFilterLaunchInfo filter_callback)
931 : PluginInstance<StructuredDataPluginCreateInstance>(
932 name, description, create_callback, debugger_init_callback),
933 filter_callback(filter_callback) {}
934
935 StructuredDataFilterLaunchInfo filter_callback = nullptr;
936};
937
938typedef PluginInstances<StructuredDataPluginInstance>
939 StructuredDataPluginInstances;
940
941static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
942 static StructuredDataPluginInstances g_instances;
943 return g_instances;
944}
945
946bool PluginManager::RegisterPlugin(
947 llvm::StringRef name, llvm::StringRef description,
948 StructuredDataPluginCreateInstance create_callback,
949 DebuggerInitializeCallback debugger_init_callback,
950 StructuredDataFilterLaunchInfo filter_callback) {
951 return GetStructuredDataPluginInstances().RegisterPlugin(
952 name, description, create_callback, debugger_init_callback,
953 filter_callback);
954}
955
956bool PluginManager::UnregisterPlugin(
957 StructuredDataPluginCreateInstance create_callback) {
958 return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback);
959}
960
961StructuredDataPluginCreateInstance
962PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
963 return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx);
964}
965
966StructuredDataFilterLaunchInfo
967PluginManager::GetStructuredDataFilterCallbackAtIndex(
968 uint32_t idx, bool &iteration_complete) {
969 const auto &instances = GetStructuredDataPluginInstances().GetInstances();
970 if (idx < instances.size()) {
971 iteration_complete = false;
972 return instances[idx].filter_callback;
973 } else {
974 iteration_complete = true;
975 }
976 return nullptr;
977}
978
979#pragma mark SymbolFile
980
981typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
982typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;
983
984static SymbolFileInstances &GetSymbolFileInstances() {
985 static SymbolFileInstances g_instances;
986 return g_instances;
987}
988
989bool PluginManager::RegisterPlugin(
990 llvm::StringRef name, llvm::StringRef description,
991 SymbolFileCreateInstance create_callback,
992 DebuggerInitializeCallback debugger_init_callback) {
993 return GetSymbolFileInstances().RegisterPlugin(
994 name, description, create_callback, debugger_init_callback);
995}
996
997bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
998 return GetSymbolFileInstances().UnregisterPlugin(create_callback);
999}
1000
1001SymbolFileCreateInstance
1002PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1003 return GetSymbolFileInstances().GetCallbackAtIndex(idx);
1004}
1005
1006#pragma mark SymbolVendor
1007
1008typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
1009typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;
1010
1011static SymbolVendorInstances &GetSymbolVendorInstances() {
1012 static SymbolVendorInstances g_instances;
1013 return g_instances;
1014}
1015
1016bool PluginManager::RegisterPlugin(llvm::StringRef name,
1017 llvm::StringRef description,
1018 SymbolVendorCreateInstance create_callback) {
1019 return GetSymbolVendorInstances().RegisterPlugin(name, description,
1020 create_callback);
1021}
1022
1023bool PluginManager::UnregisterPlugin(
1024 SymbolVendorCreateInstance create_callback) {
1025 return GetSymbolVendorInstances().UnregisterPlugin(create_callback);
1026}
1027
1028SymbolVendorCreateInstance
1029PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1030 return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
1031}
1032
1033#pragma mark Trace
1034
1035struct TraceInstance
1036 : public PluginInstance<TraceCreateInstanceFromBundle> {
1037 TraceInstance(
1038 llvm::StringRef name, llvm::StringRef description,
1039 CallbackType create_callback_from_bundle,
1040 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1041 llvm::StringRef schema)
1042 : PluginInstance<TraceCreateInstanceFromBundle>(
1043 name, description, create_callback_from_bundle),
1044 schema(schema),
1045 create_callback_for_live_process(create_callback_for_live_process) {}
1046
1047 llvm::StringRef schema;
1048 TraceCreateInstanceForLiveProcess create_callback_for_live_process;
1049};
1050
1051typedef PluginInstances<TraceInstance> TraceInstances;
1052
1053static TraceInstances &GetTracePluginInstances() {
1054 static TraceInstances g_instances;
1055 return g_instances;
1056}
1057
1058bool PluginManager::RegisterPlugin(
1059 llvm::StringRef name, llvm::StringRef description,
1060 TraceCreateInstanceFromBundle create_callback_from_bundle,
1061 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1062 llvm::StringRef schema) {
1063 return GetTracePluginInstances().RegisterPlugin(
1064 name, description, create_callback_from_bundle,
1065 create_callback_for_live_process, schema);
1066}
1067
1068bool PluginManager::UnregisterPlugin(
1069 TraceCreateInstanceFromBundle create_callback_from_bundle) {
1070 return GetTracePluginInstances().UnregisterPlugin(
1071 create_callback_from_bundle);
1072}
1073
1074TraceCreateInstanceFromBundle
1075PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) {
1076 return GetTracePluginInstances().GetCallbackForName(plugin_name);
1077}
1078
1079TraceCreateInstanceForLiveProcess
1080PluginManager::GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name) {
1081 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1082 if (instance.name == plugin_name)
1083 return instance.create_callback_for_live_process;
1084 return nullptr;
1085}
1086
1087llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) {
1088 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1089 if (instance.name == plugin_name)
1090 return instance.schema;
1091 return llvm::StringRef();
1092}
1093
1094llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
1095 if (TraceInstance *instance =
1096 GetTracePluginInstances().GetInstanceAtIndex(index))
1097 return instance->schema;
1098 return llvm::StringRef();
1099}
1100
1101#pragma mark TraceExporter
1102
1103struct TraceExporterInstance
1104 : public PluginInstance<TraceExporterCreateInstance> {
1105 TraceExporterInstance(
1106 llvm::StringRef name, llvm::StringRef description,
1107 TraceExporterCreateInstance create_instance,
1108 ThreadTraceExportCommandCreator create_thread_trace_export_command)
1109 : PluginInstance<TraceExporterCreateInstance>(name, description,
1110 create_instance),
1111 create_thread_trace_export_command(create_thread_trace_export_command) {
1112 }
1113
1114 ThreadTraceExportCommandCreator create_thread_trace_export_command;
1115};
1116
1117typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;
1118
1119static TraceExporterInstances &GetTraceExporterInstances() {
1120 static TraceExporterInstances g_instances;
1121 return g_instances;
1122}
1123
1124bool PluginManager::RegisterPlugin(
1125 llvm::StringRef name, llvm::StringRef description,
1126 TraceExporterCreateInstance create_callback,
1127 ThreadTraceExportCommandCreator create_thread_trace_export_command) {
1128 return GetTraceExporterInstances().RegisterPlugin(
1129 name, description, create_callback, create_thread_trace_export_command);
1130}
1131
1132TraceExporterCreateInstance
1133PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) {
1134 return GetTraceExporterInstances().GetCallbackForName(plugin_name);
1135}
1136
1137bool PluginManager::UnregisterPlugin(
1138 TraceExporterCreateInstance create_callback) {
1139 return GetTraceExporterInstances().UnregisterPlugin(create_callback);
1140}
1141
1142ThreadTraceExportCommandCreator
1143PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
1144 if (TraceExporterInstance *instance =
1145 GetTraceExporterInstances().GetInstanceAtIndex(index))
1146 return instance->create_thread_trace_export_command;
1147 return nullptr;
1148}
1149
1150llvm::StringRef
1151PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
1152 return GetTraceExporterInstances().GetNameAtIndex(index);
1153}
1154
1155#pragma mark UnwindAssembly
1156
1157typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
1158typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;
1159
1160static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1161 static UnwindAssemblyInstances g_instances;
1162 return g_instances;
1163}
1164
1165bool PluginManager::RegisterPlugin(
1166 llvm::StringRef name, llvm::StringRef description,
1167 UnwindAssemblyCreateInstance create_callback) {
1168 return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
1169 create_callback);
1170}
1171
1172bool PluginManager::UnregisterPlugin(
1173 UnwindAssemblyCreateInstance create_callback) {
1174 return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback);
1175}
1176
1177UnwindAssemblyCreateInstance
1178PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1179 return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx);
1180}
1181
1182#pragma mark MemoryHistory
1183
1184typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
1185typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;
1186
1187static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1188 static MemoryHistoryInstances g_instances;
1189 return g_instances;
1190}
1191
1192bool PluginManager::RegisterPlugin(
1193 llvm::StringRef name, llvm::StringRef description,
1194 MemoryHistoryCreateInstance create_callback) {
1195 return GetMemoryHistoryInstances().RegisterPlugin(name, description,
1196 create_callback);
1197}
1198
1199bool PluginManager::UnregisterPlugin(
1200 MemoryHistoryCreateInstance create_callback) {
1201 return GetMemoryHistoryInstances().UnregisterPlugin(create_callback);
1202}
1203
1204MemoryHistoryCreateInstance
1205PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1206 return GetMemoryHistoryInstances().GetCallbackAtIndex(idx);
1207}
1208
1209#pragma mark InstrumentationRuntime
1210
1211struct InstrumentationRuntimeInstance
1212 : public PluginInstance<InstrumentationRuntimeCreateInstance> {
1213 InstrumentationRuntimeInstance(
1214 llvm::StringRef name, llvm::StringRef description,
1215 CallbackType create_callback,
1216 InstrumentationRuntimeGetType get_type_callback)
1217 : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description,
1218 create_callback),
1219 get_type_callback(get_type_callback) {}
1220
1221 InstrumentationRuntimeGetType get_type_callback = nullptr;
1222};
1223
1224typedef PluginInstances<InstrumentationRuntimeInstance>
1225 InstrumentationRuntimeInstances;
1226
1227static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1228 static InstrumentationRuntimeInstances g_instances;
1229 return g_instances;
1230}
1231
1232bool PluginManager::RegisterPlugin(
1233 llvm::StringRef name, llvm::StringRef description,
1234 InstrumentationRuntimeCreateInstance create_callback,
1235 InstrumentationRuntimeGetType get_type_callback) {
1236 return GetInstrumentationRuntimeInstances().RegisterPlugin(
1237 name, description, create_callback, get_type_callback);
1238}
1239
1240bool PluginManager::UnregisterPlugin(
1241 InstrumentationRuntimeCreateInstance create_callback) {
1242 return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback);
1243}
1244
1245InstrumentationRuntimeGetType
1246PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
1247 const auto &instances = GetInstrumentationRuntimeInstances().GetInstances();
1248 if (idx < instances.size())
1249 return instances[idx].get_type_callback;
1250 return nullptr;
1251}
1252
1253InstrumentationRuntimeCreateInstance
1254PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
1255 return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx);
1256}
1257
1258#pragma mark TypeSystem
1259
1260struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
1261 TypeSystemInstance(llvm::StringRef name, llvm::StringRef description,
1262 CallbackType create_callback,
1263 LanguageSet supported_languages_for_types,
1264 LanguageSet supported_languages_for_expressions)
1265 : PluginInstance<TypeSystemCreateInstance>(name, description,
1266 create_callback),
1267 supported_languages_for_types(supported_languages_for_types),
1268 supported_languages_for_expressions(
1269 supported_languages_for_expressions) {}
1270
1271 LanguageSet supported_languages_for_types;
1272 LanguageSet supported_languages_for_expressions;
1273};
1274
1275typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;
1276
1277static TypeSystemInstances &GetTypeSystemInstances() {
1278 static TypeSystemInstances g_instances;
1279 return g_instances;
1280}
1281
1282bool PluginManager::RegisterPlugin(
1283 llvm::StringRef name, llvm::StringRef description,
1284 TypeSystemCreateInstance create_callback,
1285 LanguageSet supported_languages_for_types,
1286 LanguageSet supported_languages_for_expressions) {
1287 return GetTypeSystemInstances().RegisterPlugin(
1288 name, description, create_callback, supported_languages_for_types,
1289 supported_languages_for_expressions);
1290}
1291
1292bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
1293 return GetTypeSystemInstances().UnregisterPlugin(create_callback);
1294}
1295
1296TypeSystemCreateInstance
1297PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
1298 return GetTypeSystemInstances().GetCallbackAtIndex(idx);
1299}
1300
1301LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
1302 const auto &instances = GetTypeSystemInstances().GetInstances();
1303 LanguageSet all;
1304 for (unsigned i = 0; i < instances.size(); ++i)
1305 all.bitvector |= instances[i].supported_languages_for_types.bitvector;
1306 return all;
1307}
1308
1309LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
1310 const auto &instances = GetTypeSystemInstances().GetInstances();
1311 LanguageSet all;
1312 for (unsigned i = 0; i < instances.size(); ++i)
1313 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
1314 return all;
1315}
1316
1317#pragma mark REPL
1318
1319struct REPLInstance : public PluginInstance<REPLCreateInstance> {
1320 REPLInstance(llvm::StringRef name, llvm::StringRef description,
1321 CallbackType create_callback, LanguageSet supported_languages)
1322 : PluginInstance<REPLCreateInstance>(name, description, create_callback),
1323 supported_languages(supported_languages) {}
1324
1325 LanguageSet supported_languages;
1326};
1327
1328typedef PluginInstances<REPLInstance> REPLInstances;
1329
1330static REPLInstances &GetREPLInstances() {
1331 static REPLInstances g_instances;
1332 return g_instances;
1333}
1334
1335bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
1336 REPLCreateInstance create_callback,
1337 LanguageSet supported_languages) {
1338 return GetREPLInstances().RegisterPlugin(name, description, create_callback,
1339 supported_languages);
1340}
1341
1342bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
1343 return GetREPLInstances().UnregisterPlugin(create_callback);
1344}
1345
1346REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
1347 return GetREPLInstances().GetCallbackAtIndex(idx);
1348}
1349
1350LanguageSet PluginManager::GetREPLSupportedLanguagesAtIndex(uint32_t idx) {
1351 const auto &instances = GetREPLInstances().GetInstances();
1352 return idx < instances.size() ? instances[idx].supported_languages
1353 : LanguageSet();
1354}
1355
1356LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
1357 const auto &instances = GetREPLInstances().GetInstances();
1358 LanguageSet all;
1359 for (unsigned i = 0; i < instances.size(); ++i)
1360 all.bitvector |= instances[i].supported_languages.bitvector;
1361 return all;
1362}
1363
1364#pragma mark PluginManager
1365
1366void PluginManager::DebuggerInitialize(Debugger &debugger) {
1367 GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
1368 GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1369 GetObjectFileInstances().PerformDebuggerCallback(debugger);
1370 GetPlatformInstances().PerformDebuggerCallback(debugger);
1371 GetProcessInstances().PerformDebuggerCallback(debugger);
1372 GetSymbolFileInstances().PerformDebuggerCallback(debugger);
1373 GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
1374 GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
1375 GetTracePluginInstances().PerformDebuggerCallback(debugger);
1376}
1377
1378// This is the preferred new way to register plugin specific settings. e.g.
1379// This will put a plugin's settings under e.g.
1380// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1381static lldb::OptionValuePropertiesSP
1382GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name,
1383 ConstString plugin_type_desc, bool can_create) {
1384 lldb::OptionValuePropertiesSP parent_properties_sp(
1385 debugger.GetValueProperties());
1386 if (parent_properties_sp) {
1387 static ConstString g_property_name("plugin");
1388
1389 OptionValuePropertiesSP plugin_properties_sp =
1390 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
1391 if (!plugin_properties_sp && can_create) {
1392 plugin_properties_sp =
1393 std::make_shared<OptionValueProperties>(g_property_name);
1394 parent_properties_sp->AppendProperty(
1395 g_property_name, ConstString("Settings specify to plugins."), true,
1396 plugin_properties_sp);
1397 }
1398
1399 if (plugin_properties_sp) {
1400 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1401 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1402 if (!plugin_type_properties_sp && can_create) {
1403 plugin_type_properties_sp =
1404 std::make_shared<OptionValueProperties>(plugin_type_name);
1405 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1406 true, plugin_type_properties_sp);
1407 }
1408 return plugin_type_properties_sp;
1409 }
1410 }
1411 return lldb::OptionValuePropertiesSP();
1412}
1413
1414// This is deprecated way to register plugin specific settings. e.g.
1415// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
1416// generic settings would be under "platform.SETTINGNAME".
1417static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
1418 Debugger &debugger, ConstString plugin_type_name,
1419 ConstString plugin_type_desc, bool can_create) {
1420 static ConstString g_property_name("plugin");
1421 lldb::OptionValuePropertiesSP parent_properties_sp(
1422 debugger.GetValueProperties());
1423 if (parent_properties_sp) {
1424 OptionValuePropertiesSP plugin_properties_sp =
1425 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1426 if (!plugin_properties_sp && can_create) {
1427 plugin_properties_sp =
1428 std::make_shared<OptionValueProperties>(plugin_type_name);
1429 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1430 true, plugin_properties_sp);
1431 }
1432
1433 if (plugin_properties_sp) {
1434 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1435 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
1436 if (!plugin_type_properties_sp && can_create) {
1437 plugin_type_properties_sp =
1438 std::make_shared<OptionValueProperties>(g_property_name);
1439 plugin_properties_sp->AppendProperty(
1440 g_property_name, ConstString("Settings specific to plugins"), true,
1441 plugin_type_properties_sp);
1442 }
1443 return plugin_type_properties_sp;
1444 }
1445 }
1446 return lldb::OptionValuePropertiesSP();
1447}
1448
1449namespace {
1450
1451typedef lldb::OptionValuePropertiesSP
1452GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString,
1453 bool can_create);
1454}
1455
1456static lldb::OptionValuePropertiesSP
1457GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
1458 ConstString plugin_type_name,
1459 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1460 GetDebuggerPropertyForPlugins) {
1461 lldb::OptionValuePropertiesSP properties_sp;
1462 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
1463 debugger, plugin_type_name,
1464 ConstString(), // not creating to so we don't need the description
1465 false));
1466 if (plugin_type_properties_sp)
1467 properties_sp =
1468 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1469 return properties_sp;
1470}
1471
1472static bool
1473CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name,
1474 ConstString plugin_type_desc,
1475 const lldb::OptionValuePropertiesSP &properties_sp,
1476 ConstString description, bool is_global_property,
1477 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1478 GetDebuggerPropertyForPlugins) {
1479 if (properties_sp) {
1480 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1481 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
1482 true));
1483 if (plugin_type_properties_sp) {
1484 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1485 description, is_global_property,
1486 properties_sp);
1487 return true;
1488 }
1489 }
1490 return false;
1491}
1492
1493static const char *kDynamicLoaderPluginName("dynamic-loader");
1494static const char *kPlatformPluginName("platform");
1495static const char *kProcessPluginName("process");
1496static const char *kObjectFilePluginName("object-file");
1497static const char *kSymbolFilePluginName("symbol-file");
1498static const char *kJITLoaderPluginName("jit-loader");
1499static const char *kStructuredDataPluginName("structured-data");
1500
1501lldb::OptionValuePropertiesSP
1502PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
1503 ConstString setting_name) {
1504 return GetSettingForPlugin(debugger, setting_name,
1505 ConstString(kDynamicLoaderPluginName));
1506}
1507
1508bool PluginManager::CreateSettingForDynamicLoaderPlugin(
1509 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1510 ConstString description, bool is_global_property) {
1511 return CreateSettingForPlugin(
1512 debugger, ConstString(kDynamicLoaderPluginName),
1513 ConstString("Settings for dynamic loader plug-ins"), properties_sp,
1514 description, is_global_property);
1515}
1516
1517lldb::OptionValuePropertiesSP
1518PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
1519 ConstString setting_name) {
1520 return GetSettingForPlugin(debugger, setting_name,
1521 ConstString(kPlatformPluginName),
1522 GetDebuggerPropertyForPluginsOldStyle);
1523}
1524
1525bool PluginManager::CreateSettingForPlatformPlugin(
1526 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1527 ConstString description, bool is_global_property) {
1528 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
1529 ConstString("Settings for platform plug-ins"),
1530 properties_sp, description, is_global_property,
1531 GetDebuggerPropertyForPluginsOldStyle);
1532}
1533
1534lldb::OptionValuePropertiesSP
1535PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
1536 ConstString setting_name) {
1537 return GetSettingForPlugin(debugger, setting_name,
1538 ConstString(kProcessPluginName));
1539}
1540
1541bool PluginManager::CreateSettingForProcessPlugin(
1542 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1543 ConstString description, bool is_global_property) {
1544 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
1545 ConstString("Settings for process plug-ins"),
1546 properties_sp, description, is_global_property);
1547}
1548
1549lldb::OptionValuePropertiesSP
1550PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger,
1551 ConstString setting_name) {
1552 return GetSettingForPlugin(debugger, setting_name,
1553 ConstString(kObjectFilePluginName));
1554}
1555
1556bool PluginManager::CreateSettingForObjectFilePlugin(
1557 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1558 ConstString description, bool is_global_property) {
1559 return CreateSettingForPlugin(
1560 debugger, ConstString(kObjectFilePluginName),
1561 ConstString("Settings for object file plug-ins"), properties_sp,
1562 description, is_global_property);
1563}
1564
1565lldb::OptionValuePropertiesSP
1566PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
1567 ConstString setting_name) {
1568 return GetSettingForPlugin(debugger, setting_name,
1569 ConstString(kSymbolFilePluginName));
1570}
1571
1572bool PluginManager::CreateSettingForSymbolFilePlugin(
1573 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1574 ConstString description, bool is_global_property) {
1575 return CreateSettingForPlugin(
1576 debugger, ConstString(kSymbolFilePluginName),
1577 ConstString("Settings for symbol file plug-ins"), properties_sp,
1578 description, is_global_property);
1579}
1580
1581lldb::OptionValuePropertiesSP
1582PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
1583 ConstString setting_name) {
1584 return GetSettingForPlugin(debugger, setting_name,
1585 ConstString(kJITLoaderPluginName));
1586}
1587
1588bool PluginManager::CreateSettingForJITLoaderPlugin(
1589 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1590 ConstString description, bool is_global_property) {
1591 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
1592 ConstString("Settings for JIT loader plug-ins"),
1593 properties_sp, description, is_global_property);
1594}
1595
1596static const char *kOperatingSystemPluginName("os");
1597
1598lldb::OptionValuePropertiesSP
1599PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger,
1600 ConstString setting_name) {
1601 lldb::OptionValuePropertiesSP properties_sp;
1602 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1603 GetDebuggerPropertyForPlugins(
1604 debugger, ConstString(kOperatingSystemPluginName),
1605 ConstString(), // not creating to so we don't need the description
1606 false));
1607 if (plugin_type_properties_sp)
1608 properties_sp =
1609 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1610 return properties_sp;
1611}
1612
1613bool PluginManager::CreateSettingForOperatingSystemPlugin(
1614 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1615 ConstString description, bool is_global_property) {
1616 if (properties_sp) {
1617 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1618 GetDebuggerPropertyForPlugins(
1619 debugger, ConstString(kOperatingSystemPluginName),
1620 ConstString("Settings for operating system plug-ins"), true));
1621 if (plugin_type_properties_sp) {
1622 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1623 description, is_global_property,
1624 properties_sp);
1625 return true;
1626 }
1627 }
1628 return false;
1629}
1630
1631lldb::OptionValuePropertiesSP
1632PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
1633 ConstString setting_name) {
1634 return GetSettingForPlugin(debugger, setting_name,
1635 ConstString(kStructuredDataPluginName));
1636}
1637
1638bool PluginManager::CreateSettingForStructuredDataPlugin(
1639 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1640 ConstString description, bool is_global_property) {
1641 return CreateSettingForPlugin(
1642 debugger, ConstString(kStructuredDataPluginName),
1643 ConstString("Settings for structured data plug-ins"), properties_sp,
1644 description, is_global_property);
1645}
1646

source code of lldb/source/Core/PluginManager.cpp