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