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