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