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 ConstString name, const char *description, 477 OperatingSystemCreateInstance create_callback, 478 DebuggerInitializeCallback debugger_init_callback) { 479 return GetOperatingSystemInstances().RegisterPlugin( 480 name, description, create_callback, debugger_init_callback); 481 } 482 483 bool PluginManager::UnregisterPlugin( 484 OperatingSystemCreateInstance create_callback) { 485 return GetOperatingSystemInstances().UnregisterPlugin(create_callback); 486 } 487 488 OperatingSystemCreateInstance 489 PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) { 490 return GetOperatingSystemInstances().GetCallbackAtIndex(idx); 491 } 492 493 OperatingSystemCreateInstance 494 PluginManager::GetOperatingSystemCreateCallbackForPluginName(ConstString name) { 495 return GetOperatingSystemInstances().GetCallbackForName(name); 496 } 497 498 #pragma mark Language 499 500 typedef PluginInstance<LanguageCreateInstance> LanguageInstance; 501 typedef PluginInstances<LanguageInstance> LanguageInstances; 502 503 static LanguageInstances &GetLanguageInstances() { 504 static LanguageInstances g_instances; 505 return g_instances; 506 } 507 508 bool PluginManager::RegisterPlugin(ConstString name, const char *description, 509 LanguageCreateInstance create_callback) { 510 return GetLanguageInstances().RegisterPlugin(name, description, 511 create_callback); 512 } 513 514 bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) { 515 return GetLanguageInstances().UnregisterPlugin(create_callback); 516 } 517 518 LanguageCreateInstance 519 PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) { 520 return GetLanguageInstances().GetCallbackAtIndex(idx); 521 } 522 523 #pragma mark LanguageRuntime 524 525 struct LanguageRuntimeInstance 526 : public PluginInstance<LanguageRuntimeCreateInstance> { 527 LanguageRuntimeInstance( 528 ConstString name, std::string description, CallbackType create_callback, 529 DebuggerInitializeCallback debugger_init_callback, 530 LanguageRuntimeGetCommandObject command_callback, 531 LanguageRuntimeGetExceptionPrecondition precondition_callback) 532 : PluginInstance<LanguageRuntimeCreateInstance>( 533 name, std::move(description), create_callback, 534 debugger_init_callback), 535 command_callback(command_callback), 536 precondition_callback(precondition_callback) {} 537 538 LanguageRuntimeGetCommandObject command_callback; 539 LanguageRuntimeGetExceptionPrecondition precondition_callback; 540 }; 541 542 typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances; 543 544 static LanguageRuntimeInstances &GetLanguageRuntimeInstances() { 545 static LanguageRuntimeInstances g_instances; 546 return g_instances; 547 } 548 549 bool PluginManager::RegisterPlugin( 550 ConstString name, const char *description, 551 LanguageRuntimeCreateInstance create_callback, 552 LanguageRuntimeGetCommandObject command_callback, 553 LanguageRuntimeGetExceptionPrecondition precondition_callback) { 554 return GetLanguageRuntimeInstances().RegisterPlugin( 555 name, description, create_callback, nullptr, command_callback, 556 precondition_callback); 557 } 558 559 bool PluginManager::UnregisterPlugin( 560 LanguageRuntimeCreateInstance create_callback) { 561 return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback); 562 } 563 564 LanguageRuntimeCreateInstance 565 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) { 566 return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx); 567 } 568 569 LanguageRuntimeGetCommandObject 570 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) { 571 const auto &instances = GetLanguageRuntimeInstances().GetInstances(); 572 if (idx < instances.size()) 573 return instances[idx].command_callback; 574 return nullptr; 575 } 576 577 LanguageRuntimeGetExceptionPrecondition 578 PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) { 579 const auto &instances = GetLanguageRuntimeInstances().GetInstances(); 580 if (idx < instances.size()) 581 return instances[idx].precondition_callback; 582 return nullptr; 583 } 584 585 #pragma mark SystemRuntime 586 587 typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance; 588 typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances; 589 590 static SystemRuntimeInstances &GetSystemRuntimeInstances() { 591 static SystemRuntimeInstances g_instances; 592 return g_instances; 593 } 594 595 bool PluginManager::RegisterPlugin( 596 ConstString name, const char *description, 597 SystemRuntimeCreateInstance create_callback) { 598 return GetSystemRuntimeInstances().RegisterPlugin(name, description, 599 create_callback); 600 } 601 602 bool PluginManager::UnregisterPlugin( 603 SystemRuntimeCreateInstance create_callback) { 604 return GetSystemRuntimeInstances().UnregisterPlugin(create_callback); 605 } 606 607 SystemRuntimeCreateInstance 608 PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) { 609 return GetSystemRuntimeInstances().GetCallbackAtIndex(idx); 610 } 611 612 #pragma mark ObjectFile 613 614 struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> { 615 ObjectFileInstance( 616 ConstString name, std::string description, CallbackType create_callback, 617 ObjectFileCreateMemoryInstance create_memory_callback, 618 ObjectFileGetModuleSpecifications get_module_specifications, 619 ObjectFileSaveCore save_core) 620 : PluginInstance<ObjectFileCreateInstance>(name, std::move(description), 621 create_callback), 622 create_memory_callback(create_memory_callback), 623 get_module_specifications(get_module_specifications), 624 save_core(save_core) {} 625 626 ObjectFileCreateMemoryInstance create_memory_callback; 627 ObjectFileGetModuleSpecifications get_module_specifications; 628 ObjectFileSaveCore save_core; 629 }; 630 typedef PluginInstances<ObjectFileInstance> ObjectFileInstances; 631 632 static ObjectFileInstances &GetObjectFileInstances() { 633 static ObjectFileInstances g_instances; 634 return g_instances; 635 } 636 637 bool PluginManager::RegisterPlugin( 638 ConstString name, const char *description, 639 ObjectFileCreateInstance create_callback, 640 ObjectFileCreateMemoryInstance create_memory_callback, 641 ObjectFileGetModuleSpecifications get_module_specifications, 642 ObjectFileSaveCore save_core) { 643 return GetObjectFileInstances().RegisterPlugin( 644 name, description, create_callback, create_memory_callback, 645 get_module_specifications, save_core); 646 } 647 648 bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) { 649 return GetObjectFileInstances().UnregisterPlugin(create_callback); 650 } 651 652 ObjectFileCreateInstance 653 PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) { 654 return GetObjectFileInstances().GetCallbackAtIndex(idx); 655 } 656 657 ObjectFileCreateMemoryInstance 658 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) { 659 const auto &instances = GetObjectFileInstances().GetInstances(); 660 if (idx < instances.size()) 661 return instances[idx].create_memory_callback; 662 return nullptr; 663 } 664 665 ObjectFileGetModuleSpecifications 666 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex( 667 uint32_t idx) { 668 const auto &instances = GetObjectFileInstances().GetInstances(); 669 if (idx < instances.size()) 670 return instances[idx].get_module_specifications; 671 return nullptr; 672 } 673 674 ObjectFileCreateMemoryInstance 675 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( 676 ConstString name) { 677 if (!name) 678 return nullptr; 679 const auto &instances = GetObjectFileInstances().GetInstances(); 680 for (auto &instance : instances) { 681 if (instance.name == 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 const ConstString plugin_name) { 691 if (!plugin_name) { 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 && instance.name != plugin_name) 705 continue; 706 if (instance.save_core && 707 instance.save_core(process_sp, outfile, core_style, error)) 708 return error; 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 ConstString name, const char *description, 737 ObjectContainerCreateInstance create_callback, 738 ObjectFileGetModuleSpecifications get_module_specifications) { 739 return GetObjectContainerInstances().RegisterPlugin( 740 name, description, create_callback, get_module_specifications); 741 } 742 743 bool PluginManager::UnregisterPlugin( 744 ObjectContainerCreateInstance create_callback) { 745 return GetObjectContainerInstances().UnregisterPlugin(create_callback); 746 } 747 748 ObjectContainerCreateInstance 749 PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) { 750 return GetObjectContainerInstances().GetCallbackAtIndex(idx); 751 } 752 753 ObjectFileGetModuleSpecifications 754 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex( 755 uint32_t idx) { 756 const auto &instances = GetObjectContainerInstances().GetInstances(); 757 if (idx < instances.size()) 758 return instances[idx].get_module_specifications; 759 return nullptr; 760 } 761 762 #pragma mark Platform 763 764 typedef PluginInstance<PlatformCreateInstance> PlatformInstance; 765 typedef PluginInstances<PlatformInstance> PlatformInstances; 766 767 static PlatformInstances &GetPlatformInstances() { 768 static PlatformInstances g_platform_instances; 769 return g_platform_instances; 770 } 771 772 bool PluginManager::RegisterPlugin( 773 ConstString name, const char *description, 774 PlatformCreateInstance create_callback, 775 DebuggerInitializeCallback debugger_init_callback) { 776 return GetPlatformInstances().RegisterPlugin( 777 name, description, create_callback, debugger_init_callback); 778 } 779 780 bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { 781 return GetPlatformInstances().UnregisterPlugin(create_callback); 782 } 783 784 const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { 785 return GetPlatformInstances().GetNameAtIndex(idx); 786 } 787 788 const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { 789 return GetPlatformInstances().GetDescriptionAtIndex(idx); 790 } 791 792 PlatformCreateInstance 793 PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) { 794 return GetPlatformInstances().GetCallbackAtIndex(idx); 795 } 796 797 PlatformCreateInstance 798 PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) { 799 return GetPlatformInstances().GetCallbackForName(name); 800 } 801 802 void PluginManager::AutoCompletePlatformName(llvm::StringRef name, 803 CompletionRequest &request) { 804 for (const auto &instance : GetPlatformInstances().GetInstances()) { 805 if (instance.name.GetStringRef().startswith(name)) 806 request.AddCompletion(instance.name.GetCString()); 807 } 808 } 809 810 #pragma mark Process 811 812 typedef PluginInstance<ProcessCreateInstance> ProcessInstance; 813 typedef PluginInstances<ProcessInstance> ProcessInstances; 814 815 static ProcessInstances &GetProcessInstances() { 816 static ProcessInstances g_instances; 817 return g_instances; 818 } 819 820 bool PluginManager::RegisterPlugin( 821 ConstString name, const char *description, 822 ProcessCreateInstance create_callback, 823 DebuggerInitializeCallback debugger_init_callback) { 824 return GetProcessInstances().RegisterPlugin( 825 name, description, create_callback, debugger_init_callback); 826 } 827 828 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { 829 return GetProcessInstances().UnregisterPlugin(create_callback); 830 } 831 832 const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { 833 return GetProcessInstances().GetNameAtIndex(idx); 834 } 835 836 const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { 837 return GetProcessInstances().GetDescriptionAtIndex(idx); 838 } 839 840 ProcessCreateInstance 841 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { 842 return GetProcessInstances().GetCallbackAtIndex(idx); 843 } 844 845 ProcessCreateInstance 846 PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) { 847 return GetProcessInstances().GetCallbackForName(name); 848 } 849 850 void PluginManager::AutoCompleteProcessName(llvm::StringRef name, 851 CompletionRequest &request) { 852 for (const auto &instance : GetProcessInstances().GetInstances()) { 853 if (instance.name.GetStringRef().startswith(name)) 854 request.AddCompletion(instance.name.GetCString(), instance.description); 855 } 856 } 857 858 #pragma mark ScriptInterpreter 859 860 struct ScriptInterpreterInstance 861 : public PluginInstance<ScriptInterpreterCreateInstance> { 862 ScriptInterpreterInstance(ConstString name, std::string description, 863 CallbackType create_callback, 864 lldb::ScriptLanguage language) 865 : PluginInstance<ScriptInterpreterCreateInstance>( 866 name, std::move(description), create_callback), 867 language(language) {} 868 869 lldb::ScriptLanguage language = lldb::eScriptLanguageNone; 870 }; 871 872 typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances; 873 874 static ScriptInterpreterInstances &GetScriptInterpreterInstances() { 875 static ScriptInterpreterInstances g_instances; 876 return g_instances; 877 } 878 879 bool PluginManager::RegisterPlugin( 880 ConstString name, const char *description, 881 lldb::ScriptLanguage script_language, 882 ScriptInterpreterCreateInstance create_callback) { 883 return GetScriptInterpreterInstances().RegisterPlugin( 884 name, description, create_callback, script_language); 885 } 886 887 bool PluginManager::UnregisterPlugin( 888 ScriptInterpreterCreateInstance create_callback) { 889 return GetScriptInterpreterInstances().UnregisterPlugin(create_callback); 890 } 891 892 ScriptInterpreterCreateInstance 893 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) { 894 return GetScriptInterpreterInstances().GetCallbackAtIndex(idx); 895 } 896 897 lldb::ScriptInterpreterSP 898 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, 899 Debugger &debugger) { 900 const auto &instances = GetScriptInterpreterInstances().GetInstances(); 901 ScriptInterpreterCreateInstance none_instance = nullptr; 902 for (const auto &instance : instances) { 903 if (instance.language == lldb::eScriptLanguageNone) 904 none_instance = instance.create_callback; 905 906 if (script_lang == instance.language) 907 return instance.create_callback(debugger); 908 } 909 910 // If we didn't find one, return the ScriptInterpreter for the null language. 911 assert(none_instance != nullptr); 912 return none_instance(debugger); 913 } 914 915 #pragma mark StructuredDataPlugin 916 917 struct StructuredDataPluginInstance 918 : public PluginInstance<StructuredDataPluginCreateInstance> { 919 StructuredDataPluginInstance( 920 ConstString name, std::string description, CallbackType create_callback, 921 DebuggerInitializeCallback debugger_init_callback, 922 StructuredDataFilterLaunchInfo filter_callback) 923 : PluginInstance<StructuredDataPluginCreateInstance>( 924 name, std::move(description), create_callback, 925 debugger_init_callback), 926 filter_callback(filter_callback) {} 927 928 StructuredDataFilterLaunchInfo filter_callback = nullptr; 929 }; 930 931 typedef PluginInstances<StructuredDataPluginInstance> 932 StructuredDataPluginInstances; 933 934 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { 935 static StructuredDataPluginInstances g_instances; 936 return g_instances; 937 } 938 939 bool PluginManager::RegisterPlugin( 940 ConstString name, const char *description, 941 StructuredDataPluginCreateInstance create_callback, 942 DebuggerInitializeCallback debugger_init_callback, 943 StructuredDataFilterLaunchInfo filter_callback) { 944 return GetStructuredDataPluginInstances().RegisterPlugin( 945 name, description, create_callback, debugger_init_callback, 946 filter_callback); 947 } 948 949 bool PluginManager::UnregisterPlugin( 950 StructuredDataPluginCreateInstance create_callback) { 951 return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback); 952 } 953 954 StructuredDataPluginCreateInstance 955 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) { 956 return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx); 957 } 958 959 StructuredDataFilterLaunchInfo 960 PluginManager::GetStructuredDataFilterCallbackAtIndex( 961 uint32_t idx, bool &iteration_complete) { 962 const auto &instances = GetStructuredDataPluginInstances().GetInstances(); 963 if (idx < instances.size()) { 964 iteration_complete = false; 965 return instances[idx].filter_callback; 966 } else { 967 iteration_complete = true; 968 } 969 return nullptr; 970 } 971 972 #pragma mark SymbolFile 973 974 typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance; 975 typedef PluginInstances<SymbolFileInstance> SymbolFileInstances; 976 977 static SymbolFileInstances &GetSymbolFileInstances() { 978 static SymbolFileInstances g_instances; 979 return g_instances; 980 } 981 982 bool PluginManager::RegisterPlugin( 983 ConstString name, const char *description, 984 SymbolFileCreateInstance create_callback, 985 DebuggerInitializeCallback debugger_init_callback) { 986 return GetSymbolFileInstances().RegisterPlugin( 987 name, description, create_callback, debugger_init_callback); 988 } 989 990 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) { 991 return GetSymbolFileInstances().UnregisterPlugin(create_callback); 992 } 993 994 SymbolFileCreateInstance 995 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) { 996 return GetSymbolFileInstances().GetCallbackAtIndex(idx); 997 } 998 999 #pragma mark SymbolVendor 1000 1001 typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance; 1002 typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances; 1003 1004 static SymbolVendorInstances &GetSymbolVendorInstances() { 1005 static SymbolVendorInstances g_instances; 1006 return g_instances; 1007 } 1008 1009 bool PluginManager::RegisterPlugin(ConstString name, const char *description, 1010 SymbolVendorCreateInstance create_callback) { 1011 return GetSymbolVendorInstances().RegisterPlugin(name, description, 1012 create_callback); 1013 } 1014 1015 bool PluginManager::UnregisterPlugin( 1016 SymbolVendorCreateInstance create_callback) { 1017 return GetSymbolVendorInstances().UnregisterPlugin(create_callback); 1018 } 1019 1020 SymbolVendorCreateInstance 1021 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { 1022 return GetSymbolVendorInstances().GetCallbackAtIndex(idx); 1023 } 1024 1025 #pragma mark Trace 1026 1027 struct TraceInstance 1028 : public PluginInstance<TraceCreateInstanceForSessionFile> { 1029 TraceInstance( 1030 ConstString name, std::string description, 1031 CallbackType create_callback_for_session_file, 1032 TraceCreateInstanceForLiveProcess create_callback_for_live_process, 1033 llvm::StringRef schema) 1034 : PluginInstance<TraceCreateInstanceForSessionFile>( 1035 name, std::move(description), create_callback_for_session_file), 1036 schema(schema), 1037 create_callback_for_live_process(create_callback_for_live_process) {} 1038 1039 llvm::StringRef schema; 1040 TraceCreateInstanceForLiveProcess create_callback_for_live_process; 1041 }; 1042 1043 typedef PluginInstances<TraceInstance> TraceInstances; 1044 1045 static TraceInstances &GetTracePluginInstances() { 1046 static TraceInstances g_instances; 1047 return g_instances; 1048 } 1049 1050 bool PluginManager::RegisterPlugin( 1051 ConstString name, const char *description, 1052 TraceCreateInstanceForSessionFile create_callback_for_session_file, 1053 TraceCreateInstanceForLiveProcess create_callback_for_live_process, 1054 llvm::StringRef schema) { 1055 return GetTracePluginInstances().RegisterPlugin( 1056 name, description, create_callback_for_session_file, 1057 create_callback_for_live_process, schema); 1058 } 1059 1060 bool PluginManager::UnregisterPlugin( 1061 TraceCreateInstanceForSessionFile create_callback_for_session_file) { 1062 return GetTracePluginInstances().UnregisterPlugin( 1063 create_callback_for_session_file); 1064 } 1065 1066 TraceCreateInstanceForSessionFile 1067 PluginManager::GetTraceCreateCallback(ConstString plugin_name) { 1068 return GetTracePluginInstances().GetCallbackForName(plugin_name); 1069 } 1070 1071 TraceCreateInstanceForLiveProcess 1072 PluginManager::GetTraceCreateCallbackForLiveProcess(ConstString plugin_name) { 1073 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) 1074 if (instance.name == plugin_name) 1075 return instance.create_callback_for_live_process; 1076 return nullptr; 1077 } 1078 1079 llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) { 1080 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) 1081 if (instance.name == plugin_name) 1082 return instance.schema; 1083 return llvm::StringRef(); 1084 } 1085 1086 llvm::StringRef PluginManager::GetTraceSchema(size_t index) { 1087 if (TraceInstance *instance = 1088 GetTracePluginInstances().GetInstanceAtIndex(index)) 1089 return instance->schema; 1090 return llvm::StringRef(); 1091 } 1092 1093 #pragma mark TraceExporter 1094 1095 struct TraceExporterInstance 1096 : public PluginInstance<TraceExporterCreateInstance> { 1097 TraceExporterInstance( 1098 ConstString name, std::string description, 1099 TraceExporterCreateInstance create_instance, 1100 ThreadTraceExportCommandCreator create_thread_trace_export_command) 1101 : PluginInstance<TraceExporterCreateInstance>( 1102 name, std::move(description), create_instance), 1103 create_thread_trace_export_command(create_thread_trace_export_command) { 1104 } 1105 1106 ThreadTraceExportCommandCreator create_thread_trace_export_command; 1107 }; 1108 1109 typedef PluginInstances<TraceExporterInstance> TraceExporterInstances; 1110 1111 static TraceExporterInstances &GetTraceExporterInstances() { 1112 static TraceExporterInstances g_instances; 1113 return g_instances; 1114 } 1115 1116 bool PluginManager::RegisterPlugin( 1117 ConstString name, const char *description, 1118 TraceExporterCreateInstance create_callback, 1119 ThreadTraceExportCommandCreator create_thread_trace_export_command) { 1120 return GetTraceExporterInstances().RegisterPlugin( 1121 name, description, create_callback, create_thread_trace_export_command); 1122 } 1123 1124 TraceExporterCreateInstance 1125 PluginManager::GetTraceExporterCreateCallback(ConstString plugin_name) { 1126 return GetTraceExporterInstances().GetCallbackForName(plugin_name); 1127 } 1128 1129 bool PluginManager::UnregisterPlugin( 1130 TraceExporterCreateInstance create_callback) { 1131 return GetTraceExporterInstances().UnregisterPlugin(create_callback); 1132 } 1133 1134 ThreadTraceExportCommandCreator 1135 PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) { 1136 if (TraceExporterInstance *instance = 1137 GetTraceExporterInstances().GetInstanceAtIndex(index)) 1138 return instance->create_thread_trace_export_command; 1139 return nullptr; 1140 } 1141 1142 const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) { 1143 return GetTraceExporterInstances().GetNameAtIndex(index); 1144 } 1145 1146 #pragma mark UnwindAssembly 1147 1148 typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance; 1149 typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances; 1150 1151 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { 1152 static UnwindAssemblyInstances g_instances; 1153 return g_instances; 1154 } 1155 1156 bool PluginManager::RegisterPlugin( 1157 ConstString name, const char *description, 1158 UnwindAssemblyCreateInstance create_callback) { 1159 return GetUnwindAssemblyInstances().RegisterPlugin(name, description, 1160 create_callback); 1161 } 1162 1163 bool PluginManager::UnregisterPlugin( 1164 UnwindAssemblyCreateInstance create_callback) { 1165 return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback); 1166 } 1167 1168 UnwindAssemblyCreateInstance 1169 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) { 1170 return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx); 1171 } 1172 1173 #pragma mark MemoryHistory 1174 1175 typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance; 1176 typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances; 1177 1178 static MemoryHistoryInstances &GetMemoryHistoryInstances() { 1179 static MemoryHistoryInstances g_instances; 1180 return g_instances; 1181 } 1182 1183 bool PluginManager::RegisterPlugin( 1184 ConstString name, const char *description, 1185 MemoryHistoryCreateInstance create_callback) { 1186 return GetMemoryHistoryInstances().RegisterPlugin(name, description, 1187 create_callback); 1188 } 1189 1190 bool PluginManager::UnregisterPlugin( 1191 MemoryHistoryCreateInstance create_callback) { 1192 return GetMemoryHistoryInstances().UnregisterPlugin(create_callback); 1193 } 1194 1195 MemoryHistoryCreateInstance 1196 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { 1197 return GetMemoryHistoryInstances().GetCallbackAtIndex(idx); 1198 } 1199 1200 #pragma mark InstrumentationRuntime 1201 1202 struct InstrumentationRuntimeInstance 1203 : public PluginInstance<InstrumentationRuntimeCreateInstance> { 1204 InstrumentationRuntimeInstance( 1205 ConstString name, std::string description, CallbackType create_callback, 1206 InstrumentationRuntimeGetType get_type_callback) 1207 : PluginInstance<InstrumentationRuntimeCreateInstance>( 1208 name, std::move(description), create_callback), 1209 get_type_callback(get_type_callback) {} 1210 1211 InstrumentationRuntimeGetType get_type_callback = nullptr; 1212 }; 1213 1214 typedef PluginInstances<InstrumentationRuntimeInstance> 1215 InstrumentationRuntimeInstances; 1216 1217 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { 1218 static InstrumentationRuntimeInstances g_instances; 1219 return g_instances; 1220 } 1221 1222 bool PluginManager::RegisterPlugin( 1223 ConstString name, const char *description, 1224 InstrumentationRuntimeCreateInstance create_callback, 1225 InstrumentationRuntimeGetType get_type_callback) { 1226 return GetInstrumentationRuntimeInstances().RegisterPlugin( 1227 name, description, create_callback, get_type_callback); 1228 } 1229 1230 bool PluginManager::UnregisterPlugin( 1231 InstrumentationRuntimeCreateInstance create_callback) { 1232 return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback); 1233 } 1234 1235 InstrumentationRuntimeGetType 1236 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { 1237 const auto &instances = GetInstrumentationRuntimeInstances().GetInstances(); 1238 if (idx < instances.size()) 1239 return instances[idx].get_type_callback; 1240 return nullptr; 1241 } 1242 1243 InstrumentationRuntimeCreateInstance 1244 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { 1245 return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx); 1246 } 1247 1248 #pragma mark TypeSystem 1249 1250 struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> { 1251 TypeSystemInstance(ConstString name, std::string description, 1252 CallbackType create_callback, 1253 LanguageSet supported_languages_for_types, 1254 LanguageSet supported_languages_for_expressions) 1255 : PluginInstance<TypeSystemCreateInstance>(name, std::move(description), 1256 create_callback), 1257 supported_languages_for_types(supported_languages_for_types), 1258 supported_languages_for_expressions( 1259 supported_languages_for_expressions) {} 1260 1261 LanguageSet supported_languages_for_types; 1262 LanguageSet supported_languages_for_expressions; 1263 }; 1264 1265 typedef PluginInstances<TypeSystemInstance> TypeSystemInstances; 1266 1267 static TypeSystemInstances &GetTypeSystemInstances() { 1268 static TypeSystemInstances g_instances; 1269 return g_instances; 1270 } 1271 1272 bool PluginManager::RegisterPlugin( 1273 ConstString name, const char *description, 1274 TypeSystemCreateInstance create_callback, 1275 LanguageSet supported_languages_for_types, 1276 LanguageSet supported_languages_for_expressions) { 1277 return GetTypeSystemInstances().RegisterPlugin( 1278 name, description, create_callback, supported_languages_for_types, 1279 supported_languages_for_expressions); 1280 } 1281 1282 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) { 1283 return GetTypeSystemInstances().UnregisterPlugin(create_callback); 1284 } 1285 1286 TypeSystemCreateInstance 1287 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) { 1288 return GetTypeSystemInstances().GetCallbackAtIndex(idx); 1289 } 1290 1291 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() { 1292 const auto &instances = GetTypeSystemInstances().GetInstances(); 1293 LanguageSet all; 1294 for (unsigned i = 0; i < instances.size(); ++i) 1295 all.bitvector |= instances[i].supported_languages_for_types.bitvector; 1296 return all; 1297 } 1298 1299 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { 1300 const auto &instances = GetTypeSystemInstances().GetInstances(); 1301 LanguageSet all; 1302 for (unsigned i = 0; i < instances.size(); ++i) 1303 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector; 1304 return all; 1305 } 1306 1307 #pragma mark REPL 1308 1309 struct REPLInstance : public PluginInstance<REPLCreateInstance> { 1310 REPLInstance(ConstString name, std::string description, 1311 CallbackType create_callback, LanguageSet supported_languages) 1312 : PluginInstance<REPLCreateInstance>(name, std::move(description), 1313 create_callback), 1314 supported_languages(supported_languages) {} 1315 1316 LanguageSet supported_languages; 1317 }; 1318 1319 typedef PluginInstances<REPLInstance> REPLInstances; 1320 1321 static REPLInstances &GetREPLInstances() { 1322 static REPLInstances g_instances; 1323 return g_instances; 1324 } 1325 1326 bool PluginManager::RegisterPlugin(ConstString name, const char *description, 1327 REPLCreateInstance create_callback, 1328 LanguageSet supported_languages) { 1329 return GetREPLInstances().RegisterPlugin(name, description, create_callback, 1330 supported_languages); 1331 } 1332 1333 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) { 1334 return GetREPLInstances().UnregisterPlugin(create_callback); 1335 } 1336 1337 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) { 1338 return GetREPLInstances().GetCallbackAtIndex(idx); 1339 } 1340 1341 LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() { 1342 const auto &instances = GetREPLInstances().GetInstances(); 1343 LanguageSet all; 1344 for (unsigned i = 0; i < instances.size(); ++i) 1345 all.bitvector |= instances[i].supported_languages.bitvector; 1346 return all; 1347 } 1348 1349 #pragma mark PluginManager 1350 1351 void PluginManager::DebuggerInitialize(Debugger &debugger) { 1352 GetDynamicLoaderInstances().PerformDebuggerCallback(debugger); 1353 GetJITLoaderInstances().PerformDebuggerCallback(debugger); 1354 GetPlatformInstances().PerformDebuggerCallback(debugger); 1355 GetProcessInstances().PerformDebuggerCallback(debugger); 1356 GetSymbolFileInstances().PerformDebuggerCallback(debugger); 1357 GetOperatingSystemInstances().PerformDebuggerCallback(debugger); 1358 GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger); 1359 GetTracePluginInstances().PerformDebuggerCallback(debugger); 1360 } 1361 1362 // This is the preferred new way to register plugin specific settings. e.g. 1363 // This will put a plugin's settings under e.g. 1364 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 1365 static lldb::OptionValuePropertiesSP 1366 GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name, 1367 ConstString plugin_type_desc, bool can_create) { 1368 lldb::OptionValuePropertiesSP parent_properties_sp( 1369 debugger.GetValueProperties()); 1370 if (parent_properties_sp) { 1371 static ConstString g_property_name("plugin"); 1372 1373 OptionValuePropertiesSP plugin_properties_sp = 1374 parent_properties_sp->GetSubProperty(nullptr, g_property_name); 1375 if (!plugin_properties_sp && can_create) { 1376 plugin_properties_sp = 1377 std::make_shared<OptionValueProperties>(g_property_name); 1378 parent_properties_sp->AppendProperty( 1379 g_property_name, ConstString("Settings specify to plugins."), true, 1380 plugin_properties_sp); 1381 } 1382 1383 if (plugin_properties_sp) { 1384 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 1385 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name); 1386 if (!plugin_type_properties_sp && can_create) { 1387 plugin_type_properties_sp = 1388 std::make_shared<OptionValueProperties>(plugin_type_name); 1389 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 1390 true, plugin_type_properties_sp); 1391 } 1392 return plugin_type_properties_sp; 1393 } 1394 } 1395 return lldb::OptionValuePropertiesSP(); 1396 } 1397 1398 // This is deprecated way to register plugin specific settings. e.g. 1399 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform 1400 // generic settings would be under "platform.SETTINGNAME". 1401 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( 1402 Debugger &debugger, ConstString plugin_type_name, 1403 ConstString plugin_type_desc, bool can_create) { 1404 static ConstString g_property_name("plugin"); 1405 lldb::OptionValuePropertiesSP parent_properties_sp( 1406 debugger.GetValueProperties()); 1407 if (parent_properties_sp) { 1408 OptionValuePropertiesSP plugin_properties_sp = 1409 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name); 1410 if (!plugin_properties_sp && can_create) { 1411 plugin_properties_sp = 1412 std::make_shared<OptionValueProperties>(plugin_type_name); 1413 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 1414 true, plugin_properties_sp); 1415 } 1416 1417 if (plugin_properties_sp) { 1418 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 1419 plugin_properties_sp->GetSubProperty(nullptr, g_property_name); 1420 if (!plugin_type_properties_sp && can_create) { 1421 plugin_type_properties_sp = 1422 std::make_shared<OptionValueProperties>(g_property_name); 1423 plugin_properties_sp->AppendProperty( 1424 g_property_name, ConstString("Settings specific to plugins"), true, 1425 plugin_type_properties_sp); 1426 } 1427 return plugin_type_properties_sp; 1428 } 1429 } 1430 return lldb::OptionValuePropertiesSP(); 1431 } 1432 1433 namespace { 1434 1435 typedef lldb::OptionValuePropertiesSP 1436 GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString, 1437 bool can_create); 1438 } 1439 1440 static lldb::OptionValuePropertiesSP 1441 GetSettingForPlugin(Debugger &debugger, ConstString setting_name, 1442 ConstString plugin_type_name, 1443 GetDebuggerPropertyForPluginsPtr get_debugger_property = 1444 GetDebuggerPropertyForPlugins) { 1445 lldb::OptionValuePropertiesSP properties_sp; 1446 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property( 1447 debugger, plugin_type_name, 1448 ConstString(), // not creating to so we don't need the description 1449 false)); 1450 if (plugin_type_properties_sp) 1451 properties_sp = 1452 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 1453 return properties_sp; 1454 } 1455 1456 static bool 1457 CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name, 1458 ConstString plugin_type_desc, 1459 const lldb::OptionValuePropertiesSP &properties_sp, 1460 ConstString description, bool is_global_property, 1461 GetDebuggerPropertyForPluginsPtr get_debugger_property = 1462 GetDebuggerPropertyForPlugins) { 1463 if (properties_sp) { 1464 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 1465 get_debugger_property(debugger, plugin_type_name, plugin_type_desc, 1466 true)); 1467 if (plugin_type_properties_sp) { 1468 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 1469 description, is_global_property, 1470 properties_sp); 1471 return true; 1472 } 1473 } 1474 return false; 1475 } 1476 1477 static const char *kDynamicLoaderPluginName("dynamic-loader"); 1478 static const char *kPlatformPluginName("platform"); 1479 static const char *kProcessPluginName("process"); 1480 static const char *kSymbolFilePluginName("symbol-file"); 1481 static const char *kJITLoaderPluginName("jit-loader"); 1482 static const char *kStructuredDataPluginName("structured-data"); 1483 1484 lldb::OptionValuePropertiesSP 1485 PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger, 1486 ConstString setting_name) { 1487 return GetSettingForPlugin(debugger, setting_name, 1488 ConstString(kDynamicLoaderPluginName)); 1489 } 1490 1491 bool PluginManager::CreateSettingForDynamicLoaderPlugin( 1492 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1493 ConstString description, bool is_global_property) { 1494 return CreateSettingForPlugin( 1495 debugger, ConstString(kDynamicLoaderPluginName), 1496 ConstString("Settings for dynamic loader plug-ins"), properties_sp, 1497 description, is_global_property); 1498 } 1499 1500 lldb::OptionValuePropertiesSP 1501 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger, 1502 ConstString setting_name) { 1503 return GetSettingForPlugin(debugger, setting_name, 1504 ConstString(kPlatformPluginName), 1505 GetDebuggerPropertyForPluginsOldStyle); 1506 } 1507 1508 bool PluginManager::CreateSettingForPlatformPlugin( 1509 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1510 ConstString description, bool is_global_property) { 1511 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName), 1512 ConstString("Settings for platform plug-ins"), 1513 properties_sp, description, is_global_property, 1514 GetDebuggerPropertyForPluginsOldStyle); 1515 } 1516 1517 lldb::OptionValuePropertiesSP 1518 PluginManager::GetSettingForProcessPlugin(Debugger &debugger, 1519 ConstString setting_name) { 1520 return GetSettingForPlugin(debugger, setting_name, 1521 ConstString(kProcessPluginName)); 1522 } 1523 1524 bool PluginManager::CreateSettingForProcessPlugin( 1525 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1526 ConstString description, bool is_global_property) { 1527 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName), 1528 ConstString("Settings for process plug-ins"), 1529 properties_sp, description, is_global_property); 1530 } 1531 1532 lldb::OptionValuePropertiesSP 1533 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger, 1534 ConstString setting_name) { 1535 return GetSettingForPlugin(debugger, setting_name, 1536 ConstString(kSymbolFilePluginName)); 1537 } 1538 1539 bool PluginManager::CreateSettingForSymbolFilePlugin( 1540 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1541 ConstString description, bool is_global_property) { 1542 return CreateSettingForPlugin( 1543 debugger, ConstString(kSymbolFilePluginName), 1544 ConstString("Settings for symbol file plug-ins"), properties_sp, 1545 description, is_global_property); 1546 } 1547 1548 lldb::OptionValuePropertiesSP 1549 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger, 1550 ConstString setting_name) { 1551 return GetSettingForPlugin(debugger, setting_name, 1552 ConstString(kJITLoaderPluginName)); 1553 } 1554 1555 bool PluginManager::CreateSettingForJITLoaderPlugin( 1556 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1557 ConstString description, bool is_global_property) { 1558 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName), 1559 ConstString("Settings for JIT loader plug-ins"), 1560 properties_sp, description, is_global_property); 1561 } 1562 1563 static const char *kOperatingSystemPluginName("os"); 1564 1565 lldb::OptionValuePropertiesSP 1566 PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, 1567 ConstString setting_name) { 1568 lldb::OptionValuePropertiesSP properties_sp; 1569 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 1570 GetDebuggerPropertyForPlugins( 1571 debugger, ConstString(kOperatingSystemPluginName), 1572 ConstString(), // not creating to so we don't need the description 1573 false)); 1574 if (plugin_type_properties_sp) 1575 properties_sp = 1576 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 1577 return properties_sp; 1578 } 1579 1580 bool PluginManager::CreateSettingForOperatingSystemPlugin( 1581 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1582 ConstString description, bool is_global_property) { 1583 if (properties_sp) { 1584 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 1585 GetDebuggerPropertyForPlugins( 1586 debugger, ConstString(kOperatingSystemPluginName), 1587 ConstString("Settings for operating system plug-ins"), true)); 1588 if (plugin_type_properties_sp) { 1589 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 1590 description, is_global_property, 1591 properties_sp); 1592 return true; 1593 } 1594 } 1595 return false; 1596 } 1597 1598 lldb::OptionValuePropertiesSP 1599 PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger, 1600 ConstString setting_name) { 1601 return GetSettingForPlugin(debugger, setting_name, 1602 ConstString(kStructuredDataPluginName)); 1603 } 1604 1605 bool PluginManager::CreateSettingForStructuredDataPlugin( 1606 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1607 ConstString description, bool is_global_property) { 1608 return CreateSettingForPlugin( 1609 debugger, ConstString(kStructuredDataPluginName), 1610 ConstString("Settings for structured data plug-ins"), properties_sp, 1611 description, is_global_property); 1612 } 1613