1 //===-- PluginManager.cpp -------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Core/PluginManager.h"
10
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Host/FileSystem.h"
13 #include "lldb/Host/HostInfo.h"
14 #include "lldb/Interpreter/OptionValueProperties.h"
15 #include "lldb/Symbol/SaveCoreOptions.h"
16 #include "lldb/Target/Process.h"
17 #include "lldb/Utility/FileSpec.h"
18 #include "lldb/Utility/Status.h"
19 #include "lldb/Utility/StringList.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/DynamicLibrary.h"
22 #include "llvm/Support/FileSystem.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include <cassert>
25 #include <map>
26 #include <memory>
27 #include <mutex>
28 #include <string>
29 #include <utility>
30 #include <vector>
31 #if defined(_WIN32)
32 #include "lldb/Host/windows/PosixApi.h"
33 #endif
34
35 using namespace lldb;
36 using namespace lldb_private;
37
38 typedef bool (*PluginInitCallback)();
39 typedef void (*PluginTermCallback)();
40
41 struct PluginInfo {
42 PluginInfo() = default;
43
44 llvm::sys::DynamicLibrary library;
45 PluginInitCallback plugin_init_callback = nullptr;
46 PluginTermCallback plugin_term_callback = nullptr;
47 };
48
49 typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
50
GetPluginMapMutex()51 static std::recursive_mutex &GetPluginMapMutex() {
52 static std::recursive_mutex g_plugin_map_mutex;
53 return g_plugin_map_mutex;
54 }
55
GetPluginMap()56 static PluginTerminateMap &GetPluginMap() {
57 static PluginTerminateMap g_plugin_map;
58 return g_plugin_map;
59 }
60
PluginIsLoaded(const FileSpec & plugin_file_spec)61 static bool PluginIsLoaded(const FileSpec &plugin_file_spec) {
62 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
63 PluginTerminateMap &plugin_map = GetPluginMap();
64 return plugin_map.find(plugin_file_spec) != plugin_map.end();
65 }
66
SetPluginInfo(const FileSpec & plugin_file_spec,const PluginInfo & plugin_info)67 static void SetPluginInfo(const FileSpec &plugin_file_spec,
68 const PluginInfo &plugin_info) {
69 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
70 PluginTerminateMap &plugin_map = GetPluginMap();
71 assert(plugin_map.find(plugin_file_spec) == plugin_map.end());
72 plugin_map[plugin_file_spec] = plugin_info;
73 }
74
CastToFPtr(void * VPtr)75 template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
76 return reinterpret_cast<FPtrTy>(VPtr);
77 }
78
79 static FileSystem::EnumerateDirectoryResult
LoadPluginCallback(void * baton,llvm::sys::fs::file_type ft,llvm::StringRef path)80 LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
81 llvm::StringRef path) {
82 Status error;
83
84 namespace fs = llvm::sys::fs;
85 // If we have a regular file, a symbolic link or unknown file type, try and
86 // process the file. We must handle unknown as sometimes the directory
87 // enumeration might be enumerating a file system that doesn't have correct
88 // file type information.
89 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
90 ft == fs::file_type::type_unknown) {
91 FileSpec plugin_file_spec(path);
92 FileSystem::Instance().Resolve(plugin_file_spec);
93
94 if (PluginIsLoaded(plugin_file_spec))
95 return FileSystem::eEnumerateDirectoryResultNext;
96 else {
97 PluginInfo plugin_info;
98
99 std::string pluginLoadError;
100 plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary(
101 plugin_file_spec.GetPath().c_str(), &pluginLoadError);
102 if (plugin_info.library.isValid()) {
103 bool success = false;
104 plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>(
105 plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
106 if (plugin_info.plugin_init_callback) {
107 // Call the plug-in "bool LLDBPluginInitialize(void)" function
108 success = plugin_info.plugin_init_callback();
109 }
110
111 if (success) {
112 // It is ok for the "LLDBPluginTerminate" symbol to be nullptr
113 plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>(
114 plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
115 } else {
116 // The initialize function returned FALSE which means the plug-in
117 // might not be compatible, or might be too new or too old, or might
118 // not want to run on this machine. Set it to a default-constructed
119 // instance to invalidate it.
120 plugin_info = PluginInfo();
121 }
122
123 // Regardless of success or failure, cache the plug-in load in our
124 // plug-in info so we don't try to load it again and again.
125 SetPluginInfo(plugin_file_spec, plugin_info);
126
127 return FileSystem::eEnumerateDirectoryResultNext;
128 }
129 }
130 }
131
132 if (ft == fs::file_type::directory_file ||
133 ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
134 // Try and recurse into anything that a directory or symbolic link. We must
135 // also do this for unknown as sometimes the directory enumeration might be
136 // enumerating a file system that doesn't have correct file type
137 // information.
138 return FileSystem::eEnumerateDirectoryResultEnter;
139 }
140
141 return FileSystem::eEnumerateDirectoryResultNext;
142 }
143
Initialize()144 void PluginManager::Initialize() {
145 const bool find_directories = true;
146 const bool find_files = true;
147 const bool find_other = true;
148 char dir_path[PATH_MAX];
149 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
150 if (FileSystem::Instance().Exists(dir_spec) &&
151 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
152 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
153 find_files, find_other,
154 LoadPluginCallback, nullptr);
155 }
156 }
157
158 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
159 if (FileSystem::Instance().Exists(dir_spec) &&
160 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
161 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
162 find_files, find_other,
163 LoadPluginCallback, nullptr);
164 }
165 }
166 }
167
Terminate()168 void PluginManager::Terminate() {
169 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
170 PluginTerminateMap &plugin_map = GetPluginMap();
171
172 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
173 for (pos = plugin_map.begin(); pos != end; ++pos) {
174 // Call the plug-in "void LLDBPluginTerminate (void)" function if there is
175 // one (if the symbol was not nullptr).
176 if (pos->second.library.isValid()) {
177 if (pos->second.plugin_term_callback)
178 pos->second.plugin_term_callback();
179 }
180 }
181 plugin_map.clear();
182 }
183
184 template <typename Callback> struct PluginInstance {
185 typedef Callback CallbackType;
186
187 PluginInstance() = default;
PluginInstancePluginInstance188 PluginInstance(llvm::StringRef name, llvm::StringRef description,
189 Callback create_callback,
190 DebuggerInitializeCallback debugger_init_callback = nullptr)
191 : name(name), description(description), create_callback(create_callback),
192 debugger_init_callback(debugger_init_callback) {}
193
194 llvm::StringRef name;
195 llvm::StringRef description;
196 Callback create_callback;
197 DebuggerInitializeCallback debugger_init_callback;
198 };
199
200 template <typename Instance> class PluginInstances {
201 public:
202 template <typename... Args>
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,typename Instance::CallbackType callback,Args &&...args)203 bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
204 typename Instance::CallbackType callback,
205 Args &&...args) {
206 if (!callback)
207 return false;
208 assert(!name.empty());
209 Instance instance =
210 Instance(name, description, callback, std::forward<Args>(args)...);
211 m_instances.push_back(instance);
212 return false;
213 }
214
UnregisterPlugin(typename Instance::CallbackType callback)215 bool UnregisterPlugin(typename Instance::CallbackType callback) {
216 if (!callback)
217 return false;
218 auto pos = m_instances.begin();
219 auto end = m_instances.end();
220 for (; pos != end; ++pos) {
221 if (pos->create_callback == callback) {
222 m_instances.erase(pos);
223 return true;
224 }
225 }
226 return false;
227 }
228
GetCallbackAtIndex(uint32_t idx)229 typename Instance::CallbackType GetCallbackAtIndex(uint32_t idx) {
230 if (Instance *instance = GetInstanceAtIndex(idx))
231 return instance->create_callback;
232 return nullptr;
233 }
234
GetDescriptionAtIndex(uint32_t idx)235 llvm::StringRef GetDescriptionAtIndex(uint32_t idx) {
236 if (Instance *instance = GetInstanceAtIndex(idx))
237 return instance->description;
238 return "";
239 }
240
GetNameAtIndex(uint32_t idx)241 llvm::StringRef GetNameAtIndex(uint32_t idx) {
242 if (Instance *instance = GetInstanceAtIndex(idx))
243 return instance->name;
244 return "";
245 }
246
GetCallbackForName(llvm::StringRef name)247 typename Instance::CallbackType GetCallbackForName(llvm::StringRef name) {
248 if (name.empty())
249 return nullptr;
250 for (auto &instance : m_instances) {
251 if (name == instance.name)
252 return instance.create_callback;
253 }
254 return nullptr;
255 }
256
PerformDebuggerCallback(Debugger & debugger)257 void PerformDebuggerCallback(Debugger &debugger) {
258 for (auto &instance : m_instances) {
259 if (instance.debugger_init_callback)
260 instance.debugger_init_callback(debugger);
261 }
262 }
263
GetInstances() const264 const std::vector<Instance> &GetInstances() const { return m_instances; }
GetInstances()265 std::vector<Instance> &GetInstances() { return m_instances; }
266
GetInstanceAtIndex(uint32_t idx)267 Instance *GetInstanceAtIndex(uint32_t idx) {
268 if (idx < m_instances.size())
269 return &m_instances[idx];
270 return nullptr;
271 }
272
273 private:
274 std::vector<Instance> m_instances;
275 };
276
277 #pragma mark ABI
278
279 typedef PluginInstance<ABICreateInstance> ABIInstance;
280 typedef PluginInstances<ABIInstance> ABIInstances;
281
GetABIInstances()282 static ABIInstances &GetABIInstances() {
283 static ABIInstances g_instances;
284 return g_instances;
285 }
286
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,ABICreateInstance create_callback)287 bool PluginManager::RegisterPlugin(llvm::StringRef name,
288 llvm::StringRef description,
289 ABICreateInstance create_callback) {
290 return GetABIInstances().RegisterPlugin(name, description, create_callback);
291 }
292
UnregisterPlugin(ABICreateInstance create_callback)293 bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
294 return GetABIInstances().UnregisterPlugin(create_callback);
295 }
296
GetABICreateCallbackAtIndex(uint32_t idx)297 ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
298 return GetABIInstances().GetCallbackAtIndex(idx);
299 }
300
301 #pragma mark Architecture
302
303 typedef PluginInstance<ArchitectureCreateInstance> ArchitectureInstance;
304 typedef std::vector<ArchitectureInstance> ArchitectureInstances;
305
GetArchitectureInstances()306 static ArchitectureInstances &GetArchitectureInstances() {
307 static ArchitectureInstances g_instances;
308 return g_instances;
309 }
310
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,ArchitectureCreateInstance create_callback)311 void PluginManager::RegisterPlugin(llvm::StringRef name,
312 llvm::StringRef description,
313 ArchitectureCreateInstance create_callback) {
314 GetArchitectureInstances().push_back({name, description, create_callback});
315 }
316
UnregisterPlugin(ArchitectureCreateInstance create_callback)317 void PluginManager::UnregisterPlugin(
318 ArchitectureCreateInstance create_callback) {
319 auto &instances = GetArchitectureInstances();
320
321 for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
322 if (pos->create_callback == create_callback) {
323 instances.erase(pos);
324 return;
325 }
326 }
327 llvm_unreachable("Plugin not found");
328 }
329
330 std::unique_ptr<Architecture>
CreateArchitectureInstance(const ArchSpec & arch)331 PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
332 for (const auto &instances : GetArchitectureInstances()) {
333 if (auto plugin_up = instances.create_callback(arch))
334 return plugin_up;
335 }
336 return nullptr;
337 }
338
339 #pragma mark Disassembler
340
341 typedef PluginInstance<DisassemblerCreateInstance> DisassemblerInstance;
342 typedef PluginInstances<DisassemblerInstance> DisassemblerInstances;
343
GetDisassemblerInstances()344 static DisassemblerInstances &GetDisassemblerInstances() {
345 static DisassemblerInstances g_instances;
346 return g_instances;
347 }
348
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,DisassemblerCreateInstance create_callback)349 bool PluginManager::RegisterPlugin(llvm::StringRef name,
350 llvm::StringRef description,
351 DisassemblerCreateInstance create_callback) {
352 return GetDisassemblerInstances().RegisterPlugin(name, description,
353 create_callback);
354 }
355
UnregisterPlugin(DisassemblerCreateInstance create_callback)356 bool PluginManager::UnregisterPlugin(
357 DisassemblerCreateInstance create_callback) {
358 return GetDisassemblerInstances().UnregisterPlugin(create_callback);
359 }
360
361 DisassemblerCreateInstance
GetDisassemblerCreateCallbackAtIndex(uint32_t idx)362 PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
363 return GetDisassemblerInstances().GetCallbackAtIndex(idx);
364 }
365
366 DisassemblerCreateInstance
GetDisassemblerCreateCallbackForPluginName(llvm::StringRef name)367 PluginManager::GetDisassemblerCreateCallbackForPluginName(
368 llvm::StringRef name) {
369 return GetDisassemblerInstances().GetCallbackForName(name);
370 }
371
372 #pragma mark DynamicLoader
373
374 typedef PluginInstance<DynamicLoaderCreateInstance> DynamicLoaderInstance;
375 typedef PluginInstances<DynamicLoaderInstance> DynamicLoaderInstances;
376
GetDynamicLoaderInstances()377 static DynamicLoaderInstances &GetDynamicLoaderInstances() {
378 static DynamicLoaderInstances g_instances;
379 return g_instances;
380 }
381
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,DynamicLoaderCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)382 bool PluginManager::RegisterPlugin(
383 llvm::StringRef name, llvm::StringRef description,
384 DynamicLoaderCreateInstance create_callback,
385 DebuggerInitializeCallback debugger_init_callback) {
386 return GetDynamicLoaderInstances().RegisterPlugin(
387 name, description, create_callback, debugger_init_callback);
388 }
389
UnregisterPlugin(DynamicLoaderCreateInstance create_callback)390 bool PluginManager::UnregisterPlugin(
391 DynamicLoaderCreateInstance create_callback) {
392 return GetDynamicLoaderInstances().UnregisterPlugin(create_callback);
393 }
394
395 DynamicLoaderCreateInstance
GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx)396 PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
397 return GetDynamicLoaderInstances().GetCallbackAtIndex(idx);
398 }
399
400 DynamicLoaderCreateInstance
GetDynamicLoaderCreateCallbackForPluginName(llvm::StringRef name)401 PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
402 llvm::StringRef name) {
403 return GetDynamicLoaderInstances().GetCallbackForName(name);
404 }
405
406 #pragma mark JITLoader
407
408 typedef PluginInstance<JITLoaderCreateInstance> JITLoaderInstance;
409 typedef PluginInstances<JITLoaderInstance> JITLoaderInstances;
410
GetJITLoaderInstances()411 static JITLoaderInstances &GetJITLoaderInstances() {
412 static JITLoaderInstances g_instances;
413 return g_instances;
414 }
415
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,JITLoaderCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)416 bool PluginManager::RegisterPlugin(
417 llvm::StringRef name, llvm::StringRef description,
418 JITLoaderCreateInstance create_callback,
419 DebuggerInitializeCallback debugger_init_callback) {
420 return GetJITLoaderInstances().RegisterPlugin(
421 name, description, create_callback, debugger_init_callback);
422 }
423
UnregisterPlugin(JITLoaderCreateInstance create_callback)424 bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
425 return GetJITLoaderInstances().UnregisterPlugin(create_callback);
426 }
427
428 JITLoaderCreateInstance
GetJITLoaderCreateCallbackAtIndex(uint32_t idx)429 PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
430 return GetJITLoaderInstances().GetCallbackAtIndex(idx);
431 }
432
433 #pragma mark EmulateInstruction
434
435 typedef PluginInstance<EmulateInstructionCreateInstance>
436 EmulateInstructionInstance;
437 typedef PluginInstances<EmulateInstructionInstance> EmulateInstructionInstances;
438
GetEmulateInstructionInstances()439 static EmulateInstructionInstances &GetEmulateInstructionInstances() {
440 static EmulateInstructionInstances g_instances;
441 return g_instances;
442 }
443
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,EmulateInstructionCreateInstance create_callback)444 bool PluginManager::RegisterPlugin(
445 llvm::StringRef name, llvm::StringRef description,
446 EmulateInstructionCreateInstance create_callback) {
447 return GetEmulateInstructionInstances().RegisterPlugin(name, description,
448 create_callback);
449 }
450
UnregisterPlugin(EmulateInstructionCreateInstance create_callback)451 bool PluginManager::UnregisterPlugin(
452 EmulateInstructionCreateInstance create_callback) {
453 return GetEmulateInstructionInstances().UnregisterPlugin(create_callback);
454 }
455
456 EmulateInstructionCreateInstance
GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx)457 PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
458 return GetEmulateInstructionInstances().GetCallbackAtIndex(idx);
459 }
460
461 EmulateInstructionCreateInstance
GetEmulateInstructionCreateCallbackForPluginName(llvm::StringRef name)462 PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
463 llvm::StringRef name) {
464 return GetEmulateInstructionInstances().GetCallbackForName(name);
465 }
466
467 #pragma mark OperatingSystem
468
469 typedef PluginInstance<OperatingSystemCreateInstance> OperatingSystemInstance;
470 typedef PluginInstances<OperatingSystemInstance> OperatingSystemInstances;
471
GetOperatingSystemInstances()472 static OperatingSystemInstances &GetOperatingSystemInstances() {
473 static OperatingSystemInstances g_instances;
474 return g_instances;
475 }
476
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,OperatingSystemCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)477 bool PluginManager::RegisterPlugin(
478 llvm::StringRef name, llvm::StringRef description,
479 OperatingSystemCreateInstance create_callback,
480 DebuggerInitializeCallback debugger_init_callback) {
481 return GetOperatingSystemInstances().RegisterPlugin(
482 name, description, create_callback, debugger_init_callback);
483 }
484
UnregisterPlugin(OperatingSystemCreateInstance create_callback)485 bool PluginManager::UnregisterPlugin(
486 OperatingSystemCreateInstance create_callback) {
487 return GetOperatingSystemInstances().UnregisterPlugin(create_callback);
488 }
489
490 OperatingSystemCreateInstance
GetOperatingSystemCreateCallbackAtIndex(uint32_t idx)491 PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
492 return GetOperatingSystemInstances().GetCallbackAtIndex(idx);
493 }
494
495 OperatingSystemCreateInstance
GetOperatingSystemCreateCallbackForPluginName(llvm::StringRef name)496 PluginManager::GetOperatingSystemCreateCallbackForPluginName(
497 llvm::StringRef name) {
498 return GetOperatingSystemInstances().GetCallbackForName(name);
499 }
500
501 #pragma mark Language
502
503 typedef PluginInstance<LanguageCreateInstance> LanguageInstance;
504 typedef PluginInstances<LanguageInstance> LanguageInstances;
505
GetLanguageInstances()506 static LanguageInstances &GetLanguageInstances() {
507 static LanguageInstances g_instances;
508 return g_instances;
509 }
510
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,LanguageCreateInstance create_callback)511 bool PluginManager::RegisterPlugin(llvm::StringRef name,
512 llvm::StringRef description,
513 LanguageCreateInstance create_callback) {
514 return GetLanguageInstances().RegisterPlugin(name, description,
515 create_callback);
516 }
517
UnregisterPlugin(LanguageCreateInstance create_callback)518 bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
519 return GetLanguageInstances().UnregisterPlugin(create_callback);
520 }
521
522 LanguageCreateInstance
GetLanguageCreateCallbackAtIndex(uint32_t idx)523 PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
524 return GetLanguageInstances().GetCallbackAtIndex(idx);
525 }
526
527 #pragma mark LanguageRuntime
528
529 struct LanguageRuntimeInstance
530 : public PluginInstance<LanguageRuntimeCreateInstance> {
LanguageRuntimeInstanceLanguageRuntimeInstance531 LanguageRuntimeInstance(
532 llvm::StringRef name, llvm::StringRef description,
533 CallbackType create_callback,
534 DebuggerInitializeCallback debugger_init_callback,
535 LanguageRuntimeGetCommandObject command_callback,
536 LanguageRuntimeGetExceptionPrecondition precondition_callback)
537 : PluginInstance<LanguageRuntimeCreateInstance>(
538 name, description, create_callback, debugger_init_callback),
539 command_callback(command_callback),
540 precondition_callback(precondition_callback) {}
541
542 LanguageRuntimeGetCommandObject command_callback;
543 LanguageRuntimeGetExceptionPrecondition precondition_callback;
544 };
545
546 typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances;
547
GetLanguageRuntimeInstances()548 static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
549 static LanguageRuntimeInstances g_instances;
550 return g_instances;
551 }
552
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,LanguageRuntimeCreateInstance create_callback,LanguageRuntimeGetCommandObject command_callback,LanguageRuntimeGetExceptionPrecondition precondition_callback)553 bool PluginManager::RegisterPlugin(
554 llvm::StringRef name, llvm::StringRef description,
555 LanguageRuntimeCreateInstance create_callback,
556 LanguageRuntimeGetCommandObject command_callback,
557 LanguageRuntimeGetExceptionPrecondition precondition_callback) {
558 return GetLanguageRuntimeInstances().RegisterPlugin(
559 name, description, create_callback, nullptr, command_callback,
560 precondition_callback);
561 }
562
UnregisterPlugin(LanguageRuntimeCreateInstance create_callback)563 bool PluginManager::UnregisterPlugin(
564 LanguageRuntimeCreateInstance create_callback) {
565 return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback);
566 }
567
568 LanguageRuntimeCreateInstance
GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx)569 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
570 return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx);
571 }
572
573 LanguageRuntimeGetCommandObject
GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx)574 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
575 const auto &instances = GetLanguageRuntimeInstances().GetInstances();
576 if (idx < instances.size())
577 return instances[idx].command_callback;
578 return nullptr;
579 }
580
581 LanguageRuntimeGetExceptionPrecondition
GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx)582 PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
583 const auto &instances = GetLanguageRuntimeInstances().GetInstances();
584 if (idx < instances.size())
585 return instances[idx].precondition_callback;
586 return nullptr;
587 }
588
589 #pragma mark SystemRuntime
590
591 typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance;
592 typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances;
593
GetSystemRuntimeInstances()594 static SystemRuntimeInstances &GetSystemRuntimeInstances() {
595 static SystemRuntimeInstances g_instances;
596 return g_instances;
597 }
598
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,SystemRuntimeCreateInstance create_callback)599 bool PluginManager::RegisterPlugin(
600 llvm::StringRef name, llvm::StringRef description,
601 SystemRuntimeCreateInstance create_callback) {
602 return GetSystemRuntimeInstances().RegisterPlugin(name, description,
603 create_callback);
604 }
605
UnregisterPlugin(SystemRuntimeCreateInstance create_callback)606 bool PluginManager::UnregisterPlugin(
607 SystemRuntimeCreateInstance create_callback) {
608 return GetSystemRuntimeInstances().UnregisterPlugin(create_callback);
609 }
610
611 SystemRuntimeCreateInstance
GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx)612 PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
613 return GetSystemRuntimeInstances().GetCallbackAtIndex(idx);
614 }
615
616 #pragma mark ObjectFile
617
618 struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> {
ObjectFileInstanceObjectFileInstance619 ObjectFileInstance(
620 llvm::StringRef name, llvm::StringRef description,
621 CallbackType create_callback,
622 ObjectFileCreateMemoryInstance create_memory_callback,
623 ObjectFileGetModuleSpecifications get_module_specifications,
624 ObjectFileSaveCore save_core,
625 DebuggerInitializeCallback debugger_init_callback)
626 : PluginInstance<ObjectFileCreateInstance>(
627 name, description, create_callback, debugger_init_callback),
628 create_memory_callback(create_memory_callback),
629 get_module_specifications(get_module_specifications),
630 save_core(save_core) {}
631
632 ObjectFileCreateMemoryInstance create_memory_callback;
633 ObjectFileGetModuleSpecifications get_module_specifications;
634 ObjectFileSaveCore save_core;
635 };
636 typedef PluginInstances<ObjectFileInstance> ObjectFileInstances;
637
GetObjectFileInstances()638 static ObjectFileInstances &GetObjectFileInstances() {
639 static ObjectFileInstances g_instances;
640 return g_instances;
641 }
642
IsRegisteredObjectFilePluginName(llvm::StringRef name)643 bool PluginManager::IsRegisteredObjectFilePluginName(llvm::StringRef name) {
644 if (name.empty())
645 return false;
646
647 const auto &instances = GetObjectFileInstances().GetInstances();
648 for (auto &instance : instances) {
649 if (instance.name == name)
650 return true;
651 }
652 return false;
653 }
654
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,ObjectFileCreateInstance create_callback,ObjectFileCreateMemoryInstance create_memory_callback,ObjectFileGetModuleSpecifications get_module_specifications,ObjectFileSaveCore save_core,DebuggerInitializeCallback debugger_init_callback)655 bool PluginManager::RegisterPlugin(
656 llvm::StringRef name, llvm::StringRef description,
657 ObjectFileCreateInstance create_callback,
658 ObjectFileCreateMemoryInstance create_memory_callback,
659 ObjectFileGetModuleSpecifications get_module_specifications,
660 ObjectFileSaveCore save_core,
661 DebuggerInitializeCallback debugger_init_callback) {
662 return GetObjectFileInstances().RegisterPlugin(
663 name, description, create_callback, create_memory_callback,
664 get_module_specifications, save_core, debugger_init_callback);
665 }
666
UnregisterPlugin(ObjectFileCreateInstance create_callback)667 bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
668 return GetObjectFileInstances().UnregisterPlugin(create_callback);
669 }
670
671 ObjectFileCreateInstance
GetObjectFileCreateCallbackAtIndex(uint32_t idx)672 PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
673 return GetObjectFileInstances().GetCallbackAtIndex(idx);
674 }
675
676 ObjectFileCreateMemoryInstance
GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx)677 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
678 const auto &instances = GetObjectFileInstances().GetInstances();
679 if (idx < instances.size())
680 return instances[idx].create_memory_callback;
681 return nullptr;
682 }
683
684 ObjectFileGetModuleSpecifications
GetObjectFileGetModuleSpecificationsCallbackAtIndex(uint32_t idx)685 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
686 uint32_t idx) {
687 const auto &instances = GetObjectFileInstances().GetInstances();
688 if (idx < instances.size())
689 return instances[idx].get_module_specifications;
690 return nullptr;
691 }
692
693 ObjectFileCreateMemoryInstance
GetObjectFileCreateMemoryCallbackForPluginName(llvm::StringRef name)694 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
695 llvm::StringRef name) {
696 const auto &instances = GetObjectFileInstances().GetInstances();
697 for (auto &instance : instances) {
698 if (instance.name == name)
699 return instance.create_memory_callback;
700 }
701 return nullptr;
702 }
703
SaveCore(const lldb::ProcessSP & process_sp,const lldb_private::SaveCoreOptions & options)704 Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
705 const lldb_private::SaveCoreOptions &options) {
706 Status error;
707 if (!options.GetOutputFile()) {
708 error.SetErrorString("No output file specified");
709 return error;
710 }
711
712 if (!process_sp) {
713 error.SetErrorString("Invalid process");
714 return error;
715 }
716
717 if (!options.GetPluginName().has_value()) {
718 // Try saving core directly from the process plugin first.
719 llvm::Expected<bool> ret =
720 process_sp->SaveCore(options.GetOutputFile()->GetPath());
721 if (!ret)
722 return Status(ret.takeError());
723 if (ret.get())
724 return Status();
725 }
726
727 // Fall back to object plugins.
728 const auto &plugin_name = options.GetPluginName().value_or("");
729 auto &instances = GetObjectFileInstances().GetInstances();
730 for (auto &instance : instances) {
731 if (plugin_name.empty() || instance.name == plugin_name) {
732 if (instance.save_core && instance.save_core(process_sp, options, error))
733 return error;
734 }
735 }
736
737 // Check to see if any of the object file plugins tried and failed to save.
738 // If none ran, set the error message.
739 if (error.Success())
740 error.SetErrorString(
741 "no ObjectFile plugins were able to save a core for this process");
742 return error;
743 }
744
745 #pragma mark ObjectContainer
746
747 struct ObjectContainerInstance
748 : public PluginInstance<ObjectContainerCreateInstance> {
ObjectContainerInstanceObjectContainerInstance749 ObjectContainerInstance(
750 llvm::StringRef name, llvm::StringRef description,
751 CallbackType create_callback,
752 ObjectContainerCreateMemoryInstance create_memory_callback,
753 ObjectFileGetModuleSpecifications get_module_specifications)
754 : PluginInstance<ObjectContainerCreateInstance>(name, description,
755 create_callback),
756 create_memory_callback(create_memory_callback),
757 get_module_specifications(get_module_specifications) {}
758
759 ObjectContainerCreateMemoryInstance create_memory_callback;
760 ObjectFileGetModuleSpecifications get_module_specifications;
761 };
762 typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;
763
GetObjectContainerInstances()764 static ObjectContainerInstances &GetObjectContainerInstances() {
765 static ObjectContainerInstances g_instances;
766 return g_instances;
767 }
768
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,ObjectContainerCreateInstance create_callback,ObjectFileGetModuleSpecifications get_module_specifications,ObjectContainerCreateMemoryInstance create_memory_callback)769 bool PluginManager::RegisterPlugin(
770 llvm::StringRef name, llvm::StringRef description,
771 ObjectContainerCreateInstance create_callback,
772 ObjectFileGetModuleSpecifications get_module_specifications,
773 ObjectContainerCreateMemoryInstance create_memory_callback) {
774 return GetObjectContainerInstances().RegisterPlugin(
775 name, description, create_callback, create_memory_callback,
776 get_module_specifications);
777 }
778
UnregisterPlugin(ObjectContainerCreateInstance create_callback)779 bool PluginManager::UnregisterPlugin(
780 ObjectContainerCreateInstance create_callback) {
781 return GetObjectContainerInstances().UnregisterPlugin(create_callback);
782 }
783
784 ObjectContainerCreateInstance
GetObjectContainerCreateCallbackAtIndex(uint32_t idx)785 PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
786 return GetObjectContainerInstances().GetCallbackAtIndex(idx);
787 }
788
789 ObjectContainerCreateMemoryInstance
GetObjectContainerCreateMemoryCallbackAtIndex(uint32_t idx)790 PluginManager::GetObjectContainerCreateMemoryCallbackAtIndex(uint32_t idx) {
791 const auto &instances = GetObjectContainerInstances().GetInstances();
792 if (idx < instances.size())
793 return instances[idx].create_memory_callback;
794 return nullptr;
795 }
796
797 ObjectFileGetModuleSpecifications
GetObjectContainerGetModuleSpecificationsCallbackAtIndex(uint32_t idx)798 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
799 uint32_t idx) {
800 const auto &instances = GetObjectContainerInstances().GetInstances();
801 if (idx < instances.size())
802 return instances[idx].get_module_specifications;
803 return nullptr;
804 }
805
806 #pragma mark Platform
807
808 typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
809 typedef PluginInstances<PlatformInstance> PlatformInstances;
810
GetPlatformInstances()811 static PlatformInstances &GetPlatformInstances() {
812 static PlatformInstances g_platform_instances;
813 return g_platform_instances;
814 }
815
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,PlatformCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)816 bool PluginManager::RegisterPlugin(
817 llvm::StringRef name, llvm::StringRef description,
818 PlatformCreateInstance create_callback,
819 DebuggerInitializeCallback debugger_init_callback) {
820 return GetPlatformInstances().RegisterPlugin(
821 name, description, create_callback, debugger_init_callback);
822 }
823
UnregisterPlugin(PlatformCreateInstance create_callback)824 bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
825 return GetPlatformInstances().UnregisterPlugin(create_callback);
826 }
827
GetPlatformPluginNameAtIndex(uint32_t idx)828 llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
829 return GetPlatformInstances().GetNameAtIndex(idx);
830 }
831
832 llvm::StringRef
GetPlatformPluginDescriptionAtIndex(uint32_t idx)833 PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
834 return GetPlatformInstances().GetDescriptionAtIndex(idx);
835 }
836
837 PlatformCreateInstance
GetPlatformCreateCallbackAtIndex(uint32_t idx)838 PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
839 return GetPlatformInstances().GetCallbackAtIndex(idx);
840 }
841
842 PlatformCreateInstance
GetPlatformCreateCallbackForPluginName(llvm::StringRef name)843 PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) {
844 return GetPlatformInstances().GetCallbackForName(name);
845 }
846
AutoCompletePlatformName(llvm::StringRef name,CompletionRequest & request)847 void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
848 CompletionRequest &request) {
849 for (const auto &instance : GetPlatformInstances().GetInstances()) {
850 if (instance.name.starts_with(name))
851 request.AddCompletion(instance.name);
852 }
853 }
854
855 #pragma mark Process
856
857 typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
858 typedef PluginInstances<ProcessInstance> ProcessInstances;
859
GetProcessInstances()860 static ProcessInstances &GetProcessInstances() {
861 static ProcessInstances g_instances;
862 return g_instances;
863 }
864
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,ProcessCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)865 bool PluginManager::RegisterPlugin(
866 llvm::StringRef name, llvm::StringRef description,
867 ProcessCreateInstance create_callback,
868 DebuggerInitializeCallback debugger_init_callback) {
869 return GetProcessInstances().RegisterPlugin(
870 name, description, create_callback, debugger_init_callback);
871 }
872
UnregisterPlugin(ProcessCreateInstance create_callback)873 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
874 return GetProcessInstances().UnregisterPlugin(create_callback);
875 }
876
GetProcessPluginNameAtIndex(uint32_t idx)877 llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
878 return GetProcessInstances().GetNameAtIndex(idx);
879 }
880
GetProcessPluginDescriptionAtIndex(uint32_t idx)881 llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
882 return GetProcessInstances().GetDescriptionAtIndex(idx);
883 }
884
885 ProcessCreateInstance
GetProcessCreateCallbackAtIndex(uint32_t idx)886 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
887 return GetProcessInstances().GetCallbackAtIndex(idx);
888 }
889
890 ProcessCreateInstance
GetProcessCreateCallbackForPluginName(llvm::StringRef name)891 PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) {
892 return GetProcessInstances().GetCallbackForName(name);
893 }
894
AutoCompleteProcessName(llvm::StringRef name,CompletionRequest & request)895 void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
896 CompletionRequest &request) {
897 for (const auto &instance : GetProcessInstances().GetInstances()) {
898 if (instance.name.starts_with(name))
899 request.AddCompletion(instance.name, instance.description);
900 }
901 }
902
903 #pragma mark RegisterTypeBuilder
904
905 struct RegisterTypeBuilderInstance
906 : public PluginInstance<RegisterTypeBuilderCreateInstance> {
RegisterTypeBuilderInstanceRegisterTypeBuilderInstance907 RegisterTypeBuilderInstance(llvm::StringRef name, llvm::StringRef description,
908 CallbackType create_callback)
909 : PluginInstance<RegisterTypeBuilderCreateInstance>(name, description,
910 create_callback) {}
911 };
912
913 typedef PluginInstances<RegisterTypeBuilderInstance>
914 RegisterTypeBuilderInstances;
915
GetRegisterTypeBuilderInstances()916 static RegisterTypeBuilderInstances &GetRegisterTypeBuilderInstances() {
917 static RegisterTypeBuilderInstances g_instances;
918 return g_instances;
919 }
920
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,RegisterTypeBuilderCreateInstance create_callback)921 bool PluginManager::RegisterPlugin(
922 llvm::StringRef name, llvm::StringRef description,
923 RegisterTypeBuilderCreateInstance create_callback) {
924 return GetRegisterTypeBuilderInstances().RegisterPlugin(name, description,
925 create_callback);
926 }
927
UnregisterPlugin(RegisterTypeBuilderCreateInstance create_callback)928 bool PluginManager::UnregisterPlugin(
929 RegisterTypeBuilderCreateInstance create_callback) {
930 return GetRegisterTypeBuilderInstances().UnregisterPlugin(create_callback);
931 }
932
933 lldb::RegisterTypeBuilderSP
GetRegisterTypeBuilder(Target & target)934 PluginManager::GetRegisterTypeBuilder(Target &target) {
935 const auto &instances = GetRegisterTypeBuilderInstances().GetInstances();
936 // We assume that RegisterTypeBuilderClang is the only instance of this plugin
937 // type and is always present.
938 assert(instances.size());
939 return instances[0].create_callback(target);
940 }
941
942 #pragma mark ScriptInterpreter
943
944 struct ScriptInterpreterInstance
945 : public PluginInstance<ScriptInterpreterCreateInstance> {
ScriptInterpreterInstanceScriptInterpreterInstance946 ScriptInterpreterInstance(llvm::StringRef name, llvm::StringRef description,
947 CallbackType create_callback,
948 lldb::ScriptLanguage language)
949 : PluginInstance<ScriptInterpreterCreateInstance>(name, description,
950 create_callback),
951 language(language) {}
952
953 lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
954 };
955
956 typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;
957
GetScriptInterpreterInstances()958 static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
959 static ScriptInterpreterInstances g_instances;
960 return g_instances;
961 }
962
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,lldb::ScriptLanguage script_language,ScriptInterpreterCreateInstance create_callback)963 bool PluginManager::RegisterPlugin(
964 llvm::StringRef name, llvm::StringRef description,
965 lldb::ScriptLanguage script_language,
966 ScriptInterpreterCreateInstance create_callback) {
967 return GetScriptInterpreterInstances().RegisterPlugin(
968 name, description, create_callback, script_language);
969 }
970
UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)971 bool PluginManager::UnregisterPlugin(
972 ScriptInterpreterCreateInstance create_callback) {
973 return GetScriptInterpreterInstances().UnregisterPlugin(create_callback);
974 }
975
976 ScriptInterpreterCreateInstance
GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)977 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
978 return GetScriptInterpreterInstances().GetCallbackAtIndex(idx);
979 }
980
981 lldb::ScriptInterpreterSP
GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,Debugger & debugger)982 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
983 Debugger &debugger) {
984 const auto &instances = GetScriptInterpreterInstances().GetInstances();
985 ScriptInterpreterCreateInstance none_instance = nullptr;
986 for (const auto &instance : instances) {
987 if (instance.language == lldb::eScriptLanguageNone)
988 none_instance = instance.create_callback;
989
990 if (script_lang == instance.language)
991 return instance.create_callback(debugger);
992 }
993
994 // If we didn't find one, return the ScriptInterpreter for the null language.
995 assert(none_instance != nullptr);
996 return none_instance(debugger);
997 }
998
999 #pragma mark StructuredDataPlugin
1000
1001 struct StructuredDataPluginInstance
1002 : public PluginInstance<StructuredDataPluginCreateInstance> {
StructuredDataPluginInstanceStructuredDataPluginInstance1003 StructuredDataPluginInstance(
1004 llvm::StringRef name, llvm::StringRef description,
1005 CallbackType create_callback,
1006 DebuggerInitializeCallback debugger_init_callback,
1007 StructuredDataFilterLaunchInfo filter_callback)
1008 : PluginInstance<StructuredDataPluginCreateInstance>(
1009 name, description, create_callback, debugger_init_callback),
1010 filter_callback(filter_callback) {}
1011
1012 StructuredDataFilterLaunchInfo filter_callback = nullptr;
1013 };
1014
1015 typedef PluginInstances<StructuredDataPluginInstance>
1016 StructuredDataPluginInstances;
1017
GetStructuredDataPluginInstances()1018 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
1019 static StructuredDataPluginInstances g_instances;
1020 return g_instances;
1021 }
1022
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,StructuredDataPluginCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback,StructuredDataFilterLaunchInfo filter_callback)1023 bool PluginManager::RegisterPlugin(
1024 llvm::StringRef name, llvm::StringRef description,
1025 StructuredDataPluginCreateInstance create_callback,
1026 DebuggerInitializeCallback debugger_init_callback,
1027 StructuredDataFilterLaunchInfo filter_callback) {
1028 return GetStructuredDataPluginInstances().RegisterPlugin(
1029 name, description, create_callback, debugger_init_callback,
1030 filter_callback);
1031 }
1032
UnregisterPlugin(StructuredDataPluginCreateInstance create_callback)1033 bool PluginManager::UnregisterPlugin(
1034 StructuredDataPluginCreateInstance create_callback) {
1035 return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback);
1036 }
1037
1038 StructuredDataPluginCreateInstance
GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx)1039 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
1040 return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx);
1041 }
1042
1043 StructuredDataFilterLaunchInfo
GetStructuredDataFilterCallbackAtIndex(uint32_t idx,bool & iteration_complete)1044 PluginManager::GetStructuredDataFilterCallbackAtIndex(
1045 uint32_t idx, bool &iteration_complete) {
1046 const auto &instances = GetStructuredDataPluginInstances().GetInstances();
1047 if (idx < instances.size()) {
1048 iteration_complete = false;
1049 return instances[idx].filter_callback;
1050 } else {
1051 iteration_complete = true;
1052 }
1053 return nullptr;
1054 }
1055
1056 #pragma mark SymbolFile
1057
1058 typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
1059 typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;
1060
GetSymbolFileInstances()1061 static SymbolFileInstances &GetSymbolFileInstances() {
1062 static SymbolFileInstances g_instances;
1063 return g_instances;
1064 }
1065
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,SymbolFileCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)1066 bool PluginManager::RegisterPlugin(
1067 llvm::StringRef name, llvm::StringRef description,
1068 SymbolFileCreateInstance create_callback,
1069 DebuggerInitializeCallback debugger_init_callback) {
1070 return GetSymbolFileInstances().RegisterPlugin(
1071 name, description, create_callback, debugger_init_callback);
1072 }
1073
UnregisterPlugin(SymbolFileCreateInstance create_callback)1074 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
1075 return GetSymbolFileInstances().UnregisterPlugin(create_callback);
1076 }
1077
1078 SymbolFileCreateInstance
GetSymbolFileCreateCallbackAtIndex(uint32_t idx)1079 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1080 return GetSymbolFileInstances().GetCallbackAtIndex(idx);
1081 }
1082
1083 #pragma mark SymbolVendor
1084
1085 typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
1086 typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;
1087
GetSymbolVendorInstances()1088 static SymbolVendorInstances &GetSymbolVendorInstances() {
1089 static SymbolVendorInstances g_instances;
1090 return g_instances;
1091 }
1092
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,SymbolVendorCreateInstance create_callback)1093 bool PluginManager::RegisterPlugin(llvm::StringRef name,
1094 llvm::StringRef description,
1095 SymbolVendorCreateInstance create_callback) {
1096 return GetSymbolVendorInstances().RegisterPlugin(name, description,
1097 create_callback);
1098 }
1099
UnregisterPlugin(SymbolVendorCreateInstance create_callback)1100 bool PluginManager::UnregisterPlugin(
1101 SymbolVendorCreateInstance create_callback) {
1102 return GetSymbolVendorInstances().UnregisterPlugin(create_callback);
1103 }
1104
1105 SymbolVendorCreateInstance
GetSymbolVendorCreateCallbackAtIndex(uint32_t idx)1106 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1107 return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
1108 }
1109
1110 #pragma mark SymbolLocator
1111
1112 struct SymbolLocatorInstance
1113 : public PluginInstance<SymbolLocatorCreateInstance> {
SymbolLocatorInstanceSymbolLocatorInstance1114 SymbolLocatorInstance(
1115 llvm::StringRef name, llvm::StringRef description,
1116 CallbackType create_callback,
1117 SymbolLocatorLocateExecutableObjectFile locate_executable_object_file,
1118 SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
1119 SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
1120 SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
1121 DebuggerInitializeCallback debugger_init_callback)
1122 : PluginInstance<SymbolLocatorCreateInstance>(
1123 name, description, create_callback, debugger_init_callback),
1124 locate_executable_object_file(locate_executable_object_file),
1125 locate_executable_symbol_file(locate_executable_symbol_file),
1126 download_object_symbol_file(download_object_symbol_file),
1127 find_symbol_file_in_bundle(find_symbol_file_in_bundle) {}
1128
1129 SymbolLocatorLocateExecutableObjectFile locate_executable_object_file;
1130 SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file;
1131 SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file;
1132 SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle;
1133 };
1134 typedef PluginInstances<SymbolLocatorInstance> SymbolLocatorInstances;
1135
GetSymbolLocatorInstances()1136 static SymbolLocatorInstances &GetSymbolLocatorInstances() {
1137 static SymbolLocatorInstances g_instances;
1138 return g_instances;
1139 }
1140
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,SymbolLocatorCreateInstance create_callback,SymbolLocatorLocateExecutableObjectFile locate_executable_object_file,SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,DebuggerInitializeCallback debugger_init_callback)1141 bool PluginManager::RegisterPlugin(
1142 llvm::StringRef name, llvm::StringRef description,
1143 SymbolLocatorCreateInstance create_callback,
1144 SymbolLocatorLocateExecutableObjectFile locate_executable_object_file,
1145 SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
1146 SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
1147 SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
1148 DebuggerInitializeCallback debugger_init_callback) {
1149 return GetSymbolLocatorInstances().RegisterPlugin(
1150 name, description, create_callback, locate_executable_object_file,
1151 locate_executable_symbol_file, download_object_symbol_file,
1152 find_symbol_file_in_bundle, debugger_init_callback);
1153 }
1154
UnregisterPlugin(SymbolLocatorCreateInstance create_callback)1155 bool PluginManager::UnregisterPlugin(
1156 SymbolLocatorCreateInstance create_callback) {
1157 return GetSymbolLocatorInstances().UnregisterPlugin(create_callback);
1158 }
1159
1160 SymbolLocatorCreateInstance
GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx)1161 PluginManager::GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx) {
1162 return GetSymbolLocatorInstances().GetCallbackAtIndex(idx);
1163 }
1164
1165 ModuleSpec
LocateExecutableObjectFile(const ModuleSpec & module_spec)1166 PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
1167 auto &instances = GetSymbolLocatorInstances().GetInstances();
1168 for (auto &instance : instances) {
1169 if (instance.locate_executable_object_file) {
1170 std::optional<ModuleSpec> result =
1171 instance.locate_executable_object_file(module_spec);
1172 if (result)
1173 return *result;
1174 }
1175 }
1176 return {};
1177 }
1178
LocateExecutableSymbolFile(const ModuleSpec & module_spec,const FileSpecList & default_search_paths)1179 FileSpec PluginManager::LocateExecutableSymbolFile(
1180 const ModuleSpec &module_spec, const FileSpecList &default_search_paths) {
1181 auto &instances = GetSymbolLocatorInstances().GetInstances();
1182 for (auto &instance : instances) {
1183 if (instance.locate_executable_symbol_file) {
1184 std::optional<FileSpec> result = instance.locate_executable_symbol_file(
1185 module_spec, default_search_paths);
1186 if (result)
1187 return *result;
1188 }
1189 }
1190 return {};
1191 }
1192
DownloadObjectAndSymbolFile(ModuleSpec & module_spec,Status & error,bool force_lookup,bool copy_executable)1193 bool PluginManager::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
1194 Status &error,
1195 bool force_lookup,
1196 bool copy_executable) {
1197 auto &instances = GetSymbolLocatorInstances().GetInstances();
1198 for (auto &instance : instances) {
1199 if (instance.download_object_symbol_file) {
1200 if (instance.download_object_symbol_file(module_spec, error, force_lookup,
1201 copy_executable))
1202 return true;
1203 }
1204 }
1205 return false;
1206 }
1207
FindSymbolFileInBundle(const FileSpec & symfile_bundle,const UUID * uuid,const ArchSpec * arch)1208 FileSpec PluginManager::FindSymbolFileInBundle(const FileSpec &symfile_bundle,
1209 const UUID *uuid,
1210 const ArchSpec *arch) {
1211 auto &instances = GetSymbolLocatorInstances().GetInstances();
1212 for (auto &instance : instances) {
1213 if (instance.find_symbol_file_in_bundle) {
1214 std::optional<FileSpec> result =
1215 instance.find_symbol_file_in_bundle(symfile_bundle, uuid, arch);
1216 if (result)
1217 return *result;
1218 }
1219 }
1220 return {};
1221 }
1222
1223 #pragma mark Trace
1224
1225 struct TraceInstance
1226 : public PluginInstance<TraceCreateInstanceFromBundle> {
TraceInstanceTraceInstance1227 TraceInstance(
1228 llvm::StringRef name, llvm::StringRef description,
1229 CallbackType create_callback_from_bundle,
1230 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1231 llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback)
1232 : PluginInstance<TraceCreateInstanceFromBundle>(
1233 name, description, create_callback_from_bundle,
1234 debugger_init_callback),
1235 schema(schema),
1236 create_callback_for_live_process(create_callback_for_live_process) {}
1237
1238 llvm::StringRef schema;
1239 TraceCreateInstanceForLiveProcess create_callback_for_live_process;
1240 };
1241
1242 typedef PluginInstances<TraceInstance> TraceInstances;
1243
GetTracePluginInstances()1244 static TraceInstances &GetTracePluginInstances() {
1245 static TraceInstances g_instances;
1246 return g_instances;
1247 }
1248
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,TraceCreateInstanceFromBundle create_callback_from_bundle,TraceCreateInstanceForLiveProcess create_callback_for_live_process,llvm::StringRef schema,DebuggerInitializeCallback debugger_init_callback)1249 bool PluginManager::RegisterPlugin(
1250 llvm::StringRef name, llvm::StringRef description,
1251 TraceCreateInstanceFromBundle create_callback_from_bundle,
1252 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1253 llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback) {
1254 return GetTracePluginInstances().RegisterPlugin(
1255 name, description, create_callback_from_bundle,
1256 create_callback_for_live_process, schema, debugger_init_callback);
1257 }
1258
UnregisterPlugin(TraceCreateInstanceFromBundle create_callback_from_bundle)1259 bool PluginManager::UnregisterPlugin(
1260 TraceCreateInstanceFromBundle create_callback_from_bundle) {
1261 return GetTracePluginInstances().UnregisterPlugin(
1262 create_callback_from_bundle);
1263 }
1264
1265 TraceCreateInstanceFromBundle
GetTraceCreateCallback(llvm::StringRef plugin_name)1266 PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) {
1267 return GetTracePluginInstances().GetCallbackForName(plugin_name);
1268 }
1269
1270 TraceCreateInstanceForLiveProcess
GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name)1271 PluginManager::GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name) {
1272 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1273 if (instance.name == plugin_name)
1274 return instance.create_callback_for_live_process;
1275 return nullptr;
1276 }
1277
GetTraceSchema(llvm::StringRef plugin_name)1278 llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) {
1279 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1280 if (instance.name == plugin_name)
1281 return instance.schema;
1282 return llvm::StringRef();
1283 }
1284
GetTraceSchema(size_t index)1285 llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
1286 if (TraceInstance *instance =
1287 GetTracePluginInstances().GetInstanceAtIndex(index))
1288 return instance->schema;
1289 return llvm::StringRef();
1290 }
1291
1292 #pragma mark TraceExporter
1293
1294 struct TraceExporterInstance
1295 : public PluginInstance<TraceExporterCreateInstance> {
TraceExporterInstanceTraceExporterInstance1296 TraceExporterInstance(
1297 llvm::StringRef name, llvm::StringRef description,
1298 TraceExporterCreateInstance create_instance,
1299 ThreadTraceExportCommandCreator create_thread_trace_export_command)
1300 : PluginInstance<TraceExporterCreateInstance>(name, description,
1301 create_instance),
1302 create_thread_trace_export_command(create_thread_trace_export_command) {
1303 }
1304
1305 ThreadTraceExportCommandCreator create_thread_trace_export_command;
1306 };
1307
1308 typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;
1309
GetTraceExporterInstances()1310 static TraceExporterInstances &GetTraceExporterInstances() {
1311 static TraceExporterInstances g_instances;
1312 return g_instances;
1313 }
1314
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,TraceExporterCreateInstance create_callback,ThreadTraceExportCommandCreator create_thread_trace_export_command)1315 bool PluginManager::RegisterPlugin(
1316 llvm::StringRef name, llvm::StringRef description,
1317 TraceExporterCreateInstance create_callback,
1318 ThreadTraceExportCommandCreator create_thread_trace_export_command) {
1319 return GetTraceExporterInstances().RegisterPlugin(
1320 name, description, create_callback, create_thread_trace_export_command);
1321 }
1322
1323 TraceExporterCreateInstance
GetTraceExporterCreateCallback(llvm::StringRef plugin_name)1324 PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) {
1325 return GetTraceExporterInstances().GetCallbackForName(plugin_name);
1326 }
1327
UnregisterPlugin(TraceExporterCreateInstance create_callback)1328 bool PluginManager::UnregisterPlugin(
1329 TraceExporterCreateInstance create_callback) {
1330 return GetTraceExporterInstances().UnregisterPlugin(create_callback);
1331 }
1332
1333 ThreadTraceExportCommandCreator
GetThreadTraceExportCommandCreatorAtIndex(uint32_t index)1334 PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
1335 if (TraceExporterInstance *instance =
1336 GetTraceExporterInstances().GetInstanceAtIndex(index))
1337 return instance->create_thread_trace_export_command;
1338 return nullptr;
1339 }
1340
1341 llvm::StringRef
GetTraceExporterPluginNameAtIndex(uint32_t index)1342 PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
1343 return GetTraceExporterInstances().GetNameAtIndex(index);
1344 }
1345
1346 #pragma mark UnwindAssembly
1347
1348 typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
1349 typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;
1350
GetUnwindAssemblyInstances()1351 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1352 static UnwindAssemblyInstances g_instances;
1353 return g_instances;
1354 }
1355
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,UnwindAssemblyCreateInstance create_callback)1356 bool PluginManager::RegisterPlugin(
1357 llvm::StringRef name, llvm::StringRef description,
1358 UnwindAssemblyCreateInstance create_callback) {
1359 return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
1360 create_callback);
1361 }
1362
UnregisterPlugin(UnwindAssemblyCreateInstance create_callback)1363 bool PluginManager::UnregisterPlugin(
1364 UnwindAssemblyCreateInstance create_callback) {
1365 return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback);
1366 }
1367
1368 UnwindAssemblyCreateInstance
GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx)1369 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1370 return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx);
1371 }
1372
1373 #pragma mark MemoryHistory
1374
1375 typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
1376 typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;
1377
GetMemoryHistoryInstances()1378 static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1379 static MemoryHistoryInstances g_instances;
1380 return g_instances;
1381 }
1382
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,MemoryHistoryCreateInstance create_callback)1383 bool PluginManager::RegisterPlugin(
1384 llvm::StringRef name, llvm::StringRef description,
1385 MemoryHistoryCreateInstance create_callback) {
1386 return GetMemoryHistoryInstances().RegisterPlugin(name, description,
1387 create_callback);
1388 }
1389
UnregisterPlugin(MemoryHistoryCreateInstance create_callback)1390 bool PluginManager::UnregisterPlugin(
1391 MemoryHistoryCreateInstance create_callback) {
1392 return GetMemoryHistoryInstances().UnregisterPlugin(create_callback);
1393 }
1394
1395 MemoryHistoryCreateInstance
GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx)1396 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1397 return GetMemoryHistoryInstances().GetCallbackAtIndex(idx);
1398 }
1399
1400 #pragma mark InstrumentationRuntime
1401
1402 struct InstrumentationRuntimeInstance
1403 : public PluginInstance<InstrumentationRuntimeCreateInstance> {
InstrumentationRuntimeInstanceInstrumentationRuntimeInstance1404 InstrumentationRuntimeInstance(
1405 llvm::StringRef name, llvm::StringRef description,
1406 CallbackType create_callback,
1407 InstrumentationRuntimeGetType get_type_callback)
1408 : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description,
1409 create_callback),
1410 get_type_callback(get_type_callback) {}
1411
1412 InstrumentationRuntimeGetType get_type_callback = nullptr;
1413 };
1414
1415 typedef PluginInstances<InstrumentationRuntimeInstance>
1416 InstrumentationRuntimeInstances;
1417
GetInstrumentationRuntimeInstances()1418 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1419 static InstrumentationRuntimeInstances g_instances;
1420 return g_instances;
1421 }
1422
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,InstrumentationRuntimeCreateInstance create_callback,InstrumentationRuntimeGetType get_type_callback)1423 bool PluginManager::RegisterPlugin(
1424 llvm::StringRef name, llvm::StringRef description,
1425 InstrumentationRuntimeCreateInstance create_callback,
1426 InstrumentationRuntimeGetType get_type_callback) {
1427 return GetInstrumentationRuntimeInstances().RegisterPlugin(
1428 name, description, create_callback, get_type_callback);
1429 }
1430
UnregisterPlugin(InstrumentationRuntimeCreateInstance create_callback)1431 bool PluginManager::UnregisterPlugin(
1432 InstrumentationRuntimeCreateInstance create_callback) {
1433 return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback);
1434 }
1435
1436 InstrumentationRuntimeGetType
GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx)1437 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
1438 const auto &instances = GetInstrumentationRuntimeInstances().GetInstances();
1439 if (idx < instances.size())
1440 return instances[idx].get_type_callback;
1441 return nullptr;
1442 }
1443
1444 InstrumentationRuntimeCreateInstance
GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx)1445 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
1446 return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx);
1447 }
1448
1449 #pragma mark TypeSystem
1450
1451 struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
TypeSystemInstanceTypeSystemInstance1452 TypeSystemInstance(llvm::StringRef name, llvm::StringRef description,
1453 CallbackType create_callback,
1454 LanguageSet supported_languages_for_types,
1455 LanguageSet supported_languages_for_expressions)
1456 : PluginInstance<TypeSystemCreateInstance>(name, description,
1457 create_callback),
1458 supported_languages_for_types(supported_languages_for_types),
1459 supported_languages_for_expressions(
1460 supported_languages_for_expressions) {}
1461
1462 LanguageSet supported_languages_for_types;
1463 LanguageSet supported_languages_for_expressions;
1464 };
1465
1466 typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;
1467
GetTypeSystemInstances()1468 static TypeSystemInstances &GetTypeSystemInstances() {
1469 static TypeSystemInstances g_instances;
1470 return g_instances;
1471 }
1472
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,TypeSystemCreateInstance create_callback,LanguageSet supported_languages_for_types,LanguageSet supported_languages_for_expressions)1473 bool PluginManager::RegisterPlugin(
1474 llvm::StringRef name, llvm::StringRef description,
1475 TypeSystemCreateInstance create_callback,
1476 LanguageSet supported_languages_for_types,
1477 LanguageSet supported_languages_for_expressions) {
1478 return GetTypeSystemInstances().RegisterPlugin(
1479 name, description, create_callback, supported_languages_for_types,
1480 supported_languages_for_expressions);
1481 }
1482
UnregisterPlugin(TypeSystemCreateInstance create_callback)1483 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
1484 return GetTypeSystemInstances().UnregisterPlugin(create_callback);
1485 }
1486
1487 TypeSystemCreateInstance
GetTypeSystemCreateCallbackAtIndex(uint32_t idx)1488 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
1489 return GetTypeSystemInstances().GetCallbackAtIndex(idx);
1490 }
1491
GetAllTypeSystemSupportedLanguagesForTypes()1492 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
1493 const auto &instances = GetTypeSystemInstances().GetInstances();
1494 LanguageSet all;
1495 for (unsigned i = 0; i < instances.size(); ++i)
1496 all.bitvector |= instances[i].supported_languages_for_types.bitvector;
1497 return all;
1498 }
1499
GetAllTypeSystemSupportedLanguagesForExpressions()1500 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
1501 const auto &instances = GetTypeSystemInstances().GetInstances();
1502 LanguageSet all;
1503 for (unsigned i = 0; i < instances.size(); ++i)
1504 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
1505 return all;
1506 }
1507
1508 #pragma mark REPL
1509
1510 struct REPLInstance : public PluginInstance<REPLCreateInstance> {
REPLInstanceREPLInstance1511 REPLInstance(llvm::StringRef name, llvm::StringRef description,
1512 CallbackType create_callback, LanguageSet supported_languages)
1513 : PluginInstance<REPLCreateInstance>(name, description, create_callback),
1514 supported_languages(supported_languages) {}
1515
1516 LanguageSet supported_languages;
1517 };
1518
1519 typedef PluginInstances<REPLInstance> REPLInstances;
1520
GetREPLInstances()1521 static REPLInstances &GetREPLInstances() {
1522 static REPLInstances g_instances;
1523 return g_instances;
1524 }
1525
RegisterPlugin(llvm::StringRef name,llvm::StringRef description,REPLCreateInstance create_callback,LanguageSet supported_languages)1526 bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
1527 REPLCreateInstance create_callback,
1528 LanguageSet supported_languages) {
1529 return GetREPLInstances().RegisterPlugin(name, description, create_callback,
1530 supported_languages);
1531 }
1532
UnregisterPlugin(REPLCreateInstance create_callback)1533 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
1534 return GetREPLInstances().UnregisterPlugin(create_callback);
1535 }
1536
GetREPLCreateCallbackAtIndex(uint32_t idx)1537 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
1538 return GetREPLInstances().GetCallbackAtIndex(idx);
1539 }
1540
GetREPLSupportedLanguagesAtIndex(uint32_t idx)1541 LanguageSet PluginManager::GetREPLSupportedLanguagesAtIndex(uint32_t idx) {
1542 const auto &instances = GetREPLInstances().GetInstances();
1543 return idx < instances.size() ? instances[idx].supported_languages
1544 : LanguageSet();
1545 }
1546
GetREPLAllTypeSystemSupportedLanguages()1547 LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
1548 const auto &instances = GetREPLInstances().GetInstances();
1549 LanguageSet all;
1550 for (unsigned i = 0; i < instances.size(); ++i)
1551 all.bitvector |= instances[i].supported_languages.bitvector;
1552 return all;
1553 }
1554
1555 #pragma mark PluginManager
1556
DebuggerInitialize(Debugger & debugger)1557 void PluginManager::DebuggerInitialize(Debugger &debugger) {
1558 GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
1559 GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1560 GetObjectFileInstances().PerformDebuggerCallback(debugger);
1561 GetPlatformInstances().PerformDebuggerCallback(debugger);
1562 GetProcessInstances().PerformDebuggerCallback(debugger);
1563 GetSymbolFileInstances().PerformDebuggerCallback(debugger);
1564 GetSymbolLocatorInstances().PerformDebuggerCallback(debugger);
1565 GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
1566 GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
1567 GetTracePluginInstances().PerformDebuggerCallback(debugger);
1568 }
1569
1570 // This is the preferred new way to register plugin specific settings. e.g.
1571 // This will put a plugin's settings under e.g.
1572 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1573 static lldb::OptionValuePropertiesSP
GetDebuggerPropertyForPlugins(Debugger & debugger,llvm::StringRef plugin_type_name,llvm::StringRef plugin_type_desc,bool can_create)1574 GetDebuggerPropertyForPlugins(Debugger &debugger, llvm::StringRef plugin_type_name,
1575 llvm::StringRef plugin_type_desc,
1576 bool can_create) {
1577 lldb::OptionValuePropertiesSP parent_properties_sp(
1578 debugger.GetValueProperties());
1579 if (parent_properties_sp) {
1580 static constexpr llvm::StringLiteral g_property_name("plugin");
1581
1582 OptionValuePropertiesSP plugin_properties_sp =
1583 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
1584 if (!plugin_properties_sp && can_create) {
1585 plugin_properties_sp =
1586 std::make_shared<OptionValueProperties>(g_property_name);
1587 parent_properties_sp->AppendProperty(g_property_name,
1588 "Settings specify to plugins.", true,
1589 plugin_properties_sp);
1590 }
1591
1592 if (plugin_properties_sp) {
1593 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1594 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1595 if (!plugin_type_properties_sp && can_create) {
1596 plugin_type_properties_sp =
1597 std::make_shared<OptionValueProperties>(plugin_type_name);
1598 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1599 true, plugin_type_properties_sp);
1600 }
1601 return plugin_type_properties_sp;
1602 }
1603 }
1604 return lldb::OptionValuePropertiesSP();
1605 }
1606
1607 // This is deprecated way to register plugin specific settings. e.g.
1608 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
1609 // generic settings would be under "platform.SETTINGNAME".
GetDebuggerPropertyForPluginsOldStyle(Debugger & debugger,llvm::StringRef plugin_type_name,llvm::StringRef plugin_type_desc,bool can_create)1610 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
1611 Debugger &debugger, llvm::StringRef plugin_type_name,
1612 llvm::StringRef plugin_type_desc, bool can_create) {
1613 static constexpr llvm::StringLiteral g_property_name("plugin");
1614 lldb::OptionValuePropertiesSP parent_properties_sp(
1615 debugger.GetValueProperties());
1616 if (parent_properties_sp) {
1617 OptionValuePropertiesSP plugin_properties_sp =
1618 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1619 if (!plugin_properties_sp && can_create) {
1620 plugin_properties_sp =
1621 std::make_shared<OptionValueProperties>(plugin_type_name);
1622 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1623 true, plugin_properties_sp);
1624 }
1625
1626 if (plugin_properties_sp) {
1627 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1628 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
1629 if (!plugin_type_properties_sp && can_create) {
1630 plugin_type_properties_sp =
1631 std::make_shared<OptionValueProperties>(g_property_name);
1632 plugin_properties_sp->AppendProperty(g_property_name,
1633 "Settings specific to plugins",
1634 true, plugin_type_properties_sp);
1635 }
1636 return plugin_type_properties_sp;
1637 }
1638 }
1639 return lldb::OptionValuePropertiesSP();
1640 }
1641
1642 namespace {
1643
1644 typedef lldb::OptionValuePropertiesSP
1645 GetDebuggerPropertyForPluginsPtr(Debugger &, llvm::StringRef, llvm::StringRef,
1646 bool can_create);
1647 }
1648
1649 static lldb::OptionValuePropertiesSP
GetSettingForPlugin(Debugger & debugger,llvm::StringRef setting_name,llvm::StringRef plugin_type_name,GetDebuggerPropertyForPluginsPtr get_debugger_property=GetDebuggerPropertyForPlugins)1650 GetSettingForPlugin(Debugger &debugger, llvm::StringRef setting_name,
1651 llvm::StringRef plugin_type_name,
1652 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1653 GetDebuggerPropertyForPlugins) {
1654 lldb::OptionValuePropertiesSP properties_sp;
1655 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
1656 debugger, plugin_type_name,
1657 "", // not creating to so we don't need the description
1658 false));
1659 if (plugin_type_properties_sp)
1660 properties_sp =
1661 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1662 return properties_sp;
1663 }
1664
1665 static bool
CreateSettingForPlugin(Debugger & debugger,llvm::StringRef plugin_type_name,llvm::StringRef plugin_type_desc,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property,GetDebuggerPropertyForPluginsPtr get_debugger_property=GetDebuggerPropertyForPlugins)1666 CreateSettingForPlugin(Debugger &debugger, llvm::StringRef plugin_type_name,
1667 llvm::StringRef plugin_type_desc,
1668 const lldb::OptionValuePropertiesSP &properties_sp,
1669 llvm::StringRef description, bool is_global_property,
1670 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1671 GetDebuggerPropertyForPlugins) {
1672 if (properties_sp) {
1673 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1674 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
1675 true));
1676 if (plugin_type_properties_sp) {
1677 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1678 description, is_global_property,
1679 properties_sp);
1680 return true;
1681 }
1682 }
1683 return false;
1684 }
1685
1686 static constexpr llvm::StringLiteral kDynamicLoaderPluginName("dynamic-loader");
1687 static constexpr llvm::StringLiteral kPlatformPluginName("platform");
1688 static constexpr llvm::StringLiteral kProcessPluginName("process");
1689 static constexpr llvm::StringLiteral kTracePluginName("trace");
1690 static constexpr llvm::StringLiteral kObjectFilePluginName("object-file");
1691 static constexpr llvm::StringLiteral kSymbolFilePluginName("symbol-file");
1692 static constexpr llvm::StringLiteral kSymbolLocatorPluginName("symbol-locator");
1693 static constexpr llvm::StringLiteral kJITLoaderPluginName("jit-loader");
1694 static constexpr llvm::StringLiteral
1695 kStructuredDataPluginName("structured-data");
1696
1697 lldb::OptionValuePropertiesSP
GetSettingForDynamicLoaderPlugin(Debugger & debugger,llvm::StringRef setting_name)1698 PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
1699 llvm::StringRef setting_name) {
1700 return GetSettingForPlugin(debugger, setting_name, kDynamicLoaderPluginName);
1701 }
1702
CreateSettingForDynamicLoaderPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property)1703 bool PluginManager::CreateSettingForDynamicLoaderPlugin(
1704 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1705 llvm::StringRef description, bool is_global_property) {
1706 return CreateSettingForPlugin(debugger, kDynamicLoaderPluginName,
1707 "Settings for dynamic loader plug-ins",
1708 properties_sp, description, is_global_property);
1709 }
1710
1711 lldb::OptionValuePropertiesSP
GetSettingForPlatformPlugin(Debugger & debugger,llvm::StringRef setting_name)1712 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
1713 llvm::StringRef setting_name) {
1714 return GetSettingForPlugin(debugger, setting_name, kPlatformPluginName,
1715 GetDebuggerPropertyForPluginsOldStyle);
1716 }
1717
CreateSettingForPlatformPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property)1718 bool PluginManager::CreateSettingForPlatformPlugin(
1719 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1720 llvm::StringRef description, bool is_global_property) {
1721 return CreateSettingForPlugin(debugger, kPlatformPluginName,
1722 "Settings for platform plug-ins", properties_sp,
1723 description, is_global_property,
1724 GetDebuggerPropertyForPluginsOldStyle);
1725 }
1726
1727 lldb::OptionValuePropertiesSP
GetSettingForProcessPlugin(Debugger & debugger,llvm::StringRef setting_name)1728 PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
1729 llvm::StringRef setting_name) {
1730 return GetSettingForPlugin(debugger, setting_name, kProcessPluginName);
1731 }
1732
CreateSettingForProcessPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property)1733 bool PluginManager::CreateSettingForProcessPlugin(
1734 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1735 llvm::StringRef description, bool is_global_property) {
1736 return CreateSettingForPlugin(debugger, kProcessPluginName,
1737 "Settings for process plug-ins", properties_sp,
1738 description, is_global_property);
1739 }
1740
1741 lldb::OptionValuePropertiesSP
GetSettingForSymbolLocatorPlugin(Debugger & debugger,llvm::StringRef setting_name)1742 PluginManager::GetSettingForSymbolLocatorPlugin(Debugger &debugger,
1743 llvm::StringRef setting_name) {
1744 return GetSettingForPlugin(debugger, setting_name, kSymbolLocatorPluginName);
1745 }
1746
CreateSettingForSymbolLocatorPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property)1747 bool PluginManager::CreateSettingForSymbolLocatorPlugin(
1748 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1749 llvm::StringRef description, bool is_global_property) {
1750 return CreateSettingForPlugin(debugger, kSymbolLocatorPluginName,
1751 "Settings for symbol locator plug-ins",
1752 properties_sp, description, is_global_property);
1753 }
1754
CreateSettingForTracePlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property)1755 bool PluginManager::CreateSettingForTracePlugin(
1756 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1757 llvm::StringRef description, bool is_global_property) {
1758 return CreateSettingForPlugin(debugger, kTracePluginName,
1759 "Settings for trace plug-ins", properties_sp,
1760 description, is_global_property);
1761 }
1762
1763 lldb::OptionValuePropertiesSP
GetSettingForObjectFilePlugin(Debugger & debugger,llvm::StringRef setting_name)1764 PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger,
1765 llvm::StringRef setting_name) {
1766 return GetSettingForPlugin(debugger, setting_name, kObjectFilePluginName);
1767 }
1768
CreateSettingForObjectFilePlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property)1769 bool PluginManager::CreateSettingForObjectFilePlugin(
1770 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1771 llvm::StringRef description, bool is_global_property) {
1772 return CreateSettingForPlugin(debugger, kObjectFilePluginName,
1773 "Settings for object file plug-ins",
1774 properties_sp, description, is_global_property);
1775 }
1776
1777 lldb::OptionValuePropertiesSP
GetSettingForSymbolFilePlugin(Debugger & debugger,llvm::StringRef setting_name)1778 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
1779 llvm::StringRef setting_name) {
1780 return GetSettingForPlugin(debugger, setting_name, kSymbolFilePluginName);
1781 }
1782
CreateSettingForSymbolFilePlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property)1783 bool PluginManager::CreateSettingForSymbolFilePlugin(
1784 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1785 llvm::StringRef description, bool is_global_property) {
1786 return CreateSettingForPlugin(debugger, kSymbolFilePluginName,
1787 "Settings for symbol file plug-ins",
1788 properties_sp, description, is_global_property);
1789 }
1790
1791 lldb::OptionValuePropertiesSP
GetSettingForJITLoaderPlugin(Debugger & debugger,llvm::StringRef setting_name)1792 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
1793 llvm::StringRef setting_name) {
1794 return GetSettingForPlugin(debugger, setting_name, kJITLoaderPluginName);
1795 }
1796
CreateSettingForJITLoaderPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property)1797 bool PluginManager::CreateSettingForJITLoaderPlugin(
1798 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1799 llvm::StringRef description, bool is_global_property) {
1800 return CreateSettingForPlugin(debugger, kJITLoaderPluginName,
1801 "Settings for JIT loader plug-ins",
1802 properties_sp, description, is_global_property);
1803 }
1804
1805 static const char *kOperatingSystemPluginName("os");
1806
1807 lldb::OptionValuePropertiesSP
GetSettingForOperatingSystemPlugin(Debugger & debugger,llvm::StringRef setting_name)1808 PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger,
1809 llvm::StringRef setting_name) {
1810 lldb::OptionValuePropertiesSP properties_sp;
1811 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1812 GetDebuggerPropertyForPlugins(
1813 debugger, kOperatingSystemPluginName,
1814 "", // not creating to so we don't need the description
1815 false));
1816 if (plugin_type_properties_sp)
1817 properties_sp =
1818 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1819 return properties_sp;
1820 }
1821
CreateSettingForOperatingSystemPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property)1822 bool PluginManager::CreateSettingForOperatingSystemPlugin(
1823 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1824 llvm::StringRef description, bool is_global_property) {
1825 if (properties_sp) {
1826 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1827 GetDebuggerPropertyForPlugins(debugger, kOperatingSystemPluginName,
1828 "Settings for operating system plug-ins",
1829 true));
1830 if (plugin_type_properties_sp) {
1831 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1832 description, is_global_property,
1833 properties_sp);
1834 return true;
1835 }
1836 }
1837 return false;
1838 }
1839
1840 lldb::OptionValuePropertiesSP
GetSettingForStructuredDataPlugin(Debugger & debugger,llvm::StringRef setting_name)1841 PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
1842 llvm::StringRef setting_name) {
1843 return GetSettingForPlugin(debugger, setting_name, kStructuredDataPluginName);
1844 }
1845
CreateSettingForStructuredDataPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,llvm::StringRef description,bool is_global_property)1846 bool PluginManager::CreateSettingForStructuredDataPlugin(
1847 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1848 llvm::StringRef description, bool is_global_property) {
1849 return CreateSettingForPlugin(debugger, kStructuredDataPluginName,
1850 "Settings for structured data plug-ins",
1851 properties_sp, description, is_global_property);
1852 }
1853