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 ObjectContainerCreateMemoryInstance create_memory_callback, 728 ObjectFileGetModuleSpecifications get_module_specifications) 729 : PluginInstance<ObjectContainerCreateInstance>(name, description, 730 create_callback), 731 create_memory_callback(create_memory_callback), 732 get_module_specifications(get_module_specifications) {} 733 734 ObjectContainerCreateMemoryInstance create_memory_callback; 735 ObjectFileGetModuleSpecifications get_module_specifications; 736 }; 737 typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances; 738 739 static ObjectContainerInstances &GetObjectContainerInstances() { 740 static ObjectContainerInstances g_instances; 741 return g_instances; 742 } 743 744 bool PluginManager::RegisterPlugin( 745 llvm::StringRef name, llvm::StringRef description, 746 ObjectContainerCreateInstance create_callback, 747 ObjectFileGetModuleSpecifications get_module_specifications, 748 ObjectContainerCreateMemoryInstance create_memory_callback) { 749 return GetObjectContainerInstances().RegisterPlugin( 750 name, description, create_callback, create_memory_callback, 751 get_module_specifications); 752 } 753 754 bool PluginManager::UnregisterPlugin( 755 ObjectContainerCreateInstance create_callback) { 756 return GetObjectContainerInstances().UnregisterPlugin(create_callback); 757 } 758 759 ObjectContainerCreateInstance 760 PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) { 761 return GetObjectContainerInstances().GetCallbackAtIndex(idx); 762 } 763 764 ObjectContainerCreateMemoryInstance 765 PluginManager::GetObjectContainerCreateMemoryCallbackAtIndex(uint32_t idx) { 766 const auto &instances = GetObjectContainerInstances().GetInstances(); 767 if (idx < instances.size()) 768 return instances[idx].create_memory_callback; 769 return nullptr; 770 } 771 772 ObjectFileGetModuleSpecifications 773 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex( 774 uint32_t idx) { 775 const auto &instances = GetObjectContainerInstances().GetInstances(); 776 if (idx < instances.size()) 777 return instances[idx].get_module_specifications; 778 return nullptr; 779 } 780 781 #pragma mark Platform 782 783 typedef PluginInstance<PlatformCreateInstance> PlatformInstance; 784 typedef PluginInstances<PlatformInstance> PlatformInstances; 785 786 static PlatformInstances &GetPlatformInstances() { 787 static PlatformInstances g_platform_instances; 788 return g_platform_instances; 789 } 790 791 bool PluginManager::RegisterPlugin( 792 llvm::StringRef name, llvm::StringRef description, 793 PlatformCreateInstance create_callback, 794 DebuggerInitializeCallback debugger_init_callback) { 795 return GetPlatformInstances().RegisterPlugin( 796 name, description, create_callback, debugger_init_callback); 797 } 798 799 bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { 800 return GetPlatformInstances().UnregisterPlugin(create_callback); 801 } 802 803 llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { 804 return GetPlatformInstances().GetNameAtIndex(idx); 805 } 806 807 llvm::StringRef 808 PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { 809 return GetPlatformInstances().GetDescriptionAtIndex(idx); 810 } 811 812 PlatformCreateInstance 813 PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) { 814 return GetPlatformInstances().GetCallbackAtIndex(idx); 815 } 816 817 PlatformCreateInstance 818 PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) { 819 return GetPlatformInstances().GetCallbackForName(name); 820 } 821 822 void PluginManager::AutoCompletePlatformName(llvm::StringRef name, 823 CompletionRequest &request) { 824 for (const auto &instance : GetPlatformInstances().GetInstances()) { 825 if (instance.name.startswith(name)) 826 request.AddCompletion(instance.name); 827 } 828 } 829 830 #pragma mark Process 831 832 typedef PluginInstance<ProcessCreateInstance> ProcessInstance; 833 typedef PluginInstances<ProcessInstance> ProcessInstances; 834 835 static ProcessInstances &GetProcessInstances() { 836 static ProcessInstances g_instances; 837 return g_instances; 838 } 839 840 bool PluginManager::RegisterPlugin( 841 llvm::StringRef name, llvm::StringRef description, 842 ProcessCreateInstance create_callback, 843 DebuggerInitializeCallback debugger_init_callback) { 844 return GetProcessInstances().RegisterPlugin( 845 name, description, create_callback, debugger_init_callback); 846 } 847 848 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { 849 return GetProcessInstances().UnregisterPlugin(create_callback); 850 } 851 852 llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { 853 return GetProcessInstances().GetNameAtIndex(idx); 854 } 855 856 llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { 857 return GetProcessInstances().GetDescriptionAtIndex(idx); 858 } 859 860 ProcessCreateInstance 861 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { 862 return GetProcessInstances().GetCallbackAtIndex(idx); 863 } 864 865 ProcessCreateInstance 866 PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) { 867 return GetProcessInstances().GetCallbackForName(name); 868 } 869 870 void PluginManager::AutoCompleteProcessName(llvm::StringRef name, 871 CompletionRequest &request) { 872 for (const auto &instance : GetProcessInstances().GetInstances()) { 873 if (instance.name.startswith(name)) 874 request.AddCompletion(instance.name, instance.description); 875 } 876 } 877 878 #pragma mark ScriptInterpreter 879 880 struct ScriptInterpreterInstance 881 : public PluginInstance<ScriptInterpreterCreateInstance> { 882 ScriptInterpreterInstance(llvm::StringRef name, llvm::StringRef description, 883 CallbackType create_callback, 884 lldb::ScriptLanguage language) 885 : PluginInstance<ScriptInterpreterCreateInstance>(name, description, 886 create_callback), 887 language(language) {} 888 889 lldb::ScriptLanguage language = lldb::eScriptLanguageNone; 890 }; 891 892 typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances; 893 894 static ScriptInterpreterInstances &GetScriptInterpreterInstances() { 895 static ScriptInterpreterInstances g_instances; 896 return g_instances; 897 } 898 899 bool PluginManager::RegisterPlugin( 900 llvm::StringRef name, llvm::StringRef description, 901 lldb::ScriptLanguage script_language, 902 ScriptInterpreterCreateInstance create_callback) { 903 return GetScriptInterpreterInstances().RegisterPlugin( 904 name, description, create_callback, script_language); 905 } 906 907 bool PluginManager::UnregisterPlugin( 908 ScriptInterpreterCreateInstance create_callback) { 909 return GetScriptInterpreterInstances().UnregisterPlugin(create_callback); 910 } 911 912 ScriptInterpreterCreateInstance 913 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) { 914 return GetScriptInterpreterInstances().GetCallbackAtIndex(idx); 915 } 916 917 lldb::ScriptInterpreterSP 918 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, 919 Debugger &debugger) { 920 const auto &instances = GetScriptInterpreterInstances().GetInstances(); 921 ScriptInterpreterCreateInstance none_instance = nullptr; 922 for (const auto &instance : instances) { 923 if (instance.language == lldb::eScriptLanguageNone) 924 none_instance = instance.create_callback; 925 926 if (script_lang == instance.language) 927 return instance.create_callback(debugger); 928 } 929 930 // If we didn't find one, return the ScriptInterpreter for the null language. 931 assert(none_instance != nullptr); 932 return none_instance(debugger); 933 } 934 935 #pragma mark StructuredDataPlugin 936 937 struct StructuredDataPluginInstance 938 : public PluginInstance<StructuredDataPluginCreateInstance> { 939 StructuredDataPluginInstance( 940 llvm::StringRef name, llvm::StringRef description, 941 CallbackType create_callback, 942 DebuggerInitializeCallback debugger_init_callback, 943 StructuredDataFilterLaunchInfo filter_callback) 944 : PluginInstance<StructuredDataPluginCreateInstance>( 945 name, description, create_callback, debugger_init_callback), 946 filter_callback(filter_callback) {} 947 948 StructuredDataFilterLaunchInfo filter_callback = nullptr; 949 }; 950 951 typedef PluginInstances<StructuredDataPluginInstance> 952 StructuredDataPluginInstances; 953 954 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { 955 static StructuredDataPluginInstances g_instances; 956 return g_instances; 957 } 958 959 bool PluginManager::RegisterPlugin( 960 llvm::StringRef name, llvm::StringRef description, 961 StructuredDataPluginCreateInstance create_callback, 962 DebuggerInitializeCallback debugger_init_callback, 963 StructuredDataFilterLaunchInfo filter_callback) { 964 return GetStructuredDataPluginInstances().RegisterPlugin( 965 name, description, create_callback, debugger_init_callback, 966 filter_callback); 967 } 968 969 bool PluginManager::UnregisterPlugin( 970 StructuredDataPluginCreateInstance create_callback) { 971 return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback); 972 } 973 974 StructuredDataPluginCreateInstance 975 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) { 976 return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx); 977 } 978 979 StructuredDataFilterLaunchInfo 980 PluginManager::GetStructuredDataFilterCallbackAtIndex( 981 uint32_t idx, bool &iteration_complete) { 982 const auto &instances = GetStructuredDataPluginInstances().GetInstances(); 983 if (idx < instances.size()) { 984 iteration_complete = false; 985 return instances[idx].filter_callback; 986 } else { 987 iteration_complete = true; 988 } 989 return nullptr; 990 } 991 992 #pragma mark SymbolFile 993 994 typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance; 995 typedef PluginInstances<SymbolFileInstance> SymbolFileInstances; 996 997 static SymbolFileInstances &GetSymbolFileInstances() { 998 static SymbolFileInstances g_instances; 999 return g_instances; 1000 } 1001 1002 bool PluginManager::RegisterPlugin( 1003 llvm::StringRef name, llvm::StringRef description, 1004 SymbolFileCreateInstance create_callback, 1005 DebuggerInitializeCallback debugger_init_callback) { 1006 return GetSymbolFileInstances().RegisterPlugin( 1007 name, description, create_callback, debugger_init_callback); 1008 } 1009 1010 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) { 1011 return GetSymbolFileInstances().UnregisterPlugin(create_callback); 1012 } 1013 1014 SymbolFileCreateInstance 1015 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) { 1016 return GetSymbolFileInstances().GetCallbackAtIndex(idx); 1017 } 1018 1019 #pragma mark SymbolVendor 1020 1021 typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance; 1022 typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances; 1023 1024 static SymbolVendorInstances &GetSymbolVendorInstances() { 1025 static SymbolVendorInstances g_instances; 1026 return g_instances; 1027 } 1028 1029 bool PluginManager::RegisterPlugin(llvm::StringRef name, 1030 llvm::StringRef description, 1031 SymbolVendorCreateInstance create_callback) { 1032 return GetSymbolVendorInstances().RegisterPlugin(name, description, 1033 create_callback); 1034 } 1035 1036 bool PluginManager::UnregisterPlugin( 1037 SymbolVendorCreateInstance create_callback) { 1038 return GetSymbolVendorInstances().UnregisterPlugin(create_callback); 1039 } 1040 1041 SymbolVendorCreateInstance 1042 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { 1043 return GetSymbolVendorInstances().GetCallbackAtIndex(idx); 1044 } 1045 1046 #pragma mark Trace 1047 1048 struct TraceInstance 1049 : public PluginInstance<TraceCreateInstanceFromBundle> { 1050 TraceInstance( 1051 llvm::StringRef name, llvm::StringRef description, 1052 CallbackType create_callback_from_bundle, 1053 TraceCreateInstanceForLiveProcess create_callback_for_live_process, 1054 llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback) 1055 : PluginInstance<TraceCreateInstanceFromBundle>( 1056 name, description, create_callback_from_bundle, 1057 debugger_init_callback), 1058 schema(schema), 1059 create_callback_for_live_process(create_callback_for_live_process) {} 1060 1061 llvm::StringRef schema; 1062 TraceCreateInstanceForLiveProcess create_callback_for_live_process; 1063 }; 1064 1065 typedef PluginInstances<TraceInstance> TraceInstances; 1066 1067 static TraceInstances &GetTracePluginInstances() { 1068 static TraceInstances g_instances; 1069 return g_instances; 1070 } 1071 1072 bool PluginManager::RegisterPlugin( 1073 llvm::StringRef name, llvm::StringRef description, 1074 TraceCreateInstanceFromBundle create_callback_from_bundle, 1075 TraceCreateInstanceForLiveProcess create_callback_for_live_process, 1076 llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback) { 1077 return GetTracePluginInstances().RegisterPlugin( 1078 name, description, create_callback_from_bundle, 1079 create_callback_for_live_process, schema, debugger_init_callback); 1080 } 1081 1082 bool PluginManager::UnregisterPlugin( 1083 TraceCreateInstanceFromBundle create_callback_from_bundle) { 1084 return GetTracePluginInstances().UnregisterPlugin( 1085 create_callback_from_bundle); 1086 } 1087 1088 TraceCreateInstanceFromBundle 1089 PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) { 1090 return GetTracePluginInstances().GetCallbackForName(plugin_name); 1091 } 1092 1093 TraceCreateInstanceForLiveProcess 1094 PluginManager::GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name) { 1095 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) 1096 if (instance.name == plugin_name) 1097 return instance.create_callback_for_live_process; 1098 return nullptr; 1099 } 1100 1101 llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) { 1102 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) 1103 if (instance.name == plugin_name) 1104 return instance.schema; 1105 return llvm::StringRef(); 1106 } 1107 1108 llvm::StringRef PluginManager::GetTraceSchema(size_t index) { 1109 if (TraceInstance *instance = 1110 GetTracePluginInstances().GetInstanceAtIndex(index)) 1111 return instance->schema; 1112 return llvm::StringRef(); 1113 } 1114 1115 #pragma mark TraceExporter 1116 1117 struct TraceExporterInstance 1118 : public PluginInstance<TraceExporterCreateInstance> { 1119 TraceExporterInstance( 1120 llvm::StringRef name, llvm::StringRef description, 1121 TraceExporterCreateInstance create_instance, 1122 ThreadTraceExportCommandCreator create_thread_trace_export_command) 1123 : PluginInstance<TraceExporterCreateInstance>(name, description, 1124 create_instance), 1125 create_thread_trace_export_command(create_thread_trace_export_command) { 1126 } 1127 1128 ThreadTraceExportCommandCreator create_thread_trace_export_command; 1129 }; 1130 1131 typedef PluginInstances<TraceExporterInstance> TraceExporterInstances; 1132 1133 static TraceExporterInstances &GetTraceExporterInstances() { 1134 static TraceExporterInstances g_instances; 1135 return g_instances; 1136 } 1137 1138 bool PluginManager::RegisterPlugin( 1139 llvm::StringRef name, llvm::StringRef description, 1140 TraceExporterCreateInstance create_callback, 1141 ThreadTraceExportCommandCreator create_thread_trace_export_command) { 1142 return GetTraceExporterInstances().RegisterPlugin( 1143 name, description, create_callback, create_thread_trace_export_command); 1144 } 1145 1146 TraceExporterCreateInstance 1147 PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) { 1148 return GetTraceExporterInstances().GetCallbackForName(plugin_name); 1149 } 1150 1151 bool PluginManager::UnregisterPlugin( 1152 TraceExporterCreateInstance create_callback) { 1153 return GetTraceExporterInstances().UnregisterPlugin(create_callback); 1154 } 1155 1156 ThreadTraceExportCommandCreator 1157 PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) { 1158 if (TraceExporterInstance *instance = 1159 GetTraceExporterInstances().GetInstanceAtIndex(index)) 1160 return instance->create_thread_trace_export_command; 1161 return nullptr; 1162 } 1163 1164 llvm::StringRef 1165 PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) { 1166 return GetTraceExporterInstances().GetNameAtIndex(index); 1167 } 1168 1169 #pragma mark UnwindAssembly 1170 1171 typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance; 1172 typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances; 1173 1174 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { 1175 static UnwindAssemblyInstances g_instances; 1176 return g_instances; 1177 } 1178 1179 bool PluginManager::RegisterPlugin( 1180 llvm::StringRef name, llvm::StringRef description, 1181 UnwindAssemblyCreateInstance create_callback) { 1182 return GetUnwindAssemblyInstances().RegisterPlugin(name, description, 1183 create_callback); 1184 } 1185 1186 bool PluginManager::UnregisterPlugin( 1187 UnwindAssemblyCreateInstance create_callback) { 1188 return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback); 1189 } 1190 1191 UnwindAssemblyCreateInstance 1192 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) { 1193 return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx); 1194 } 1195 1196 #pragma mark MemoryHistory 1197 1198 typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance; 1199 typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances; 1200 1201 static MemoryHistoryInstances &GetMemoryHistoryInstances() { 1202 static MemoryHistoryInstances g_instances; 1203 return g_instances; 1204 } 1205 1206 bool PluginManager::RegisterPlugin( 1207 llvm::StringRef name, llvm::StringRef description, 1208 MemoryHistoryCreateInstance create_callback) { 1209 return GetMemoryHistoryInstances().RegisterPlugin(name, description, 1210 create_callback); 1211 } 1212 1213 bool PluginManager::UnregisterPlugin( 1214 MemoryHistoryCreateInstance create_callback) { 1215 return GetMemoryHistoryInstances().UnregisterPlugin(create_callback); 1216 } 1217 1218 MemoryHistoryCreateInstance 1219 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { 1220 return GetMemoryHistoryInstances().GetCallbackAtIndex(idx); 1221 } 1222 1223 #pragma mark InstrumentationRuntime 1224 1225 struct InstrumentationRuntimeInstance 1226 : public PluginInstance<InstrumentationRuntimeCreateInstance> { 1227 InstrumentationRuntimeInstance( 1228 llvm::StringRef name, llvm::StringRef description, 1229 CallbackType create_callback, 1230 InstrumentationRuntimeGetType get_type_callback) 1231 : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description, 1232 create_callback), 1233 get_type_callback(get_type_callback) {} 1234 1235 InstrumentationRuntimeGetType get_type_callback = nullptr; 1236 }; 1237 1238 typedef PluginInstances<InstrumentationRuntimeInstance> 1239 InstrumentationRuntimeInstances; 1240 1241 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { 1242 static InstrumentationRuntimeInstances g_instances; 1243 return g_instances; 1244 } 1245 1246 bool PluginManager::RegisterPlugin( 1247 llvm::StringRef name, llvm::StringRef description, 1248 InstrumentationRuntimeCreateInstance create_callback, 1249 InstrumentationRuntimeGetType get_type_callback) { 1250 return GetInstrumentationRuntimeInstances().RegisterPlugin( 1251 name, description, create_callback, get_type_callback); 1252 } 1253 1254 bool PluginManager::UnregisterPlugin( 1255 InstrumentationRuntimeCreateInstance create_callback) { 1256 return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback); 1257 } 1258 1259 InstrumentationRuntimeGetType 1260 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { 1261 const auto &instances = GetInstrumentationRuntimeInstances().GetInstances(); 1262 if (idx < instances.size()) 1263 return instances[idx].get_type_callback; 1264 return nullptr; 1265 } 1266 1267 InstrumentationRuntimeCreateInstance 1268 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { 1269 return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx); 1270 } 1271 1272 #pragma mark TypeSystem 1273 1274 struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> { 1275 TypeSystemInstance(llvm::StringRef name, llvm::StringRef description, 1276 CallbackType create_callback, 1277 LanguageSet supported_languages_for_types, 1278 LanguageSet supported_languages_for_expressions) 1279 : PluginInstance<TypeSystemCreateInstance>(name, description, 1280 create_callback), 1281 supported_languages_for_types(supported_languages_for_types), 1282 supported_languages_for_expressions( 1283 supported_languages_for_expressions) {} 1284 1285 LanguageSet supported_languages_for_types; 1286 LanguageSet supported_languages_for_expressions; 1287 }; 1288 1289 typedef PluginInstances<TypeSystemInstance> TypeSystemInstances; 1290 1291 static TypeSystemInstances &GetTypeSystemInstances() { 1292 static TypeSystemInstances g_instances; 1293 return g_instances; 1294 } 1295 1296 bool PluginManager::RegisterPlugin( 1297 llvm::StringRef name, llvm::StringRef description, 1298 TypeSystemCreateInstance create_callback, 1299 LanguageSet supported_languages_for_types, 1300 LanguageSet supported_languages_for_expressions) { 1301 return GetTypeSystemInstances().RegisterPlugin( 1302 name, description, create_callback, supported_languages_for_types, 1303 supported_languages_for_expressions); 1304 } 1305 1306 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) { 1307 return GetTypeSystemInstances().UnregisterPlugin(create_callback); 1308 } 1309 1310 TypeSystemCreateInstance 1311 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) { 1312 return GetTypeSystemInstances().GetCallbackAtIndex(idx); 1313 } 1314 1315 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() { 1316 const auto &instances = GetTypeSystemInstances().GetInstances(); 1317 LanguageSet all; 1318 for (unsigned i = 0; i < instances.size(); ++i) 1319 all.bitvector |= instances[i].supported_languages_for_types.bitvector; 1320 return all; 1321 } 1322 1323 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { 1324 const auto &instances = GetTypeSystemInstances().GetInstances(); 1325 LanguageSet all; 1326 for (unsigned i = 0; i < instances.size(); ++i) 1327 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector; 1328 return all; 1329 } 1330 1331 #pragma mark REPL 1332 1333 struct REPLInstance : public PluginInstance<REPLCreateInstance> { 1334 REPLInstance(llvm::StringRef name, llvm::StringRef description, 1335 CallbackType create_callback, LanguageSet supported_languages) 1336 : PluginInstance<REPLCreateInstance>(name, description, create_callback), 1337 supported_languages(supported_languages) {} 1338 1339 LanguageSet supported_languages; 1340 }; 1341 1342 typedef PluginInstances<REPLInstance> REPLInstances; 1343 1344 static REPLInstances &GetREPLInstances() { 1345 static REPLInstances g_instances; 1346 return g_instances; 1347 } 1348 1349 bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description, 1350 REPLCreateInstance create_callback, 1351 LanguageSet supported_languages) { 1352 return GetREPLInstances().RegisterPlugin(name, description, create_callback, 1353 supported_languages); 1354 } 1355 1356 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) { 1357 return GetREPLInstances().UnregisterPlugin(create_callback); 1358 } 1359 1360 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) { 1361 return GetREPLInstances().GetCallbackAtIndex(idx); 1362 } 1363 1364 LanguageSet PluginManager::GetREPLSupportedLanguagesAtIndex(uint32_t idx) { 1365 const auto &instances = GetREPLInstances().GetInstances(); 1366 return idx < instances.size() ? instances[idx].supported_languages 1367 : LanguageSet(); 1368 } 1369 1370 LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() { 1371 const auto &instances = GetREPLInstances().GetInstances(); 1372 LanguageSet all; 1373 for (unsigned i = 0; i < instances.size(); ++i) 1374 all.bitvector |= instances[i].supported_languages.bitvector; 1375 return all; 1376 } 1377 1378 #pragma mark PluginManager 1379 1380 void PluginManager::DebuggerInitialize(Debugger &debugger) { 1381 GetDynamicLoaderInstances().PerformDebuggerCallback(debugger); 1382 GetJITLoaderInstances().PerformDebuggerCallback(debugger); 1383 GetObjectFileInstances().PerformDebuggerCallback(debugger); 1384 GetPlatformInstances().PerformDebuggerCallback(debugger); 1385 GetProcessInstances().PerformDebuggerCallback(debugger); 1386 GetSymbolFileInstances().PerformDebuggerCallback(debugger); 1387 GetOperatingSystemInstances().PerformDebuggerCallback(debugger); 1388 GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger); 1389 GetTracePluginInstances().PerformDebuggerCallback(debugger); 1390 } 1391 1392 // This is the preferred new way to register plugin specific settings. e.g. 1393 // This will put a plugin's settings under e.g. 1394 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 1395 static lldb::OptionValuePropertiesSP 1396 GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name, 1397 ConstString plugin_type_desc, bool can_create) { 1398 lldb::OptionValuePropertiesSP parent_properties_sp( 1399 debugger.GetValueProperties()); 1400 if (parent_properties_sp) { 1401 static ConstString g_property_name("plugin"); 1402 1403 OptionValuePropertiesSP plugin_properties_sp = 1404 parent_properties_sp->GetSubProperty(nullptr, g_property_name); 1405 if (!plugin_properties_sp && can_create) { 1406 plugin_properties_sp = 1407 std::make_shared<OptionValueProperties>(g_property_name); 1408 parent_properties_sp->AppendProperty( 1409 g_property_name, ConstString("Settings specify to plugins."), true, 1410 plugin_properties_sp); 1411 } 1412 1413 if (plugin_properties_sp) { 1414 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 1415 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name); 1416 if (!plugin_type_properties_sp && can_create) { 1417 plugin_type_properties_sp = 1418 std::make_shared<OptionValueProperties>(plugin_type_name); 1419 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 1420 true, plugin_type_properties_sp); 1421 } 1422 return plugin_type_properties_sp; 1423 } 1424 } 1425 return lldb::OptionValuePropertiesSP(); 1426 } 1427 1428 // This is deprecated way to register plugin specific settings. e.g. 1429 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform 1430 // generic settings would be under "platform.SETTINGNAME". 1431 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( 1432 Debugger &debugger, ConstString plugin_type_name, 1433 ConstString plugin_type_desc, bool can_create) { 1434 static ConstString g_property_name("plugin"); 1435 lldb::OptionValuePropertiesSP parent_properties_sp( 1436 debugger.GetValueProperties()); 1437 if (parent_properties_sp) { 1438 OptionValuePropertiesSP plugin_properties_sp = 1439 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name); 1440 if (!plugin_properties_sp && can_create) { 1441 plugin_properties_sp = 1442 std::make_shared<OptionValueProperties>(plugin_type_name); 1443 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 1444 true, plugin_properties_sp); 1445 } 1446 1447 if (plugin_properties_sp) { 1448 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 1449 plugin_properties_sp->GetSubProperty(nullptr, g_property_name); 1450 if (!plugin_type_properties_sp && can_create) { 1451 plugin_type_properties_sp = 1452 std::make_shared<OptionValueProperties>(g_property_name); 1453 plugin_properties_sp->AppendProperty( 1454 g_property_name, ConstString("Settings specific to plugins"), true, 1455 plugin_type_properties_sp); 1456 } 1457 return plugin_type_properties_sp; 1458 } 1459 } 1460 return lldb::OptionValuePropertiesSP(); 1461 } 1462 1463 namespace { 1464 1465 typedef lldb::OptionValuePropertiesSP 1466 GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString, 1467 bool can_create); 1468 } 1469 1470 static lldb::OptionValuePropertiesSP 1471 GetSettingForPlugin(Debugger &debugger, ConstString setting_name, 1472 ConstString plugin_type_name, 1473 GetDebuggerPropertyForPluginsPtr get_debugger_property = 1474 GetDebuggerPropertyForPlugins) { 1475 lldb::OptionValuePropertiesSP properties_sp; 1476 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property( 1477 debugger, plugin_type_name, 1478 ConstString(), // not creating to so we don't need the description 1479 false)); 1480 if (plugin_type_properties_sp) 1481 properties_sp = 1482 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 1483 return properties_sp; 1484 } 1485 1486 static bool 1487 CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name, 1488 ConstString plugin_type_desc, 1489 const lldb::OptionValuePropertiesSP &properties_sp, 1490 ConstString description, bool is_global_property, 1491 GetDebuggerPropertyForPluginsPtr get_debugger_property = 1492 GetDebuggerPropertyForPlugins) { 1493 if (properties_sp) { 1494 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 1495 get_debugger_property(debugger, plugin_type_name, plugin_type_desc, 1496 true)); 1497 if (plugin_type_properties_sp) { 1498 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 1499 description, is_global_property, 1500 properties_sp); 1501 return true; 1502 } 1503 } 1504 return false; 1505 } 1506 1507 static const char *kDynamicLoaderPluginName("dynamic-loader"); 1508 static const char *kPlatformPluginName("platform"); 1509 static const char *kProcessPluginName("process"); 1510 static const char *kTracePluginName("trace"); 1511 static const char *kObjectFilePluginName("object-file"); 1512 static const char *kSymbolFilePluginName("symbol-file"); 1513 static const char *kJITLoaderPluginName("jit-loader"); 1514 static const char *kStructuredDataPluginName("structured-data"); 1515 1516 lldb::OptionValuePropertiesSP 1517 PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger, 1518 ConstString setting_name) { 1519 return GetSettingForPlugin(debugger, setting_name, 1520 ConstString(kDynamicLoaderPluginName)); 1521 } 1522 1523 bool PluginManager::CreateSettingForDynamicLoaderPlugin( 1524 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1525 ConstString description, bool is_global_property) { 1526 return CreateSettingForPlugin( 1527 debugger, ConstString(kDynamicLoaderPluginName), 1528 ConstString("Settings for dynamic loader plug-ins"), properties_sp, 1529 description, is_global_property); 1530 } 1531 1532 lldb::OptionValuePropertiesSP 1533 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger, 1534 ConstString setting_name) { 1535 return GetSettingForPlugin(debugger, setting_name, 1536 ConstString(kPlatformPluginName), 1537 GetDebuggerPropertyForPluginsOldStyle); 1538 } 1539 1540 bool PluginManager::CreateSettingForPlatformPlugin( 1541 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1542 ConstString description, bool is_global_property) { 1543 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName), 1544 ConstString("Settings for platform plug-ins"), 1545 properties_sp, description, is_global_property, 1546 GetDebuggerPropertyForPluginsOldStyle); 1547 } 1548 1549 lldb::OptionValuePropertiesSP 1550 PluginManager::GetSettingForProcessPlugin(Debugger &debugger, 1551 ConstString setting_name) { 1552 return GetSettingForPlugin(debugger, setting_name, 1553 ConstString(kProcessPluginName)); 1554 } 1555 1556 bool PluginManager::CreateSettingForProcessPlugin( 1557 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1558 ConstString description, bool is_global_property) { 1559 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName), 1560 ConstString("Settings for process plug-ins"), 1561 properties_sp, description, is_global_property); 1562 } 1563 1564 bool PluginManager::CreateSettingForTracePlugin( 1565 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1566 ConstString description, bool is_global_property) { 1567 return CreateSettingForPlugin(debugger, ConstString(kTracePluginName), 1568 ConstString("Settings for trace plug-ins"), 1569 properties_sp, description, is_global_property); 1570 } 1571 1572 lldb::OptionValuePropertiesSP 1573 PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger, 1574 ConstString setting_name) { 1575 return GetSettingForPlugin(debugger, setting_name, 1576 ConstString(kObjectFilePluginName)); 1577 } 1578 1579 bool PluginManager::CreateSettingForObjectFilePlugin( 1580 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1581 ConstString description, bool is_global_property) { 1582 return CreateSettingForPlugin( 1583 debugger, ConstString(kObjectFilePluginName), 1584 ConstString("Settings for object file plug-ins"), properties_sp, 1585 description, is_global_property); 1586 } 1587 1588 lldb::OptionValuePropertiesSP 1589 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger, 1590 ConstString setting_name) { 1591 return GetSettingForPlugin(debugger, setting_name, 1592 ConstString(kSymbolFilePluginName)); 1593 } 1594 1595 bool PluginManager::CreateSettingForSymbolFilePlugin( 1596 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1597 ConstString description, bool is_global_property) { 1598 return CreateSettingForPlugin( 1599 debugger, ConstString(kSymbolFilePluginName), 1600 ConstString("Settings for symbol file plug-ins"), properties_sp, 1601 description, is_global_property); 1602 } 1603 1604 lldb::OptionValuePropertiesSP 1605 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger, 1606 ConstString setting_name) { 1607 return GetSettingForPlugin(debugger, setting_name, 1608 ConstString(kJITLoaderPluginName)); 1609 } 1610 1611 bool PluginManager::CreateSettingForJITLoaderPlugin( 1612 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1613 ConstString description, bool is_global_property) { 1614 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName), 1615 ConstString("Settings for JIT loader plug-ins"), 1616 properties_sp, description, is_global_property); 1617 } 1618 1619 static const char *kOperatingSystemPluginName("os"); 1620 1621 lldb::OptionValuePropertiesSP 1622 PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, 1623 ConstString setting_name) { 1624 lldb::OptionValuePropertiesSP properties_sp; 1625 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 1626 GetDebuggerPropertyForPlugins( 1627 debugger, ConstString(kOperatingSystemPluginName), 1628 ConstString(), // not creating to so we don't need the description 1629 false)); 1630 if (plugin_type_properties_sp) 1631 properties_sp = 1632 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 1633 return properties_sp; 1634 } 1635 1636 bool PluginManager::CreateSettingForOperatingSystemPlugin( 1637 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1638 ConstString description, bool is_global_property) { 1639 if (properties_sp) { 1640 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 1641 GetDebuggerPropertyForPlugins( 1642 debugger, ConstString(kOperatingSystemPluginName), 1643 ConstString("Settings for operating system plug-ins"), true)); 1644 if (plugin_type_properties_sp) { 1645 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 1646 description, is_global_property, 1647 properties_sp); 1648 return true; 1649 } 1650 } 1651 return false; 1652 } 1653 1654 lldb::OptionValuePropertiesSP 1655 PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger, 1656 ConstString setting_name) { 1657 return GetSettingForPlugin(debugger, setting_name, 1658 ConstString(kStructuredDataPluginName)); 1659 } 1660 1661 bool PluginManager::CreateSettingForStructuredDataPlugin( 1662 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 1663 ConstString description, bool is_global_property) { 1664 return CreateSettingForPlugin( 1665 debugger, ConstString(kStructuredDataPluginName), 1666 ConstString("Settings for structured data plug-ins"), properties_sp, 1667 description, is_global_property); 1668 } 1669