Bug Summary

File:src/gnu/usr.bin/clang/liblldbCore/../../../llvm/lldb/source/Core/PluginManager.cpp
Warning:line 898, column 10
Called function pointer is null (null dereference)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name PluginManager.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbCore/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/liblldbCore/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/liblldbCore/../include -I /usr/src/gnu/usr.bin/clang/liblldbCore/obj -I /usr/src/gnu/usr.bin/clang/liblldbCore/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -I /usr/src/gnu/usr.bin/clang/liblldbCore/../../../llvm/lldb/include -I /usr/src/gnu/usr.bin/clang/liblldbCore/../../../llvm/lldb/source -I /usr/src/gnu/usr.bin/clang/liblldbCore/../../../llvm/clang/include -I /usr/src/gnu/usr.bin/clang/liblldbCore/obj/../include/lldb/Core -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbCore/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/liblldbCore/../../../llvm/lldb/source/Core/PluginManager.cpp
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 <cassert>
24#include <map>
25#include <memory>
26#include <mutex>
27#include <string>
28#include <utility>
29#include <vector>
30#if defined(_WIN32)
31#include "lldb/Host/windows/PosixApi.h"
32#endif
33
34using namespace lldb;
35using namespace lldb_private;
36
37typedef bool (*PluginInitCallback)();
38typedef void (*PluginTermCallback)();
39
40struct PluginInfo {
41 PluginInfo() = default;
42
43 llvm::sys::DynamicLibrary library;
44 PluginInitCallback plugin_init_callback = nullptr;
45 PluginTermCallback plugin_term_callback = nullptr;
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())((void)0);
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_MAX1024];
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)((void)0);
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")__builtin_unreachable();
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 lldb::SaveCoreStyle &core_style) {
689 Status error;
690 auto &instances = GetObjectFileInstances().GetInstances();
691 for (auto &instance : instances) {
692 if (instance.save_core &&
693 instance.save_core(process_sp, outfile, core_style, error))
694 return error;
695 }
696 error.SetErrorString(
697 "no ObjectFile plugins were able to save a core for this process");
698 return error;
699}
700
701#pragma mark ObjectContainer
702
703struct ObjectContainerInstance
704 : public PluginInstance<ObjectContainerCreateInstance> {
705 ObjectContainerInstance(
706 ConstString name, std::string description, CallbackType create_callback,
707 ObjectFileGetModuleSpecifications get_module_specifications)
708 : PluginInstance<ObjectContainerCreateInstance>(
709 name, std::move(description), create_callback),
710 get_module_specifications(get_module_specifications) {}
711
712 ObjectFileGetModuleSpecifications get_module_specifications;
713};
714typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;
715
716static ObjectContainerInstances &GetObjectContainerInstances() {
717 static ObjectContainerInstances g_instances;
718 return g_instances;
719}
720
721bool PluginManager::RegisterPlugin(
722 ConstString name, const char *description,
723 ObjectContainerCreateInstance create_callback,
724 ObjectFileGetModuleSpecifications get_module_specifications) {
725 return GetObjectContainerInstances().RegisterPlugin(
726 name, description, create_callback, get_module_specifications);
727}
728
729bool PluginManager::UnregisterPlugin(
730 ObjectContainerCreateInstance create_callback) {
731 return GetObjectContainerInstances().UnregisterPlugin(create_callback);
732}
733
734ObjectContainerCreateInstance
735PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
736 return GetObjectContainerInstances().GetCallbackAtIndex(idx);
737}
738
739ObjectFileGetModuleSpecifications
740PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
741 uint32_t idx) {
742 const auto &instances = GetObjectContainerInstances().GetInstances();
743 if (idx < instances.size())
744 return instances[idx].get_module_specifications;
745 return nullptr;
746}
747
748#pragma mark Platform
749
750typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
751typedef PluginInstances<PlatformInstance> PlatformInstances;
752
753static PlatformInstances &GetPlatformInstances() {
754 static PlatformInstances g_platform_instances;
755 return g_platform_instances;
756}
757
758bool PluginManager::RegisterPlugin(
759 ConstString name, const char *description,
760 PlatformCreateInstance create_callback,
761 DebuggerInitializeCallback debugger_init_callback) {
762 return GetPlatformInstances().RegisterPlugin(
763 name, description, create_callback, debugger_init_callback);
764}
765
766bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
767 return GetPlatformInstances().UnregisterPlugin(create_callback);
768}
769
770const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
771 return GetPlatformInstances().GetNameAtIndex(idx);
772}
773
774const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
775 return GetPlatformInstances().GetDescriptionAtIndex(idx);
776}
777
778PlatformCreateInstance
779PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
780 return GetPlatformInstances().GetCallbackAtIndex(idx);
781}
782
783PlatformCreateInstance
784PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) {
785 return GetPlatformInstances().GetCallbackForName(name);
786}
787
788void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
789 CompletionRequest &request) {
790 for (const auto &instance : GetPlatformInstances().GetInstances()) {
791 if (instance.name.GetStringRef().startswith(name))
792 request.AddCompletion(instance.name.GetCString());
793 }
794}
795
796#pragma mark Process
797
798typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
799typedef PluginInstances<ProcessInstance> ProcessInstances;
800
801static ProcessInstances &GetProcessInstances() {
802 static ProcessInstances g_instances;
803 return g_instances;
804}
805
806bool PluginManager::RegisterPlugin(
807 ConstString name, const char *description,
808 ProcessCreateInstance create_callback,
809 DebuggerInitializeCallback debugger_init_callback) {
810 return GetProcessInstances().RegisterPlugin(
811 name, description, create_callback, debugger_init_callback);
812}
813
814bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
815 return GetProcessInstances().UnregisterPlugin(create_callback);
816}
817
818const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
819 return GetProcessInstances().GetNameAtIndex(idx);
820}
821
822const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
823 return GetProcessInstances().GetDescriptionAtIndex(idx);
824}
825
826ProcessCreateInstance
827PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
828 return GetProcessInstances().GetCallbackAtIndex(idx);
829}
830
831ProcessCreateInstance
832PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) {
833 return GetProcessInstances().GetCallbackForName(name);
834}
835
836void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
837 CompletionRequest &request) {
838 for (const auto &instance : GetProcessInstances().GetInstances()) {
839 if (instance.name.GetStringRef().startswith(name))
840 request.AddCompletion(instance.name.GetCString(), instance.description);
841 }
842}
843
844#pragma mark ScriptInterpreter
845
846struct ScriptInterpreterInstance
847 : public PluginInstance<ScriptInterpreterCreateInstance> {
848 ScriptInterpreterInstance(ConstString name, std::string description,
849 CallbackType create_callback,
850 lldb::ScriptLanguage language)
851 : PluginInstance<ScriptInterpreterCreateInstance>(
852 name, std::move(description), create_callback),
853 language(language) {}
854
855 lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
856};
857
858typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;
859
860static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
861 static ScriptInterpreterInstances g_instances;
862 return g_instances;
863}
864
865bool PluginManager::RegisterPlugin(
866 ConstString name, const char *description,
867 lldb::ScriptLanguage script_language,
868 ScriptInterpreterCreateInstance create_callback) {
869 return GetScriptInterpreterInstances().RegisterPlugin(
870 name, description, create_callback, script_language);
871}
872
873bool PluginManager::UnregisterPlugin(
874 ScriptInterpreterCreateInstance create_callback) {
875 return GetScriptInterpreterInstances().UnregisterPlugin(create_callback);
876}
877
878ScriptInterpreterCreateInstance
879PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
880 return GetScriptInterpreterInstances().GetCallbackAtIndex(idx);
881}
882
883lldb::ScriptInterpreterSP
884PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
885 Debugger &debugger) {
886 const auto &instances = GetScriptInterpreterInstances().GetInstances();
887 ScriptInterpreterCreateInstance none_instance = nullptr;
1
'none_instance' initialized to a null pointer value
888 for (const auto &instance : instances) {
889 if (instance.language == lldb::eScriptLanguageNone)
890 none_instance = instance.create_callback;
891
892 if (script_lang == instance.language)
893 return instance.create_callback(debugger);
894 }
895
896 // If we didn't find one, return the ScriptInterpreter for the null language.
897 assert(none_instance != nullptr)((void)0);
898 return none_instance(debugger);
2
Called function pointer is null (null dereference)
899}
900
901#pragma mark StructuredDataPlugin
902
903struct StructuredDataPluginInstance
904 : public PluginInstance<StructuredDataPluginCreateInstance> {
905 StructuredDataPluginInstance(
906 ConstString name, std::string description, CallbackType create_callback,
907 DebuggerInitializeCallback debugger_init_callback,
908 StructuredDataFilterLaunchInfo filter_callback)
909 : PluginInstance<StructuredDataPluginCreateInstance>(
910 name, std::move(description), create_callback,
911 debugger_init_callback),
912 filter_callback(filter_callback) {}
913
914 StructuredDataFilterLaunchInfo filter_callback = nullptr;
915};
916
917typedef PluginInstances<StructuredDataPluginInstance>
918 StructuredDataPluginInstances;
919
920static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
921 static StructuredDataPluginInstances g_instances;
922 return g_instances;
923}
924
925bool PluginManager::RegisterPlugin(
926 ConstString name, const char *description,
927 StructuredDataPluginCreateInstance create_callback,
928 DebuggerInitializeCallback debugger_init_callback,
929 StructuredDataFilterLaunchInfo filter_callback) {
930 return GetStructuredDataPluginInstances().RegisterPlugin(
931 name, description, create_callback, debugger_init_callback,
932 filter_callback);
933}
934
935bool PluginManager::UnregisterPlugin(
936 StructuredDataPluginCreateInstance create_callback) {
937 return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback);
938}
939
940StructuredDataPluginCreateInstance
941PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
942 return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx);
943}
944
945StructuredDataFilterLaunchInfo
946PluginManager::GetStructuredDataFilterCallbackAtIndex(
947 uint32_t idx, bool &iteration_complete) {
948 const auto &instances = GetStructuredDataPluginInstances().GetInstances();
949 if (idx < instances.size()) {
950 iteration_complete = false;
951 return instances[idx].filter_callback;
952 } else {
953 iteration_complete = true;
954 }
955 return nullptr;
956}
957
958#pragma mark SymbolFile
959
960typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
961typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;
962
963static SymbolFileInstances &GetSymbolFileInstances() {
964 static SymbolFileInstances g_instances;
965 return g_instances;
966}
967
968bool PluginManager::RegisterPlugin(
969 ConstString name, const char *description,
970 SymbolFileCreateInstance create_callback,
971 DebuggerInitializeCallback debugger_init_callback) {
972 return GetSymbolFileInstances().RegisterPlugin(
973 name, description, create_callback, debugger_init_callback);
974}
975
976bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
977 return GetSymbolFileInstances().UnregisterPlugin(create_callback);
978}
979
980SymbolFileCreateInstance
981PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
982 return GetSymbolFileInstances().GetCallbackAtIndex(idx);
983}
984
985#pragma mark SymbolVendor
986
987typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
988typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;
989
990static SymbolVendorInstances &GetSymbolVendorInstances() {
991 static SymbolVendorInstances g_instances;
992 return g_instances;
993}
994
995bool PluginManager::RegisterPlugin(ConstString name, const char *description,
996 SymbolVendorCreateInstance create_callback) {
997 return GetSymbolVendorInstances().RegisterPlugin(name, description,
998 create_callback);
999}
1000
1001bool PluginManager::UnregisterPlugin(
1002 SymbolVendorCreateInstance create_callback) {
1003 return GetSymbolVendorInstances().UnregisterPlugin(create_callback);
1004}
1005
1006SymbolVendorCreateInstance
1007PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1008 return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
1009}
1010
1011#pragma mark Trace
1012
1013struct TraceInstance
1014 : public PluginInstance<TraceCreateInstanceForSessionFile> {
1015 TraceInstance(
1016 ConstString name, std::string description,
1017 CallbackType create_callback_for_session_file,
1018 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1019 llvm::StringRef schema)
1020 : PluginInstance<TraceCreateInstanceForSessionFile>(
1021 name, std::move(description), create_callback_for_session_file),
1022 schema(schema),
1023 create_callback_for_live_process(create_callback_for_live_process) {}
1024
1025 llvm::StringRef schema;
1026 TraceCreateInstanceForLiveProcess create_callback_for_live_process;
1027};
1028
1029typedef PluginInstances<TraceInstance> TraceInstances;
1030
1031static TraceInstances &GetTracePluginInstances() {
1032 static TraceInstances g_instances;
1033 return g_instances;
1034}
1035
1036bool PluginManager::RegisterPlugin(
1037 ConstString name, const char *description,
1038 TraceCreateInstanceForSessionFile create_callback_for_session_file,
1039 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1040 llvm::StringRef schema) {
1041 return GetTracePluginInstances().RegisterPlugin(
1042 name, description, create_callback_for_session_file,
1043 create_callback_for_live_process, schema);
1044}
1045
1046bool PluginManager::UnregisterPlugin(
1047 TraceCreateInstanceForSessionFile create_callback_for_session_file) {
1048 return GetTracePluginInstances().UnregisterPlugin(
1049 create_callback_for_session_file);
1050}
1051
1052TraceCreateInstanceForSessionFile
1053PluginManager::GetTraceCreateCallback(ConstString plugin_name) {
1054 return GetTracePluginInstances().GetCallbackForName(plugin_name);
1055}
1056
1057TraceCreateInstanceForLiveProcess
1058PluginManager::GetTraceCreateCallbackForLiveProcess(ConstString plugin_name) {
1059 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1060 if (instance.name == plugin_name)
1061 return instance.create_callback_for_live_process;
1062 return nullptr;
1063}
1064
1065llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) {
1066 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1067 if (instance.name == plugin_name)
1068 return instance.schema;
1069 return llvm::StringRef();
1070}
1071
1072llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
1073 if (TraceInstance *instance =
1074 GetTracePluginInstances().GetInstanceAtIndex(index))
1075 return instance->schema;
1076 return llvm::StringRef();
1077}
1078
1079#pragma mark TraceExporter
1080
1081struct TraceExporterInstance
1082 : public PluginInstance<TraceExporterCreateInstance> {
1083 TraceExporterInstance(
1084 ConstString name, std::string description,
1085 TraceExporterCreateInstance create_instance,
1086 ThreadTraceExportCommandCreator create_thread_trace_export_command)
1087 : PluginInstance<TraceExporterCreateInstance>(
1088 name, std::move(description), create_instance),
1089 create_thread_trace_export_command(create_thread_trace_export_command) {
1090 }
1091
1092 ThreadTraceExportCommandCreator create_thread_trace_export_command;
1093};
1094
1095typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;
1096
1097static TraceExporterInstances &GetTraceExporterInstances() {
1098 static TraceExporterInstances g_instances;
1099 return g_instances;
1100}
1101
1102bool PluginManager::RegisterPlugin(
1103 ConstString name, const char *description,
1104 TraceExporterCreateInstance create_callback,
1105 ThreadTraceExportCommandCreator create_thread_trace_export_command) {
1106 return GetTraceExporterInstances().RegisterPlugin(
1107 name, description, create_callback, create_thread_trace_export_command);
1108}
1109
1110TraceExporterCreateInstance
1111PluginManager::GetTraceExporterCreateCallback(ConstString plugin_name) {
1112 return GetTraceExporterInstances().GetCallbackForName(plugin_name);
1113}
1114
1115bool PluginManager::UnregisterPlugin(
1116 TraceExporterCreateInstance create_callback) {
1117 return GetTraceExporterInstances().UnregisterPlugin(create_callback);
1118}
1119
1120ThreadTraceExportCommandCreator
1121PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
1122 if (TraceExporterInstance *instance =
1123 GetTraceExporterInstances().GetInstanceAtIndex(index))
1124 return instance->create_thread_trace_export_command;
1125 return nullptr;
1126}
1127
1128const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
1129 return GetTraceExporterInstances().GetNameAtIndex(index);
1130}
1131
1132#pragma mark UnwindAssembly
1133
1134typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
1135typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;
1136
1137static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1138 static UnwindAssemblyInstances g_instances;
1139 return g_instances;
1140}
1141
1142bool PluginManager::RegisterPlugin(
1143 ConstString name, const char *description,
1144 UnwindAssemblyCreateInstance create_callback) {
1145 return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
1146 create_callback);
1147}
1148
1149bool PluginManager::UnregisterPlugin(
1150 UnwindAssemblyCreateInstance create_callback) {
1151 return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback);
1152}
1153
1154UnwindAssemblyCreateInstance
1155PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1156 return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx);
1157}
1158
1159#pragma mark MemoryHistory
1160
1161typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
1162typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;
1163
1164static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1165 static MemoryHistoryInstances g_instances;
1166 return g_instances;
1167}
1168
1169bool PluginManager::RegisterPlugin(
1170 ConstString name, const char *description,
1171 MemoryHistoryCreateInstance create_callback) {
1172 return GetMemoryHistoryInstances().RegisterPlugin(name, description,
1173 create_callback);
1174}
1175
1176bool PluginManager::UnregisterPlugin(
1177 MemoryHistoryCreateInstance create_callback) {
1178 return GetMemoryHistoryInstances().UnregisterPlugin(create_callback);
1179}
1180
1181MemoryHistoryCreateInstance
1182PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1183 return GetMemoryHistoryInstances().GetCallbackAtIndex(idx);
1184}
1185
1186#pragma mark InstrumentationRuntime
1187
1188struct InstrumentationRuntimeInstance
1189 : public PluginInstance<InstrumentationRuntimeCreateInstance> {
1190 InstrumentationRuntimeInstance(
1191 ConstString name, std::string description, CallbackType create_callback,
1192 InstrumentationRuntimeGetType get_type_callback)
1193 : PluginInstance<InstrumentationRuntimeCreateInstance>(
1194 name, std::move(description), create_callback),
1195 get_type_callback(get_type_callback) {}
1196
1197 InstrumentationRuntimeGetType get_type_callback = nullptr;
1198};
1199
1200typedef PluginInstances<InstrumentationRuntimeInstance>
1201 InstrumentationRuntimeInstances;
1202
1203static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1204 static InstrumentationRuntimeInstances g_instances;
1205 return g_instances;
1206}
1207
1208bool PluginManager::RegisterPlugin(
1209 ConstString name, const char *description,
1210 InstrumentationRuntimeCreateInstance create_callback,
1211 InstrumentationRuntimeGetType get_type_callback) {
1212 return GetInstrumentationRuntimeInstances().RegisterPlugin(
1213 name, description, create_callback, get_type_callback);
1214}
1215
1216bool PluginManager::UnregisterPlugin(
1217 InstrumentationRuntimeCreateInstance create_callback) {
1218 return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback);
1219}
1220
1221InstrumentationRuntimeGetType
1222PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
1223 const auto &instances = GetInstrumentationRuntimeInstances().GetInstances();
1224 if (idx < instances.size())
1225 return instances[idx].get_type_callback;
1226 return nullptr;
1227}
1228
1229InstrumentationRuntimeCreateInstance
1230PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
1231 return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx);
1232}
1233
1234#pragma mark TypeSystem
1235
1236struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
1237 TypeSystemInstance(ConstString name, std::string description,
1238 CallbackType create_callback,
1239 LanguageSet supported_languages_for_types,
1240 LanguageSet supported_languages_for_expressions)
1241 : PluginInstance<TypeSystemCreateInstance>(name, std::move(description),
1242 create_callback),
1243 supported_languages_for_types(supported_languages_for_types),
1244 supported_languages_for_expressions(
1245 supported_languages_for_expressions) {}
1246
1247 LanguageSet supported_languages_for_types;
1248 LanguageSet supported_languages_for_expressions;
1249};
1250
1251typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;
1252
1253static TypeSystemInstances &GetTypeSystemInstances() {
1254 static TypeSystemInstances g_instances;
1255 return g_instances;
1256}
1257
1258bool PluginManager::RegisterPlugin(
1259 ConstString name, const char *description,
1260 TypeSystemCreateInstance create_callback,
1261 LanguageSet supported_languages_for_types,
1262 LanguageSet supported_languages_for_expressions) {
1263 return GetTypeSystemInstances().RegisterPlugin(
1264 name, description, create_callback, supported_languages_for_types,
1265 supported_languages_for_expressions);
1266}
1267
1268bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
1269 return GetTypeSystemInstances().UnregisterPlugin(create_callback);
1270}
1271
1272TypeSystemCreateInstance
1273PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
1274 return GetTypeSystemInstances().GetCallbackAtIndex(idx);
1275}
1276
1277LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
1278 const auto &instances = GetTypeSystemInstances().GetInstances();
1279 LanguageSet all;
1280 for (unsigned i = 0; i < instances.size(); ++i)
1281 all.bitvector |= instances[i].supported_languages_for_types.bitvector;
1282 return all;
1283}
1284
1285LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
1286 const auto &instances = GetTypeSystemInstances().GetInstances();
1287 LanguageSet all;
1288 for (unsigned i = 0; i < instances.size(); ++i)
1289 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
1290 return all;
1291}
1292
1293#pragma mark REPL
1294
1295struct REPLInstance : public PluginInstance<REPLCreateInstance> {
1296 REPLInstance(ConstString name, std::string description,
1297 CallbackType create_callback, LanguageSet supported_languages)
1298 : PluginInstance<REPLCreateInstance>(name, std::move(description),
1299 create_callback),
1300 supported_languages(supported_languages) {}
1301
1302 LanguageSet supported_languages;
1303};
1304
1305typedef PluginInstances<REPLInstance> REPLInstances;
1306
1307static REPLInstances &GetREPLInstances() {
1308 static REPLInstances g_instances;
1309 return g_instances;
1310}
1311
1312bool PluginManager::RegisterPlugin(ConstString name, const char *description,
1313 REPLCreateInstance create_callback,
1314 LanguageSet supported_languages) {
1315 return GetREPLInstances().RegisterPlugin(name, description, create_callback,
1316 supported_languages);
1317}
1318
1319bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
1320 return GetREPLInstances().UnregisterPlugin(create_callback);
1321}
1322
1323REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
1324 return GetREPLInstances().GetCallbackAtIndex(idx);
1325}
1326
1327LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
1328 const auto &instances = GetREPLInstances().GetInstances();
1329 LanguageSet all;
1330 for (unsigned i = 0; i < instances.size(); ++i)
1331 all.bitvector |= instances[i].supported_languages.bitvector;
1332 return all;
1333}
1334
1335#pragma mark PluginManager
1336
1337void PluginManager::DebuggerInitialize(Debugger &debugger) {
1338 GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
1339 GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1340 GetPlatformInstances().PerformDebuggerCallback(debugger);
1341 GetProcessInstances().PerformDebuggerCallback(debugger);
1342 GetSymbolFileInstances().PerformDebuggerCallback(debugger);
1343 GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
1344 GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
1345 GetTracePluginInstances().PerformDebuggerCallback(debugger);
1346}
1347
1348// This is the preferred new way to register plugin specific settings. e.g.
1349// This will put a plugin's settings under e.g.
1350// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1351static lldb::OptionValuePropertiesSP
1352GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name,
1353 ConstString plugin_type_desc, bool can_create) {
1354 lldb::OptionValuePropertiesSP parent_properties_sp(
1355 debugger.GetValueProperties());
1356 if (parent_properties_sp) {
1357 static ConstString g_property_name("plugin");
1358
1359 OptionValuePropertiesSP plugin_properties_sp =
1360 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
1361 if (!plugin_properties_sp && can_create) {
1362 plugin_properties_sp =
1363 std::make_shared<OptionValueProperties>(g_property_name);
1364 parent_properties_sp->AppendProperty(
1365 g_property_name, ConstString("Settings specify to plugins."), true,
1366 plugin_properties_sp);
1367 }
1368
1369 if (plugin_properties_sp) {
1370 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1371 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1372 if (!plugin_type_properties_sp && can_create) {
1373 plugin_type_properties_sp =
1374 std::make_shared<OptionValueProperties>(plugin_type_name);
1375 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1376 true, plugin_type_properties_sp);
1377 }
1378 return plugin_type_properties_sp;
1379 }
1380 }
1381 return lldb::OptionValuePropertiesSP();
1382}
1383
1384// This is deprecated way to register plugin specific settings. e.g.
1385// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
1386// generic settings would be under "platform.SETTINGNAME".
1387static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
1388 Debugger &debugger, ConstString plugin_type_name,
1389 ConstString plugin_type_desc, bool can_create) {
1390 static ConstString g_property_name("plugin");
1391 lldb::OptionValuePropertiesSP parent_properties_sp(
1392 debugger.GetValueProperties());
1393 if (parent_properties_sp) {
1394 OptionValuePropertiesSP plugin_properties_sp =
1395 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1396 if (!plugin_properties_sp && can_create) {
1397 plugin_properties_sp =
1398 std::make_shared<OptionValueProperties>(plugin_type_name);
1399 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1400 true, plugin_properties_sp);
1401 }
1402
1403 if (plugin_properties_sp) {
1404 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1405 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
1406 if (!plugin_type_properties_sp && can_create) {
1407 plugin_type_properties_sp =
1408 std::make_shared<OptionValueProperties>(g_property_name);
1409 plugin_properties_sp->AppendProperty(
1410 g_property_name, ConstString("Settings specific to plugins"), true,
1411 plugin_type_properties_sp);
1412 }
1413 return plugin_type_properties_sp;
1414 }
1415 }
1416 return lldb::OptionValuePropertiesSP();
1417}
1418
1419namespace {
1420
1421typedef lldb::OptionValuePropertiesSP
1422GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString,
1423 bool can_create);
1424
1425lldb::OptionValuePropertiesSP
1426GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
1427 ConstString plugin_type_name,
1428 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1429 GetDebuggerPropertyForPlugins) {
1430 lldb::OptionValuePropertiesSP properties_sp;
1431 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
1432 debugger, plugin_type_name,
1433 ConstString(), // not creating to so we don't need the description
1434 false));
1435 if (plugin_type_properties_sp)
1436 properties_sp =
1437 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1438 return properties_sp;
1439}
1440
1441bool CreateSettingForPlugin(
1442 Debugger &debugger, ConstString plugin_type_name,
1443 ConstString plugin_type_desc,
1444 const lldb::OptionValuePropertiesSP &properties_sp, ConstString description,
1445 bool is_global_property,
1446 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1447 GetDebuggerPropertyForPlugins) {
1448 if (properties_sp) {
1449 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1450 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
1451 true));
1452 if (plugin_type_properties_sp) {
1453 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1454 description, is_global_property,
1455 properties_sp);
1456 return true;
1457 }
1458 }
1459 return false;
1460}
1461
1462const char *kDynamicLoaderPluginName("dynamic-loader");
1463const char *kPlatformPluginName("platform");
1464const char *kProcessPluginName("process");
1465const char *kSymbolFilePluginName("symbol-file");
1466const char *kJITLoaderPluginName("jit-loader");
1467const char *kStructuredDataPluginName("structured-data");
1468
1469} // anonymous namespace
1470
1471lldb::OptionValuePropertiesSP
1472PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
1473 ConstString setting_name) {
1474 return GetSettingForPlugin(debugger, setting_name,
1475 ConstString(kDynamicLoaderPluginName));
1476}
1477
1478bool PluginManager::CreateSettingForDynamicLoaderPlugin(
1479 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1480 ConstString description, bool is_global_property) {
1481 return CreateSettingForPlugin(
1482 debugger, ConstString(kDynamicLoaderPluginName),
1483 ConstString("Settings for dynamic loader plug-ins"), properties_sp,
1484 description, is_global_property);
1485}
1486
1487lldb::OptionValuePropertiesSP
1488PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
1489 ConstString setting_name) {
1490 return GetSettingForPlugin(debugger, setting_name,
1491 ConstString(kPlatformPluginName),
1492 GetDebuggerPropertyForPluginsOldStyle);
1493}
1494
1495bool PluginManager::CreateSettingForPlatformPlugin(
1496 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1497 ConstString description, bool is_global_property) {
1498 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
1499 ConstString("Settings for platform plug-ins"),
1500 properties_sp, description, is_global_property,
1501 GetDebuggerPropertyForPluginsOldStyle);
1502}
1503
1504lldb::OptionValuePropertiesSP
1505PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
1506 ConstString setting_name) {
1507 return GetSettingForPlugin(debugger, setting_name,
1508 ConstString(kProcessPluginName));
1509}
1510
1511bool PluginManager::CreateSettingForProcessPlugin(
1512 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1513 ConstString description, bool is_global_property) {
1514 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
1515 ConstString("Settings for process plug-ins"),
1516 properties_sp, description, is_global_property);
1517}
1518
1519lldb::OptionValuePropertiesSP
1520PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
1521 ConstString setting_name) {
1522 return GetSettingForPlugin(debugger, setting_name,
1523 ConstString(kSymbolFilePluginName));
1524}
1525
1526bool PluginManager::CreateSettingForSymbolFilePlugin(
1527 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1528 ConstString description, bool is_global_property) {
1529 return CreateSettingForPlugin(
1530 debugger, ConstString(kSymbolFilePluginName),
1531 ConstString("Settings for symbol file plug-ins"), properties_sp,
1532 description, is_global_property);
1533}
1534
1535lldb::OptionValuePropertiesSP
1536PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
1537 ConstString setting_name) {
1538 return GetSettingForPlugin(debugger, setting_name,
1539 ConstString(kJITLoaderPluginName));
1540}
1541
1542bool PluginManager::CreateSettingForJITLoaderPlugin(
1543 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1544 ConstString description, bool is_global_property) {
1545 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
1546 ConstString("Settings for JIT loader plug-ins"),
1547 properties_sp, description, is_global_property);
1548}
1549
1550static const char *kOperatingSystemPluginName("os");
1551
1552lldb::OptionValuePropertiesSP
1553PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger,
1554 ConstString setting_name) {
1555 lldb::OptionValuePropertiesSP properties_sp;
1556 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1557 GetDebuggerPropertyForPlugins(
1558 debugger, ConstString(kOperatingSystemPluginName),
1559 ConstString(), // not creating to so we don't need the description
1560 false));
1561 if (plugin_type_properties_sp)
1562 properties_sp =
1563 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1564 return properties_sp;
1565}
1566
1567bool PluginManager::CreateSettingForOperatingSystemPlugin(
1568 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1569 ConstString description, bool is_global_property) {
1570 if (properties_sp) {
1571 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1572 GetDebuggerPropertyForPlugins(
1573 debugger, ConstString(kOperatingSystemPluginName),
1574 ConstString("Settings for operating system plug-ins"), true));
1575 if (plugin_type_properties_sp) {
1576 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1577 description, is_global_property,
1578 properties_sp);
1579 return true;
1580 }
1581 }
1582 return false;
1583}
1584
1585lldb::OptionValuePropertiesSP
1586PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
1587 ConstString setting_name) {
1588 return GetSettingForPlugin(debugger, setting_name,
1589 ConstString(kStructuredDataPluginName));
1590}
1591
1592bool PluginManager::CreateSettingForStructuredDataPlugin(
1593 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1594 ConstString description, bool is_global_property) {
1595 return CreateSettingForPlugin(
1596 debugger, ConstString(kStructuredDataPluginName),
1597 ConstString("Settings for structured data plug-ins"), properties_sp,
1598 description, is_global_property);
1599}