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