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/ConstString.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(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(plugin_file_spec); 93 94 if (PluginIsLoaded(plugin_file_spec)) 95 return FileSystem::eEnumerateDirectoryResultNext; 96 else { 97 PluginInfo plugin_info; 98 99 std::string pluginLoadError; 100 plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary( 101 plugin_file_spec.GetPath().c_str(), &pluginLoadError); 102 if (plugin_info.library.isValid()) { 103 bool success = false; 104 plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>( 105 plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize")); 106 if (plugin_info.plugin_init_callback) { 107 // Call the plug-in "bool LLDBPluginInitialize(void)" function 108 success = plugin_info.plugin_init_callback(); 109 } 110 111 if (success) { 112 // It is ok for the "LLDBPluginTerminate" symbol to be nullptr 113 plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>( 114 plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate")); 115 } else { 116 // The initialize function returned FALSE which means the plug-in 117 // might not be compatible, or might be too new or too old, or might 118 // not want to run on this machine. Set it to a default-constructed 119 // instance to invalidate it. 120 plugin_info = PluginInfo(); 121 } 122 123 // Regardless of success or failure, cache the plug-in load in our 124 // plug-in info so we don't try to load it again and again. 125 SetPluginInfo(plugin_file_spec, plugin_info); 126 127 return FileSystem::eEnumerateDirectoryResultNext; 128 } 129 } 130 } 131 132 if (ft == fs::file_type::directory_file || 133 ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) { 134 // Try and recurse into anything that a directory or symbolic link. We must 135 // also do this for unknown as sometimes the directory enumeration might be 136 // enumerating a file system that doesn't have correct file type 137 // information. 138 return FileSystem::eEnumerateDirectoryResultEnter; 139 } 140 141 return FileSystem::eEnumerateDirectoryResultNext; 142 } 143 144 void PluginManager::Initialize() { 145 const bool find_directories = true; 146 const bool find_files = true; 147 const bool find_other = true; 148 char dir_path[PATH_MAX]; 149 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) { 150 if (FileSystem::Instance().Exists(dir_spec) && 151 dir_spec.GetPath(dir_path, sizeof(dir_path))) { 152 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, 153 find_files, find_other, 154 LoadPluginCallback, nullptr); 155 } 156 } 157 158 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) { 159 if (FileSystem::Instance().Exists(dir_spec) && 160 dir_spec.GetPath(dir_path, sizeof(dir_path))) { 161 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, 162 find_files, find_other, 163 LoadPluginCallback, nullptr); 164 } 165 } 166 } 167 168 void PluginManager::Terminate() { 169 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex()); 170 PluginTerminateMap &plugin_map = GetPluginMap(); 171 172 PluginTerminateMap::const_iterator pos, end = plugin_map.end(); 173 for (pos = plugin_map.begin(); pos != end; ++pos) { 174 // Call the plug-in "void LLDBPluginTerminate (void)" function if there is 175 // one (if the symbol was not nullptr). 176 if (pos->second.library.isValid()) { 177 if (pos->second.plugin_term_callback) 178 pos->second.plugin_term_callback(); 179 } 180 } 181 plugin_map.clear(); 182 } 183 184 template <typename Callback> struct PluginInstance { 185 typedef Callback CallbackType; 186 187 PluginInstance() = default; 188 PluginInstance(ConstString name, std::string description, 189 Callback create_callback = nullptr, 190 DebuggerInitializeCallback debugger_init_callback = nullptr) 191 : name(name), description(std::move(description)), 192 create_callback(create_callback), 193 debugger_init_callback(debugger_init_callback) {} 194 195 ConstString name; 196 std::string description; 197 Callback create_callback; 198 DebuggerInitializeCallback debugger_init_callback; 199 }; 200 201 template <typename Instance> class PluginInstances { 202 public: 203 template <typename... Args> 204 bool RegisterPlugin(ConstString name, const char *description, 205 typename Instance::CallbackType callback, 206 Args &&... args) { 207 if (!callback) 208 return false; 209 assert((bool)name); 210 Instance instance = 211 Instance(name, description, callback, std::forward<Args>(args)...); 212 m_instances.push_back(instance); 213 return false; 214 } 215 216 bool UnregisterPlugin(typename Instance::CallbackType callback) { 217 if (!callback) 218 return false; 219 auto pos = m_instances.begin(); 220 auto end = m_instances.end(); 221 for (; pos != end; ++pos) { 222 if (pos->create_callback == callback) { 223 m_instances.erase(pos); 224 return true; 225 } 226 } 227 return false; 228 } 229 230 typename Instance::CallbackType GetCallbackAtIndex(uint32_t idx) { 231 if (Instance *instance = GetInstanceAtIndex(idx)) 232 return instance->create_callback; 233 return nullptr; 234 } 235 236 const char *GetDescriptionAtIndex(uint32_t idx) { 237 if (Instance *instance = GetInstanceAtIndex(idx)) 238 return instance->description.c_str(); 239 return nullptr; 240 } 241 242 const char *GetNameAtIndex(uint32_t idx) { 243 if (Instance *instance = GetInstanceAtIndex(idx)) 244 return instance->name.GetCString(); 245 return nullptr; 246 } 247 248 typename Instance::CallbackType GetCallbackForName(ConstString name) { 249 if (!name) 250 return nullptr; 251 for (auto &instance : m_instances) { 252 if (name == instance.name) 253 return instance.create_callback; 254 } 255 return nullptr; 256 } 257 258 void PerformDebuggerCallback(Debugger &debugger) { 259 for (auto &instance : m_instances) { 260 if (instance.debugger_init_callback) 261 instance.debugger_init_callback(debugger); 262 } 263 } 264 265 const std::vector<Instance> &GetInstances() const { return m_instances; } 266 std::vector<Instance> &GetInstances() { return m_instances; } 267 268 Instance *GetInstanceAtIndex(uint32_t idx) { 269 if (idx < m_instances.size()) 270 return &m_instances[idx]; 271 return nullptr; 272 } 273 274 private: 275 std::vector<Instance> m_instances; 276 }; 277 278 #pragma mark ABI 279 280 typedef PluginInstance<ABICreateInstance> ABIInstance; 281 typedef PluginInstances<ABIInstance> ABIInstances; 282 283 static ABIInstances &GetABIInstances() { 284 static ABIInstances g_instances; 285 return g_instances; 286 } 287 288 bool PluginManager::RegisterPlugin(ConstString name, const char *description, 289 ABICreateInstance create_callback) { 290 return GetABIInstances().RegisterPlugin(name, description, create_callback); 291 } 292 293 bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) { 294 return GetABIInstances().UnregisterPlugin(create_callback); 295 } 296 297 ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) { 298 return GetABIInstances().GetCallbackAtIndex(idx); 299 } 300 301 #pragma mark Architecture 302 303 typedef PluginInstance<ArchitectureCreateInstance> ArchitectureInstance; 304 typedef std::vector<ArchitectureInstance> ArchitectureInstances; 305 306 static ArchitectureInstances &GetArchitectureInstances() { 307 static ArchitectureInstances g_instances; 308 return g_instances; 309 } 310 311 void PluginManager::RegisterPlugin(ConstString name, 312 llvm::StringRef description, 313 ArchitectureCreateInstance create_callback) { 314 GetArchitectureInstances().push_back( 315 {name, std::string(description), create_callback}); 316 } 317 318 void PluginManager::UnregisterPlugin( 319 ArchitectureCreateInstance create_callback) { 320 auto &instances = GetArchitectureInstances(); 321 322 for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) { 323 if (pos->create_callback == create_callback) { 324 instances.erase(pos); 325 return; 326 } 327 } 328 llvm_unreachable("Plugin not found"); 329 } 330 331 std::unique_ptr<Architecture> 332 PluginManager::CreateArchitectureInstance(const ArchSpec &arch) { 333 for (const auto &instances : GetArchitectureInstances()) { 334 if (auto plugin_up = instances.create_callback(arch)) 335 return plugin_up; 336 } 337 return nullptr; 338 } 339 340 #pragma mark Disassembler 341 342 typedef PluginInstance<DisassemblerCreateInstance> DisassemblerInstance; 343 typedef PluginInstances<DisassemblerInstance> DisassemblerInstances; 344 345 static DisassemblerInstances &GetDisassemblerInstances() { 346 static DisassemblerInstances g_instances; 347 return g_instances; 348 } 349 350 bool PluginManager::RegisterPlugin(ConstString name, const char *description, 351 DisassemblerCreateInstance create_callback) { 352 return GetDisassemblerInstances().RegisterPlugin(name, description, 353 create_callback); 354 } 355 356 bool PluginManager::UnregisterPlugin( 357 DisassemblerCreateInstance create_callback) { 358 return GetDisassemblerInstances().UnregisterPlugin(create_callback); 359 } 360 361 DisassemblerCreateInstance 362 PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) { 363 return GetDisassemblerInstances().GetCallbackAtIndex(idx); 364 } 365 366 DisassemblerCreateInstance 367 PluginManager::GetDisassemblerCreateCallbackForPluginName(ConstString 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 ConstString name, const char *description, 383 DynamicLoaderCreateInstance create_callback, 384 DebuggerInitializeCallback debugger_init_callback) { 385 return GetDynamicLoaderInstances().RegisterPlugin( 386 name, description, create_callback, debugger_init_callback); 387 } 388 389 bool PluginManager::UnregisterPlugin( 390 DynamicLoaderCreateInstance create_callback) { 391 return GetDynamicLoaderInstances().UnregisterPlugin(create_callback); 392 } 393 394 DynamicLoaderCreateInstance 395 PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) { 396 return GetDynamicLoaderInstances().GetCallbackAtIndex(idx); 397 } 398 399 DynamicLoaderCreateInstance 400 PluginManager::GetDynamicLoaderCreateCallbackForPluginName(ConstString name) { 401 return GetDynamicLoaderInstances().GetCallbackForName(name); 402 } 403 404 #pragma mark JITLoader 405 406 typedef PluginInstance<JITLoaderCreateInstance> JITLoaderInstance; 407 typedef PluginInstances<JITLoaderInstance> JITLoaderInstances; 408 409 static JITLoaderInstances &GetJITLoaderInstances() { 410 static JITLoaderInstances g_instances; 411 return g_instances; 412 } 413 414 bool PluginManager::RegisterPlugin( 415 ConstString name, const char *description, 416 JITLoaderCreateInstance create_callback, 417 DebuggerInitializeCallback debugger_init_callback) { 418 return GetJITLoaderInstances().RegisterPlugin( 419 name, description, create_callback, debugger_init_callback); 420 } 421 422 bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) { 423 return GetJITLoaderInstances().UnregisterPlugin(create_callback); 424 } 425 426 JITLoaderCreateInstance 427 PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) { 428 return GetJITLoaderInstances().GetCallbackAtIndex(idx); 429 } 430 431 #pragma mark EmulateInstruction 432 433 typedef PluginInstance<EmulateInstructionCreateInstance> 434 EmulateInstructionInstance; 435 typedef PluginInstances<EmulateInstructionInstance> EmulateInstructionInstances; 436 437 static EmulateInstructionInstances &GetEmulateInstructionInstances() { 438 static EmulateInstructionInstances g_instances; 439 return g_instances; 440 } 441 442 bool PluginManager::RegisterPlugin( 443 ConstString name, const char *description, 444 EmulateInstructionCreateInstance create_callback) { 445 return GetEmulateInstructionInstances().RegisterPlugin(name, description, 446 create_callback); 447 } 448 449 bool PluginManager::UnregisterPlugin( 450 EmulateInstructionCreateInstance create_callback) { 451 return GetEmulateInstructionInstances().UnregisterPlugin(create_callback); 452 } 453 454 EmulateInstructionCreateInstance 455 PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) { 456 return GetEmulateInstructionInstances().GetCallbackAtIndex(idx); 457 } 458 459 EmulateInstructionCreateInstance 460 PluginManager::GetEmulateInstructionCreateCallbackForPluginName( 461 ConstString name) { 462 return GetEmulateInstructionInstances().GetCallbackForName(name); 463 } 464 465 #pragma mark OperatingSystem 466 467 typedef PluginInstance<OperatingSystemCreateInstance> OperatingSystemInstance; 468 typedef PluginInstances<OperatingSystemInstance> OperatingSystemInstances; 469 470 static OperatingSystemInstances &GetOperatingSystemInstances() { 471 static OperatingSystemInstances g_instances; 472 return g_instances; 473 } 474 475 bool PluginManager::RegisterPlugin( 476 llvm::StringRef name, llvm::StringRef description, 477 OperatingSystemCreateInstance create_callback, 478 DebuggerInitializeCallback debugger_init_callback) { 479 return GetOperatingSystemInstances().RegisterPlugin( 480 ConstString(name), description.str().c_str(), create_callback, 481 debugger_init_callback); 482 } 483 484 bool PluginManager::UnregisterPlugin( 485 OperatingSystemCreateInstance create_callback) { 486 return GetOperatingSystemInstances().UnregisterPlugin(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(ConstString(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(ConstString name, const char *description, 511 LanguageCreateInstance create_callback) { 512 return GetLanguageInstances().RegisterPlugin(name, description, 513 create_callback); 514 } 515 516 bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) { 517 return GetLanguageInstances().UnregisterPlugin(create_callback); 518 } 519 520 LanguageCreateInstance 521 PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) { 522 return GetLanguageInstances().GetCallbackAtIndex(idx); 523 } 524 525 #pragma mark LanguageRuntime 526 527 struct LanguageRuntimeInstance 528 : public PluginInstance<LanguageRuntimeCreateInstance> { 529 LanguageRuntimeInstance( 530 ConstString name, std::string description, CallbackType create_callback, 531 DebuggerInitializeCallback debugger_init_callback, 532 LanguageRuntimeGetCommandObject command_callback, 533 LanguageRuntimeGetExceptionPrecondition precondition_callback) 534 : PluginInstance<LanguageRuntimeCreateInstance>( 535 name, std::move(description), create_callback, 536 debugger_init_callback), 537 command_callback(command_callback), 538 precondition_callback(precondition_callback) {} 539 540 LanguageRuntimeGetCommandObject command_callback; 541 LanguageRuntimeGetExceptionPrecondition precondition_callback; 542 }; 543 544 typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances; 545 546 static LanguageRuntimeInstances &GetLanguageRuntimeInstances() { 547 static LanguageRuntimeInstances g_instances; 548 return g_instances; 549 } 550 551 bool PluginManager::RegisterPlugin( 552 ConstString name, const char *description, 553 LanguageRuntimeCreateInstance create_callback, 554 LanguageRuntimeGetCommandObject command_callback, 555 LanguageRuntimeGetExceptionPrecondition precondition_callback) { 556 return GetLanguageRuntimeInstances().RegisterPlugin( 557 name, description, create_callback, nullptr, command_callback, 558 precondition_callback); 559 } 560 561 bool PluginManager::UnregisterPlugin( 562 LanguageRuntimeCreateInstance create_callback) { 563 return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback); 564 } 565 566 LanguageRuntimeCreateInstance 567 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) { 568 return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx); 569 } 570 571 LanguageRuntimeGetCommandObject 572 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) { 573 const auto &instances = GetLanguageRuntimeInstances().GetInstances(); 574 if (idx < instances.size()) 575 return instances[idx].command_callback; 576 return nullptr; 577 } 578 579 LanguageRuntimeGetExceptionPrecondition 580 PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) { 581 const auto &instances = GetLanguageRuntimeInstances().GetInstances(); 582 if (idx < instances.size()) 583 return instances[idx].precondition_callback; 584 return nullptr; 585 } 586 587 #pragma mark SystemRuntime 588 589 typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance; 590 typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances; 591 592 static SystemRuntimeInstances &GetSystemRuntimeInstances() { 593 static SystemRuntimeInstances g_instances; 594 return g_instances; 595 } 596 597 bool PluginManager::RegisterPlugin( 598 ConstString name, const char *description, 599 SystemRuntimeCreateInstance create_callback) { 600 return GetSystemRuntimeInstances().RegisterPlugin(name, description, 601 create_callback); 602 } 603 604 bool PluginManager::UnregisterPlugin( 605 SystemRuntimeCreateInstance create_callback) { 606 return GetSystemRuntimeInstances().UnregisterPlugin(create_callback); 607 } 608 609 SystemRuntimeCreateInstance 610 PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) { 611 return GetSystemRuntimeInstances().GetCallbackAtIndex(idx); 612 } 613 614 #pragma mark ObjectFile 615 616 struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> { 617 ObjectFileInstance( 618 ConstString name, std::string description, CallbackType create_callback, 619 ObjectFileCreateMemoryInstance create_memory_callback, 620 ObjectFileGetModuleSpecifications get_module_specifications, 621 ObjectFileSaveCore save_core) 622 : PluginInstance<ObjectFileCreateInstance>(name, std::move(description), 623 create_callback), 624 create_memory_callback(create_memory_callback), 625 get_module_specifications(get_module_specifications), 626 save_core(save_core) {} 627 628 ObjectFileCreateMemoryInstance create_memory_callback; 629 ObjectFileGetModuleSpecifications get_module_specifications; 630 ObjectFileSaveCore save_core; 631 }; 632 typedef PluginInstances<ObjectFileInstance> ObjectFileInstances; 633 634 static ObjectFileInstances &GetObjectFileInstances() { 635 static ObjectFileInstances g_instances; 636 return g_instances; 637 } 638 639 bool PluginManager::RegisterPlugin( 640 llvm::StringRef name, llvm::StringRef description, 641 ObjectFileCreateInstance create_callback, 642 ObjectFileCreateMemoryInstance create_memory_callback, 643 ObjectFileGetModuleSpecifications get_module_specifications, 644 ObjectFileSaveCore save_core) { 645 return GetObjectFileInstances().RegisterPlugin( 646 ConstString(name), description.str().c_str(), create_callback, 647 create_memory_callback, get_module_specifications, save_core); 648 } 649 650 bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) { 651 return GetObjectFileInstances().UnregisterPlugin(create_callback); 652 } 653 654 ObjectFileCreateInstance 655 PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) { 656 return GetObjectFileInstances().GetCallbackAtIndex(idx); 657 } 658 659 ObjectFileCreateMemoryInstance 660 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) { 661 const auto &instances = GetObjectFileInstances().GetInstances(); 662 if (idx < instances.size()) 663 return instances[idx].create_memory_callback; 664 return nullptr; 665 } 666 667 ObjectFileGetModuleSpecifications 668 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex( 669 uint32_t idx) { 670 const auto &instances = GetObjectFileInstances().GetInstances(); 671 if (idx < instances.size()) 672 return instances[idx].get_module_specifications; 673 return nullptr; 674 } 675 676 ObjectFileCreateMemoryInstance 677 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( 678 llvm::StringRef name) { 679 const auto &instances = GetObjectFileInstances().GetInstances(); 680 for (auto &instance : instances) { 681 if (instance.name.GetStringRef() == name) 682 return instance.create_memory_callback; 683 } 684 return nullptr; 685 } 686 687 Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, 688 const FileSpec &outfile, 689 lldb::SaveCoreStyle &core_style, 690 llvm::StringRef plugin_name) { 691 if (plugin_name.empty()) { 692 // Try saving core directly from the process plugin first. 693 llvm::Expected<bool> ret = process_sp->SaveCore(outfile.GetPath()); 694 if (!ret) 695 return Status(ret.takeError()); 696 if (ret.get()) 697 return Status(); 698 } 699 700 // Fall back to object plugins. 701 Status error; 702 auto &instances = GetObjectFileInstances().GetInstances(); 703 for (auto &instance : instances) { 704 if (plugin_name.empty() || instance.name.GetStringRef() == plugin_name) { 705 if (instance.save_core && 706 instance.save_core(process_sp, outfile, core_style, error)) 707 return error; 708 } 709 } 710 error.SetErrorString( 711 "no ObjectFile plugins were able to save a core for this process"); 712 return error; 713 } 714 715 #pragma mark ObjectContainer 716 717 struct ObjectContainerInstance 718 : public PluginInstance<ObjectContainerCreateInstance> { 719 ObjectContainerInstance( 720 ConstString name, std::string description, CallbackType create_callback, 721 ObjectFileGetModuleSpecifications get_module_specifications) 722 : PluginInstance<ObjectContainerCreateInstance>( 723 name, std::move(description), create_callback), 724 get_module_specifications(get_module_specifications) {} 725 726 ObjectFileGetModuleSpecifications get_module_specifications; 727 }; 728 typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances; 729 730 static ObjectContainerInstances &GetObjectContainerInstances() { 731 static ObjectContainerInstances g_instances; 732 return g_instances; 733 } 734 735 bool PluginManager::RegisterPlugin( 736 llvm::StringRef name, llvm::StringRef description, 737 ObjectContainerCreateInstance create_callback, 738 ObjectFileGetModuleSpecifications get_module_specifications) { 739 return GetObjectContainerInstances().RegisterPlugin( 740 ConstString(name), description.str().c_str(), create_callback, 741 get_module_specifications); 742 } 743 744 bool PluginManager::UnregisterPlugin( 745 ObjectContainerCreateInstance create_callback) { 746 return GetObjectContainerInstances().UnregisterPlugin(create_callback); 747 } 748 749 ObjectContainerCreateInstance 750 PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) { 751 return GetObjectContainerInstances().GetCallbackAtIndex(idx); 752 } 753 754 ObjectFileGetModuleSpecifications 755 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex( 756 uint32_t idx) { 757 const auto &instances = GetObjectContainerInstances().GetInstances(); 758 if (idx < instances.size()) 759 return instances[idx].get_module_specifications; 760 return nullptr; 761 } 762 763 #pragma mark Platform 764 765 typedef PluginInstance<PlatformCreateInstance> PlatformInstance; 766 typedef PluginInstances<PlatformInstance> PlatformInstances; 767 768 static PlatformInstances &GetPlatformInstances() { 769 static PlatformInstances g_platform_instances; 770 return g_platform_instances; 771 } 772 773 bool PluginManager::RegisterPlugin( 774 ConstString name, const char *description, 775 PlatformCreateInstance create_callback, 776 DebuggerInitializeCallback debugger_init_callback) { 777 return GetPlatformInstances().RegisterPlugin( 778 name, description, create_callback, debugger_init_callback); 779 } 780 781 bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { 782 return GetPlatformInstances().UnregisterPlugin(create_callback); 783 } 784 785 const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { 786 return GetPlatformInstances().GetNameAtIndex(idx); 787 } 788 789 const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { 790 return GetPlatformInstances().GetDescriptionAtIndex(idx); 791 } 792 793 PlatformCreateInstance 794 PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) { 795 return GetPlatformInstances().GetCallbackAtIndex(idx); 796 } 797 798 PlatformCreateInstance 799 PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) { 800 return GetPlatformInstances().GetCallbackForName(name); 801 } 802 803 void PluginManager::AutoCompletePlatformName(llvm::StringRef name, 804 CompletionRequest &request) { 805 for (const auto &instance : GetPlatformInstances().GetInstances()) { 806 if (instance.name.GetStringRef().startswith(name)) 807 request.AddCompletion(instance.name.GetCString()); 808 } 809 } 810 811 #pragma mark Process 812 813 typedef PluginInstance<ProcessCreateInstance> ProcessInstance; 814 typedef PluginInstances<ProcessInstance> ProcessInstances; 815 816 static ProcessInstances &GetProcessInstances() { 817 static ProcessInstances g_instances; 818 return g_instances; 819 } 820 821 bool PluginManager::RegisterPlugin( 822 ConstString name, const char *description, 823 ProcessCreateInstance create_callback, 824 DebuggerInitializeCallback debugger_init_callback) { 825 return GetProcessInstances().RegisterPlugin( 826 name, description, create_callback, debugger_init_callback); 827 } 828 829 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { 830 return GetProcessInstances().UnregisterPlugin(create_callback); 831 } 832 833 const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { 834 return GetProcessInstances().GetNameAtIndex(idx); 835 } 836 837 const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { 838 return GetProcessInstances().GetDescriptionAtIndex(idx); 839 } 840 841 ProcessCreateInstance 842 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { 843 return GetProcessInstances().GetCallbackAtIndex(idx); 844 } 845 846 ProcessCreateInstance 847 PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) { 848 return GetProcessInstances().GetCallbackForName(name); 849 } 850 851 void PluginManager::AutoCompleteProcessName(llvm::StringRef name, 852 CompletionRequest &request) { 853 for (const auto &instance : GetProcessInstances().GetInstances()) { 854 if (instance.name.GetStringRef().startswith(name)) 855 request.AddCompletion(instance.name.GetCString(), instance.description); 856 } 857 } 858 859 #pragma mark ScriptInterpreter 860 861 struct ScriptInterpreterInstance 862 : public PluginInstance<ScriptInterpreterCreateInstance> { 863 ScriptInterpreterInstance(ConstString name, std::string description, 864 CallbackType create_callback, 865 lldb::ScriptLanguage language) 866 : PluginInstance<ScriptInterpreterCreateInstance>( 867 name, std::move(description), create_callback), 868 language(language) {} 869 870 lldb::ScriptLanguage language = lldb::eScriptLanguageNone; 871 }; 872 873 typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances; 874 875 static ScriptInterpreterInstances &GetScriptInterpreterInstances() { 876 static ScriptInterpreterInstances g_instances; 877 return g_instances; 878 } 879 880 bool PluginManager::RegisterPlugin( 881 ConstString name, const char *description, 882 lldb::ScriptLanguage script_language, 883 ScriptInterpreterCreateInstance create_callback) { 884 return GetScriptInterpreterInstances().RegisterPlugin( 885 name, description, create_callback, script_language); 886 } 887 888 bool PluginManager::UnregisterPlugin( 889 ScriptInterpreterCreateInstance create_callback) { 890 return GetScriptInterpreterInstances().UnregisterPlugin(create_callback); 891 } 892 893 ScriptInterpreterCreateInstance 894 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) { 895 return GetScriptInterpreterInstances().GetCallbackAtIndex(idx); 896 } 897 898 lldb::ScriptInterpreterSP 899 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, 900 Debugger &debugger) { 901 const auto &instances = GetScriptInterpreterInstances().GetInstances(); 902 ScriptInterpreterCreateInstance none_instance = nullptr; 903 for (const auto &instance : instances) { 904 if (instance.language == lldb::eScriptLanguageNone) 905 none_instance = instance.create_callback; 906 907 if (script_lang == instance.language) 908 return instance.create_callback(debugger); 909 } 910 911 // If we didn't find one, return the ScriptInterpreter for the null language. 912 assert(none_instance != nullptr); 913 return none_instance(debugger); 914 } 915 916 #pragma mark StructuredDataPlugin 917 918 struct StructuredDataPluginInstance 919 : public PluginInstance<StructuredDataPluginCreateInstance> { 920 StructuredDataPluginInstance( 921 ConstString name, std::string description, CallbackType create_callback, 922 DebuggerInitializeCallback debugger_init_callback, 923 StructuredDataFilterLaunchInfo filter_callback) 924 : PluginInstance<StructuredDataPluginCreateInstance>( 925 name, std::move(description), create_callback, 926 debugger_init_callback), 927 filter_callback(filter_callback) {} 928 929 StructuredDataFilterLaunchInfo filter_callback = nullptr; 930 }; 931 932 typedef PluginInstances<StructuredDataPluginInstance> 933 StructuredDataPluginInstances; 934 935 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { 936 static StructuredDataPluginInstances g_instances; 937 return g_instances; 938 } 939 940 bool PluginManager::RegisterPlugin( 941 ConstString name, const char *description, 942 StructuredDataPluginCreateInstance create_callback, 943 DebuggerInitializeCallback debugger_init_callback, 944 StructuredDataFilterLaunchInfo filter_callback) { 945 return GetStructuredDataPluginInstances().RegisterPlugin( 946 name, description, create_callback, debugger_init_callback, 947 filter_callback); 948 } 949 950 bool PluginManager::UnregisterPlugin( 951 StructuredDataPluginCreateInstance create_callback) { 952 return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback); 953 } 954 955 StructuredDataPluginCreateInstance 956 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) { 957 return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx); 958 } 959 960 StructuredDataFilterLaunchInfo 961 PluginManager::GetStructuredDataFilterCallbackAtIndex( 962 uint32_t idx, bool &iteration_complete) { 963 const auto &instances = GetStructuredDataPluginInstances().GetInstances(); 964 if (idx < instances.size()) { 965 iteration_complete = false; 966 return instances[idx].filter_callback; 967 } else { 968 iteration_complete = true; 969 } 970 return nullptr; 971 } 972 973 #pragma mark SymbolFile 974 975 typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance; 976 typedef PluginInstances<SymbolFileInstance> SymbolFileInstances; 977 978 static SymbolFileInstances &GetSymbolFileInstances() { 979 static SymbolFileInstances g_instances; 980 return g_instances; 981 } 982 983 bool PluginManager::RegisterPlugin( 984 ConstString name, const char *description, 985 SymbolFileCreateInstance create_callback, 986 DebuggerInitializeCallback debugger_init_callback) { 987 return GetSymbolFileInstances().RegisterPlugin( 988 name, description, create_callback, debugger_init_callback); 989 } 990 991 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) { 992 return GetSymbolFileInstances().UnregisterPlugin(create_callback); 993 } 994 995 SymbolFileCreateInstance 996 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) { 997 return GetSymbolFileInstances().GetCallbackAtIndex(idx); 998 } 999 1000 #pragma mark SymbolVendor 1001 1002 typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance; 1003 typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances; 1004 1005 static SymbolVendorInstances &GetSymbolVendorInstances() { 1006 static SymbolVendorInstances g_instances; 1007 return g_instances; 1008 } 1009 1010 bool PluginManager::RegisterPlugin(ConstString name, const char *description, 1011 SymbolVendorCreateInstance create_callback) { 1012 return GetSymbolVendorInstances().RegisterPlugin(name, description, 1013 create_callback); 1014 } 1015 1016 bool PluginManager::UnregisterPlugin( 1017 SymbolVendorCreateInstance create_callback) { 1018 return GetSymbolVendorInstances().UnregisterPlugin(create_callback); 1019 } 1020 1021 SymbolVendorCreateInstance 1022 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { 1023 return GetSymbolVendorInstances().GetCallbackAtIndex(idx); 1024 } 1025 1026 #pragma mark Trace 1027 1028 struct TraceInstance 1029 : public PluginInstance<TraceCreateInstanceForSessionFile> { 1030 TraceInstance( 1031 ConstString name, std::string description, 1032 CallbackType create_callback_for_session_file, 1033 TraceCreateInstanceForLiveProcess create_callback_for_live_process, 1034 llvm::StringRef schema) 1035 : PluginInstance<TraceCreateInstanceForSessionFile>( 1036 name, std::move(description), create_callback_for_session_file), 1037 schema(schema), 1038 create_callback_for_live_process(create_callback_for_live_process) {} 1039 1040 llvm::StringRef schema; 1041 TraceCreateInstanceForLiveProcess create_callback_for_live_process; 1042 }; 1043 1044 typedef PluginInstances<TraceInstance> TraceInstances; 1045 1046 static TraceInstances &GetTracePluginInstances() { 1047 static TraceInstances g_instances; 1048 return g_instances; 1049 } 1050 1051 bool PluginManager::RegisterPlugin( 1052 ConstString name, const char *description, 1053 TraceCreateInstanceForSessionFile create_callback_for_session_file, 1054 TraceCreateInstanceForLiveProcess create_callback_for_live_process, 1055 llvm::StringRef schema) { 1056 return GetTracePluginInstances().RegisterPlugin( 1057 name, description, create_callback_for_session_file, 1058 create_callback_for_live_process, schema); 1059 } 1060 1061 bool PluginManager::UnregisterPlugin( 1062 TraceCreateInstanceForSessionFile create_callback_for_session_file) { 1063 return GetTracePluginInstances().UnregisterPlugin( 1064 create_callback_for_session_file); 1065 } 1066 1067 TraceCreateInstanceForSessionFile 1068 PluginManager::GetTraceCreateCallback(ConstString plugin_name) { 1069 return GetTracePluginInstances().GetCallbackForName(plugin_name); 1070 } 1071 1072 TraceCreateInstanceForLiveProcess 1073 PluginManager::GetTraceCreateCallbackForLiveProcess(ConstString plugin_name) { 1074 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) 1075 if (instance.name == plugin_name) 1076 return instance.create_callback_for_live_process; 1077 return nullptr; 1078 } 1079 1080 llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) { 1081 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) 1082 if (instance.name == plugin_name) 1083 return instance.schema; 1084 return llvm::StringRef(); 1085 } 1086 1087 llvm::StringRef PluginManager::GetTraceSchema(size_t index) { 1088 if (TraceInstance *instance = 1089 GetTracePluginInstances().GetInstanceAtIndex(index)) 1090 return instance->schema; 1091 return llvm::StringRef(); 1092 } 1093 1094 #pragma mark TraceExporter 1095 1096 struct TraceExporterInstance 1097 : public PluginInstance<TraceExporterCreateInstance> { 1098 TraceExporterInstance( 1099 ConstString name, std::string description, 1100 TraceExporterCreateInstance create_instance, 1101 ThreadTraceExportCommandCreator create_thread_trace_export_command) 1102 : PluginInstance<TraceExporterCreateInstance>( 1103 name, std::move(description), create_instance), 1104 create_thread_trace_export_command(create_thread_trace_export_command) { 1105 } 1106 1107 ThreadTraceExportCommandCreator create_thread_trace_export_command; 1108 }; 1109 1110 typedef PluginInstances<TraceExporterInstance> TraceExporterInstances; 1111 1112 static TraceExporterInstances &GetTraceExporterInstances() { 1113 static TraceExporterInstances g_instances; 1114 return g_instances; 1115 } 1116 1117 bool PluginManager::RegisterPlugin( 1118 ConstString name, const char *description, 1119 TraceExporterCreateInstance create_callback, 1120 ThreadTraceExportCommandCreator create_thread_trace_export_command) { 1121 return GetTraceExporterInstances().RegisterPlugin( 1122 name, description, create_callback, create_thread_trace_export_command); 1123 } 1124 1125 TraceExporterCreateInstance 1126 PluginManager::GetTraceExporterCreateCallback(ConstString plugin_name) { 1127 return GetTraceExporterInstances().GetCallbackForName(plugin_name); 1128 } 1129 1130 bool PluginManager::UnregisterPlugin( 1131 TraceExporterCreateInstance create_callback) { 1132 return GetTraceExporterInstances().UnregisterPlugin(create_callback); 1133 } 1134 1135 ThreadTraceExportCommandCreator 1136 PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) { 1137 if (TraceExporterInstance *instance = 1138 GetTraceExporterInstances().GetInstanceAtIndex(index)) 1139 return instance->create_thread_trace_export_command; 1140 return nullptr; 1141 } 1142 1143 const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) { 1144 return GetTraceExporterInstances().GetNameAtIndex(index); 1145 } 1146 1147 #pragma mark UnwindAssembly 1148 1149 typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance; 1150 typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances; 1151 1152 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { 1153 static UnwindAssemblyInstances g_instances; 1154 return g_instances; 1155 } 1156 1157 bool PluginManager::RegisterPlugin( 1158 ConstString name, const char *description, 1159 UnwindAssemblyCreateInstance create_callback) { 1160 return GetUnwindAssemblyInstances().RegisterPlugin(name, description, 1161 create_callback); 1162 } 1163 1164 bool PluginManager::UnregisterPlugin( 1165 UnwindAssemblyCreateInstance create_callback) { 1166 return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback); 1167 } 1168 1169 UnwindAssemblyCreateInstance 1170 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) { 1171 return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx); 1172 } 1173 1174 #pragma mark MemoryHistory 1175 1176 typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance; 1177 typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances; 1178 1179 static MemoryHistoryInstances &GetMemoryHistoryInstances() { 1180 static MemoryHistoryInstances g_instances; 1181 return g_instances; 1182 } 1183 1184 bool PluginManager::RegisterPlugin( 1185 ConstString name, const char *description, 1186 MemoryHistoryCreateInstance create_callback) { 1187 return GetMemoryHistoryInstances().RegisterPlugin(name, description, 1188 create_callback); 1189 } 1190 1191 bool PluginManager::UnregisterPlugin( 1192 MemoryHistoryCreateInstance create_callback) { 1193 return GetMemoryHistoryInstances().UnregisterPlugin(create_callback); 1194 } 1195 1196 MemoryHistoryCreateInstance 1197 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { 1198 return GetMemoryHistoryInstances().GetCallbackAtIndex(idx); 1199 } 1200 1201 #pragma mark InstrumentationRuntime 1202 1203 struct InstrumentationRuntimeInstance 1204 : public PluginInstance<InstrumentationRuntimeCreateInstance> { 1205 InstrumentationRuntimeInstance( 1206 ConstString name, std::string description, CallbackType create_callback, 1207 InstrumentationRuntimeGetType get_type_callback) 1208 : PluginInstance<InstrumentationRuntimeCreateInstance>( 1209 name, std::move(description), create_callback), 1210 get_type_callback(get_type_callback) {} 1211 1212 InstrumentationRuntimeGetType get_type_callback = nullptr; 1213 }; 1214 1215 typedef PluginInstances<InstrumentationRuntimeInstance> 1216 InstrumentationRuntimeInstances; 1217 1218 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { 1219 static InstrumentationRuntimeInstances g_instances; 1220 return g_instances; 1221 } 1222 1223 bool PluginManager::RegisterPlugin( 1224 ConstString name, const char *description, 1225 InstrumentationRuntimeCreateInstance create_callback, 1226 InstrumentationRuntimeGetType get_type_callback) { 1227 return GetInstrumentationRuntimeInstances().RegisterPlugin( 1228 name, description, create_callback, get_type_callback); 1229 } 1230 1231 bool PluginManager::UnregisterPlugin( 1232 InstrumentationRuntimeCreateInstance create_callback) { 1233 return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback); 1234 } 1235 1236 InstrumentationRuntimeGetType 1237 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { 1238 const auto &instances = GetInstrumentationRuntimeInstances().GetInstances(); 1239 if (idx < instances.size()) 1240 return instances[idx].get_type_callback; 1241 return nullptr; 1242 } 1243 1244 InstrumentationRuntimeCreateInstance 1245 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { 1246 return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx); 1247 } 1248 1249 #pragma mark TypeSystem 1250 1251 struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> { 1252 TypeSystemInstance(ConstString name, std::string description, 1253 CallbackType create_callback, 1254 LanguageSet supported_languages_for_types, 1255 LanguageSet supported_languages_for_expressions) 1256 : PluginInstance<TypeSystemCreateInstance>(name, std::move(description), 1257 create_callback), 1258 supported_languages_for_types(supported_languages_for_types), 1259 supported_languages_for_expressions( 1260 supported_languages_for_expressions) {} 1261 1262 LanguageSet supported_languages_for_types; 1263 LanguageSet supported_languages_for_expressions; 1264 }; 1265 1266 typedef PluginInstances<TypeSystemInstance> TypeSystemInstances; 1267 1268 static TypeSystemInstances &GetTypeSystemInstances() { 1269 static TypeSystemInstances g_instances; 1270 return g_instances; 1271 } 1272 1273 bool PluginManager::RegisterPlugin( 1274 ConstString name, const char *description, 1275 TypeSystemCreateInstance create_callback, 1276 LanguageSet supported_languages_for_types, 1277 LanguageSet supported_languages_for_expressions) { 1278 return GetTypeSystemInstances().RegisterPlugin( 1279 name, description, create_callback, supported_languages_for_types, 1280 supported_languages_for_expressions); 1281 } 1282 1283 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) { 1284 return GetTypeSystemInstances().UnregisterPlugin(create_callback); 1285 } 1286 1287 TypeSystemCreateInstance 1288 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) { 1289 return GetTypeSystemInstances().GetCallbackAtIndex(idx); 1290 } 1291 1292 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() { 1293 const auto &instances = GetTypeSystemInstances().GetInstances(); 1294 LanguageSet all; 1295 for (unsigned i = 0; i < instances.size(); ++i) 1296 all.bitvector |= instances[i].supported_languages_for_types.bitvector; 1297 return all; 1298 } 1299 1300 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { 1301 const auto &instances = GetTypeSystemInstances().GetInstances(); 1302 LanguageSet all; 1303 for (unsigned i = 0; i < instances.size(); ++i) 1304 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector; 1305 return all; 1306 } 1307 1308 #pragma mark REPL 1309 1310 struct REPLInstance : public PluginInstance<REPLCreateInstance> { 1311 REPLInstance(ConstString name, std::string description, 1312 CallbackType create_callback, LanguageSet supported_languages) 1313 : PluginInstance<REPLCreateInstance>(name, std::move(description), 1314 create_callback), 1315 supported_languages(supported_languages) {} 1316 1317 LanguageSet supported_languages; 1318 }; 1319 1320 typedef PluginInstances<REPLInstance> REPLInstances; 1321 1322 static REPLInstances &GetREPLInstances() { 1323 static REPLInstances g_instances; 1324 return g_instances; 1325 } 1326 1327 bool PluginManager::RegisterPlugin(ConstString name, const char *description, 1328 REPLCreateInstance create_callback, 1329 LanguageSet supported_languages) { 1330 return GetREPLInstances().RegisterPlugin(name, description, create_callback, 1331 supported_languages); 1332 } 1333 1334 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) { 1335 return GetREPLInstances().UnregisterPlugin(create_callback); 1336 } 1337 1338 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) { 1339 return GetREPLInstances().GetCallbackAtIndex(idx); 1340 } 1341 1342 LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() { 1343 const auto &instances = GetREPLInstances().GetInstances(); 1344 LanguageSet all; 1345 for (unsigned i = 0; i < instances.size(); ++i) 1346 all.bitvector |= instances[i].supported_languages.bitvector; 1347 return all; 1348 } 1349 1350 #pragma mark PluginManager 1351 1352 void PluginManager::DebuggerInitialize(Debugger &debugger) { 1353 GetDynamicLoaderInstances().PerformDebuggerCallback(debugger); 1354 GetJITLoaderInstances().PerformDebuggerCallback(debugger); 1355 GetPlatformInstances().PerformDebuggerCallback(debugger); 1356 GetProcessInstances().PerformDebuggerCallback(debugger); 1357 GetSymbolFileInstances().PerformDebuggerCallback(debugger); 1358 GetOperatingSystemInstances().PerformDebuggerCallback(debugger); 1359 GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger); 1360 GetTracePluginInstances().PerformDebuggerCallback(debugger); 1361 } 1362 1363 // This is the preferred new way to register plugin specific settings. e.g. 1364 // This will put a plugin's settings under e.g. 1365 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 1366 static lldb::OptionValuePropertiesSP 1367 GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name, 1368 ConstString plugin_type_desc, bool can_create) { 1369 lldb::OptionValuePropertiesSP parent_properties_sp( 1370 debugger.GetValueProperties()); 1371 if (parent_properties_sp) { 1372 static ConstString g_property_name("plugin"); 1373 1374 OptionValuePropertiesSP plugin_properties_sp = 1375 parent_properties_sp->GetSubProperty(nullptr, g_property_name); 1376 if (!plugin_properties_sp && can_create) { 1377 plugin_properties_sp = 1378 std::make_shared<OptionValueProperties>(g_property_name); 1379 parent_properties_sp->AppendProperty( 1380 g_property_name, ConstString("Settings specify to plugins."), true, 1381 plugin_properties_sp); 1382 } 1383 1384 if (plugin_properties_sp) { 1385 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 1386 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name); 1387 if (!plugin_type_properties_sp && can_create) { 1388 plugin_type_properties_sp = 1389 std::make_shared<OptionValueProperties>(plugin_type_name); 1390 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 1391 true, plugin_type_properties_sp); 1392 } 1393 return plugin_type_properties_sp; 1394 } 1395 } 1396 return lldb::OptionValuePropertiesSP(); 1397 } 1398 1399 // This is deprecated way to register plugin specific settings. e.g. 1400 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform 1401 // generic settings would be under "platform.SETTINGNAME". 1402 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( 1403 Debugger &debugger, ConstString plugin_type_name, 1404 ConstString plugin_type_desc, bool can_create) { 1405 static ConstString g_property_name("plugin"); 1406 lldb::OptionValuePropertiesSP parent_properties_sp( 1407 debugger.GetValueProperties()); 1408 if (parent_properties_sp) { 1409 OptionValuePropertiesSP plugin_properties_sp = 1410 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name); 1411 if (!plugin_properties_sp && can_create) { 1412 plugin_properties_sp = 1413 std::make_shared<OptionValueProperties>(plugin_type_name); 1414 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 1415 true, plugin_properties_sp); 1416 } 1417 1418 if (plugin_properties_sp) { 1419 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 1420 plugin_properties_sp->GetSubProperty(nullptr, g_property_name); 1421 if (!plugin_type_properties_sp && can_create) { 1422 plugin_type_properties_sp = 1423 std::make_shared<OptionValueProperties>(g_property_name); 1424 plugin_properties_sp->AppendProperty( 1425 g_property_name, ConstString("Settings specific to plugins"), true, 1426 plugin_type_properties_sp); 1427 } 1428 return plugin_type_properties_sp; 1429 } 1430 } 1431 return lldb::OptionValuePropertiesSP(); 1432 } 1433 1434 namespace { 1435 1436 typedef lldb::OptionValuePropertiesSP 1437 GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString, 1438 bool can_create); 1439 } 1440 1441 static lldb::OptionValuePropertiesSP 1442 GetSettingForPlugin(Debugger &debugger, ConstString setting_name, 1443 ConstString plugin_type_name, 1444 GetDebuggerPropertyForPluginsPtr get_debugger_property = 1445 GetDebuggerPropertyForPlugins) { 1446 lldb::OptionValuePropertiesSP properties_sp; 1447 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property( 1448 debugger, plugin_type_name, 1449 ConstString(), // not creating to so we don't need the description 1450 false)); 1451 if (plugin_type_properties_sp) 1452 properties_sp = 1453 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 1454 return properties_sp; 1455 } 1456 1457 static bool 1458 CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name, 1459 ConstString plugin_type_desc, 1460 const lldb::OptionValuePropertiesSP &properties_sp, 1461 ConstString description, bool is_global_property, 1462 GetDebuggerPropertyForPluginsPtr get_debugger_property = 1463 GetDebuggerPropertyForPlugins) { 1464 if (properties_sp) { 1465 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 1466 get_debugger_property(debugger, plugin_type_name, plugin_type_desc, 1467 true)); 1468 if (plugin_type_properties_sp) { 1469 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 1470 description, is_global_property, 1471 properties_sp); 1472 return true; 1473 } 1474 } 1475 return false; 1476 } 1477 1478 static const char *kDynamicLoaderPluginName("dynamic-loader"); 1479 static const char *kPlatformPluginName("platform"); 1480 static const char *kProcessPluginName("process"); 1481 static const char *kSymbolFilePluginName("symbol-file"); 1482 static const char *kJITLoaderPluginName("jit-loader"); 1483 static const char *kStructuredDataPluginName("structured-data"); 1484 1485 lldb::OptionValuePropertiesSP 1486 PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger, 1487 ConstString setting_name) { 1488 return GetSettingForPlugin(debugger, setting_name, 1489 ConstString(kDynamicLoaderPluginName)); 1490 } 1491 1492 bool PluginManager::CreateSettingForDynamicLoaderPlugin( 1493 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1494 ConstString description, bool is_global_property) { 1495 return CreateSettingForPlugin( 1496 debugger, ConstString(kDynamicLoaderPluginName), 1497 ConstString("Settings for dynamic loader plug-ins"), properties_sp, 1498 description, is_global_property); 1499 } 1500 1501 lldb::OptionValuePropertiesSP 1502 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger, 1503 ConstString setting_name) { 1504 return GetSettingForPlugin(debugger, setting_name, 1505 ConstString(kPlatformPluginName), 1506 GetDebuggerPropertyForPluginsOldStyle); 1507 } 1508 1509 bool PluginManager::CreateSettingForPlatformPlugin( 1510 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1511 ConstString description, bool is_global_property) { 1512 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName), 1513 ConstString("Settings for platform plug-ins"), 1514 properties_sp, description, is_global_property, 1515 GetDebuggerPropertyForPluginsOldStyle); 1516 } 1517 1518 lldb::OptionValuePropertiesSP 1519 PluginManager::GetSettingForProcessPlugin(Debugger &debugger, 1520 ConstString setting_name) { 1521 return GetSettingForPlugin(debugger, setting_name, 1522 ConstString(kProcessPluginName)); 1523 } 1524 1525 bool PluginManager::CreateSettingForProcessPlugin( 1526 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1527 ConstString description, bool is_global_property) { 1528 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName), 1529 ConstString("Settings for process plug-ins"), 1530 properties_sp, description, is_global_property); 1531 } 1532 1533 lldb::OptionValuePropertiesSP 1534 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger, 1535 ConstString setting_name) { 1536 return GetSettingForPlugin(debugger, setting_name, 1537 ConstString(kSymbolFilePluginName)); 1538 } 1539 1540 bool PluginManager::CreateSettingForSymbolFilePlugin( 1541 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1542 ConstString description, bool is_global_property) { 1543 return CreateSettingForPlugin( 1544 debugger, ConstString(kSymbolFilePluginName), 1545 ConstString("Settings for symbol file plug-ins"), properties_sp, 1546 description, is_global_property); 1547 } 1548 1549 lldb::OptionValuePropertiesSP 1550 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger, 1551 ConstString setting_name) { 1552 return GetSettingForPlugin(debugger, setting_name, 1553 ConstString(kJITLoaderPluginName)); 1554 } 1555 1556 bool PluginManager::CreateSettingForJITLoaderPlugin( 1557 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1558 ConstString description, bool is_global_property) { 1559 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName), 1560 ConstString("Settings for JIT loader plug-ins"), 1561 properties_sp, description, is_global_property); 1562 } 1563 1564 static const char *kOperatingSystemPluginName("os"); 1565 1566 lldb::OptionValuePropertiesSP 1567 PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, 1568 ConstString setting_name) { 1569 lldb::OptionValuePropertiesSP properties_sp; 1570 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 1571 GetDebuggerPropertyForPlugins( 1572 debugger, ConstString(kOperatingSystemPluginName), 1573 ConstString(), // not creating to so we don't need the description 1574 false)); 1575 if (plugin_type_properties_sp) 1576 properties_sp = 1577 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 1578 return properties_sp; 1579 } 1580 1581 bool PluginManager::CreateSettingForOperatingSystemPlugin( 1582 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1583 ConstString description, bool is_global_property) { 1584 if (properties_sp) { 1585 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 1586 GetDebuggerPropertyForPlugins( 1587 debugger, ConstString(kOperatingSystemPluginName), 1588 ConstString("Settings for operating system plug-ins"), true)); 1589 if (plugin_type_properties_sp) { 1590 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 1591 description, is_global_property, 1592 properties_sp); 1593 return true; 1594 } 1595 } 1596 return false; 1597 } 1598 1599 lldb::OptionValuePropertiesSP 1600 PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger, 1601 ConstString setting_name) { 1602 return GetSettingForPlugin(debugger, setting_name, 1603 ConstString(kStructuredDataPluginName)); 1604 } 1605 1606 bool PluginManager::CreateSettingForStructuredDataPlugin( 1607 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1608 ConstString description, bool is_global_property) { 1609 return CreateSettingForPlugin( 1610 debugger, ConstString(kStructuredDataPluginName), 1611 ConstString("Settings for structured data plug-ins"), properties_sp, 1612 description, is_global_property); 1613 } 1614