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