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