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 | |
50 | static std::recursive_mutex &GetPluginMapMutex() { |
51 | static std::recursive_mutex g_plugin_map_mutex; |
52 | return g_plugin_map_mutex; |
53 | } |
54 | |
55 | static PluginTerminateMap &GetPluginMap() { |
56 | static PluginTerminateMap g_plugin_map; |
57 | return g_plugin_map; |
58 | } |
59 | |
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(x: plugin_file_spec) != plugin_map.end(); |
64 | } |
65 | |
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 | |
74 | template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) { |
75 | return reinterpret_cast<FPtrTy>(VPtr); |
76 | } |
77 | |
78 | static FileSystem::EnumerateDirectoryResult |
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(file_spec&: 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 | filename: plugin_file_spec.GetPath().c_str(), errMsg: &pluginLoadError); |
101 | if (plugin_info.library.isValid()) { |
102 | bool success = false; |
103 | plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>( |
104 | VPtr: plugin_info.library.getAddressOfSymbol(symbolName: "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 | VPtr: plugin_info.library.getAddressOfSymbol(symbolName: "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 | |
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(file_spec: dir_spec) && |
150 | dir_spec.GetPath(path: dir_path, max_path_length: sizeof(dir_path))) { |
151 | FileSystem::Instance().EnumerateDirectory(path: dir_path, find_directories, |
152 | find_files, find_other, |
153 | callback: LoadPluginCallback, callback_baton: nullptr); |
154 | } |
155 | } |
156 | |
157 | if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) { |
158 | if (FileSystem::Instance().Exists(file_spec: dir_spec) && |
159 | dir_spec.GetPath(path: dir_path, max_path_length: sizeof(dir_path))) { |
160 | FileSystem::Instance().EnumerateDirectory(path: dir_path, find_directories, |
161 | find_files, find_other, |
162 | callback: LoadPluginCallback, callback_baton: nullptr); |
163 | } |
164 | } |
165 | } |
166 | |
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; |
187 | 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> |
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 | |
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 | |
228 | typename Instance::CallbackType GetCallbackAtIndex(uint32_t idx) { |
229 | if (Instance *instance = GetInstanceAtIndex(idx)) |
230 | return instance->create_callback; |
231 | return nullptr; |
232 | } |
233 | |
234 | llvm::StringRef GetDescriptionAtIndex(uint32_t idx) { |
235 | if (Instance *instance = GetInstanceAtIndex(idx)) |
236 | return instance->description; |
237 | return "" ; |
238 | } |
239 | |
240 | llvm::StringRef GetNameAtIndex(uint32_t idx) { |
241 | if (Instance *instance = GetInstanceAtIndex(idx)) |
242 | return instance->name; |
243 | return "" ; |
244 | } |
245 | |
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 | |
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 | |
263 | const std::vector<Instance> &GetInstances() const { return m_instances; } |
264 | std::vector<Instance> &GetInstances() { return m_instances; } |
265 | |
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 | |
281 | static ABIInstances &GetABIInstances() { |
282 | static ABIInstances g_instances; |
283 | return g_instances; |
284 | } |
285 | |
286 | bool PluginManager::RegisterPlugin(llvm::StringRef name, |
287 | llvm::StringRef description, |
288 | ABICreateInstance create_callback) { |
289 | return GetABIInstances().RegisterPlugin(name, description, callback: create_callback); |
290 | } |
291 | |
292 | bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) { |
293 | return GetABIInstances().UnregisterPlugin(callback: create_callback); |
294 | } |
295 | |
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 | |
305 | static ArchitectureInstances &GetArchitectureInstances() { |
306 | static ArchitectureInstances g_instances; |
307 | return g_instances; |
308 | } |
309 | |
310 | void PluginManager::RegisterPlugin(llvm::StringRef name, |
311 | llvm::StringRef description, |
312 | ArchitectureCreateInstance create_callback) { |
313 | GetArchitectureInstances().push_back(x: {name, description, create_callback}); |
314 | } |
315 | |
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(position: pos); |
323 | return; |
324 | } |
325 | } |
326 | llvm_unreachable("Plugin not found" ); |
327 | } |
328 | |
329 | std::unique_ptr<Architecture> |
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 | |
343 | static DisassemblerInstances &GetDisassemblerInstances() { |
344 | static DisassemblerInstances g_instances; |
345 | return g_instances; |
346 | } |
347 | |
348 | bool PluginManager::RegisterPlugin(llvm::StringRef name, |
349 | llvm::StringRef description, |
350 | DisassemblerCreateInstance create_callback) { |
351 | return GetDisassemblerInstances().RegisterPlugin(name, description, |
352 | callback: create_callback); |
353 | } |
354 | |
355 | bool PluginManager::UnregisterPlugin( |
356 | DisassemblerCreateInstance create_callback) { |
357 | return GetDisassemblerInstances().UnregisterPlugin(callback: create_callback); |
358 | } |
359 | |
360 | DisassemblerCreateInstance |
361 | PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) { |
362 | return GetDisassemblerInstances().GetCallbackAtIndex(idx); |
363 | } |
364 | |
365 | DisassemblerCreateInstance |
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 | |
376 | static DynamicLoaderInstances &GetDynamicLoaderInstances() { |
377 | static DynamicLoaderInstances g_instances; |
378 | return g_instances; |
379 | } |
380 | |
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, callback: create_callback, args&: debugger_init_callback); |
387 | } |
388 | |
389 | bool PluginManager::UnregisterPlugin( |
390 | DynamicLoaderCreateInstance create_callback) { |
391 | return GetDynamicLoaderInstances().UnregisterPlugin(callback: create_callback); |
392 | } |
393 | |
394 | DynamicLoaderCreateInstance |
395 | PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) { |
396 | return GetDynamicLoaderInstances().GetCallbackAtIndex(idx); |
397 | } |
398 | |
399 | DynamicLoaderCreateInstance |
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 | |
410 | static JITLoaderInstances &GetJITLoaderInstances() { |
411 | static JITLoaderInstances g_instances; |
412 | return g_instances; |
413 | } |
414 | |
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, callback: create_callback, args&: debugger_init_callback); |
421 | } |
422 | |
423 | bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) { |
424 | return GetJITLoaderInstances().UnregisterPlugin(callback: create_callback); |
425 | } |
426 | |
427 | JITLoaderCreateInstance |
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 | |
438 | static EmulateInstructionInstances &GetEmulateInstructionInstances() { |
439 | static EmulateInstructionInstances g_instances; |
440 | return g_instances; |
441 | } |
442 | |
443 | bool PluginManager::RegisterPlugin( |
444 | llvm::StringRef name, llvm::StringRef description, |
445 | EmulateInstructionCreateInstance create_callback) { |
446 | return GetEmulateInstructionInstances().RegisterPlugin(name, description, |
447 | callback: create_callback); |
448 | } |
449 | |
450 | bool PluginManager::UnregisterPlugin( |
451 | EmulateInstructionCreateInstance create_callback) { |
452 | return GetEmulateInstructionInstances().UnregisterPlugin(callback: create_callback); |
453 | } |
454 | |
455 | EmulateInstructionCreateInstance |
456 | PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) { |
457 | return GetEmulateInstructionInstances().GetCallbackAtIndex(idx); |
458 | } |
459 | |
460 | EmulateInstructionCreateInstance |
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 | |
471 | static OperatingSystemInstances &GetOperatingSystemInstances() { |
472 | static OperatingSystemInstances g_instances; |
473 | return g_instances; |
474 | } |
475 | |
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, callback: create_callback, args&: debugger_init_callback); |
482 | } |
483 | |
484 | bool PluginManager::UnregisterPlugin( |
485 | OperatingSystemCreateInstance create_callback) { |
486 | return GetOperatingSystemInstances().UnregisterPlugin(callback: create_callback); |
487 | } |
488 | |
489 | OperatingSystemCreateInstance |
490 | PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) { |
491 | return GetOperatingSystemInstances().GetCallbackAtIndex(idx); |
492 | } |
493 | |
494 | OperatingSystemCreateInstance |
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 | |
505 | static LanguageInstances &GetLanguageInstances() { |
506 | static LanguageInstances g_instances; |
507 | return g_instances; |
508 | } |
509 | |
510 | bool PluginManager::RegisterPlugin(llvm::StringRef name, |
511 | llvm::StringRef description, |
512 | LanguageCreateInstance create_callback) { |
513 | return GetLanguageInstances().RegisterPlugin(name, description, |
514 | callback: create_callback); |
515 | } |
516 | |
517 | bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) { |
518 | return GetLanguageInstances().UnregisterPlugin(callback: create_callback); |
519 | } |
520 | |
521 | LanguageCreateInstance |
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> { |
530 | 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 | |
547 | static LanguageRuntimeInstances &GetLanguageRuntimeInstances() { |
548 | static LanguageRuntimeInstances g_instances; |
549 | return g_instances; |
550 | } |
551 | |
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, callback: create_callback, args: nullptr, args&: command_callback, |
559 | args&: precondition_callback); |
560 | } |
561 | |
562 | bool PluginManager::UnregisterPlugin( |
563 | LanguageRuntimeCreateInstance create_callback) { |
564 | return GetLanguageRuntimeInstances().UnregisterPlugin(callback: create_callback); |
565 | } |
566 | |
567 | LanguageRuntimeCreateInstance |
568 | PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) { |
569 | return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx); |
570 | } |
571 | |
572 | LanguageRuntimeGetCommandObject |
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 |
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 | |
593 | static SystemRuntimeInstances &GetSystemRuntimeInstances() { |
594 | static SystemRuntimeInstances g_instances; |
595 | return g_instances; |
596 | } |
597 | |
598 | bool PluginManager::RegisterPlugin( |
599 | llvm::StringRef name, llvm::StringRef description, |
600 | SystemRuntimeCreateInstance create_callback) { |
601 | return GetSystemRuntimeInstances().RegisterPlugin(name, description, |
602 | callback: create_callback); |
603 | } |
604 | |
605 | bool PluginManager::UnregisterPlugin( |
606 | SystemRuntimeCreateInstance create_callback) { |
607 | return GetSystemRuntimeInstances().UnregisterPlugin(callback: create_callback); |
608 | } |
609 | |
610 | SystemRuntimeCreateInstance |
611 | PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) { |
612 | return GetSystemRuntimeInstances().GetCallbackAtIndex(idx); |
613 | } |
614 | |
615 | #pragma mark ObjectFile |
616 | |
617 | struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> { |
618 | 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 | |
637 | static ObjectFileInstances &GetObjectFileInstances() { |
638 | static ObjectFileInstances g_instances; |
639 | return g_instances; |
640 | } |
641 | |
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, callback: create_callback, args&: create_memory_callback, |
651 | args&: get_module_specifications, args&: save_core, args&: debugger_init_callback); |
652 | } |
653 | |
654 | bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) { |
655 | return GetObjectFileInstances().UnregisterPlugin(callback: create_callback); |
656 | } |
657 | |
658 | ObjectFileCreateInstance |
659 | PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) { |
660 | return GetObjectFileInstances().GetCallbackAtIndex(idx); |
661 | } |
662 | |
663 | ObjectFileCreateMemoryInstance |
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 |
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 |
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 | |
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: 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> { |
723 | 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 | |
738 | static ObjectContainerInstances &GetObjectContainerInstances() { |
739 | static ObjectContainerInstances g_instances; |
740 | return g_instances; |
741 | } |
742 | |
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, callback: create_callback, args&: create_memory_callback, |
750 | args&: get_module_specifications); |
751 | } |
752 | |
753 | bool PluginManager::UnregisterPlugin( |
754 | ObjectContainerCreateInstance create_callback) { |
755 | return GetObjectContainerInstances().UnregisterPlugin(callback: create_callback); |
756 | } |
757 | |
758 | ObjectContainerCreateInstance |
759 | PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) { |
760 | return GetObjectContainerInstances().GetCallbackAtIndex(idx); |
761 | } |
762 | |
763 | ObjectContainerCreateMemoryInstance |
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 |
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 | |
785 | static PlatformInstances &GetPlatformInstances() { |
786 | static PlatformInstances g_platform_instances; |
787 | return g_platform_instances; |
788 | } |
789 | |
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, callback: create_callback, args&: debugger_init_callback); |
796 | } |
797 | |
798 | bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { |
799 | return GetPlatformInstances().UnregisterPlugin(callback: create_callback); |
800 | } |
801 | |
802 | llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { |
803 | return GetPlatformInstances().GetNameAtIndex(idx); |
804 | } |
805 | |
806 | llvm::StringRef |
807 | PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { |
808 | return GetPlatformInstances().GetDescriptionAtIndex(idx); |
809 | } |
810 | |
811 | PlatformCreateInstance |
812 | PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) { |
813 | return GetPlatformInstances().GetCallbackAtIndex(idx); |
814 | } |
815 | |
816 | PlatformCreateInstance |
817 | PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) { |
818 | return GetPlatformInstances().GetCallbackForName(name); |
819 | } |
820 | |
821 | void PluginManager::AutoCompletePlatformName(llvm::StringRef name, |
822 | CompletionRequest &request) { |
823 | for (const auto &instance : GetPlatformInstances().GetInstances()) { |
824 | if (instance.name.starts_with(Prefix: name)) |
825 | request.AddCompletion(completion: instance.name); |
826 | } |
827 | } |
828 | |
829 | #pragma mark Process |
830 | |
831 | typedef PluginInstance<ProcessCreateInstance> ProcessInstance; |
832 | typedef PluginInstances<ProcessInstance> ProcessInstances; |
833 | |
834 | static ProcessInstances &GetProcessInstances() { |
835 | static ProcessInstances g_instances; |
836 | return g_instances; |
837 | } |
838 | |
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, callback: create_callback, args&: debugger_init_callback); |
845 | } |
846 | |
847 | bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { |
848 | return GetProcessInstances().UnregisterPlugin(callback: create_callback); |
849 | } |
850 | |
851 | llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { |
852 | return GetProcessInstances().GetNameAtIndex(idx); |
853 | } |
854 | |
855 | llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { |
856 | return GetProcessInstances().GetDescriptionAtIndex(idx); |
857 | } |
858 | |
859 | ProcessCreateInstance |
860 | PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { |
861 | return GetProcessInstances().GetCallbackAtIndex(idx); |
862 | } |
863 | |
864 | ProcessCreateInstance |
865 | PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) { |
866 | return GetProcessInstances().GetCallbackForName(name); |
867 | } |
868 | |
869 | void PluginManager::AutoCompleteProcessName(llvm::StringRef name, |
870 | CompletionRequest &request) { |
871 | for (const auto &instance : GetProcessInstances().GetInstances()) { |
872 | if (instance.name.starts_with(Prefix: name)) |
873 | request.AddCompletion(completion: instance.name, description: instance.description); |
874 | } |
875 | } |
876 | |
877 | #pragma mark RegisterTypeBuilder |
878 | |
879 | struct RegisterTypeBuilderInstance |
880 | : public PluginInstance<RegisterTypeBuilderCreateInstance> { |
881 | 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 | |
890 | static RegisterTypeBuilderInstances &GetRegisterTypeBuilderInstances() { |
891 | static RegisterTypeBuilderInstances g_instances; |
892 | return g_instances; |
893 | } |
894 | |
895 | bool PluginManager::RegisterPlugin( |
896 | llvm::StringRef name, llvm::StringRef description, |
897 | RegisterTypeBuilderCreateInstance create_callback) { |
898 | return GetRegisterTypeBuilderInstances().RegisterPlugin(name, description, |
899 | callback: create_callback); |
900 | } |
901 | |
902 | bool PluginManager::UnregisterPlugin( |
903 | RegisterTypeBuilderCreateInstance create_callback) { |
904 | return GetRegisterTypeBuilderInstances().UnregisterPlugin(callback: create_callback); |
905 | } |
906 | |
907 | lldb::RegisterTypeBuilderSP |
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> { |
920 | 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 | |
932 | static ScriptInterpreterInstances &GetScriptInterpreterInstances() { |
933 | static ScriptInterpreterInstances g_instances; |
934 | return g_instances; |
935 | } |
936 | |
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, callback: create_callback, args&: script_language); |
943 | } |
944 | |
945 | bool PluginManager::UnregisterPlugin( |
946 | ScriptInterpreterCreateInstance create_callback) { |
947 | return GetScriptInterpreterInstances().UnregisterPlugin(callback: create_callback); |
948 | } |
949 | |
950 | ScriptInterpreterCreateInstance |
951 | PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) { |
952 | return GetScriptInterpreterInstances().GetCallbackAtIndex(idx); |
953 | } |
954 | |
955 | lldb::ScriptInterpreterSP |
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> { |
977 | 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 | |
992 | static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { |
993 | static StructuredDataPluginInstances g_instances; |
994 | return g_instances; |
995 | } |
996 | |
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, callback: create_callback, args&: debugger_init_callback, |
1004 | args&: filter_callback); |
1005 | } |
1006 | |
1007 | bool PluginManager::UnregisterPlugin( |
1008 | StructuredDataPluginCreateInstance create_callback) { |
1009 | return GetStructuredDataPluginInstances().UnregisterPlugin(callback: create_callback); |
1010 | } |
1011 | |
1012 | StructuredDataPluginCreateInstance |
1013 | PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) { |
1014 | return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx); |
1015 | } |
1016 | |
1017 | StructuredDataFilterLaunchInfo |
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 | |
1035 | static SymbolFileInstances &GetSymbolFileInstances() { |
1036 | static SymbolFileInstances g_instances; |
1037 | return g_instances; |
1038 | } |
1039 | |
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, callback: create_callback, args&: debugger_init_callback); |
1046 | } |
1047 | |
1048 | bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) { |
1049 | return GetSymbolFileInstances().UnregisterPlugin(callback: create_callback); |
1050 | } |
1051 | |
1052 | SymbolFileCreateInstance |
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 | |
1062 | static SymbolVendorInstances &GetSymbolVendorInstances() { |
1063 | static SymbolVendorInstances g_instances; |
1064 | return g_instances; |
1065 | } |
1066 | |
1067 | bool PluginManager::RegisterPlugin(llvm::StringRef name, |
1068 | llvm::StringRef description, |
1069 | SymbolVendorCreateInstance create_callback) { |
1070 | return GetSymbolVendorInstances().RegisterPlugin(name, description, |
1071 | callback: create_callback); |
1072 | } |
1073 | |
1074 | bool PluginManager::UnregisterPlugin( |
1075 | SymbolVendorCreateInstance create_callback) { |
1076 | return GetSymbolVendorInstances().UnregisterPlugin(callback: create_callback); |
1077 | } |
1078 | |
1079 | SymbolVendorCreateInstance |
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> { |
1088 | 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 | |
1110 | static SymbolLocatorInstances &GetSymbolLocatorInstances() { |
1111 | static SymbolLocatorInstances g_instances; |
1112 | return g_instances; |
1113 | } |
1114 | |
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, callback: create_callback, args&: locate_executable_object_file, |
1125 | args&: locate_executable_symbol_file, args&: download_object_symbol_file, |
1126 | args&: find_symbol_file_in_bundle, args&: debugger_init_callback); |
1127 | } |
1128 | |
1129 | bool PluginManager::UnregisterPlugin( |
1130 | SymbolLocatorCreateInstance create_callback) { |
1131 | return GetSymbolLocatorInstances().UnregisterPlugin(callback: create_callback); |
1132 | } |
1133 | |
1134 | SymbolLocatorCreateInstance |
1135 | PluginManager::GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx) { |
1136 | return GetSymbolLocatorInstances().GetCallbackAtIndex(idx); |
1137 | } |
1138 | |
1139 | ModuleSpec |
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 | |
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 | |
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 | |
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> { |
1201 | 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 | |
1218 | static TraceInstances &GetTracePluginInstances() { |
1219 | static TraceInstances g_instances; |
1220 | return g_instances; |
1221 | } |
1222 | |
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, callback: create_callback_from_bundle, |
1230 | args&: create_callback_for_live_process, args&: schema, args&: debugger_init_callback); |
1231 | } |
1232 | |
1233 | bool PluginManager::UnregisterPlugin( |
1234 | TraceCreateInstanceFromBundle create_callback_from_bundle) { |
1235 | return GetTracePluginInstances().UnregisterPlugin( |
1236 | callback: create_callback_from_bundle); |
1237 | } |
1238 | |
1239 | TraceCreateInstanceFromBundle |
1240 | PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) { |
1241 | return GetTracePluginInstances().GetCallbackForName(name: plugin_name); |
1242 | } |
1243 | |
1244 | TraceCreateInstanceForLiveProcess |
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 | |
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 | |
1259 | llvm::StringRef PluginManager::GetTraceSchema(size_t index) { |
1260 | if (TraceInstance *instance = |
1261 | GetTracePluginInstances().GetInstanceAtIndex(idx: index)) |
1262 | return instance->schema; |
1263 | return llvm::StringRef(); |
1264 | } |
1265 | |
1266 | #pragma mark TraceExporter |
1267 | |
1268 | struct TraceExporterInstance |
1269 | : public PluginInstance<TraceExporterCreateInstance> { |
1270 | 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 | |
1284 | static TraceExporterInstances &GetTraceExporterInstances() { |
1285 | static TraceExporterInstances g_instances; |
1286 | return g_instances; |
1287 | } |
1288 | |
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, callback: create_callback, args&: create_thread_trace_export_command); |
1295 | } |
1296 | |
1297 | TraceExporterCreateInstance |
1298 | PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) { |
1299 | return GetTraceExporterInstances().GetCallbackForName(name: plugin_name); |
1300 | } |
1301 | |
1302 | bool PluginManager::UnregisterPlugin( |
1303 | TraceExporterCreateInstance create_callback) { |
1304 | return GetTraceExporterInstances().UnregisterPlugin(callback: create_callback); |
1305 | } |
1306 | |
1307 | ThreadTraceExportCommandCreator |
1308 | PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) { |
1309 | if (TraceExporterInstance *instance = |
1310 | GetTraceExporterInstances().GetInstanceAtIndex(idx: index)) |
1311 | return instance->create_thread_trace_export_command; |
1312 | return nullptr; |
1313 | } |
1314 | |
1315 | llvm::StringRef |
1316 | PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) { |
1317 | return GetTraceExporterInstances().GetNameAtIndex(idx: index); |
1318 | } |
1319 | |
1320 | #pragma mark UnwindAssembly |
1321 | |
1322 | typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance; |
1323 | typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances; |
1324 | |
1325 | static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { |
1326 | static UnwindAssemblyInstances g_instances; |
1327 | return g_instances; |
1328 | } |
1329 | |
1330 | bool PluginManager::RegisterPlugin( |
1331 | llvm::StringRef name, llvm::StringRef description, |
1332 | UnwindAssemblyCreateInstance create_callback) { |
1333 | return GetUnwindAssemblyInstances().RegisterPlugin(name, description, |
1334 | callback: create_callback); |
1335 | } |
1336 | |
1337 | bool PluginManager::UnregisterPlugin( |
1338 | UnwindAssemblyCreateInstance create_callback) { |
1339 | return GetUnwindAssemblyInstances().UnregisterPlugin(callback: create_callback); |
1340 | } |
1341 | |
1342 | UnwindAssemblyCreateInstance |
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 | |
1352 | static MemoryHistoryInstances &GetMemoryHistoryInstances() { |
1353 | static MemoryHistoryInstances g_instances; |
1354 | return g_instances; |
1355 | } |
1356 | |
1357 | bool PluginManager::RegisterPlugin( |
1358 | llvm::StringRef name, llvm::StringRef description, |
1359 | MemoryHistoryCreateInstance create_callback) { |
1360 | return GetMemoryHistoryInstances().RegisterPlugin(name, description, |
1361 | callback: create_callback); |
1362 | } |
1363 | |
1364 | bool PluginManager::UnregisterPlugin( |
1365 | MemoryHistoryCreateInstance create_callback) { |
1366 | return GetMemoryHistoryInstances().UnregisterPlugin(callback: create_callback); |
1367 | } |
1368 | |
1369 | MemoryHistoryCreateInstance |
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> { |
1378 | 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 | |
1392 | static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { |
1393 | static InstrumentationRuntimeInstances g_instances; |
1394 | return g_instances; |
1395 | } |
1396 | |
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, callback: create_callback, args&: get_type_callback); |
1403 | } |
1404 | |
1405 | bool PluginManager::UnregisterPlugin( |
1406 | InstrumentationRuntimeCreateInstance create_callback) { |
1407 | return GetInstrumentationRuntimeInstances().UnregisterPlugin(callback: create_callback); |
1408 | } |
1409 | |
1410 | InstrumentationRuntimeGetType |
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 |
1419 | PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { |
1420 | return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx); |
1421 | } |
1422 | |
1423 | #pragma mark TypeSystem |
1424 | |
1425 | struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> { |
1426 | 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 | |
1442 | static TypeSystemInstances &GetTypeSystemInstances() { |
1443 | static TypeSystemInstances g_instances; |
1444 | return g_instances; |
1445 | } |
1446 | |
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, callback: create_callback, args&: supported_languages_for_types, |
1454 | args&: supported_languages_for_expressions); |
1455 | } |
1456 | |
1457 | bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) { |
1458 | return GetTypeSystemInstances().UnregisterPlugin(callback: create_callback); |
1459 | } |
1460 | |
1461 | TypeSystemCreateInstance |
1462 | PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) { |
1463 | return GetTypeSystemInstances().GetCallbackAtIndex(idx); |
1464 | } |
1465 | |
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 | |
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> { |
1485 | 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 | |
1495 | static REPLInstances &GetREPLInstances() { |
1496 | static REPLInstances g_instances; |
1497 | return g_instances; |
1498 | } |
1499 | |
1500 | bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description, |
1501 | REPLCreateInstance create_callback, |
1502 | LanguageSet supported_languages) { |
1503 | return GetREPLInstances().RegisterPlugin(name, description, callback: create_callback, |
1504 | args&: supported_languages); |
1505 | } |
1506 | |
1507 | bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) { |
1508 | return GetREPLInstances().UnregisterPlugin(callback: create_callback); |
1509 | } |
1510 | |
1511 | REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) { |
1512 | return GetREPLInstances().GetCallbackAtIndex(idx); |
1513 | } |
1514 | |
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 | |
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 | |
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 |
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(exe_ctx: nullptr, name: g_property_name); |
1558 | if (!plugin_properties_sp && can_create) { |
1559 | plugin_properties_sp = |
1560 | std::make_shared<OptionValueProperties>(args: g_property_name); |
1561 | parent_properties_sp->AppendProperty(name: g_property_name, |
1562 | desc: "Settings specify to plugins." , is_global: true, |
1563 | value_sp: plugin_properties_sp); |
1564 | } |
1565 | |
1566 | if (plugin_properties_sp) { |
1567 | lldb::OptionValuePropertiesSP plugin_type_properties_sp = |
1568 | plugin_properties_sp->GetSubProperty(exe_ctx: nullptr, name: plugin_type_name); |
1569 | if (!plugin_type_properties_sp && can_create) { |
1570 | plugin_type_properties_sp = |
1571 | std::make_shared<OptionValueProperties>(args&: plugin_type_name); |
1572 | plugin_properties_sp->AppendProperty(name: plugin_type_name, desc: plugin_type_desc, |
1573 | is_global: true, value_sp: 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". |
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(exe_ctx: nullptr, name: plugin_type_name); |
1593 | if (!plugin_properties_sp && can_create) { |
1594 | plugin_properties_sp = |
1595 | std::make_shared<OptionValueProperties>(args&: plugin_type_name); |
1596 | parent_properties_sp->AppendProperty(name: plugin_type_name, desc: plugin_type_desc, |
1597 | is_global: true, value_sp: plugin_properties_sp); |
1598 | } |
1599 | |
1600 | if (plugin_properties_sp) { |
1601 | lldb::OptionValuePropertiesSP plugin_type_properties_sp = |
1602 | plugin_properties_sp->GetSubProperty(exe_ctx: nullptr, name: g_property_name); |
1603 | if (!plugin_type_properties_sp && can_create) { |
1604 | plugin_type_properties_sp = |
1605 | std::make_shared<OptionValueProperties>(args: g_property_name); |
1606 | plugin_properties_sp->AppendProperty(name: g_property_name, |
1607 | desc: "Settings specific to plugins" , |
1608 | is_global: true, value_sp: 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 |
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(exe_ctx: nullptr, name: setting_name); |
1636 | return properties_sp; |
1637 | } |
1638 | |
1639 | static bool |
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(name: properties_sp->GetName(), |
1652 | desc: description, is_global: is_global_property, |
1653 | value_sp: 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 |
1672 | PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger, |
1673 | llvm::StringRef setting_name) { |
1674 | return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kDynamicLoaderPluginName); |
1675 | } |
1676 | |
1677 | bool PluginManager::CreateSettingForDynamicLoaderPlugin( |
1678 | Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, |
1679 | llvm::StringRef description, bool is_global_property) { |
1680 | return CreateSettingForPlugin(debugger, plugin_type_name: kDynamicLoaderPluginName, |
1681 | plugin_type_desc: "Settings for dynamic loader plug-ins" , |
1682 | properties_sp, description, is_global_property); |
1683 | } |
1684 | |
1685 | lldb::OptionValuePropertiesSP |
1686 | PluginManager::GetSettingForPlatformPlugin(Debugger &debugger, |
1687 | llvm::StringRef setting_name) { |
1688 | return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kPlatformPluginName, |
1689 | get_debugger_property: GetDebuggerPropertyForPluginsOldStyle); |
1690 | } |
1691 | |
1692 | bool PluginManager::CreateSettingForPlatformPlugin( |
1693 | Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, |
1694 | llvm::StringRef description, bool is_global_property) { |
1695 | return CreateSettingForPlugin(debugger, plugin_type_name: kPlatformPluginName, |
1696 | plugin_type_desc: "Settings for platform plug-ins" , properties_sp, |
1697 | description, is_global_property, |
1698 | get_debugger_property: GetDebuggerPropertyForPluginsOldStyle); |
1699 | } |
1700 | |
1701 | lldb::OptionValuePropertiesSP |
1702 | PluginManager::GetSettingForProcessPlugin(Debugger &debugger, |
1703 | llvm::StringRef setting_name) { |
1704 | return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kProcessPluginName); |
1705 | } |
1706 | |
1707 | bool PluginManager::CreateSettingForProcessPlugin( |
1708 | Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, |
1709 | llvm::StringRef description, bool is_global_property) { |
1710 | return CreateSettingForPlugin(debugger, plugin_type_name: kProcessPluginName, |
1711 | plugin_type_desc: "Settings for process plug-ins" , properties_sp, |
1712 | description, is_global_property); |
1713 | } |
1714 | |
1715 | lldb::OptionValuePropertiesSP |
1716 | PluginManager::GetSettingForSymbolLocatorPlugin(Debugger &debugger, |
1717 | llvm::StringRef setting_name) { |
1718 | return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kSymbolLocatorPluginName); |
1719 | } |
1720 | |
1721 | bool PluginManager::CreateSettingForSymbolLocatorPlugin( |
1722 | Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, |
1723 | llvm::StringRef description, bool is_global_property) { |
1724 | return CreateSettingForPlugin(debugger, plugin_type_name: kSymbolLocatorPluginName, |
1725 | plugin_type_desc: "Settings for symbol locator plug-ins" , |
1726 | properties_sp, description, is_global_property); |
1727 | } |
1728 | |
1729 | bool PluginManager::CreateSettingForTracePlugin( |
1730 | Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, |
1731 | llvm::StringRef description, bool is_global_property) { |
1732 | return CreateSettingForPlugin(debugger, plugin_type_name: kTracePluginName, |
1733 | plugin_type_desc: "Settings for trace plug-ins" , properties_sp, |
1734 | description, is_global_property); |
1735 | } |
1736 | |
1737 | lldb::OptionValuePropertiesSP |
1738 | PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger, |
1739 | llvm::StringRef setting_name) { |
1740 | return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kObjectFilePluginName); |
1741 | } |
1742 | |
1743 | bool PluginManager::CreateSettingForObjectFilePlugin( |
1744 | Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, |
1745 | llvm::StringRef description, bool is_global_property) { |
1746 | return CreateSettingForPlugin(debugger, plugin_type_name: kObjectFilePluginName, |
1747 | plugin_type_desc: "Settings for object file plug-ins" , |
1748 | properties_sp, description, is_global_property); |
1749 | } |
1750 | |
1751 | lldb::OptionValuePropertiesSP |
1752 | PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger, |
1753 | llvm::StringRef setting_name) { |
1754 | return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kSymbolFilePluginName); |
1755 | } |
1756 | |
1757 | bool PluginManager::CreateSettingForSymbolFilePlugin( |
1758 | Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, |
1759 | llvm::StringRef description, bool is_global_property) { |
1760 | return CreateSettingForPlugin(debugger, plugin_type_name: kSymbolFilePluginName, |
1761 | plugin_type_desc: "Settings for symbol file plug-ins" , |
1762 | properties_sp, description, is_global_property); |
1763 | } |
1764 | |
1765 | lldb::OptionValuePropertiesSP |
1766 | PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger, |
1767 | llvm::StringRef setting_name) { |
1768 | return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kJITLoaderPluginName); |
1769 | } |
1770 | |
1771 | bool PluginManager::CreateSettingForJITLoaderPlugin( |
1772 | Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, |
1773 | llvm::StringRef description, bool is_global_property) { |
1774 | return CreateSettingForPlugin(debugger, plugin_type_name: kJITLoaderPluginName, |
1775 | plugin_type_desc: "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 |
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, plugin_type_name: kOperatingSystemPluginName, |
1788 | plugin_type_desc: "" , // not creating to so we don't need the description |
1789 | can_create: false)); |
1790 | if (plugin_type_properties_sp) |
1791 | properties_sp = |
1792 | plugin_type_properties_sp->GetSubProperty(exe_ctx: nullptr, name: setting_name); |
1793 | return properties_sp; |
1794 | } |
1795 | |
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, plugin_type_name: kOperatingSystemPluginName, |
1802 | plugin_type_desc: "Settings for operating system plug-ins" , |
1803 | can_create: true)); |
1804 | if (plugin_type_properties_sp) { |
1805 | plugin_type_properties_sp->AppendProperty(name: properties_sp->GetName(), |
1806 | desc: description, is_global: is_global_property, |
1807 | value_sp: properties_sp); |
1808 | return true; |
1809 | } |
1810 | } |
1811 | return false; |
1812 | } |
1813 | |
1814 | lldb::OptionValuePropertiesSP |
1815 | PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger, |
1816 | llvm::StringRef setting_name) { |
1817 | return GetSettingForPlugin(debugger, setting_name, plugin_type_name: kStructuredDataPluginName); |
1818 | } |
1819 | |
1820 | bool PluginManager::CreateSettingForStructuredDataPlugin( |
1821 | Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, |
1822 | llvm::StringRef description, bool is_global_property) { |
1823 | return CreateSettingForPlugin(debugger, plugin_type_name: kStructuredDataPluginName, |
1824 | plugin_type_desc: "Settings for structured data plug-ins" , |
1825 | properties_sp, description, is_global_property); |
1826 | } |
1827 | |