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