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/Utility/ConstString.h"
16#include "lldb/Utility/FileSpec.h"
17#include "lldb/Utility/Status.h"
18#include "lldb/Utility/StringList.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/DynamicLibrary.h"
21#include "llvm/Support/FileSystem.h"
22#include "llvm/Support/raw_ostream.h"
23#include <assert.h>
24#include <map>
25#include <memory>
26#include <mutex>
27#include <string>
28#include <utility>
29#include <vector>
30#if defined(_WIN32)
31#include "lldb/Host/windows/PosixApi.h"
32#endif
33
34using namespace lldb;
35using namespace lldb_private;
36
37typedef bool (*PluginInitCallback)();
38typedef void (*PluginTermCallback)();
39
40struct PluginInfo {
41 PluginInfo() : plugin_init_callback(nullptr), plugin_term_callback(nullptr) {}
42
43 llvm::sys::DynamicLibrary library;
44 PluginInitCallback plugin_init_callback;
45 PluginTermCallback plugin_term_callback;
46};
47
48typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
49
50static std::recursive_mutex &GetPluginMapMutex() {
51 static std::recursive_mutex g_plugin_map_mutex;
52 return g_plugin_map_mutex;
53}
54
55static PluginTerminateMap &GetPluginMap() {
56 static PluginTerminateMap g_plugin_map;
57 return g_plugin_map;
58}
59
60static bool PluginIsLoaded(const FileSpec &plugin_file_spec) {
61 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
62 PluginTerminateMap &plugin_map = GetPluginMap();
63 return plugin_map.find(plugin_file_spec) != plugin_map.end();
64}
65
66static void SetPluginInfo(const FileSpec &plugin_file_spec,
67 const PluginInfo &plugin_info) {
68 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
69 PluginTerminateMap &plugin_map = GetPluginMap();
70 assert(plugin_map.find(plugin_file_spec) == plugin_map.end());
71 plugin_map[plugin_file_spec] = plugin_info;
72}
73
74template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
75 return reinterpret_cast<FPtrTy>(VPtr);
76}
77
78static FileSystem::EnumerateDirectoryResult
79LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
80 llvm::StringRef path) {
81 Status error;
82
83 namespace fs = llvm::sys::fs;
84 // If we have a regular file, a symbolic link or unknown file type, try and
85 // process the file. We must handle unknown as sometimes the directory
86 // enumeration might be enumerating a file system that doesn't have correct
87 // file type information.
88 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
89 ft == fs::file_type::type_unknown) {
90 FileSpec plugin_file_spec(path);
91 FileSystem::Instance().Resolve(plugin_file_spec);
92
93 if (PluginIsLoaded(plugin_file_spec))
94 return FileSystem::eEnumerateDirectoryResultNext;
95 else {
96 PluginInfo plugin_info;
97
98 std::string pluginLoadError;
99 plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary(
100 plugin_file_spec.GetPath().c_str(), &pluginLoadError);
101 if (plugin_info.library.isValid()) {
102 bool success = false;
103 plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>(
104 plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
105 if (plugin_info.plugin_init_callback) {
106 // Call the plug-in "bool LLDBPluginInitialize(void)" function
107 success = plugin_info.plugin_init_callback();
108 }
109
110 if (success) {
111 // It is ok for the "LLDBPluginTerminate" symbol to be nullptr
112 plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>(
113 plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
114 } else {
115 // The initialize function returned FALSE which means the plug-in
116 // might not be compatible, or might be too new or too old, or might
117 // not want to run on this machine. Set it to a default-constructed
118 // instance to invalidate it.
119 plugin_info = PluginInfo();
120 }
121
122 // Regardless of success or failure, cache the plug-in load in our
123 // plug-in info so we don't try to load it again and again.
124 SetPluginInfo(plugin_file_spec, plugin_info);
125
126 return FileSystem::eEnumerateDirectoryResultNext;
127 }
128 }
129 }
130
131 if (ft == fs::file_type::directory_file ||
132 ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
133 // Try and recurse into anything that a directory or symbolic link. We must
134 // also do this for unknown as sometimes the directory enumeration might be
135 // enumerating a file system that doesn't have correct file type
136 // information.
137 return FileSystem::eEnumerateDirectoryResultEnter;
138 }
139
140 return FileSystem::eEnumerateDirectoryResultNext;
141}
142
143void PluginManager::Initialize() {
144 const bool find_directories = true;
145 const bool find_files = true;
146 const bool find_other = true;
147 char dir_path[PATH_MAX];
148 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
149 if (FileSystem::Instance().Exists(dir_spec) &&
150 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
151 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
152 find_files, find_other,
153 LoadPluginCallback, nullptr);
154 }
155 }
156
157 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
158 if (FileSystem::Instance().Exists(dir_spec) &&
159 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
160 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
161 find_files, find_other,
162 LoadPluginCallback, nullptr);
163 }
164 }
165}
166
167void PluginManager::Terminate() {
168 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
169 PluginTerminateMap &plugin_map = GetPluginMap();
170
171 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
172 for (pos = plugin_map.begin(); pos != end; ++pos) {
173 // Call the plug-in "void LLDBPluginTerminate (void)" function if there is
174 // one (if the symbol was not nullptr).
175 if (pos->second.library.isValid()) {
176 if (pos->second.plugin_term_callback)
177 pos->second.plugin_term_callback();
178 }
179 }
180 plugin_map.clear();
181}
182
183template <typename Callback> struct PluginInstance {
184 typedef Callback CallbackType;
185
186 PluginInstance() = default;
187 PluginInstance(ConstString name, std::string description,
188 Callback create_callback = nullptr,
189 DebuggerInitializeCallback debugger_init_callback = nullptr)
190 : name(name), description(std::move(description)),
191 create_callback(create_callback),
192 debugger_init_callback(debugger_init_callback) {}
193
194 ConstString name;
195 std::string 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(ConstString name, const char *description,
204 typename Instance::CallbackType callback,
205 Args &&... args) {
206 if (!callback)
207 return false;
208 assert((bool)name);
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 const char *GetDescriptionAtIndex(uint32_t idx) {
236 if (Instance *instance = GetInstanceAtIndex(idx))
237 return instance->description.c_str();
238 return nullptr;
239 }
240
241 const char *GetNameAtIndex(uint32_t idx) {
242 if (Instance *instance = GetInstanceAtIndex(idx))
243 return instance->name.GetCString();
244 return nullptr;
245 }
246
247 typename Instance::CallbackType GetCallbackForName(ConstString name) {
248 if (!name)
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(ConstString name, const char *description,
288 ABICreateInstance create_callback) {
289 return GetABIInstances().RegisterPlugin(name, description, create_callback);
290}
291
292bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
293 return GetABIInstances().UnregisterPlugin(create_callback);
294}
295
296ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
297 return GetABIInstances().GetCallbackAtIndex(idx);
298}
299
300#pragma mark Architecture
301
302typedef PluginInstance<ArchitectureCreateInstance> ArchitectureInstance;
303typedef std::vector<ArchitectureInstance> ArchitectureInstances;
304
305static ArchitectureInstances &GetArchitectureInstances() {
306 static ArchitectureInstances g_instances;
307 return g_instances;
308}
309
310void PluginManager::RegisterPlugin(ConstString name,
311 llvm::StringRef description,
312 ArchitectureCreateInstance create_callback) {
313 GetArchitectureInstances().push_back(
314 {name, std::string(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(ConstString name, const char *description,
350 DisassemblerCreateInstance create_callback) {
351 return GetDisassemblerInstances().RegisterPlugin(name, description,
352 create_callback);
353}
354
355bool PluginManager::UnregisterPlugin(
356 DisassemblerCreateInstance create_callback) {
357 return GetDisassemblerInstances().UnregisterPlugin(create_callback);
358}
359
360DisassemblerCreateInstance
361PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
362 return GetDisassemblerInstances().GetCallbackAtIndex(idx);
363}
364
365DisassemblerCreateInstance
366PluginManager::GetDisassemblerCreateCallbackForPluginName(ConstString name) {
367 return GetDisassemblerInstances().GetCallbackForName(name);
368}
369
370#pragma mark DynamicLoader
371
372typedef PluginInstance<DynamicLoaderCreateInstance> DynamicLoaderInstance;
373typedef PluginInstances<DynamicLoaderInstance> DynamicLoaderInstances;
374
375static DynamicLoaderInstances &GetDynamicLoaderInstances() {
376 static DynamicLoaderInstances g_instances;
377 return g_instances;
378}
379
380bool PluginManager::RegisterPlugin(
381 ConstString name, const char *description,
382 DynamicLoaderCreateInstance create_callback,
383 DebuggerInitializeCallback debugger_init_callback) {
384 return GetDynamicLoaderInstances().RegisterPlugin(
385 name, description, create_callback, debugger_init_callback);
386}
387
388bool PluginManager::UnregisterPlugin(
389 DynamicLoaderCreateInstance create_callback) {
390 return GetDynamicLoaderInstances().UnregisterPlugin(create_callback);
391}
392
393DynamicLoaderCreateInstance
394PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
395 return GetDynamicLoaderInstances().GetCallbackAtIndex(idx);
396}
397
398DynamicLoaderCreateInstance
399PluginManager::GetDynamicLoaderCreateCallbackForPluginName(ConstString name) {
400 return GetDynamicLoaderInstances().GetCallbackForName(name);
401}
402
403#pragma mark JITLoader
404
405typedef PluginInstance<JITLoaderCreateInstance> JITLoaderInstance;
406typedef PluginInstances<JITLoaderInstance> JITLoaderInstances;
407
408static JITLoaderInstances &GetJITLoaderInstances() {
409 static JITLoaderInstances g_instances;
410 return g_instances;
411}
412
413bool PluginManager::RegisterPlugin(
414 ConstString name, const char *description,
415 JITLoaderCreateInstance create_callback,
416 DebuggerInitializeCallback debugger_init_callback) {
417 return GetJITLoaderInstances().RegisterPlugin(
418 name, description, create_callback, debugger_init_callback);
419}
420
421bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
422 return GetJITLoaderInstances().UnregisterPlugin(create_callback);
423}
424
425JITLoaderCreateInstance
426PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
427 return GetJITLoaderInstances().GetCallbackAtIndex(idx);
428}
429
430#pragma mark EmulateInstruction
431
432typedef PluginInstance<EmulateInstructionCreateInstance>
433 EmulateInstructionInstance;
434typedef PluginInstances<EmulateInstructionInstance> EmulateInstructionInstances;
435
436static EmulateInstructionInstances &GetEmulateInstructionInstances() {
437 static EmulateInstructionInstances g_instances;
438 return g_instances;
439}
440
441bool PluginManager::RegisterPlugin(
442 ConstString name, const char *description,
443 EmulateInstructionCreateInstance create_callback) {
444 return GetEmulateInstructionInstances().RegisterPlugin(name, description,
445 create_callback);
446}
447
448bool PluginManager::UnregisterPlugin(
449 EmulateInstructionCreateInstance create_callback) {
450 return GetEmulateInstructionInstances().UnregisterPlugin(create_callback);
451}
452
453EmulateInstructionCreateInstance
454PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
455 return GetEmulateInstructionInstances().GetCallbackAtIndex(idx);
456}
457
458EmulateInstructionCreateInstance
459PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
460 ConstString name) {
461 return GetEmulateInstructionInstances().GetCallbackForName(name);
462}
463
464#pragma mark OperatingSystem
465
466typedef PluginInstance<OperatingSystemCreateInstance> OperatingSystemInstance;
467typedef PluginInstances<OperatingSystemInstance> OperatingSystemInstances;
468
469static OperatingSystemInstances &GetOperatingSystemInstances() {
470 static OperatingSystemInstances g_instances;
471 return g_instances;
472}
473
474bool PluginManager::RegisterPlugin(
475 ConstString name, const char *description,
476 OperatingSystemCreateInstance create_callback,
477 DebuggerInitializeCallback debugger_init_callback) {
478 return GetOperatingSystemInstances().RegisterPlugin(
479 name, description, create_callback, debugger_init_callback);
480}
481
482bool PluginManager::UnregisterPlugin(
483 OperatingSystemCreateInstance create_callback) {
484 return GetOperatingSystemInstances().UnregisterPlugin(create_callback);
485}
486
487OperatingSystemCreateInstance
488PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
489 return GetOperatingSystemInstances().GetCallbackAtIndex(idx);
490}
491
492OperatingSystemCreateInstance
493PluginManager::GetOperatingSystemCreateCallbackForPluginName(ConstString name) {
494 return GetOperatingSystemInstances().GetCallbackForName(name);
495}
496
497#pragma mark Language
498
499typedef PluginInstance<LanguageCreateInstance> LanguageInstance;
500typedef PluginInstances<LanguageInstance> LanguageInstances;
501
502static LanguageInstances &GetLanguageInstances() {
503 static LanguageInstances g_instances;
504 return g_instances;
505}
506
507bool PluginManager::RegisterPlugin(ConstString name, const char *description,
508 LanguageCreateInstance create_callback) {
509 return GetLanguageInstances().RegisterPlugin(name, description,
510 create_callback);
511}
512
513bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
514 return GetLanguageInstances().UnregisterPlugin(create_callback);
515}
516
517LanguageCreateInstance
518PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
519 return GetLanguageInstances().GetCallbackAtIndex(idx);
520}
521
522#pragma mark LanguageRuntime
523
524struct LanguageRuntimeInstance
525 : public PluginInstance<LanguageRuntimeCreateInstance> {
526 LanguageRuntimeInstance(
527 ConstString name, std::string description, CallbackType create_callback,
528 DebuggerInitializeCallback debugger_init_callback,
529 LanguageRuntimeGetCommandObject command_callback,
530 LanguageRuntimeGetExceptionPrecondition precondition_callback)
531 : PluginInstance<LanguageRuntimeCreateInstance>(
532 name, std::move(description), create_callback,
533 debugger_init_callback),
534 command_callback(command_callback),
535 precondition_callback(precondition_callback) {}
536
537 LanguageRuntimeGetCommandObject command_callback;
538 LanguageRuntimeGetExceptionPrecondition precondition_callback;
539};
540
541typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances;
542
543static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
544 static LanguageRuntimeInstances g_instances;
545 return g_instances;
546}
547
548bool PluginManager::RegisterPlugin(
549 ConstString name, const char *description,
550 LanguageRuntimeCreateInstance create_callback,
551 LanguageRuntimeGetCommandObject command_callback,
552 LanguageRuntimeGetExceptionPrecondition precondition_callback) {
553 return GetLanguageRuntimeInstances().RegisterPlugin(
554 name, description, create_callback, nullptr, command_callback,
555 precondition_callback);
556}
557
558bool PluginManager::UnregisterPlugin(
559 LanguageRuntimeCreateInstance create_callback) {
560 return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback);
561}
562
563LanguageRuntimeCreateInstance
564PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
565 return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx);
566}
567
568LanguageRuntimeGetCommandObject
569PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
570 const auto &instances = GetLanguageRuntimeInstances().GetInstances();
571 if (idx < instances.size())
572 return instances[idx].command_callback;
573 return nullptr;
574}
575
576LanguageRuntimeGetExceptionPrecondition
577PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
578 const auto &instances = GetLanguageRuntimeInstances().GetInstances();
579 if (idx < instances.size())
580 return instances[idx].precondition_callback;
581 return nullptr;
582}
583
584#pragma mark SystemRuntime
585
586typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance;
587typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances;
588
589static SystemRuntimeInstances &GetSystemRuntimeInstances() {
590 static SystemRuntimeInstances g_instances;
591 return g_instances;
592}
593
594bool PluginManager::RegisterPlugin(
595 ConstString name, const char *description,
596 SystemRuntimeCreateInstance create_callback) {
597 return GetSystemRuntimeInstances().RegisterPlugin(name, description,
598 create_callback);
599}
600
601bool PluginManager::UnregisterPlugin(
602 SystemRuntimeCreateInstance create_callback) {
603 return GetSystemRuntimeInstances().UnregisterPlugin(create_callback);
604}
605
606SystemRuntimeCreateInstance
607PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
608 return GetSystemRuntimeInstances().GetCallbackAtIndex(idx);
609}
610
611#pragma mark ObjectFile
612
613struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> {
614 ObjectFileInstance(
615 ConstString name, std::string description, CallbackType create_callback,
616 ObjectFileCreateMemoryInstance create_memory_callback,
617 ObjectFileGetModuleSpecifications get_module_specifications,
618 ObjectFileSaveCore save_core)
619 : PluginInstance<ObjectFileCreateInstance>(name, std::move(description),
620 create_callback),
621 create_memory_callback(create_memory_callback),
622 get_module_specifications(get_module_specifications),
623 save_core(save_core) {}
624
625 ObjectFileCreateMemoryInstance create_memory_callback;
626 ObjectFileGetModuleSpecifications get_module_specifications;
627 ObjectFileSaveCore save_core;
628};
629typedef PluginInstances<ObjectFileInstance> ObjectFileInstances;
630
631static ObjectFileInstances &GetObjectFileInstances() {
632 static ObjectFileInstances g_instances;
633 return g_instances;
634}
635
636bool PluginManager::RegisterPlugin(
637 ConstString name, const char *description,
638 ObjectFileCreateInstance create_callback,
639 ObjectFileCreateMemoryInstance create_memory_callback,
640 ObjectFileGetModuleSpecifications get_module_specifications,
641 ObjectFileSaveCore save_core) {
642 return GetObjectFileInstances().RegisterPlugin(
643 name, description, create_callback, create_memory_callback,
644 get_module_specifications, save_core);
645}
646
647bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
648 return GetObjectFileInstances().UnregisterPlugin(create_callback);
649}
650
651ObjectFileCreateInstance
652PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
653 return GetObjectFileInstances().GetCallbackAtIndex(idx);
654}
655
656ObjectFileCreateMemoryInstance
657PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
658 const auto &instances = GetObjectFileInstances().GetInstances();
659 if (idx < instances.size())
660 return instances[idx].create_memory_callback;
661 return nullptr;
662}
663
664ObjectFileGetModuleSpecifications
665PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
666 uint32_t idx) {
667 const auto &instances = GetObjectFileInstances().GetInstances();
668 if (idx < instances.size())
669 return instances[idx].get_module_specifications;
670 return nullptr;
671}
672
673ObjectFileCreateMemoryInstance
674PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
675 ConstString name) {
676 if (!name)
677 return nullptr;
678 const auto &instances = GetObjectFileInstances().GetInstances();
679 for (auto &instance : instances) {
680 if (instance.name == name)
681 return instance.create_memory_callback;
682 }
683 return nullptr;
684}
685
686Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
687 const FileSpec &outfile) {
688 Status error;
689 auto &instances = GetObjectFileInstances().GetInstances();
690 for (auto &instance : instances) {
691 if (instance.save_core && instance.save_core(process_sp, outfile, error))
692 return error;
693 }
694 error.SetErrorString(
695 "no ObjectFile plugins were able to save a core for this process");
696 return error;
697}
698
699#pragma mark ObjectContainer
700
701struct ObjectContainerInstance
702 : public PluginInstance<ObjectContainerCreateInstance> {
703 ObjectContainerInstance(
704 ConstString name, std::string description, CallbackType create_callback,
705 ObjectFileGetModuleSpecifications get_module_specifications)
706 : PluginInstance<ObjectContainerCreateInstance>(
707 name, std::move(description), create_callback),
708 get_module_specifications(get_module_specifications) {}
709
710 ObjectFileGetModuleSpecifications get_module_specifications;
711};
712typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;
713
714static ObjectContainerInstances &GetObjectContainerInstances() {
715 static ObjectContainerInstances g_instances;
716 return g_instances;
717}
718
719bool PluginManager::RegisterPlugin(
720 ConstString name, const char *description,
721 ObjectContainerCreateInstance create_callback,
722 ObjectFileGetModuleSpecifications get_module_specifications) {
723 return GetObjectContainerInstances().RegisterPlugin(
724 name, description, create_callback, get_module_specifications);
725}
726
727bool PluginManager::UnregisterPlugin(
728 ObjectContainerCreateInstance create_callback) {
729 return GetObjectContainerInstances().UnregisterPlugin(create_callback);
730}
731
732ObjectContainerCreateInstance
733PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
734 return GetObjectContainerInstances().GetCallbackAtIndex(idx);
735}
736
737ObjectFileGetModuleSpecifications
738PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
739 uint32_t idx) {
740 const auto &instances = GetObjectContainerInstances().GetInstances();
741 if (idx < instances.size())
742 return instances[idx].get_module_specifications;
743 return nullptr;
744}
745
746#pragma mark Platform
747
748typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
749typedef PluginInstances<PlatformInstance> PlatformInstances;
750
751static PlatformInstances &GetPlatformInstances() {
752 static PlatformInstances g_platform_instances;
753 return g_platform_instances;
754}
755
756bool PluginManager::RegisterPlugin(
757 ConstString name, const char *description,
758 PlatformCreateInstance create_callback,
759 DebuggerInitializeCallback debugger_init_callback) {
760 return GetPlatformInstances().RegisterPlugin(
761 name, description, create_callback, debugger_init_callback);
762}
763
764bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
765 return GetPlatformInstances().UnregisterPlugin(create_callback);
766}
767
768const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
769 return GetPlatformInstances().GetNameAtIndex(idx);
770}
771
772const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
773 return GetPlatformInstances().GetDescriptionAtIndex(idx);
774}
775
776PlatformCreateInstance
777PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
778 return GetPlatformInstances().GetCallbackAtIndex(idx);
779}
780
781PlatformCreateInstance
782PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) {
783 return GetPlatformInstances().GetCallbackForName(name);
784}
785
786void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
787 CompletionRequest &request) {
788 for (const auto &instance : GetPlatformInstances().GetInstances()) {
789 if (instance.name.GetStringRef().startswith(name))
790 request.AddCompletion(instance.name.GetCString());
791 }
792}
793
794#pragma mark Process
795
796typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
797typedef PluginInstances<ProcessInstance> ProcessInstances;
798
799static ProcessInstances &GetProcessInstances() {
800 static ProcessInstances g_instances;
801 return g_instances;
802}
803
804bool PluginManager::RegisterPlugin(
805 ConstString name, const char *description,
806 ProcessCreateInstance create_callback,
807 DebuggerInitializeCallback debugger_init_callback) {
808 return GetProcessInstances().RegisterPlugin(
809 name, description, create_callback, debugger_init_callback);
810}
811
812bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
813 return GetProcessInstances().UnregisterPlugin(create_callback);
814}
815
816const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
817 return GetProcessInstances().GetNameAtIndex(idx);
818}
819
820const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
821 return GetProcessInstances().GetDescriptionAtIndex(idx);
822}
823
824ProcessCreateInstance
825PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
826 return GetProcessInstances().GetCallbackAtIndex(idx);
827}
828
829ProcessCreateInstance
830PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) {
831 return GetProcessInstances().GetCallbackForName(name);
832}
833
834void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
835 CompletionRequest &request) {
836 for (const auto &instance : GetProcessInstances().GetInstances()) {
837 if (instance.name.GetStringRef().startswith(name))
838 request.AddCompletion(instance.name.GetCString(), instance.description);
839 }
840}
841
842#pragma mark ScriptInterpreter
843
844struct ScriptInterpreterInstance
845 : public PluginInstance<ScriptInterpreterCreateInstance> {
846 ScriptInterpreterInstance(ConstString name, std::string description,
847 CallbackType create_callback,
848 lldb::ScriptLanguage language)
849 : PluginInstance<ScriptInterpreterCreateInstance>(
850 name, std::move(description), create_callback),
851 language(language) {}
852
853 lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
854};
855
856typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;
857
858static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
859 static ScriptInterpreterInstances g_instances;
860 return g_instances;
861}
862
863bool PluginManager::RegisterPlugin(
864 ConstString name, const char *description,
865 lldb::ScriptLanguage script_language,
866 ScriptInterpreterCreateInstance create_callback) {
867 return GetScriptInterpreterInstances().RegisterPlugin(
868 name, description, create_callback, script_language);
869}
870
871bool PluginManager::UnregisterPlugin(
872 ScriptInterpreterCreateInstance create_callback) {
873 return GetScriptInterpreterInstances().UnregisterPlugin(create_callback);
874}
875
876ScriptInterpreterCreateInstance
877PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
878 return GetScriptInterpreterInstances().GetCallbackAtIndex(idx);
879}
880
881lldb::ScriptInterpreterSP
882PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
883 Debugger &debugger) {
884 const auto &instances = GetScriptInterpreterInstances().GetInstances();
885 ScriptInterpreterCreateInstance none_instance = nullptr;
886 for (const auto &instance : instances) {
887 if (instance.language == lldb::eScriptLanguageNone)
888 none_instance = instance.create_callback;
889
890 if (script_lang == instance.language)
891 return instance.create_callback(debugger);
892 }
893
894 // If we didn't find one, return the ScriptInterpreter for the null language.
895 assert(none_instance != nullptr);
896 return none_instance(debugger);
897}
898
899#pragma mark StructuredDataPlugin
900
901struct StructuredDataPluginInstance
902 : public PluginInstance<StructuredDataPluginCreateInstance> {
903 StructuredDataPluginInstance(
904 ConstString name, std::string description, CallbackType create_callback,
905 DebuggerInitializeCallback debugger_init_callback,
906 StructuredDataFilterLaunchInfo filter_callback)
907 : PluginInstance<StructuredDataPluginCreateInstance>(
908 name, std::move(description), create_callback,
909 debugger_init_callback),
910 filter_callback(filter_callback) {}
911
912 StructuredDataFilterLaunchInfo filter_callback = nullptr;
913};
914
915typedef PluginInstances<StructuredDataPluginInstance>
916 StructuredDataPluginInstances;
917
918static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
919 static StructuredDataPluginInstances g_instances;
920 return g_instances;
921}
922
923bool PluginManager::RegisterPlugin(
924 ConstString name, const char *description,
925 StructuredDataPluginCreateInstance create_callback,
926 DebuggerInitializeCallback debugger_init_callback,
927 StructuredDataFilterLaunchInfo filter_callback) {
928 return GetStructuredDataPluginInstances().RegisterPlugin(
929 name, description, create_callback, debugger_init_callback,
930 filter_callback);
931}
932
933bool PluginManager::UnregisterPlugin(
934 StructuredDataPluginCreateInstance create_callback) {
935 return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback);
936}
937
938StructuredDataPluginCreateInstance
939PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
940 return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx);
941}
942
943StructuredDataFilterLaunchInfo
944PluginManager::GetStructuredDataFilterCallbackAtIndex(
945 uint32_t idx, bool &iteration_complete) {
946 const auto &instances = GetStructuredDataPluginInstances().GetInstances();
947 if (idx < instances.size()) {
948 iteration_complete = false;
949 return instances[idx].filter_callback;
950 } else {
951 iteration_complete = true;
952 }
953 return nullptr;
954}
955
956#pragma mark SymbolFile
957
958typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
959typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;
960
961static SymbolFileInstances &GetSymbolFileInstances() {
962 static SymbolFileInstances g_instances;
963 return g_instances;
964}
965
966bool PluginManager::RegisterPlugin(
967 ConstString name, const char *description,
968 SymbolFileCreateInstance create_callback,
969 DebuggerInitializeCallback debugger_init_callback) {
970 return GetSymbolFileInstances().RegisterPlugin(
971 name, description, create_callback, debugger_init_callback);
972}
973
974bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
975 return GetSymbolFileInstances().UnregisterPlugin(create_callback);
976}
977
978SymbolFileCreateInstance
979PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
980 return GetSymbolFileInstances().GetCallbackAtIndex(idx);
981}
982
983#pragma mark SymbolVendor
984
985typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
986typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;
987
988static SymbolVendorInstances &GetSymbolVendorInstances() {
989 static SymbolVendorInstances g_instances;
990 return g_instances;
991}
992
993bool PluginManager::RegisterPlugin(ConstString name, const char *description,
994 SymbolVendorCreateInstance create_callback) {
995 return GetSymbolVendorInstances().RegisterPlugin(name, description,
996 create_callback);
997}
998
999bool PluginManager::UnregisterPlugin(
1000 SymbolVendorCreateInstance create_callback) {
1001 return GetSymbolVendorInstances().UnregisterPlugin(create_callback);
1002}
1003
1004SymbolVendorCreateInstance
1005PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1006 return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
1007}
1008
1009#pragma mark Trace
1010
1011struct TraceInstance
1012 : public PluginInstance<TraceCreateInstanceForSessionFile> {
1013 TraceInstance(
1014 ConstString name, std::string description,
1015 CallbackType create_callback_for_session_file,
1016 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1017 llvm::StringRef schema)
1018 : PluginInstance<TraceCreateInstanceForSessionFile>(
1019 name, std::move(description), create_callback_for_session_file),
1020 schema(schema),
1021 create_callback_for_live_process(create_callback_for_live_process) {}
1022
1023 llvm::StringRef schema;
1024 TraceCreateInstanceForLiveProcess create_callback_for_live_process;
1025};
1026
1027typedef PluginInstances<TraceInstance> TraceInstances;
1028
1029static TraceInstances &GetTracePluginInstances() {
1030 static TraceInstances g_instances;
1031 return g_instances;
1032}
1033
1034bool PluginManager::RegisterPlugin(
1035 ConstString name, const char *description,
1036 TraceCreateInstanceForSessionFile create_callback_for_session_file,
1037 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1038 llvm::StringRef schema) {
1039 return GetTracePluginInstances().RegisterPlugin(
1040 name, description, create_callback_for_session_file,
1041 create_callback_for_live_process, schema);
1042}
1043
1044bool PluginManager::UnregisterPlugin(
1045 TraceCreateInstanceForSessionFile create_callback_for_session_file) {
1046 return GetTracePluginInstances().UnregisterPlugin(
1047 create_callback_for_session_file);
1048}
1049
1050TraceCreateInstanceForSessionFile
1051PluginManager::GetTraceCreateCallback(ConstString plugin_name) {
1052 return GetTracePluginInstances().GetCallbackForName(plugin_name);
1053}
1054
1055TraceCreateInstanceForLiveProcess
1056PluginManager::GetTraceCreateCallbackForLiveProcess(ConstString plugin_name) {
1057 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1058 if (instance.name == plugin_name)
1059 return instance.create_callback_for_live_process;
1060 return nullptr;
1061}
1062
1063llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) {
1064 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1065 if (instance.name == plugin_name)
1066 return instance.schema;
1067 return llvm::StringRef();
1068}
1069
1070llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
1071 if (TraceInstance *instance =
1072 GetTracePluginInstances().GetInstanceAtIndex(index))
1073 return instance->schema;
1074 return llvm::StringRef();
1075}
1076
1077#pragma mark UnwindAssembly
1078
1079typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
1080typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;
1081
1082static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1083 static UnwindAssemblyInstances g_instances;
1084 return g_instances;
1085}
1086
1087bool PluginManager::RegisterPlugin(
1088 ConstString name, const char *description,
1089 UnwindAssemblyCreateInstance create_callback) {
1090 return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
1091 create_callback);
1092}
1093
1094bool PluginManager::UnregisterPlugin(
1095 UnwindAssemblyCreateInstance create_callback) {
1096 return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback);
1097}
1098
1099UnwindAssemblyCreateInstance
1100PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1101 return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx);
1102}
1103
1104#pragma mark MemoryHistory
1105
1106typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
1107typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;
1108
1109static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1110 static MemoryHistoryInstances g_instances;
1111 return g_instances;
1112}
1113
1114bool PluginManager::RegisterPlugin(
1115 ConstString name, const char *description,
1116 MemoryHistoryCreateInstance create_callback) {
1117 return GetMemoryHistoryInstances().RegisterPlugin(name, description,
1118 create_callback);
1119}
1120
1121bool PluginManager::UnregisterPlugin(
1122 MemoryHistoryCreateInstance create_callback) {
1123 return GetMemoryHistoryInstances().UnregisterPlugin(create_callback);
1124}
1125
1126MemoryHistoryCreateInstance
1127PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1128 return GetMemoryHistoryInstances().GetCallbackAtIndex(idx);
1129}
1130
1131#pragma mark InstrumentationRuntime
1132
1133struct InstrumentationRuntimeInstance
1134 : public PluginInstance<InstrumentationRuntimeCreateInstance> {
1135 InstrumentationRuntimeInstance(
1136 ConstString name, std::string description, CallbackType create_callback,
1137 InstrumentationRuntimeGetType get_type_callback)
1138 : PluginInstance<InstrumentationRuntimeCreateInstance>(
1139 name, std::move(description), create_callback),
1140 get_type_callback(get_type_callback) {}
1141
1142 InstrumentationRuntimeGetType get_type_callback = nullptr;
1143};
1144
1145typedef PluginInstances<InstrumentationRuntimeInstance>
1146 InstrumentationRuntimeInstances;
1147
1148static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1149 static InstrumentationRuntimeInstances g_instances;
1150 return g_instances;
1151}
1152
1153bool PluginManager::RegisterPlugin(
1154 ConstString name, const char *description,
1155 InstrumentationRuntimeCreateInstance create_callback,
1156 InstrumentationRuntimeGetType get_type_callback) {
1157 return GetInstrumentationRuntimeInstances().RegisterPlugin(
1158 name, description, create_callback, get_type_callback);
1159}
1160
1161bool PluginManager::UnregisterPlugin(
1162 InstrumentationRuntimeCreateInstance create_callback) {
1163 return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback);
1164}
1165
1166InstrumentationRuntimeGetType
1167PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
1168 const auto &instances = GetInstrumentationRuntimeInstances().GetInstances();
1169 if (idx < instances.size())
1170 return instances[idx].get_type_callback;
1171 return nullptr;
1172}
1173
1174InstrumentationRuntimeCreateInstance
1175PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
1176 return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx);
1177}
1178
1179#pragma mark TypeSystem
1180
1181struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
1182 TypeSystemInstance(ConstString name, std::string description,
1183 CallbackType create_callback,
1184 LanguageSet supported_languages_for_types,
1185 LanguageSet supported_languages_for_expressions)
1186 : PluginInstance<TypeSystemCreateInstance>(name, std::move(description),
1187 create_callback),
1188 supported_languages_for_types(supported_languages_for_types),
1189 supported_languages_for_expressions(
1190 supported_languages_for_expressions) {}
1191
1192 LanguageSet supported_languages_for_types;
1193 LanguageSet supported_languages_for_expressions;
1194};
1195
1196typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;
1197
1198static TypeSystemInstances &GetTypeSystemInstances() {
1199 static TypeSystemInstances g_instances;
1200 return g_instances;
1201}
1202
1203bool PluginManager::RegisterPlugin(
1204 ConstString name, const char *description,
1205 TypeSystemCreateInstance create_callback,
1206 LanguageSet supported_languages_for_types,
1207 LanguageSet supported_languages_for_expressions) {
1208 return GetTypeSystemInstances().RegisterPlugin(
1209 name, description, create_callback, supported_languages_for_types,
1210 supported_languages_for_expressions);
1211}
1212
1213bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
1214 return GetTypeSystemInstances().UnregisterPlugin(create_callback);
1215}
1216
1217TypeSystemCreateInstance
1218PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
1219 return GetTypeSystemInstances().GetCallbackAtIndex(idx);
1220}
1221
1222LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
1223 const auto &instances = GetTypeSystemInstances().GetInstances();
1224 LanguageSet all;
1225 for (unsigned i = 0; i < instances.size(); ++i)
1226 all.bitvector |= instances[i].supported_languages_for_types.bitvector;
1227 return all;
1228}
1229
1230LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
1231 const auto &instances = GetTypeSystemInstances().GetInstances();
1232 LanguageSet all;
1233 for (unsigned i = 0; i < instances.size(); ++i)
1234 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
1235 return all;
1236}
1237
1238#pragma mark REPL
1239
1240struct REPLInstance : public PluginInstance<REPLCreateInstance> {
1241 REPLInstance(ConstString name, std::string description,
1242 CallbackType create_callback, LanguageSet supported_languages)
1243 : PluginInstance<REPLCreateInstance>(name, std::move(description),
1244 create_callback),
1245 supported_languages(supported_languages) {}
1246
1247 LanguageSet supported_languages;
1248};
1249
1250typedef PluginInstances<REPLInstance> REPLInstances;
1251
1252static REPLInstances &GetREPLInstances() {
1253 static REPLInstances g_instances;
1254 return g_instances;
1255}
1256
1257bool PluginManager::RegisterPlugin(ConstString name, const char *description,
1258 REPLCreateInstance create_callback,
1259 LanguageSet supported_languages) {
1260 return GetREPLInstances().RegisterPlugin(name, description, create_callback,
1261 supported_languages);
1262}
1263
1264bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
1265 return GetREPLInstances().UnregisterPlugin(create_callback);
1266}
1267
1268REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
1269 return GetREPLInstances().GetCallbackAtIndex(idx);
1270}
1271
1272LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
1273 const auto &instances = GetREPLInstances().GetInstances();
1274 LanguageSet all;
1275 for (unsigned i = 0; i < instances.size(); ++i)
1276 all.bitvector |= instances[i].supported_languages.bitvector;
1277 return all;
1278}
1279
1280#pragma mark PluginManager
1281
1282void PluginManager::DebuggerInitialize(Debugger &debugger) {
1283 GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
1284 GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1285 GetPlatformInstances().PerformDebuggerCallback(debugger);
1286 GetProcessInstances().PerformDebuggerCallback(debugger);
1287 GetSymbolFileInstances().PerformDebuggerCallback(debugger);
1288 GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
1289 GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
1290 GetTracePluginInstances().PerformDebuggerCallback(debugger);
1291}
1292
1293// This is the preferred new way to register plugin specific settings. e.g.
1294// This will put a plugin's settings under e.g.
1295// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1296static lldb::OptionValuePropertiesSP
1297GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name,
1298 ConstString plugin_type_desc, bool can_create) {
1299 lldb::OptionValuePropertiesSP parent_properties_sp(
1300 debugger.GetValueProperties());
1301 if (parent_properties_sp) {
1302 static ConstString g_property_name("plugin");
1303
1304 OptionValuePropertiesSP plugin_properties_sp =
1305 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
1306 if (!plugin_properties_sp && can_create) {
1307 plugin_properties_sp =
1308 std::make_shared<OptionValueProperties>(g_property_name);
1309 parent_properties_sp->AppendProperty(
1310 g_property_name, ConstString("Settings specify to plugins."), true,
1311 plugin_properties_sp);
1312 }
1313
1314 if (plugin_properties_sp) {
1315 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1316 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1317 if (!plugin_type_properties_sp && can_create) {
1318 plugin_type_properties_sp =
1319 std::make_shared<OptionValueProperties>(plugin_type_name);
1320 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1321 true, plugin_type_properties_sp);
1322 }
1323 return plugin_type_properties_sp;
1324 }
1325 }
1326 return lldb::OptionValuePropertiesSP();
1327}
1328
1329// This is deprecated way to register plugin specific settings. e.g.
1330// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
1331// generic settings would be under "platform.SETTINGNAME".
1332static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
1333 Debugger &debugger, ConstString plugin_type_name,
1334 ConstString plugin_type_desc, bool can_create) {
1335 static ConstString g_property_name("plugin");
1336 lldb::OptionValuePropertiesSP parent_properties_sp(
1337 debugger.GetValueProperties());
1338 if (parent_properties_sp) {
1339 OptionValuePropertiesSP plugin_properties_sp =
1340 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1341 if (!plugin_properties_sp && can_create) {
1342 plugin_properties_sp =
1343 std::make_shared<OptionValueProperties>(plugin_type_name);
1344 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1345 true, plugin_properties_sp);
1346 }
1347
1348 if (plugin_properties_sp) {
1349 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1350 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
1351 if (!plugin_type_properties_sp && can_create) {
1352 plugin_type_properties_sp =
1353 std::make_shared<OptionValueProperties>(g_property_name);
1354 plugin_properties_sp->AppendProperty(
1355 g_property_name, ConstString("Settings specific to plugins"), true,
1356 plugin_type_properties_sp);
1357 }
1358 return plugin_type_properties_sp;
1359 }
1360 }
1361 return lldb::OptionValuePropertiesSP();
1362}
1363
1364namespace {
1365
1366typedef lldb::OptionValuePropertiesSP
1367GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString,
1368 bool can_create);
1369
1370lldb::OptionValuePropertiesSP
1371GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
1372 ConstString plugin_type_name,
1373 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1374 GetDebuggerPropertyForPlugins) {
1375 lldb::OptionValuePropertiesSP properties_sp;
1376 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
1377 debugger, plugin_type_name,
1378 ConstString(), // not creating to so we don't need the description
1379 false));
1380 if (plugin_type_properties_sp)
1381 properties_sp =
1382 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1383 return properties_sp;
1384}
1385
1386bool CreateSettingForPlugin(
1387 Debugger &debugger, ConstString plugin_type_name,
1388 ConstString plugin_type_desc,
1389 const lldb::OptionValuePropertiesSP &properties_sp, ConstString description,
1390 bool is_global_property,
1391 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1392 GetDebuggerPropertyForPlugins) {
1393 if (properties_sp) {
1394 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1395 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
1396 true));
1397 if (plugin_type_properties_sp) {
1398 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1399 description, is_global_property,
1400 properties_sp);
1401 return true;
1402 }
1403 }
1404 return false;
1405}
1406
1407const char *kDynamicLoaderPluginName("dynamic-loader");
1408const char *kPlatformPluginName("platform");
1409const char *kProcessPluginName("process");
1410const char *kSymbolFilePluginName("symbol-file");
1411const char *kJITLoaderPluginName("jit-loader");
1412const char *kStructuredDataPluginName("structured-data");
1413
1414} // anonymous namespace
1415
1416lldb::OptionValuePropertiesSP
1417PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
1418 ConstString setting_name) {
1419 return GetSettingForPlugin(debugger, setting_name,
1420 ConstString(kDynamicLoaderPluginName));
1421}
1422
1423bool PluginManager::CreateSettingForDynamicLoaderPlugin(
1424 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1425 ConstString description, bool is_global_property) {
1426 return CreateSettingForPlugin(
1427 debugger, ConstString(kDynamicLoaderPluginName),
1428 ConstString("Settings for dynamic loader plug-ins"), properties_sp,
1429 description, is_global_property);
1430}
1431
1432lldb::OptionValuePropertiesSP
1433PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
1434 ConstString setting_name) {
1435 return GetSettingForPlugin(debugger, setting_name,
1436 ConstString(kPlatformPluginName),
1437 GetDebuggerPropertyForPluginsOldStyle);
1438}
1439
1440bool PluginManager::CreateSettingForPlatformPlugin(
1441 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1442 ConstString description, bool is_global_property) {
1443 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
1444 ConstString("Settings for platform plug-ins"),
1445 properties_sp, description, is_global_property,
1446 GetDebuggerPropertyForPluginsOldStyle);
1447}
1448
1449lldb::OptionValuePropertiesSP
1450PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
1451 ConstString setting_name) {
1452 return GetSettingForPlugin(debugger, setting_name,
1453 ConstString(kProcessPluginName));
1454}
1455
1456bool PluginManager::CreateSettingForProcessPlugin(
1457 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1458 ConstString description, bool is_global_property) {
1459 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
1460 ConstString("Settings for process plug-ins"),
1461 properties_sp, description, is_global_property);
1462}
1463
1464lldb::OptionValuePropertiesSP
1465PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
1466 ConstString setting_name) {
1467 return GetSettingForPlugin(debugger, setting_name,
1468 ConstString(kSymbolFilePluginName));
1469}
1470
1471bool PluginManager::CreateSettingForSymbolFilePlugin(
1472 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1473 ConstString description, bool is_global_property) {
1474 return CreateSettingForPlugin(
1475 debugger, ConstString(kSymbolFilePluginName),
1476 ConstString("Settings for symbol file plug-ins"), properties_sp,
1477 description, is_global_property);
1478}
1479
1480lldb::OptionValuePropertiesSP
1481PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
1482 ConstString setting_name) {
1483 return GetSettingForPlugin(debugger, setting_name,
1484 ConstString(kJITLoaderPluginName));
1485}
1486
1487bool PluginManager::CreateSettingForJITLoaderPlugin(
1488 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1489 ConstString description, bool is_global_property) {
1490 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
1491 ConstString("Settings for JIT loader plug-ins"),
1492 properties_sp, description, is_global_property);
1493}
1494
1495static const char *kOperatingSystemPluginName("os");
1496
1497lldb::OptionValuePropertiesSP
1498PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger,
1499 ConstString setting_name) {
1500 lldb::OptionValuePropertiesSP properties_sp;
1501 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1502 GetDebuggerPropertyForPlugins(
1503 debugger, ConstString(kOperatingSystemPluginName),
1504 ConstString(), // not creating to so we don't need the description
1505 false));
1506 if (plugin_type_properties_sp)
1507 properties_sp =
1508 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1509 return properties_sp;
1510}
1511
1512bool PluginManager::CreateSettingForOperatingSystemPlugin(
1513 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1514 ConstString description, bool is_global_property) {
1515 if (properties_sp) {
1516 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1517 GetDebuggerPropertyForPlugins(
1518 debugger, ConstString(kOperatingSystemPluginName),
1519 ConstString("Settings for operating system plug-ins"), true));
1520 if (plugin_type_properties_sp) {
1521 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1522 description, is_global_property,
1523 properties_sp);
1524 return true;
1525 }
1526 }
1527 return false;
1528}
1529
1530lldb::OptionValuePropertiesSP
1531PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
1532 ConstString setting_name) {
1533 return GetSettingForPlugin(debugger, setting_name,
1534 ConstString(kStructuredDataPluginName));
1535}
1536
1537bool PluginManager::CreateSettingForStructuredDataPlugin(
1538 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1539 ConstString description, bool is_global_property) {
1540 return CreateSettingForPlugin(
1541 debugger, ConstString(kStructuredDataPluginName),
1542 ConstString("Settings for structured data plug-ins"), properties_sp,
1543 description, is_global_property);
1544}
1545