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