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