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