1//===-- PluginManager.cpp -------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Core/PluginManager.h"
10
11#include "lldb/Core/Debugger.h"
12#include "lldb/Host/FileSystem.h"
13#include "lldb/Host/HostInfo.h"
14#include "lldb/Interpreter/OptionValueProperties.h"
15#include "lldb/Symbol/SaveCoreOptions.h"
16#include "lldb/Target/Process.h"
17#include "lldb/Utility/FileSpec.h"
18#include "lldb/Utility/Status.h"
19#include "lldb/Utility/StringList.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/DynamicLibrary.h"
22#include "llvm/Support/FileSystem.h"
23#include "llvm/Support/raw_ostream.h"
24#include <cassert>
25#include <map>
26#include <memory>
27#include <mutex>
28#include <string>
29#include <utility>
30#include <vector>
31#if defined(_WIN32)
32#include "lldb/Host/windows/PosixApi.h"
33#endif
34
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(x: 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(file_spec&: 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 filename: plugin_file_spec.GetPath().c_str(), errMsg: &pluginLoadError);
102 if (plugin_info.library.isValid()) {
103 bool success = false;
104 plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>(
105 VPtr: plugin_info.library.getAddressOfSymbol(symbolName: "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 VPtr: plugin_info.library.getAddressOfSymbol(symbolName: "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(file_spec: dir_spec) &&
151 dir_spec.GetPath(path: dir_path, max_path_length: sizeof(dir_path))) {
152 FileSystem::Instance().EnumerateDirectory(path: dir_path, find_directories,
153 find_files, find_other,
154 callback: LoadPluginCallback, callback_baton: nullptr);
155 }
156 }
157
158 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
159 if (FileSystem::Instance().Exists(file_spec: dir_spec) &&
160 dir_spec.GetPath(path: dir_path, max_path_length: sizeof(dir_path))) {
161 FileSystem::Instance().EnumerateDirectory(path: dir_path, find_directories,
162 find_files, find_other,
163 callback: LoadPluginCallback, callback_baton: 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
184llvm::ArrayRef<PluginNamespace> PluginManager::GetPluginNamespaces() {
185 // Currently supported set of plugin namespaces. This will be expanded
186 // over time.
187 static PluginNamespace PluginNamespaces[] = {
188 {.name: "system-runtime", .get_info: PluginManager::GetSystemRuntimePluginInfo,
189 .set_enabled: PluginManager::SetSystemRuntimePluginEnabled},
190 {.name: "instrumentation-runtime",
191 .get_info: PluginManager::GetInstrumentationRuntimePluginInfo,
192 .set_enabled: PluginManager::SetInstrumentationRuntimePluginEnabled}};
193
194 return PluginNamespaces;
195}
196
197llvm::json::Object PluginManager::GetJSON(llvm::StringRef pattern) {
198 llvm::json::Object plugin_stats;
199
200 for (const PluginNamespace &plugin_ns : GetPluginNamespaces()) {
201 llvm::json::Array namespace_stats;
202
203 for (const RegisteredPluginInfo &plugin : plugin_ns.get_info()) {
204 if (MatchPluginName(pattern, plugin_ns, plugin)) {
205 llvm::json::Object plugin_json;
206 plugin_json.try_emplace(K: "name", Args: plugin.name);
207 plugin_json.try_emplace(K: "enabled", Args: plugin.enabled);
208 namespace_stats.emplace_back(A: std::move(plugin_json));
209 }
210 }
211 if (!namespace_stats.empty())
212 plugin_stats.try_emplace(K: plugin_ns.name, Args: std::move(namespace_stats));
213 }
214
215 return plugin_stats;
216}
217
218bool PluginManager::MatchPluginName(llvm::StringRef pattern,
219 const PluginNamespace &plugin_ns,
220 const RegisteredPluginInfo &plugin_info) {
221 // The empty pattern matches all plugins.
222 if (pattern.empty())
223 return true;
224
225 // Check if the pattern matches the namespace.
226 if (pattern == plugin_ns.name)
227 return true;
228
229 // Check if the pattern matches the qualified name.
230 std::string qualified_name = (plugin_ns.name + "." + plugin_info.name).str();
231 return pattern == qualified_name;
232}
233
234template <typename Callback> struct PluginInstance {
235 typedef Callback CallbackType;
236
237 PluginInstance() = default;
238 PluginInstance(llvm::StringRef name, llvm::StringRef description,
239 Callback create_callback,
240 DebuggerInitializeCallback debugger_init_callback = nullptr)
241 : name(name), description(description), enabled(true),
242 create_callback(create_callback),
243 debugger_init_callback(debugger_init_callback) {}
244
245 llvm::StringRef name;
246 llvm::StringRef description;
247 bool enabled;
248 Callback create_callback;
249 DebuggerInitializeCallback debugger_init_callback;
250};
251
252template <typename Instance> class PluginInstances {
253public:
254 template <typename... Args>
255 bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
256 typename Instance::CallbackType callback,
257 Args &&...args) {
258 if (!callback)
259 return false;
260 assert(!name.empty());
261 m_instances.emplace_back(name, description, callback,
262 std::forward<Args>(args)...);
263 return true;
264 }
265
266 bool UnregisterPlugin(typename Instance::CallbackType callback) {
267 if (!callback)
268 return false;
269 auto pos = m_instances.begin();
270 auto end = m_instances.end();
271 for (; pos != end; ++pos) {
272 if (pos->create_callback == callback) {
273 m_instances.erase(pos);
274 return true;
275 }
276 }
277 return false;
278 }
279
280 typename Instance::CallbackType GetCallbackAtIndex(uint32_t idx) {
281 if (const Instance *instance = GetInstanceAtIndex(idx))
282 return instance->create_callback;
283 return nullptr;
284 }
285
286 llvm::StringRef GetDescriptionAtIndex(uint32_t idx) {
287 if (const Instance *instance = GetInstanceAtIndex(idx))
288 return instance->description;
289 return "";
290 }
291
292 llvm::StringRef GetNameAtIndex(uint32_t idx) {
293 if (const Instance *instance = GetInstanceAtIndex(idx))
294 return instance->name;
295 return "";
296 }
297
298 typename Instance::CallbackType GetCallbackForName(llvm::StringRef name) {
299 if (const Instance *instance = GetInstanceForName(name))
300 return instance->create_callback;
301 return nullptr;
302 }
303
304 void PerformDebuggerCallback(Debugger &debugger) {
305 for (const auto &instance : m_instances) {
306 if (!instance.enabled)
307 continue;
308 if (instance.debugger_init_callback)
309 instance.debugger_init_callback(debugger);
310 }
311 }
312
313 // Return a copy of all the enabled instances.
314 // Note that this is a copy of the internal state so modifications
315 // to the returned instances will not be reflected back to instances
316 // stored by the PluginInstances object.
317 std::vector<Instance> GetSnapshot() {
318 std::vector<Instance> enabled_instances;
319 for (const auto &instance : m_instances) {
320 if (instance.enabled)
321 enabled_instances.push_back(instance);
322 }
323 return enabled_instances;
324 }
325
326 const Instance *GetInstanceAtIndex(uint32_t idx) {
327 uint32_t count = 0;
328
329 return FindEnabledInstance(
330 predicate: [&](const Instance &instance) { return count++ == idx; });
331 }
332
333 const Instance *GetInstanceForName(llvm::StringRef name) {
334 if (name.empty())
335 return nullptr;
336
337 return FindEnabledInstance(
338 predicate: [&](const Instance &instance) { return instance.name == name; });
339 }
340
341 const Instance *
342 FindEnabledInstance(std::function<bool(const Instance &)> predicate) const {
343 for (const auto &instance : m_instances) {
344 if (!instance.enabled)
345 continue;
346 if (predicate(instance))
347 return &instance;
348 }
349 return nullptr;
350 }
351
352 // Return a list of all the registered plugin instances. This includes both
353 // enabled and disabled instances. The instances are listed in the order they
354 // were registered which is the order they would be queried if they were all
355 // enabled.
356 std::vector<RegisteredPluginInfo> GetPluginInfoForAllInstances() {
357 // Lookup the plugin info for each instance in the sorted order.
358 std::vector<RegisteredPluginInfo> plugin_infos;
359 plugin_infos.reserve(n: m_instances.size());
360 for (const Instance &instance : m_instances)
361 plugin_infos.push_back(
362 {instance.name, instance.description, instance.enabled});
363
364 return plugin_infos;
365 }
366
367 bool SetInstanceEnabled(llvm::StringRef name, bool enable) {
368 auto it = llvm::find_if(m_instances, [&](const Instance &instance) {
369 return instance.name == name;
370 });
371
372 if (it == m_instances.end())
373 return false;
374
375 it->enabled = enable;
376 return true;
377 }
378
379private:
380 std::vector<Instance> m_instances;
381};
382
383#pragma mark ABI
384
385typedef PluginInstance<ABICreateInstance> ABIInstance;
386typedef PluginInstances<ABIInstance> ABIInstances;
387
388static ABIInstances &GetABIInstances() {
389 static ABIInstances g_instances;
390 return g_instances;
391}
392
393bool PluginManager::RegisterPlugin(llvm::StringRef name,
394 llvm::StringRef description,
395 ABICreateInstance create_callback) {
396 return GetABIInstances().RegisterPlugin(name, description, callback: create_callback);
397}
398
399bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
400 return GetABIInstances().UnregisterPlugin(callback: create_callback);
401}
402
403ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
404 return GetABIInstances().GetCallbackAtIndex(idx);
405}
406
407#pragma mark Architecture
408
409typedef PluginInstance<ArchitectureCreateInstance> ArchitectureInstance;
410typedef std::vector<ArchitectureInstance> ArchitectureInstances;
411
412static ArchitectureInstances &GetArchitectureInstances() {
413 static ArchitectureInstances g_instances;
414 return g_instances;
415}
416
417void PluginManager::RegisterPlugin(llvm::StringRef name,
418 llvm::StringRef description,
419 ArchitectureCreateInstance create_callback) {
420 GetArchitectureInstances().push_back(x: {name, description, create_callback});
421}
422
423void PluginManager::UnregisterPlugin(
424 ArchitectureCreateInstance create_callback) {
425 auto &instances = GetArchitectureInstances();
426
427 for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
428 if (pos->create_callback == create_callback) {
429 instances.erase(position: pos);
430 return;
431 }
432 }
433 llvm_unreachable("Plugin not found");
434}
435
436std::unique_ptr<Architecture>
437PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
438 for (const auto &instances : GetArchitectureInstances()) {
439 if (auto plugin_up = instances.create_callback(arch))
440 return plugin_up;
441 }
442 return nullptr;
443}
444
445#pragma mark Disassembler
446
447typedef PluginInstance<DisassemblerCreateInstance> DisassemblerInstance;
448typedef PluginInstances<DisassemblerInstance> DisassemblerInstances;
449
450static DisassemblerInstances &GetDisassemblerInstances() {
451 static DisassemblerInstances g_instances;
452 return g_instances;
453}
454
455bool PluginManager::RegisterPlugin(llvm::StringRef name,
456 llvm::StringRef description,
457 DisassemblerCreateInstance create_callback) {
458 return GetDisassemblerInstances().RegisterPlugin(name, description,
459 callback: create_callback);
460}
461
462bool PluginManager::UnregisterPlugin(
463 DisassemblerCreateInstance create_callback) {
464 return GetDisassemblerInstances().UnregisterPlugin(callback: create_callback);
465}
466
467DisassemblerCreateInstance
468PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
469 return GetDisassemblerInstances().GetCallbackAtIndex(idx);
470}
471
472DisassemblerCreateInstance
473PluginManager::GetDisassemblerCreateCallbackForPluginName(
474 llvm::StringRef name) {
475 return GetDisassemblerInstances().GetCallbackForName(name);
476}
477
478#pragma mark DynamicLoader
479
480typedef PluginInstance<DynamicLoaderCreateInstance> DynamicLoaderInstance;
481typedef PluginInstances<DynamicLoaderInstance> DynamicLoaderInstances;
482
483static DynamicLoaderInstances &GetDynamicLoaderInstances() {
484 static DynamicLoaderInstances g_instances;
485 return g_instances;
486}
487
488bool PluginManager::RegisterPlugin(
489 llvm::StringRef name, llvm::StringRef description,
490 DynamicLoaderCreateInstance create_callback,
491 DebuggerInitializeCallback debugger_init_callback) {
492 return GetDynamicLoaderInstances().RegisterPlugin(
493 name, description, callback: create_callback, args&: debugger_init_callback);
494}
495
496bool PluginManager::UnregisterPlugin(
497 DynamicLoaderCreateInstance create_callback) {
498 return GetDynamicLoaderInstances().UnregisterPlugin(callback: create_callback);
499}
500
501DynamicLoaderCreateInstance
502PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
503 return GetDynamicLoaderInstances().GetCallbackAtIndex(idx);
504}
505
506DynamicLoaderCreateInstance
507PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
508 llvm::StringRef name) {
509 return GetDynamicLoaderInstances().GetCallbackForName(name);
510}
511
512#pragma mark JITLoader
513
514typedef PluginInstance<JITLoaderCreateInstance> JITLoaderInstance;
515typedef PluginInstances<JITLoaderInstance> JITLoaderInstances;
516
517static JITLoaderInstances &GetJITLoaderInstances() {
518 static JITLoaderInstances g_instances;
519 return g_instances;
520}
521
522bool PluginManager::RegisterPlugin(
523 llvm::StringRef name, llvm::StringRef description,
524 JITLoaderCreateInstance create_callback,
525 DebuggerInitializeCallback debugger_init_callback) {
526 return GetJITLoaderInstances().RegisterPlugin(
527 name, description, callback: create_callback, args&: debugger_init_callback);
528}
529
530bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
531 return GetJITLoaderInstances().UnregisterPlugin(callback: create_callback);
532}
533
534JITLoaderCreateInstance
535PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
536 return GetJITLoaderInstances().GetCallbackAtIndex(idx);
537}
538
539#pragma mark EmulateInstruction
540
541typedef PluginInstance<EmulateInstructionCreateInstance>
542 EmulateInstructionInstance;
543typedef PluginInstances<EmulateInstructionInstance> EmulateInstructionInstances;
544
545static EmulateInstructionInstances &GetEmulateInstructionInstances() {
546 static EmulateInstructionInstances g_instances;
547 return g_instances;
548}
549
550bool PluginManager::RegisterPlugin(
551 llvm::StringRef name, llvm::StringRef description,
552 EmulateInstructionCreateInstance create_callback) {
553 return GetEmulateInstructionInstances().RegisterPlugin(name, description,
554 callback: create_callback);
555}
556
557bool PluginManager::UnregisterPlugin(
558 EmulateInstructionCreateInstance create_callback) {
559 return GetEmulateInstructionInstances().UnregisterPlugin(callback: create_callback);
560}
561
562EmulateInstructionCreateInstance
563PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
564 return GetEmulateInstructionInstances().GetCallbackAtIndex(idx);
565}
566
567EmulateInstructionCreateInstance
568PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
569 llvm::StringRef name) {
570 return GetEmulateInstructionInstances().GetCallbackForName(name);
571}
572
573#pragma mark OperatingSystem
574
575typedef PluginInstance<OperatingSystemCreateInstance> OperatingSystemInstance;
576typedef PluginInstances<OperatingSystemInstance> OperatingSystemInstances;
577
578static OperatingSystemInstances &GetOperatingSystemInstances() {
579 static OperatingSystemInstances g_instances;
580 return g_instances;
581}
582
583bool PluginManager::RegisterPlugin(
584 llvm::StringRef name, llvm::StringRef description,
585 OperatingSystemCreateInstance create_callback,
586 DebuggerInitializeCallback debugger_init_callback) {
587 return GetOperatingSystemInstances().RegisterPlugin(
588 name, description, callback: create_callback, args&: debugger_init_callback);
589}
590
591bool PluginManager::UnregisterPlugin(
592 OperatingSystemCreateInstance create_callback) {
593 return GetOperatingSystemInstances().UnregisterPlugin(callback: create_callback);
594}
595
596OperatingSystemCreateInstance
597PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
598 return GetOperatingSystemInstances().GetCallbackAtIndex(idx);
599}
600
601OperatingSystemCreateInstance
602PluginManager::GetOperatingSystemCreateCallbackForPluginName(
603 llvm::StringRef name) {
604 return GetOperatingSystemInstances().GetCallbackForName(name);
605}
606
607#pragma mark Language
608
609typedef PluginInstance<LanguageCreateInstance> LanguageInstance;
610typedef PluginInstances<LanguageInstance> LanguageInstances;
611
612static LanguageInstances &GetLanguageInstances() {
613 static LanguageInstances g_instances;
614 return g_instances;
615}
616
617bool PluginManager::RegisterPlugin(
618 llvm::StringRef name, llvm::StringRef description,
619 LanguageCreateInstance create_callback,
620 DebuggerInitializeCallback debugger_init_callback) {
621 return GetLanguageInstances().RegisterPlugin(
622 name, description, callback: create_callback, args&: debugger_init_callback);
623}
624
625bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
626 return GetLanguageInstances().UnregisterPlugin(callback: create_callback);
627}
628
629LanguageCreateInstance
630PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
631 return GetLanguageInstances().GetCallbackAtIndex(idx);
632}
633
634#pragma mark LanguageRuntime
635
636struct LanguageRuntimeInstance
637 : public PluginInstance<LanguageRuntimeCreateInstance> {
638 LanguageRuntimeInstance(
639 llvm::StringRef name, llvm::StringRef description,
640 CallbackType create_callback,
641 DebuggerInitializeCallback debugger_init_callback,
642 LanguageRuntimeGetCommandObject command_callback,
643 LanguageRuntimeGetExceptionPrecondition precondition_callback)
644 : PluginInstance<LanguageRuntimeCreateInstance>(
645 name, description, create_callback, debugger_init_callback),
646 command_callback(command_callback),
647 precondition_callback(precondition_callback) {}
648
649 LanguageRuntimeGetCommandObject command_callback;
650 LanguageRuntimeGetExceptionPrecondition precondition_callback;
651};
652
653typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances;
654
655static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
656 static LanguageRuntimeInstances g_instances;
657 return g_instances;
658}
659
660bool PluginManager::RegisterPlugin(
661 llvm::StringRef name, llvm::StringRef description,
662 LanguageRuntimeCreateInstance create_callback,
663 LanguageRuntimeGetCommandObject command_callback,
664 LanguageRuntimeGetExceptionPrecondition precondition_callback) {
665 return GetLanguageRuntimeInstances().RegisterPlugin(
666 name, description, callback: create_callback, args: nullptr, args&: command_callback,
667 args&: precondition_callback);
668}
669
670bool PluginManager::UnregisterPlugin(
671 LanguageRuntimeCreateInstance create_callback) {
672 return GetLanguageRuntimeInstances().UnregisterPlugin(callback: create_callback);
673}
674
675LanguageRuntimeCreateInstance
676PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
677 return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx);
678}
679
680LanguageRuntimeGetCommandObject
681PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
682 if (auto instance = GetLanguageRuntimeInstances().GetInstanceAtIndex(idx))
683 return instance->command_callback;
684 return nullptr;
685}
686
687LanguageRuntimeGetExceptionPrecondition
688PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
689 if (auto instance = GetLanguageRuntimeInstances().GetInstanceAtIndex(idx))
690 return instance->precondition_callback;
691 return nullptr;
692}
693
694#pragma mark SystemRuntime
695
696typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance;
697typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances;
698
699static SystemRuntimeInstances &GetSystemRuntimeInstances() {
700 static SystemRuntimeInstances g_instances;
701 return g_instances;
702}
703
704bool PluginManager::RegisterPlugin(
705 llvm::StringRef name, llvm::StringRef description,
706 SystemRuntimeCreateInstance create_callback) {
707 return GetSystemRuntimeInstances().RegisterPlugin(name, description,
708 callback: create_callback);
709}
710
711bool PluginManager::UnregisterPlugin(
712 SystemRuntimeCreateInstance create_callback) {
713 return GetSystemRuntimeInstances().UnregisterPlugin(callback: create_callback);
714}
715
716SystemRuntimeCreateInstance
717PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
718 return GetSystemRuntimeInstances().GetCallbackAtIndex(idx);
719}
720
721std::vector<RegisteredPluginInfo> PluginManager::GetSystemRuntimePluginInfo() {
722 return GetSystemRuntimeInstances().GetPluginInfoForAllInstances();
723}
724
725bool PluginManager::SetSystemRuntimePluginEnabled(llvm::StringRef name,
726 bool enable) {
727 return GetSystemRuntimeInstances().SetInstanceEnabled(name, enable);
728}
729
730#pragma mark ObjectFile
731
732struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> {
733 ObjectFileInstance(
734 llvm::StringRef name, llvm::StringRef description,
735 CallbackType create_callback,
736 ObjectFileCreateMemoryInstance create_memory_callback,
737 ObjectFileGetModuleSpecifications get_module_specifications,
738 ObjectFileSaveCore save_core,
739 DebuggerInitializeCallback debugger_init_callback)
740 : PluginInstance<ObjectFileCreateInstance>(
741 name, description, create_callback, debugger_init_callback),
742 create_memory_callback(create_memory_callback),
743 get_module_specifications(get_module_specifications),
744 save_core(save_core) {}
745
746 ObjectFileCreateMemoryInstance create_memory_callback;
747 ObjectFileGetModuleSpecifications get_module_specifications;
748 ObjectFileSaveCore save_core;
749};
750typedef PluginInstances<ObjectFileInstance> ObjectFileInstances;
751
752static ObjectFileInstances &GetObjectFileInstances() {
753 static ObjectFileInstances g_instances;
754 return g_instances;
755}
756
757bool PluginManager::IsRegisteredObjectFilePluginName(llvm::StringRef name) {
758 if (name.empty())
759 return false;
760
761 return GetObjectFileInstances().GetInstanceForName(name) != nullptr;
762}
763
764bool PluginManager::RegisterPlugin(
765 llvm::StringRef name, llvm::StringRef description,
766 ObjectFileCreateInstance create_callback,
767 ObjectFileCreateMemoryInstance create_memory_callback,
768 ObjectFileGetModuleSpecifications get_module_specifications,
769 ObjectFileSaveCore save_core,
770 DebuggerInitializeCallback debugger_init_callback) {
771 return GetObjectFileInstances().RegisterPlugin(
772 name, description, callback: create_callback, args&: create_memory_callback,
773 args&: get_module_specifications, args&: save_core, args&: debugger_init_callback);
774}
775
776bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
777 return GetObjectFileInstances().UnregisterPlugin(callback: create_callback);
778}
779
780ObjectFileCreateInstance
781PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
782 return GetObjectFileInstances().GetCallbackAtIndex(idx);
783}
784
785ObjectFileCreateMemoryInstance
786PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
787 if (auto instance = GetObjectFileInstances().GetInstanceAtIndex(idx))
788 return instance->create_memory_callback;
789 return nullptr;
790}
791
792ObjectFileGetModuleSpecifications
793PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
794 uint32_t idx) {
795 if (auto instance = GetObjectFileInstances().GetInstanceAtIndex(idx))
796 return instance->get_module_specifications;
797 return nullptr;
798}
799
800ObjectFileCreateMemoryInstance
801PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
802 llvm::StringRef name) {
803 if (auto instance = GetObjectFileInstances().GetInstanceForName(name))
804 return instance->create_memory_callback;
805 return nullptr;
806}
807
808Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
809 lldb_private::SaveCoreOptions &options) {
810 Status error;
811 if (!options.GetOutputFile()) {
812 error = Status::FromErrorString(str: "No output file specified");
813 return error;
814 }
815
816 if (!process_sp) {
817 error = Status::FromErrorString(str: "Invalid process");
818 return error;
819 }
820
821 error = options.EnsureValidConfiguration(process_sp);
822 if (error.Fail())
823 return error;
824
825 if (!options.GetPluginName().has_value()) {
826 // Try saving core directly from the process plugin first.
827 llvm::Expected<bool> ret =
828 process_sp->SaveCore(outfile: options.GetOutputFile()->GetPath());
829 if (!ret)
830 return Status::FromError(error: ret.takeError());
831 if (ret.get())
832 return Status();
833 }
834
835 // Fall back to object plugins.
836 const auto &plugin_name = options.GetPluginName().value_or(u: "");
837 auto instances = GetObjectFileInstances().GetSnapshot();
838 for (auto &instance : instances) {
839 if (plugin_name.empty() || instance.name == plugin_name) {
840 if (instance.save_core && instance.save_core(process_sp, options, error))
841 return error;
842 }
843 }
844
845 // Check to see if any of the object file plugins tried and failed to save.
846 // If none ran, set the error message.
847 if (error.Success())
848 error = Status::FromErrorString(
849 str: "no ObjectFile plugins were able to save a core for this process");
850 return error;
851}
852
853#pragma mark ObjectContainer
854
855struct ObjectContainerInstance
856 : public PluginInstance<ObjectContainerCreateInstance> {
857 ObjectContainerInstance(
858 llvm::StringRef name, llvm::StringRef description,
859 CallbackType create_callback,
860 ObjectContainerCreateMemoryInstance create_memory_callback,
861 ObjectFileGetModuleSpecifications get_module_specifications)
862 : PluginInstance<ObjectContainerCreateInstance>(name, description,
863 create_callback),
864 create_memory_callback(create_memory_callback),
865 get_module_specifications(get_module_specifications) {}
866
867 ObjectContainerCreateMemoryInstance create_memory_callback;
868 ObjectFileGetModuleSpecifications get_module_specifications;
869};
870typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;
871
872static ObjectContainerInstances &GetObjectContainerInstances() {
873 static ObjectContainerInstances g_instances;
874 return g_instances;
875}
876
877bool PluginManager::RegisterPlugin(
878 llvm::StringRef name, llvm::StringRef description,
879 ObjectContainerCreateInstance create_callback,
880 ObjectFileGetModuleSpecifications get_module_specifications,
881 ObjectContainerCreateMemoryInstance create_memory_callback) {
882 return GetObjectContainerInstances().RegisterPlugin(
883 name, description, callback: create_callback, args&: create_memory_callback,
884 args&: get_module_specifications);
885}
886
887bool PluginManager::UnregisterPlugin(
888 ObjectContainerCreateInstance create_callback) {
889 return GetObjectContainerInstances().UnregisterPlugin(callback: create_callback);
890}
891
892ObjectContainerCreateInstance
893PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
894 return GetObjectContainerInstances().GetCallbackAtIndex(idx);
895}
896
897ObjectContainerCreateMemoryInstance
898PluginManager::GetObjectContainerCreateMemoryCallbackAtIndex(uint32_t idx) {
899 if (auto instance = GetObjectContainerInstances().GetInstanceAtIndex(idx))
900 return instance->create_memory_callback;
901 return nullptr;
902}
903
904ObjectFileGetModuleSpecifications
905PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
906 uint32_t idx) {
907 if (auto instance = GetObjectContainerInstances().GetInstanceAtIndex(idx))
908 return instance->get_module_specifications;
909 return nullptr;
910}
911
912#pragma mark Platform
913
914typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
915typedef PluginInstances<PlatformInstance> PlatformInstances;
916
917static PlatformInstances &GetPlatformInstances() {
918 static PlatformInstances g_platform_instances;
919 return g_platform_instances;
920}
921
922bool PluginManager::RegisterPlugin(
923 llvm::StringRef name, llvm::StringRef description,
924 PlatformCreateInstance create_callback,
925 DebuggerInitializeCallback debugger_init_callback) {
926 return GetPlatformInstances().RegisterPlugin(
927 name, description, callback: create_callback, args&: debugger_init_callback);
928}
929
930bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
931 return GetPlatformInstances().UnregisterPlugin(callback: create_callback);
932}
933
934llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
935 return GetPlatformInstances().GetNameAtIndex(idx);
936}
937
938llvm::StringRef
939PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
940 return GetPlatformInstances().GetDescriptionAtIndex(idx);
941}
942
943PlatformCreateInstance
944PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
945 return GetPlatformInstances().GetCallbackAtIndex(idx);
946}
947
948PlatformCreateInstance
949PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) {
950 return GetPlatformInstances().GetCallbackForName(name);
951}
952
953void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
954 CompletionRequest &request) {
955 for (const auto &instance : GetPlatformInstances().GetSnapshot()) {
956 if (instance.name.starts_with(Prefix: name))
957 request.AddCompletion(completion: instance.name);
958 }
959}
960
961#pragma mark Process
962
963typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
964typedef PluginInstances<ProcessInstance> ProcessInstances;
965
966static ProcessInstances &GetProcessInstances() {
967 static ProcessInstances g_instances;
968 return g_instances;
969}
970
971bool PluginManager::RegisterPlugin(
972 llvm::StringRef name, llvm::StringRef description,
973 ProcessCreateInstance create_callback,
974 DebuggerInitializeCallback debugger_init_callback) {
975 return GetProcessInstances().RegisterPlugin(
976 name, description, callback: create_callback, args&: debugger_init_callback);
977}
978
979bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
980 return GetProcessInstances().UnregisterPlugin(callback: create_callback);
981}
982
983llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
984 return GetProcessInstances().GetNameAtIndex(idx);
985}
986
987llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
988 return GetProcessInstances().GetDescriptionAtIndex(idx);
989}
990
991ProcessCreateInstance
992PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
993 return GetProcessInstances().GetCallbackAtIndex(idx);
994}
995
996ProcessCreateInstance
997PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) {
998 return GetProcessInstances().GetCallbackForName(name);
999}
1000
1001void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
1002 CompletionRequest &request) {
1003 for (const auto &instance : GetProcessInstances().GetSnapshot()) {
1004 if (instance.name.starts_with(Prefix: name))
1005 request.AddCompletion(completion: instance.name, description: instance.description);
1006 }
1007}
1008
1009#pragma mark RegisterTypeBuilder
1010
1011struct RegisterTypeBuilderInstance
1012 : public PluginInstance<RegisterTypeBuilderCreateInstance> {
1013 RegisterTypeBuilderInstance(llvm::StringRef name, llvm::StringRef description,
1014 CallbackType create_callback)
1015 : PluginInstance<RegisterTypeBuilderCreateInstance>(name, description,
1016 create_callback) {}
1017};
1018
1019typedef PluginInstances<RegisterTypeBuilderInstance>
1020 RegisterTypeBuilderInstances;
1021
1022static RegisterTypeBuilderInstances &GetRegisterTypeBuilderInstances() {
1023 static RegisterTypeBuilderInstances g_instances;
1024 return g_instances;
1025}
1026
1027bool PluginManager::RegisterPlugin(
1028 llvm::StringRef name, llvm::StringRef description,
1029 RegisterTypeBuilderCreateInstance create_callback) {
1030 return GetRegisterTypeBuilderInstances().RegisterPlugin(name, description,
1031 callback: create_callback);
1032}
1033
1034bool PluginManager::UnregisterPlugin(
1035 RegisterTypeBuilderCreateInstance create_callback) {
1036 return GetRegisterTypeBuilderInstances().UnregisterPlugin(callback: create_callback);
1037}
1038
1039lldb::RegisterTypeBuilderSP
1040PluginManager::GetRegisterTypeBuilder(Target &target) {
1041 // We assume that RegisterTypeBuilderClang is the only instance of this plugin
1042 // type and is always present.
1043 auto instance = GetRegisterTypeBuilderInstances().GetInstanceAtIndex(idx: 0);
1044 assert(instance);
1045 return instance->create_callback(target);
1046}
1047
1048#pragma mark ScriptInterpreter
1049
1050struct ScriptInterpreterInstance
1051 : public PluginInstance<ScriptInterpreterCreateInstance> {
1052 ScriptInterpreterInstance(llvm::StringRef name, llvm::StringRef description,
1053 CallbackType create_callback,
1054 lldb::ScriptLanguage language)
1055 : PluginInstance<ScriptInterpreterCreateInstance>(name, description,
1056 create_callback),
1057 language(language) {}
1058
1059 lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
1060};
1061
1062typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;
1063
1064static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
1065 static ScriptInterpreterInstances g_instances;
1066 return g_instances;
1067}
1068
1069bool PluginManager::RegisterPlugin(
1070 llvm::StringRef name, llvm::StringRef description,
1071 lldb::ScriptLanguage script_language,
1072 ScriptInterpreterCreateInstance create_callback) {
1073 return GetScriptInterpreterInstances().RegisterPlugin(
1074 name, description, callback: create_callback, args&: script_language);
1075}
1076
1077bool PluginManager::UnregisterPlugin(
1078 ScriptInterpreterCreateInstance create_callback) {
1079 return GetScriptInterpreterInstances().UnregisterPlugin(callback: create_callback);
1080}
1081
1082ScriptInterpreterCreateInstance
1083PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
1084 return GetScriptInterpreterInstances().GetCallbackAtIndex(idx);
1085}
1086
1087lldb::ScriptInterpreterSP
1088PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
1089 Debugger &debugger) {
1090 const auto instances = GetScriptInterpreterInstances().GetSnapshot();
1091 ScriptInterpreterCreateInstance none_instance = nullptr;
1092 for (const auto &instance : instances) {
1093 if (instance.language == lldb::eScriptLanguageNone)
1094 none_instance = instance.create_callback;
1095
1096 if (script_lang == instance.language)
1097 return instance.create_callback(debugger);
1098 }
1099
1100 // If we didn't find one, return the ScriptInterpreter for the null language.
1101 assert(none_instance != nullptr);
1102 return none_instance(debugger);
1103}
1104
1105#pragma mark StructuredDataPlugin
1106
1107struct StructuredDataPluginInstance
1108 : public PluginInstance<StructuredDataPluginCreateInstance> {
1109 StructuredDataPluginInstance(
1110 llvm::StringRef name, llvm::StringRef description,
1111 CallbackType create_callback,
1112 DebuggerInitializeCallback debugger_init_callback,
1113 StructuredDataFilterLaunchInfo filter_callback)
1114 : PluginInstance<StructuredDataPluginCreateInstance>(
1115 name, description, create_callback, debugger_init_callback),
1116 filter_callback(filter_callback) {}
1117
1118 StructuredDataFilterLaunchInfo filter_callback = nullptr;
1119};
1120
1121typedef PluginInstances<StructuredDataPluginInstance>
1122 StructuredDataPluginInstances;
1123
1124static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
1125 static StructuredDataPluginInstances g_instances;
1126 return g_instances;
1127}
1128
1129bool PluginManager::RegisterPlugin(
1130 llvm::StringRef name, llvm::StringRef description,
1131 StructuredDataPluginCreateInstance create_callback,
1132 DebuggerInitializeCallback debugger_init_callback,
1133 StructuredDataFilterLaunchInfo filter_callback) {
1134 return GetStructuredDataPluginInstances().RegisterPlugin(
1135 name, description, callback: create_callback, args&: debugger_init_callback,
1136 args&: filter_callback);
1137}
1138
1139bool PluginManager::UnregisterPlugin(
1140 StructuredDataPluginCreateInstance create_callback) {
1141 return GetStructuredDataPluginInstances().UnregisterPlugin(callback: create_callback);
1142}
1143
1144StructuredDataPluginCreateInstance
1145PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
1146 return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx);
1147}
1148
1149StructuredDataFilterLaunchInfo
1150PluginManager::GetStructuredDataFilterCallbackAtIndex(
1151 uint32_t idx, bool &iteration_complete) {
1152 if (auto instance =
1153 GetStructuredDataPluginInstances().GetInstanceAtIndex(idx)) {
1154 iteration_complete = false;
1155 return instance->filter_callback;
1156 }
1157 iteration_complete = true;
1158 return nullptr;
1159}
1160
1161#pragma mark SymbolFile
1162
1163typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
1164typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;
1165
1166static SymbolFileInstances &GetSymbolFileInstances() {
1167 static SymbolFileInstances g_instances;
1168 return g_instances;
1169}
1170
1171bool PluginManager::RegisterPlugin(
1172 llvm::StringRef name, llvm::StringRef description,
1173 SymbolFileCreateInstance create_callback,
1174 DebuggerInitializeCallback debugger_init_callback) {
1175 return GetSymbolFileInstances().RegisterPlugin(
1176 name, description, callback: create_callback, args&: debugger_init_callback);
1177}
1178
1179bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
1180 return GetSymbolFileInstances().UnregisterPlugin(callback: create_callback);
1181}
1182
1183SymbolFileCreateInstance
1184PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1185 return GetSymbolFileInstances().GetCallbackAtIndex(idx);
1186}
1187
1188#pragma mark SymbolVendor
1189
1190typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
1191typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;
1192
1193static SymbolVendorInstances &GetSymbolVendorInstances() {
1194 static SymbolVendorInstances g_instances;
1195 return g_instances;
1196}
1197
1198bool PluginManager::RegisterPlugin(llvm::StringRef name,
1199 llvm::StringRef description,
1200 SymbolVendorCreateInstance create_callback) {
1201 return GetSymbolVendorInstances().RegisterPlugin(name, description,
1202 callback: create_callback);
1203}
1204
1205bool PluginManager::UnregisterPlugin(
1206 SymbolVendorCreateInstance create_callback) {
1207 return GetSymbolVendorInstances().UnregisterPlugin(callback: create_callback);
1208}
1209
1210SymbolVendorCreateInstance
1211PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1212 return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
1213}
1214
1215#pragma mark SymbolLocator
1216
1217struct SymbolLocatorInstance
1218 : public PluginInstance<SymbolLocatorCreateInstance> {
1219 SymbolLocatorInstance(
1220 llvm::StringRef name, llvm::StringRef description,
1221 CallbackType create_callback,
1222 SymbolLocatorLocateExecutableObjectFile locate_executable_object_file,
1223 SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
1224 SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
1225 SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
1226 DebuggerInitializeCallback debugger_init_callback)
1227 : PluginInstance<SymbolLocatorCreateInstance>(
1228 name, description, create_callback, debugger_init_callback),
1229 locate_executable_object_file(locate_executable_object_file),
1230 locate_executable_symbol_file(locate_executable_symbol_file),
1231 download_object_symbol_file(download_object_symbol_file),
1232 find_symbol_file_in_bundle(find_symbol_file_in_bundle) {}
1233
1234 SymbolLocatorLocateExecutableObjectFile locate_executable_object_file;
1235 SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file;
1236 SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file;
1237 SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle;
1238};
1239typedef PluginInstances<SymbolLocatorInstance> SymbolLocatorInstances;
1240
1241static SymbolLocatorInstances &GetSymbolLocatorInstances() {
1242 static SymbolLocatorInstances g_instances;
1243 return g_instances;
1244}
1245
1246bool PluginManager::RegisterPlugin(
1247 llvm::StringRef name, llvm::StringRef description,
1248 SymbolLocatorCreateInstance create_callback,
1249 SymbolLocatorLocateExecutableObjectFile locate_executable_object_file,
1250 SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
1251 SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
1252 SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
1253 DebuggerInitializeCallback debugger_init_callback) {
1254 return GetSymbolLocatorInstances().RegisterPlugin(
1255 name, description, callback: create_callback, args&: locate_executable_object_file,
1256 args&: locate_executable_symbol_file, args&: download_object_symbol_file,
1257 args&: find_symbol_file_in_bundle, args&: debugger_init_callback);
1258}
1259
1260bool PluginManager::UnregisterPlugin(
1261 SymbolLocatorCreateInstance create_callback) {
1262 return GetSymbolLocatorInstances().UnregisterPlugin(callback: create_callback);
1263}
1264
1265SymbolLocatorCreateInstance
1266PluginManager::GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx) {
1267 return GetSymbolLocatorInstances().GetCallbackAtIndex(idx);
1268}
1269
1270ModuleSpec
1271PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec,
1272 StatisticsMap &map) {
1273 auto instances = GetSymbolLocatorInstances().GetSnapshot();
1274 for (auto &instance : instances) {
1275 if (instance.locate_executable_object_file) {
1276 StatsDuration time;
1277 std::optional<ModuleSpec> result;
1278 {
1279 ElapsedTime elapsed(time);
1280 result = instance.locate_executable_object_file(module_spec);
1281 }
1282 map.add(key: instance.name, value: time.get().count());
1283 if (result)
1284 return *result;
1285 }
1286 }
1287 return {};
1288}
1289
1290FileSpec PluginManager::LocateExecutableSymbolFile(
1291 const ModuleSpec &module_spec, const FileSpecList &default_search_paths,
1292 StatisticsMap &map) {
1293 auto instances = GetSymbolLocatorInstances().GetSnapshot();
1294 for (auto &instance : instances) {
1295 if (instance.locate_executable_symbol_file) {
1296 StatsDuration time;
1297 std::optional<FileSpec> result;
1298 {
1299 ElapsedTime elapsed(time);
1300 result = instance.locate_executable_symbol_file(module_spec,
1301 default_search_paths);
1302 }
1303 map.add(key: instance.name, value: time.get().count());
1304 if (result)
1305 return *result;
1306 }
1307 }
1308 return {};
1309}
1310
1311bool PluginManager::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
1312 Status &error,
1313 bool force_lookup,
1314 bool copy_executable) {
1315 auto instances = GetSymbolLocatorInstances().GetSnapshot();
1316 for (auto &instance : instances) {
1317 if (instance.download_object_symbol_file) {
1318 if (instance.download_object_symbol_file(module_spec, error, force_lookup,
1319 copy_executable))
1320 return true;
1321 }
1322 }
1323 return false;
1324}
1325
1326FileSpec PluginManager::FindSymbolFileInBundle(const FileSpec &symfile_bundle,
1327 const UUID *uuid,
1328 const ArchSpec *arch) {
1329 auto instances = GetSymbolLocatorInstances().GetSnapshot();
1330 for (auto &instance : instances) {
1331 if (instance.find_symbol_file_in_bundle) {
1332 std::optional<FileSpec> result =
1333 instance.find_symbol_file_in_bundle(symfile_bundle, uuid, arch);
1334 if (result)
1335 return *result;
1336 }
1337 }
1338 return {};
1339}
1340
1341#pragma mark Trace
1342
1343struct TraceInstance
1344 : public PluginInstance<TraceCreateInstanceFromBundle> {
1345 TraceInstance(
1346 llvm::StringRef name, llvm::StringRef description,
1347 CallbackType create_callback_from_bundle,
1348 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1349 llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback)
1350 : PluginInstance<TraceCreateInstanceFromBundle>(
1351 name, description, create_callback_from_bundle,
1352 debugger_init_callback),
1353 schema(schema),
1354 create_callback_for_live_process(create_callback_for_live_process) {}
1355
1356 llvm::StringRef schema;
1357 TraceCreateInstanceForLiveProcess create_callback_for_live_process;
1358};
1359
1360typedef PluginInstances<TraceInstance> TraceInstances;
1361
1362static TraceInstances &GetTracePluginInstances() {
1363 static TraceInstances g_instances;
1364 return g_instances;
1365}
1366
1367bool PluginManager::RegisterPlugin(
1368 llvm::StringRef name, llvm::StringRef description,
1369 TraceCreateInstanceFromBundle create_callback_from_bundle,
1370 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1371 llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback) {
1372 return GetTracePluginInstances().RegisterPlugin(
1373 name, description, callback: create_callback_from_bundle,
1374 args&: create_callback_for_live_process, args&: schema, args&: debugger_init_callback);
1375}
1376
1377bool PluginManager::UnregisterPlugin(
1378 TraceCreateInstanceFromBundle create_callback_from_bundle) {
1379 return GetTracePluginInstances().UnregisterPlugin(
1380 callback: create_callback_from_bundle);
1381}
1382
1383TraceCreateInstanceFromBundle
1384PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) {
1385 return GetTracePluginInstances().GetCallbackForName(name: plugin_name);
1386}
1387
1388TraceCreateInstanceForLiveProcess
1389PluginManager::GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name) {
1390 if (auto instance = GetTracePluginInstances().GetInstanceForName(name: plugin_name))
1391 return instance->create_callback_for_live_process;
1392
1393 return nullptr;
1394}
1395
1396llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) {
1397 if (auto instance = GetTracePluginInstances().GetInstanceForName(name: plugin_name))
1398 return instance->schema;
1399 return llvm::StringRef();
1400}
1401
1402llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
1403 if (const TraceInstance *instance =
1404 GetTracePluginInstances().GetInstanceAtIndex(idx: index))
1405 return instance->schema;
1406 return llvm::StringRef();
1407}
1408
1409#pragma mark TraceExporter
1410
1411struct TraceExporterInstance
1412 : public PluginInstance<TraceExporterCreateInstance> {
1413 TraceExporterInstance(
1414 llvm::StringRef name, llvm::StringRef description,
1415 TraceExporterCreateInstance create_instance,
1416 ThreadTraceExportCommandCreator create_thread_trace_export_command)
1417 : PluginInstance<TraceExporterCreateInstance>(name, description,
1418 create_instance),
1419 create_thread_trace_export_command(create_thread_trace_export_command) {
1420 }
1421
1422 ThreadTraceExportCommandCreator create_thread_trace_export_command;
1423};
1424
1425typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;
1426
1427static TraceExporterInstances &GetTraceExporterInstances() {
1428 static TraceExporterInstances g_instances;
1429 return g_instances;
1430}
1431
1432bool PluginManager::RegisterPlugin(
1433 llvm::StringRef name, llvm::StringRef description,
1434 TraceExporterCreateInstance create_callback,
1435 ThreadTraceExportCommandCreator create_thread_trace_export_command) {
1436 return GetTraceExporterInstances().RegisterPlugin(
1437 name, description, callback: create_callback, args&: create_thread_trace_export_command);
1438}
1439
1440TraceExporterCreateInstance
1441PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) {
1442 return GetTraceExporterInstances().GetCallbackForName(name: plugin_name);
1443}
1444
1445bool PluginManager::UnregisterPlugin(
1446 TraceExporterCreateInstance create_callback) {
1447 return GetTraceExporterInstances().UnregisterPlugin(callback: create_callback);
1448}
1449
1450ThreadTraceExportCommandCreator
1451PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
1452 if (const TraceExporterInstance *instance =
1453 GetTraceExporterInstances().GetInstanceAtIndex(idx: index))
1454 return instance->create_thread_trace_export_command;
1455 return nullptr;
1456}
1457
1458llvm::StringRef
1459PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
1460 return GetTraceExporterInstances().GetNameAtIndex(idx: index);
1461}
1462
1463#pragma mark UnwindAssembly
1464
1465typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
1466typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;
1467
1468static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1469 static UnwindAssemblyInstances g_instances;
1470 return g_instances;
1471}
1472
1473bool PluginManager::RegisterPlugin(
1474 llvm::StringRef name, llvm::StringRef description,
1475 UnwindAssemblyCreateInstance create_callback) {
1476 return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
1477 callback: create_callback);
1478}
1479
1480bool PluginManager::UnregisterPlugin(
1481 UnwindAssemblyCreateInstance create_callback) {
1482 return GetUnwindAssemblyInstances().UnregisterPlugin(callback: create_callback);
1483}
1484
1485UnwindAssemblyCreateInstance
1486PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1487 return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx);
1488}
1489
1490#pragma mark MemoryHistory
1491
1492typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
1493typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;
1494
1495static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1496 static MemoryHistoryInstances g_instances;
1497 return g_instances;
1498}
1499
1500bool PluginManager::RegisterPlugin(
1501 llvm::StringRef name, llvm::StringRef description,
1502 MemoryHistoryCreateInstance create_callback) {
1503 return GetMemoryHistoryInstances().RegisterPlugin(name, description,
1504 callback: create_callback);
1505}
1506
1507bool PluginManager::UnregisterPlugin(
1508 MemoryHistoryCreateInstance create_callback) {
1509 return GetMemoryHistoryInstances().UnregisterPlugin(callback: create_callback);
1510}
1511
1512MemoryHistoryCreateInstance
1513PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1514 return GetMemoryHistoryInstances().GetCallbackAtIndex(idx);
1515}
1516
1517#pragma mark InstrumentationRuntime
1518
1519struct InstrumentationRuntimeInstance
1520 : public PluginInstance<InstrumentationRuntimeCreateInstance> {
1521 InstrumentationRuntimeInstance(
1522 llvm::StringRef name, llvm::StringRef description,
1523 CallbackType create_callback,
1524 InstrumentationRuntimeGetType get_type_callback)
1525 : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description,
1526 create_callback),
1527 get_type_callback(get_type_callback) {}
1528
1529 InstrumentationRuntimeGetType get_type_callback = nullptr;
1530};
1531
1532typedef PluginInstances<InstrumentationRuntimeInstance>
1533 InstrumentationRuntimeInstances;
1534
1535static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1536 static InstrumentationRuntimeInstances g_instances;
1537 return g_instances;
1538}
1539
1540bool PluginManager::RegisterPlugin(
1541 llvm::StringRef name, llvm::StringRef description,
1542 InstrumentationRuntimeCreateInstance create_callback,
1543 InstrumentationRuntimeGetType get_type_callback) {
1544 return GetInstrumentationRuntimeInstances().RegisterPlugin(
1545 name, description, callback: create_callback, args&: get_type_callback);
1546}
1547
1548bool PluginManager::UnregisterPlugin(
1549 InstrumentationRuntimeCreateInstance create_callback) {
1550 return GetInstrumentationRuntimeInstances().UnregisterPlugin(callback: create_callback);
1551}
1552
1553InstrumentationRuntimeGetType
1554PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
1555 if (auto instance =
1556 GetInstrumentationRuntimeInstances().GetInstanceAtIndex(idx))
1557 return instance->get_type_callback;
1558 return nullptr;
1559}
1560
1561InstrumentationRuntimeCreateInstance
1562PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
1563 return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx);
1564}
1565
1566std::vector<RegisteredPluginInfo>
1567PluginManager::GetInstrumentationRuntimePluginInfo() {
1568 return GetInstrumentationRuntimeInstances().GetPluginInfoForAllInstances();
1569}
1570
1571bool PluginManager::SetInstrumentationRuntimePluginEnabled(llvm::StringRef name,
1572 bool enable) {
1573 return GetInstrumentationRuntimeInstances().SetInstanceEnabled(name, enable);
1574}
1575
1576#pragma mark TypeSystem
1577
1578struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
1579 TypeSystemInstance(llvm::StringRef name, llvm::StringRef description,
1580 CallbackType create_callback,
1581 LanguageSet supported_languages_for_types,
1582 LanguageSet supported_languages_for_expressions)
1583 : PluginInstance<TypeSystemCreateInstance>(name, description,
1584 create_callback),
1585 supported_languages_for_types(supported_languages_for_types),
1586 supported_languages_for_expressions(
1587 supported_languages_for_expressions) {}
1588
1589 LanguageSet supported_languages_for_types;
1590 LanguageSet supported_languages_for_expressions;
1591};
1592
1593typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;
1594
1595static TypeSystemInstances &GetTypeSystemInstances() {
1596 static TypeSystemInstances g_instances;
1597 return g_instances;
1598}
1599
1600bool PluginManager::RegisterPlugin(
1601 llvm::StringRef name, llvm::StringRef description,
1602 TypeSystemCreateInstance create_callback,
1603 LanguageSet supported_languages_for_types,
1604 LanguageSet supported_languages_for_expressions) {
1605 return GetTypeSystemInstances().RegisterPlugin(
1606 name, description, callback: create_callback, args&: supported_languages_for_types,
1607 args&: supported_languages_for_expressions);
1608}
1609
1610bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
1611 return GetTypeSystemInstances().UnregisterPlugin(callback: create_callback);
1612}
1613
1614TypeSystemCreateInstance
1615PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
1616 return GetTypeSystemInstances().GetCallbackAtIndex(idx);
1617}
1618
1619LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
1620 const auto instances = GetTypeSystemInstances().GetSnapshot();
1621 LanguageSet all;
1622 for (unsigned i = 0; i < instances.size(); ++i)
1623 all.bitvector |= instances[i].supported_languages_for_types.bitvector;
1624 return all;
1625}
1626
1627LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
1628 const auto instances = GetTypeSystemInstances().GetSnapshot();
1629 LanguageSet all;
1630 for (unsigned i = 0; i < instances.size(); ++i)
1631 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
1632 return all;
1633}
1634
1635#pragma mark ScriptedInterfaces
1636
1637struct ScriptedInterfaceInstance
1638 : public PluginInstance<ScriptedInterfaceCreateInstance> {
1639 ScriptedInterfaceInstance(llvm::StringRef name, llvm::StringRef description,
1640 ScriptedInterfaceCreateInstance create_callback,
1641 lldb::ScriptLanguage language,
1642 ScriptedInterfaceUsages usages)
1643 : PluginInstance<ScriptedInterfaceCreateInstance>(name, description,
1644 create_callback),
1645 language(language), usages(usages) {}
1646
1647 lldb::ScriptLanguage language;
1648 ScriptedInterfaceUsages usages;
1649};
1650
1651typedef PluginInstances<ScriptedInterfaceInstance> ScriptedInterfaceInstances;
1652
1653static ScriptedInterfaceInstances &GetScriptedInterfaceInstances() {
1654 static ScriptedInterfaceInstances g_instances;
1655 return g_instances;
1656}
1657
1658bool PluginManager::RegisterPlugin(
1659 llvm::StringRef name, llvm::StringRef description,
1660 ScriptedInterfaceCreateInstance create_callback,
1661 lldb::ScriptLanguage language, ScriptedInterfaceUsages usages) {
1662 return GetScriptedInterfaceInstances().RegisterPlugin(
1663 name, description, callback: create_callback, args&: language, args&: usages);
1664}
1665
1666bool PluginManager::UnregisterPlugin(
1667 ScriptedInterfaceCreateInstance create_callback) {
1668 return GetScriptedInterfaceInstances().UnregisterPlugin(callback: create_callback);
1669}
1670
1671uint32_t PluginManager::GetNumScriptedInterfaces() {
1672 return GetScriptedInterfaceInstances().GetSnapshot().size();
1673}
1674
1675llvm::StringRef PluginManager::GetScriptedInterfaceNameAtIndex(uint32_t index) {
1676 return GetScriptedInterfaceInstances().GetNameAtIndex(idx: index);
1677}
1678
1679llvm::StringRef
1680PluginManager::GetScriptedInterfaceDescriptionAtIndex(uint32_t index) {
1681 return GetScriptedInterfaceInstances().GetDescriptionAtIndex(idx: index);
1682}
1683
1684lldb::ScriptLanguage
1685PluginManager::GetScriptedInterfaceLanguageAtIndex(uint32_t idx) {
1686 if (auto instance = GetScriptedInterfaceInstances().GetInstanceAtIndex(idx))
1687 return instance->language;
1688 return ScriptLanguage::eScriptLanguageNone;
1689}
1690
1691ScriptedInterfaceUsages
1692PluginManager::GetScriptedInterfaceUsagesAtIndex(uint32_t idx) {
1693 if (auto instance = GetScriptedInterfaceInstances().GetInstanceAtIndex(idx))
1694 return instance->usages;
1695 return {};
1696}
1697
1698#pragma mark REPL
1699
1700struct REPLInstance : public PluginInstance<REPLCreateInstance> {
1701 REPLInstance(llvm::StringRef name, llvm::StringRef description,
1702 CallbackType create_callback, LanguageSet supported_languages)
1703 : PluginInstance<REPLCreateInstance>(name, description, create_callback),
1704 supported_languages(supported_languages) {}
1705
1706 LanguageSet supported_languages;
1707};
1708
1709typedef PluginInstances<REPLInstance> REPLInstances;
1710
1711static REPLInstances &GetREPLInstances() {
1712 static REPLInstances g_instances;
1713 return g_instances;
1714}
1715
1716bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
1717 REPLCreateInstance create_callback,
1718 LanguageSet supported_languages) {
1719 return GetREPLInstances().RegisterPlugin(name, description, callback: create_callback,
1720 args&: supported_languages);
1721}
1722
1723bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
1724 return GetREPLInstances().UnregisterPlugin(callback: create_callback);
1725}
1726
1727REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
1728 return GetREPLInstances().GetCallbackAtIndex(idx);
1729}
1730
1731LanguageSet PluginManager::GetREPLSupportedLanguagesAtIndex(uint32_t idx) {
1732 if (auto instance = GetREPLInstances().GetInstanceAtIndex(idx))
1733 return instance->supported_languages;
1734 return LanguageSet();
1735}
1736
1737LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
1738 const auto instances = GetREPLInstances().GetSnapshot();
1739 LanguageSet all;
1740 for (unsigned i = 0; i < instances.size(); ++i)
1741 all.bitvector |= instances[i].supported_languages.bitvector;
1742 return all;
1743}
1744
1745#pragma mark PluginManager
1746
1747void PluginManager::DebuggerInitialize(Debugger &debugger) {
1748 GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
1749 GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1750 GetObjectFileInstances().PerformDebuggerCallback(debugger);
1751 GetPlatformInstances().PerformDebuggerCallback(debugger);
1752 GetProcessInstances().PerformDebuggerCallback(debugger);
1753 GetSymbolFileInstances().PerformDebuggerCallback(debugger);
1754 GetSymbolLocatorInstances().PerformDebuggerCallback(debugger);
1755 GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
1756 GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
1757 GetTracePluginInstances().PerformDebuggerCallback(debugger);
1758 GetScriptedInterfaceInstances().PerformDebuggerCallback(debugger);
1759 GetLanguageInstances().PerformDebuggerCallback(debugger);
1760}
1761
1762// This is the preferred new way to register plugin specific settings. e.g.
1763// This will put a plugin's settings under e.g.
1764// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1765static lldb::OptionValuePropertiesSP
1766GetDebuggerPropertyForPlugins(Debugger &debugger, llvm::StringRef plugin_type_name,
1767 llvm::StringRef plugin_type_desc,
1768 bool can_create) {
1769 lldb::OptionValuePropertiesSP parent_properties_sp(
1770 debugger.GetValueProperties());
1771 if (parent_properties_sp) {
1772 static constexpr llvm::StringLiteral g_property_name("plugin");
1773
1774 OptionValuePropertiesSP plugin_properties_sp =
1775 parent_properties_sp->GetSubProperty(exe_ctx: nullptr, name: g_property_name);
1776 if (!plugin_properties_sp && can_create) {
1777 plugin_properties_sp =
1778 std::make_shared<OptionValueProperties>(args: g_property_name);
1779 parent_properties_sp->AppendProperty(name: g_property_name,
1780 desc: "Settings specify to plugins.", is_global: true,
1781 value_sp: plugin_properties_sp);
1782 }
1783
1784 if (plugin_properties_sp) {
1785 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1786 plugin_properties_sp->GetSubProperty(exe_ctx: nullptr, name: plugin_type_name);
1787 if (!plugin_type_properties_sp && can_create) {
1788 plugin_type_properties_sp =
1789 std::make_shared<OptionValueProperties>(args&: plugin_type_name);
1790 plugin_properties_sp->AppendProperty(name: plugin_type_name, desc: plugin_type_desc,
1791 is_global: true, value_sp: plugin_type_properties_sp);
1792 }
1793 return plugin_type_properties_sp;
1794 }
1795 }
1796 return lldb::OptionValuePropertiesSP();
1797}
1798
1799// This is deprecated way to register plugin specific settings. e.g.
1800// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
1801// generic settings would be under "platform.SETTINGNAME".
1802static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
1803 Debugger &debugger, llvm::StringRef plugin_type_name,
1804 llvm::StringRef plugin_type_desc, bool can_create) {
1805 static constexpr llvm::StringLiteral g_property_name("plugin");
1806 lldb::OptionValuePropertiesSP parent_properties_sp(
1807 debugger.GetValueProperties());
1808 if (parent_properties_sp) {
1809 OptionValuePropertiesSP plugin_properties_sp =
1810 parent_properties_sp->GetSubProperty(exe_ctx: nullptr, name: plugin_type_name);
1811 if (!plugin_properties_sp && can_create) {
1812 plugin_properties_sp =
1813 std::make_shared<OptionValueProperties>(args&: plugin_type_name);
1814 parent_properties_sp->AppendProperty(name: plugin_type_name, desc: plugin_type_desc,
1815 is_global: true, value_sp: plugin_properties_sp);
1816 }
1817
1818 if (plugin_properties_sp) {
1819 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1820 plugin_properties_sp->GetSubProperty(exe_ctx: nullptr, name: g_property_name);
1821 if (!plugin_type_properties_sp && can_create) {
1822 plugin_type_properties_sp =
1823 std::make_shared<OptionValueProperties>(args: g_property_name);
1824 plugin_properties_sp->AppendProperty(name: g_property_name,
1825 desc: "Settings specific to plugins",
1826 is_global: true, value_sp: plugin_type_properties_sp);
1827 }
1828 return plugin_type_properties_sp;
1829 }
1830 }
1831 return lldb::OptionValuePropertiesSP();
1832}
1833
1834namespace {
1835
1836typedef lldb::OptionValuePropertiesSP
1837GetDebuggerPropertyForPluginsPtr(Debugger &, llvm::StringRef, llvm::StringRef,
1838 bool can_create);
1839}
1840
1841static lldb::OptionValuePropertiesSP
1842GetSettingForPlugin(Debugger &debugger, llvm::StringRef setting_name,
1843 llvm::StringRef plugin_type_name,
1844 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1845 GetDebuggerPropertyForPlugins) {
1846 lldb::OptionValuePropertiesSP properties_sp;
1847 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
1848 debugger, plugin_type_name,
1849 "", // not creating to so we don't need the description
1850 false));
1851 if (plugin_type_properties_sp)
1852 properties_sp =
1853 plugin_type_properties_sp->GetSubProperty(exe_ctx: nullptr, name: setting_name);
1854 return properties_sp;
1855}
1856
1857static bool
1858CreateSettingForPlugin(Debugger &debugger, llvm::StringRef plugin_type_name,
1859 llvm::StringRef plugin_type_desc,
1860 const lldb::OptionValuePropertiesSP &properties_sp,
1861 llvm::StringRef description, bool is_global_property,
1862 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1863 GetDebuggerPropertyForPlugins) {
1864 if (properties_sp) {
1865 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1866 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
1867 true));
1868 if (plugin_type_properties_sp) {
1869 plugin_type_properties_sp->AppendProperty(name: properties_sp->GetName(),
1870 desc: description, is_global: is_global_property,
1871 value_sp: properties_sp);
1872 return true;
1873 }
1874 }
1875 return false;
1876}
1877
1878static constexpr llvm::StringLiteral kDynamicLoaderPluginName("dynamic-loader");
1879static constexpr llvm::StringLiteral kPlatformPluginName("platform");
1880static constexpr llvm::StringLiteral kProcessPluginName("process");
1881static constexpr llvm::StringLiteral kTracePluginName("trace");
1882static constexpr llvm::StringLiteral kObjectFilePluginName("object-file");
1883static constexpr llvm::StringLiteral kSymbolFilePluginName("symbol-file");
1884static constexpr llvm::StringLiteral kSymbolLocatorPluginName("symbol-locator");
1885static constexpr llvm::StringLiteral kJITLoaderPluginName("jit-loader");
1886static constexpr llvm::StringLiteral
1887 kStructuredDataPluginName("structured-data");
1888static constexpr llvm::StringLiteral kCPlusPlusLanguagePlugin("cplusplus");
1889
1890lldb::OptionValuePropertiesSP
1891PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
1892 llvm::StringRef setting_name) {
1893 return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kDynamicLoaderPluginName);
1894}
1895
1896bool PluginManager::CreateSettingForDynamicLoaderPlugin(
1897 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1898 llvm::StringRef description, bool is_global_property) {
1899 return CreateSettingForPlugin(debugger, plugin_type_name: kDynamicLoaderPluginName,
1900 plugin_type_desc: "Settings for dynamic loader plug-ins",
1901 properties_sp, description, is_global_property);
1902}
1903
1904lldb::OptionValuePropertiesSP
1905PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
1906 llvm::StringRef setting_name) {
1907 return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kPlatformPluginName,
1908 get_debugger_property: GetDebuggerPropertyForPluginsOldStyle);
1909}
1910
1911bool PluginManager::CreateSettingForPlatformPlugin(
1912 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1913 llvm::StringRef description, bool is_global_property) {
1914 return CreateSettingForPlugin(debugger, plugin_type_name: kPlatformPluginName,
1915 plugin_type_desc: "Settings for platform plug-ins", properties_sp,
1916 description, is_global_property,
1917 get_debugger_property: GetDebuggerPropertyForPluginsOldStyle);
1918}
1919
1920lldb::OptionValuePropertiesSP
1921PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
1922 llvm::StringRef setting_name) {
1923 return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kProcessPluginName);
1924}
1925
1926bool PluginManager::CreateSettingForProcessPlugin(
1927 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1928 llvm::StringRef description, bool is_global_property) {
1929 return CreateSettingForPlugin(debugger, plugin_type_name: kProcessPluginName,
1930 plugin_type_desc: "Settings for process plug-ins", properties_sp,
1931 description, is_global_property);
1932}
1933
1934lldb::OptionValuePropertiesSP
1935PluginManager::GetSettingForSymbolLocatorPlugin(Debugger &debugger,
1936 llvm::StringRef setting_name) {
1937 return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kSymbolLocatorPluginName);
1938}
1939
1940bool PluginManager::CreateSettingForSymbolLocatorPlugin(
1941 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1942 llvm::StringRef description, bool is_global_property) {
1943 return CreateSettingForPlugin(debugger, plugin_type_name: kSymbolLocatorPluginName,
1944 plugin_type_desc: "Settings for symbol locator plug-ins",
1945 properties_sp, description, is_global_property);
1946}
1947
1948bool PluginManager::CreateSettingForTracePlugin(
1949 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1950 llvm::StringRef description, bool is_global_property) {
1951 return CreateSettingForPlugin(debugger, plugin_type_name: kTracePluginName,
1952 plugin_type_desc: "Settings for trace plug-ins", properties_sp,
1953 description, is_global_property);
1954}
1955
1956lldb::OptionValuePropertiesSP
1957PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger,
1958 llvm::StringRef setting_name) {
1959 return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kObjectFilePluginName);
1960}
1961
1962bool PluginManager::CreateSettingForObjectFilePlugin(
1963 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1964 llvm::StringRef description, bool is_global_property) {
1965 return CreateSettingForPlugin(debugger, plugin_type_name: kObjectFilePluginName,
1966 plugin_type_desc: "Settings for object file plug-ins",
1967 properties_sp, description, is_global_property);
1968}
1969
1970lldb::OptionValuePropertiesSP
1971PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
1972 llvm::StringRef setting_name) {
1973 return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kSymbolFilePluginName);
1974}
1975
1976bool PluginManager::CreateSettingForSymbolFilePlugin(
1977 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1978 llvm::StringRef description, bool is_global_property) {
1979 return CreateSettingForPlugin(debugger, plugin_type_name: kSymbolFilePluginName,
1980 plugin_type_desc: "Settings for symbol file plug-ins",
1981 properties_sp, description, is_global_property);
1982}
1983
1984lldb::OptionValuePropertiesSP
1985PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
1986 llvm::StringRef setting_name) {
1987 return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kJITLoaderPluginName);
1988}
1989
1990bool PluginManager::CreateSettingForJITLoaderPlugin(
1991 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1992 llvm::StringRef description, bool is_global_property) {
1993 return CreateSettingForPlugin(debugger, plugin_type_name: kJITLoaderPluginName,
1994 plugin_type_desc: "Settings for JIT loader plug-ins",
1995 properties_sp, description, is_global_property);
1996}
1997
1998static const char *kOperatingSystemPluginName("os");
1999
2000lldb::OptionValuePropertiesSP
2001PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger,
2002 llvm::StringRef setting_name) {
2003 lldb::OptionValuePropertiesSP properties_sp;
2004 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2005 GetDebuggerPropertyForPlugins(
2006 debugger, plugin_type_name: kOperatingSystemPluginName,
2007 plugin_type_desc: "", // not creating to so we don't need the description
2008 can_create: false));
2009 if (plugin_type_properties_sp)
2010 properties_sp =
2011 plugin_type_properties_sp->GetSubProperty(exe_ctx: nullptr, name: setting_name);
2012 return properties_sp;
2013}
2014
2015bool PluginManager::CreateSettingForOperatingSystemPlugin(
2016 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2017 llvm::StringRef description, bool is_global_property) {
2018 if (properties_sp) {
2019 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
2020 GetDebuggerPropertyForPlugins(debugger, plugin_type_name: kOperatingSystemPluginName,
2021 plugin_type_desc: "Settings for operating system plug-ins",
2022 can_create: true));
2023 if (plugin_type_properties_sp) {
2024 plugin_type_properties_sp->AppendProperty(name: properties_sp->GetName(),
2025 desc: description, is_global: is_global_property,
2026 value_sp: properties_sp);
2027 return true;
2028 }
2029 }
2030 return false;
2031}
2032
2033lldb::OptionValuePropertiesSP
2034PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
2035 llvm::StringRef setting_name) {
2036 return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kStructuredDataPluginName);
2037}
2038
2039bool PluginManager::CreateSettingForStructuredDataPlugin(
2040 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2041 llvm::StringRef description, bool is_global_property) {
2042 return CreateSettingForPlugin(debugger, plugin_type_name: kStructuredDataPluginName,
2043 plugin_type_desc: "Settings for structured data plug-ins",
2044 properties_sp, description, is_global_property);
2045}
2046
2047lldb::OptionValuePropertiesSP
2048PluginManager::GetSettingForCPlusPlusLanguagePlugin(
2049 Debugger &debugger, llvm::StringRef setting_name) {
2050 return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kCPlusPlusLanguagePlugin);
2051}
2052
2053bool PluginManager::CreateSettingForCPlusPlusLanguagePlugin(
2054 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
2055 llvm::StringRef description, bool is_global_property) {
2056 return CreateSettingForPlugin(debugger, plugin_type_name: kCPlusPlusLanguagePlugin,
2057 plugin_type_desc: "Settings for CPlusPlus language plug-ins",
2058 properties_sp, description, is_global_property);
2059}
2060

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