1 //===-- PluginManager.cpp ---------------------------------------*- C++ -*-===// 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 20 #if defined(_WIN32) 21 #include "lldb/Host/windows/PosixApi.h" 22 #endif 23 24 #include "llvm/ADT/StringRef.h" 25 #include "llvm/Support/DynamicLibrary.h" 26 #include "llvm/Support/FileSystem.h" 27 #include "llvm/Support/raw_ostream.h" 28 29 #include <map> 30 #include <memory> 31 #include <mutex> 32 #include <string> 33 #include <utility> 34 #include <vector> 35 36 #include <assert.h> 37 38 namespace lldb_private { 39 class CommandInterpreter; 40 } 41 42 using namespace lldb; 43 using namespace lldb_private; 44 45 enum PluginAction { 46 ePluginRegisterInstance, 47 ePluginUnregisterInstance, 48 ePluginGetInstanceAtIndex 49 }; 50 51 typedef bool (*PluginInitCallback)(); 52 typedef void (*PluginTermCallback)(); 53 54 struct PluginInfo { 55 PluginInfo() : plugin_init_callback(nullptr), plugin_term_callback(nullptr) {} 56 57 llvm::sys::DynamicLibrary library; 58 PluginInitCallback plugin_init_callback; 59 PluginTermCallback plugin_term_callback; 60 }; 61 62 typedef std::map<FileSpec, PluginInfo> PluginTerminateMap; 63 64 static std::recursive_mutex &GetPluginMapMutex() { 65 static std::recursive_mutex g_plugin_map_mutex; 66 return g_plugin_map_mutex; 67 } 68 69 static PluginTerminateMap &GetPluginMap() { 70 static PluginTerminateMap g_plugin_map; 71 return g_plugin_map; 72 } 73 74 static bool PluginIsLoaded(const FileSpec &plugin_file_spec) { 75 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex()); 76 PluginTerminateMap &plugin_map = GetPluginMap(); 77 return plugin_map.find(plugin_file_spec) != plugin_map.end(); 78 } 79 80 static void SetPluginInfo(const FileSpec &plugin_file_spec, 81 const PluginInfo &plugin_info) { 82 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex()); 83 PluginTerminateMap &plugin_map = GetPluginMap(); 84 assert(plugin_map.find(plugin_file_spec) == plugin_map.end()); 85 plugin_map[plugin_file_spec] = plugin_info; 86 } 87 88 template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) { 89 return reinterpret_cast<FPtrTy>(VPtr); 90 } 91 92 static FileSystem::EnumerateDirectoryResult 93 LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, 94 llvm::StringRef path) { 95 // PluginManager *plugin_manager = (PluginManager *)baton; 96 Status error; 97 98 namespace fs = llvm::sys::fs; 99 // If we have a regular file, a symbolic link or unknown file type, try and 100 // process the file. We must handle unknown as sometimes the directory 101 // enumeration might be enumerating a file system that doesn't have correct 102 // file type information. 103 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file || 104 ft == fs::file_type::type_unknown) { 105 FileSpec plugin_file_spec(path); 106 FileSystem::Instance().Resolve(plugin_file_spec); 107 108 if (PluginIsLoaded(plugin_file_spec)) 109 return FileSystem::eEnumerateDirectoryResultNext; 110 else { 111 PluginInfo plugin_info; 112 113 std::string pluginLoadError; 114 plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary( 115 plugin_file_spec.GetPath().c_str(), &pluginLoadError); 116 if (plugin_info.library.isValid()) { 117 bool success = false; 118 plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>( 119 plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize")); 120 if (plugin_info.plugin_init_callback) { 121 // Call the plug-in "bool LLDBPluginInitialize(void)" function 122 success = plugin_info.plugin_init_callback(); 123 } 124 125 if (success) { 126 // It is ok for the "LLDBPluginTerminate" symbol to be nullptr 127 plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>( 128 plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate")); 129 } else { 130 // The initialize function returned FALSE which means the plug-in 131 // might not be compatible, or might be too new or too old, or might 132 // not want to run on this machine. Set it to a default-constructed 133 // instance to invalidate it. 134 plugin_info = PluginInfo(); 135 } 136 137 // Regardless of success or failure, cache the plug-in load in our 138 // plug-in info so we don't try to load it again and again. 139 SetPluginInfo(plugin_file_spec, plugin_info); 140 141 return FileSystem::eEnumerateDirectoryResultNext; 142 } 143 } 144 } 145 146 if (ft == fs::file_type::directory_file || 147 ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) { 148 // Try and recurse into anything that a directory or symbolic link. We must 149 // also do this for unknown as sometimes the directory enumeration might be 150 // enumerating a file system that doesn't have correct file type 151 // information. 152 return FileSystem::eEnumerateDirectoryResultEnter; 153 } 154 155 return FileSystem::eEnumerateDirectoryResultNext; 156 } 157 158 void PluginManager::Initialize() { 159 #if 1 160 const bool find_directories = true; 161 const bool find_files = true; 162 const bool find_other = true; 163 char dir_path[PATH_MAX]; 164 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) { 165 if (FileSystem::Instance().Exists(dir_spec) && 166 dir_spec.GetPath(dir_path, sizeof(dir_path))) { 167 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, 168 find_files, find_other, 169 LoadPluginCallback, nullptr); 170 } 171 } 172 173 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) { 174 if (FileSystem::Instance().Exists(dir_spec) && 175 dir_spec.GetPath(dir_path, sizeof(dir_path))) { 176 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, 177 find_files, find_other, 178 LoadPluginCallback, nullptr); 179 } 180 } 181 #endif 182 } 183 184 void PluginManager::Terminate() { 185 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex()); 186 PluginTerminateMap &plugin_map = GetPluginMap(); 187 188 PluginTerminateMap::const_iterator pos, end = plugin_map.end(); 189 for (pos = plugin_map.begin(); pos != end; ++pos) { 190 // Call the plug-in "void LLDBPluginTerminate (void)" function if there is 191 // one (if the symbol was not nullptr). 192 if (pos->second.library.isValid()) { 193 if (pos->second.plugin_term_callback) 194 pos->second.plugin_term_callback(); 195 } 196 } 197 plugin_map.clear(); 198 } 199 200 #pragma mark ABI 201 202 struct ABIInstance { 203 ABIInstance() : name(), description(), create_callback(nullptr) {} 204 205 ConstString name; 206 std::string description; 207 ABICreateInstance create_callback; 208 }; 209 210 typedef std::vector<ABIInstance> ABIInstances; 211 212 static std::recursive_mutex &GetABIInstancesMutex() { 213 static std::recursive_mutex g_instances_mutex; 214 return g_instances_mutex; 215 } 216 217 static ABIInstances &GetABIInstances() { 218 static ABIInstances g_instances; 219 return g_instances; 220 } 221 222 bool PluginManager::RegisterPlugin(ConstString name, 223 const char *description, 224 ABICreateInstance create_callback) { 225 if (create_callback) { 226 ABIInstance instance; 227 assert((bool)name); 228 instance.name = name; 229 if (description && description[0]) 230 instance.description = description; 231 instance.create_callback = create_callback; 232 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex()); 233 GetABIInstances().push_back(instance); 234 return true; 235 } 236 return false; 237 } 238 239 bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) { 240 if (create_callback) { 241 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex()); 242 ABIInstances &instances = GetABIInstances(); 243 244 ABIInstances::iterator pos, end = instances.end(); 245 for (pos = instances.begin(); pos != end; ++pos) { 246 if (pos->create_callback == create_callback) { 247 instances.erase(pos); 248 return true; 249 } 250 } 251 } 252 return false; 253 } 254 255 ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) { 256 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex()); 257 ABIInstances &instances = GetABIInstances(); 258 if (idx < instances.size()) 259 return instances[idx].create_callback; 260 return nullptr; 261 } 262 263 ABICreateInstance 264 PluginManager::GetABICreateCallbackForPluginName(ConstString name) { 265 if (name) { 266 std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex()); 267 ABIInstances &instances = GetABIInstances(); 268 269 ABIInstances::iterator pos, end = instances.end(); 270 for (pos = instances.begin(); pos != end; ++pos) { 271 if (name == pos->name) 272 return pos->create_callback; 273 } 274 } 275 return nullptr; 276 } 277 278 #pragma mark Architecture 279 280 struct ArchitectureInstance { 281 ConstString name; 282 std::string description; 283 PluginManager::ArchitectureCreateInstance create_callback; 284 }; 285 286 typedef std::vector<ArchitectureInstance> ArchitectureInstances; 287 288 static std::mutex &GetArchitectureMutex() { 289 static std::mutex g_architecture_mutex; 290 return g_architecture_mutex; 291 } 292 293 static ArchitectureInstances &GetArchitectureInstances() { 294 static ArchitectureInstances g_instances; 295 return g_instances; 296 } 297 298 void PluginManager::RegisterPlugin(ConstString name, 299 llvm::StringRef description, 300 ArchitectureCreateInstance create_callback) { 301 std::lock_guard<std::mutex> guard(GetArchitectureMutex()); 302 GetArchitectureInstances().push_back({name, description, create_callback}); 303 } 304 305 void PluginManager::UnregisterPlugin( 306 ArchitectureCreateInstance create_callback) { 307 std::lock_guard<std::mutex> guard(GetArchitectureMutex()); 308 auto &instances = GetArchitectureInstances(); 309 310 for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) { 311 if (pos->create_callback == create_callback) { 312 instances.erase(pos); 313 return; 314 } 315 } 316 llvm_unreachable("Plugin not found"); 317 } 318 319 std::unique_ptr<Architecture> 320 PluginManager::CreateArchitectureInstance(const ArchSpec &arch) { 321 std::lock_guard<std::mutex> guard(GetArchitectureMutex()); 322 for (const auto &instances : GetArchitectureInstances()) { 323 if (auto plugin_up = instances.create_callback(arch)) 324 return plugin_up; 325 } 326 return nullptr; 327 } 328 329 #pragma mark Disassembler 330 331 struct DisassemblerInstance { 332 DisassemblerInstance() : name(), description(), create_callback(nullptr) {} 333 334 ConstString name; 335 std::string description; 336 DisassemblerCreateInstance create_callback; 337 }; 338 339 typedef std::vector<DisassemblerInstance> DisassemblerInstances; 340 341 static std::recursive_mutex &GetDisassemblerMutex() { 342 static std::recursive_mutex g_instances_mutex; 343 return g_instances_mutex; 344 } 345 346 static DisassemblerInstances &GetDisassemblerInstances() { 347 static DisassemblerInstances g_instances; 348 return g_instances; 349 } 350 351 bool PluginManager::RegisterPlugin(ConstString name, 352 const char *description, 353 DisassemblerCreateInstance create_callback) { 354 if (create_callback) { 355 DisassemblerInstance instance; 356 assert((bool)name); 357 instance.name = name; 358 if (description && description[0]) 359 instance.description = description; 360 instance.create_callback = create_callback; 361 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex()); 362 GetDisassemblerInstances().push_back(instance); 363 return true; 364 } 365 return false; 366 } 367 368 bool PluginManager::UnregisterPlugin( 369 DisassemblerCreateInstance create_callback) { 370 if (create_callback) { 371 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex()); 372 DisassemblerInstances &instances = GetDisassemblerInstances(); 373 374 DisassemblerInstances::iterator pos, end = instances.end(); 375 for (pos = instances.begin(); pos != end; ++pos) { 376 if (pos->create_callback == create_callback) { 377 instances.erase(pos); 378 return true; 379 } 380 } 381 } 382 return false; 383 } 384 385 DisassemblerCreateInstance 386 PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) { 387 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex()); 388 DisassemblerInstances &instances = GetDisassemblerInstances(); 389 if (idx < instances.size()) 390 return instances[idx].create_callback; 391 return nullptr; 392 } 393 394 DisassemblerCreateInstance 395 PluginManager::GetDisassemblerCreateCallbackForPluginName( 396 ConstString name) { 397 if (name) { 398 std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex()); 399 DisassemblerInstances &instances = GetDisassemblerInstances(); 400 401 DisassemblerInstances::iterator pos, end = instances.end(); 402 for (pos = instances.begin(); pos != end; ++pos) { 403 if (name == pos->name) 404 return pos->create_callback; 405 } 406 } 407 return nullptr; 408 } 409 410 #pragma mark DynamicLoader 411 412 struct DynamicLoaderInstance { 413 DynamicLoaderInstance() 414 : name(), description(), create_callback(nullptr), 415 debugger_init_callback(nullptr) {} 416 417 ConstString name; 418 std::string description; 419 DynamicLoaderCreateInstance create_callback; 420 DebuggerInitializeCallback debugger_init_callback; 421 }; 422 423 typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances; 424 425 static std::recursive_mutex &GetDynamicLoaderMutex() { 426 static std::recursive_mutex g_instances_mutex; 427 return g_instances_mutex; 428 } 429 430 static DynamicLoaderInstances &GetDynamicLoaderInstances() { 431 static DynamicLoaderInstances g_instances; 432 return g_instances; 433 } 434 435 bool PluginManager::RegisterPlugin( 436 ConstString name, const char *description, 437 DynamicLoaderCreateInstance create_callback, 438 DebuggerInitializeCallback debugger_init_callback) { 439 if (create_callback) { 440 DynamicLoaderInstance instance; 441 assert((bool)name); 442 instance.name = name; 443 if (description && description[0]) 444 instance.description = description; 445 instance.create_callback = create_callback; 446 instance.debugger_init_callback = debugger_init_callback; 447 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); 448 GetDynamicLoaderInstances().push_back(instance); 449 } 450 return false; 451 } 452 453 bool PluginManager::UnregisterPlugin( 454 DynamicLoaderCreateInstance create_callback) { 455 if (create_callback) { 456 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); 457 DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); 458 459 DynamicLoaderInstances::iterator pos, end = instances.end(); 460 for (pos = instances.begin(); pos != end; ++pos) { 461 if (pos->create_callback == create_callback) { 462 instances.erase(pos); 463 return true; 464 } 465 } 466 } 467 return false; 468 } 469 470 DynamicLoaderCreateInstance 471 PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) { 472 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); 473 DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); 474 if (idx < instances.size()) 475 return instances[idx].create_callback; 476 return nullptr; 477 } 478 479 DynamicLoaderCreateInstance 480 PluginManager::GetDynamicLoaderCreateCallbackForPluginName( 481 ConstString name) { 482 if (name) { 483 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); 484 DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); 485 486 DynamicLoaderInstances::iterator pos, end = instances.end(); 487 for (pos = instances.begin(); pos != end; ++pos) { 488 if (name == pos->name) 489 return pos->create_callback; 490 } 491 } 492 return nullptr; 493 } 494 495 #pragma mark JITLoader 496 497 struct JITLoaderInstance { 498 JITLoaderInstance() 499 : name(), description(), create_callback(nullptr), 500 debugger_init_callback(nullptr) {} 501 502 ConstString name; 503 std::string description; 504 JITLoaderCreateInstance create_callback; 505 DebuggerInitializeCallback debugger_init_callback; 506 }; 507 508 typedef std::vector<JITLoaderInstance> JITLoaderInstances; 509 510 static std::recursive_mutex &GetJITLoaderMutex() { 511 static std::recursive_mutex g_instances_mutex; 512 return g_instances_mutex; 513 } 514 515 static JITLoaderInstances &GetJITLoaderInstances() { 516 static JITLoaderInstances g_instances; 517 return g_instances; 518 } 519 520 bool PluginManager::RegisterPlugin( 521 ConstString name, const char *description, 522 JITLoaderCreateInstance create_callback, 523 DebuggerInitializeCallback debugger_init_callback) { 524 if (create_callback) { 525 JITLoaderInstance instance; 526 assert((bool)name); 527 instance.name = name; 528 if (description && description[0]) 529 instance.description = description; 530 instance.create_callback = create_callback; 531 instance.debugger_init_callback = debugger_init_callback; 532 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); 533 GetJITLoaderInstances().push_back(instance); 534 } 535 return false; 536 } 537 538 bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) { 539 if (create_callback) { 540 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); 541 JITLoaderInstances &instances = GetJITLoaderInstances(); 542 543 JITLoaderInstances::iterator pos, end = instances.end(); 544 for (pos = instances.begin(); pos != end; ++pos) { 545 if (pos->create_callback == create_callback) { 546 instances.erase(pos); 547 return true; 548 } 549 } 550 } 551 return false; 552 } 553 554 JITLoaderCreateInstance 555 PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) { 556 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); 557 JITLoaderInstances &instances = GetJITLoaderInstances(); 558 if (idx < instances.size()) 559 return instances[idx].create_callback; 560 return nullptr; 561 } 562 563 JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName( 564 ConstString name) { 565 if (name) { 566 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); 567 JITLoaderInstances &instances = GetJITLoaderInstances(); 568 569 JITLoaderInstances::iterator pos, end = instances.end(); 570 for (pos = instances.begin(); pos != end; ++pos) { 571 if (name == pos->name) 572 return pos->create_callback; 573 } 574 } 575 return nullptr; 576 } 577 578 #pragma mark EmulateInstruction 579 580 struct EmulateInstructionInstance { 581 EmulateInstructionInstance() 582 : name(), description(), create_callback(nullptr) {} 583 584 ConstString name; 585 std::string description; 586 EmulateInstructionCreateInstance create_callback; 587 }; 588 589 typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances; 590 591 static std::recursive_mutex &GetEmulateInstructionMutex() { 592 static std::recursive_mutex g_instances_mutex; 593 return g_instances_mutex; 594 } 595 596 static EmulateInstructionInstances &GetEmulateInstructionInstances() { 597 static EmulateInstructionInstances g_instances; 598 return g_instances; 599 } 600 601 bool PluginManager::RegisterPlugin( 602 ConstString name, const char *description, 603 EmulateInstructionCreateInstance create_callback) { 604 if (create_callback) { 605 EmulateInstructionInstance instance; 606 assert((bool)name); 607 instance.name = name; 608 if (description && description[0]) 609 instance.description = description; 610 instance.create_callback = create_callback; 611 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex()); 612 GetEmulateInstructionInstances().push_back(instance); 613 } 614 return false; 615 } 616 617 bool PluginManager::UnregisterPlugin( 618 EmulateInstructionCreateInstance create_callback) { 619 if (create_callback) { 620 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex()); 621 EmulateInstructionInstances &instances = GetEmulateInstructionInstances(); 622 623 EmulateInstructionInstances::iterator pos, end = instances.end(); 624 for (pos = instances.begin(); pos != end; ++pos) { 625 if (pos->create_callback == create_callback) { 626 instances.erase(pos); 627 return true; 628 } 629 } 630 } 631 return false; 632 } 633 634 EmulateInstructionCreateInstance 635 PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) { 636 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex()); 637 EmulateInstructionInstances &instances = GetEmulateInstructionInstances(); 638 if (idx < instances.size()) 639 return instances[idx].create_callback; 640 return nullptr; 641 } 642 643 EmulateInstructionCreateInstance 644 PluginManager::GetEmulateInstructionCreateCallbackForPluginName( 645 ConstString name) { 646 if (name) { 647 std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex()); 648 EmulateInstructionInstances &instances = GetEmulateInstructionInstances(); 649 650 EmulateInstructionInstances::iterator pos, end = instances.end(); 651 for (pos = instances.begin(); pos != end; ++pos) { 652 if (name == pos->name) 653 return pos->create_callback; 654 } 655 } 656 return nullptr; 657 } 658 659 #pragma mark OperatingSystem 660 661 struct OperatingSystemInstance { 662 OperatingSystemInstance() 663 : name(), description(), create_callback(nullptr), 664 debugger_init_callback(nullptr) {} 665 666 ConstString name; 667 std::string description; 668 OperatingSystemCreateInstance create_callback; 669 DebuggerInitializeCallback debugger_init_callback; 670 }; 671 672 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances; 673 674 static std::recursive_mutex &GetOperatingSystemMutex() { 675 static std::recursive_mutex g_instances_mutex; 676 return g_instances_mutex; 677 } 678 679 static OperatingSystemInstances &GetOperatingSystemInstances() { 680 static OperatingSystemInstances g_instances; 681 return g_instances; 682 } 683 684 bool PluginManager::RegisterPlugin( 685 ConstString name, const char *description, 686 OperatingSystemCreateInstance create_callback, 687 DebuggerInitializeCallback debugger_init_callback) { 688 if (create_callback) { 689 OperatingSystemInstance instance; 690 assert((bool)name); 691 instance.name = name; 692 if (description && description[0]) 693 instance.description = description; 694 instance.create_callback = create_callback; 695 instance.debugger_init_callback = debugger_init_callback; 696 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); 697 GetOperatingSystemInstances().push_back(instance); 698 } 699 return false; 700 } 701 702 bool PluginManager::UnregisterPlugin( 703 OperatingSystemCreateInstance create_callback) { 704 if (create_callback) { 705 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); 706 OperatingSystemInstances &instances = GetOperatingSystemInstances(); 707 708 OperatingSystemInstances::iterator pos, end = instances.end(); 709 for (pos = instances.begin(); pos != end; ++pos) { 710 if (pos->create_callback == create_callback) { 711 instances.erase(pos); 712 return true; 713 } 714 } 715 } 716 return false; 717 } 718 719 OperatingSystemCreateInstance 720 PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) { 721 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); 722 OperatingSystemInstances &instances = GetOperatingSystemInstances(); 723 if (idx < instances.size()) 724 return instances[idx].create_callback; 725 return nullptr; 726 } 727 728 OperatingSystemCreateInstance 729 PluginManager::GetOperatingSystemCreateCallbackForPluginName( 730 ConstString name) { 731 if (name) { 732 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); 733 OperatingSystemInstances &instances = GetOperatingSystemInstances(); 734 735 OperatingSystemInstances::iterator pos, end = instances.end(); 736 for (pos = instances.begin(); pos != end; ++pos) { 737 if (name == pos->name) 738 return pos->create_callback; 739 } 740 } 741 return nullptr; 742 } 743 744 #pragma mark Language 745 746 struct LanguageInstance { 747 LanguageInstance() : name(), description(), create_callback(nullptr) {} 748 749 ConstString name; 750 std::string description; 751 LanguageCreateInstance create_callback; 752 }; 753 754 typedef std::vector<LanguageInstance> LanguageInstances; 755 756 static std::recursive_mutex &GetLanguageMutex() { 757 static std::recursive_mutex g_instances_mutex; 758 return g_instances_mutex; 759 } 760 761 static LanguageInstances &GetLanguageInstances() { 762 static LanguageInstances g_instances; 763 return g_instances; 764 } 765 766 bool PluginManager::RegisterPlugin(ConstString name, 767 const char *description, 768 LanguageCreateInstance create_callback) { 769 if (create_callback) { 770 LanguageInstance instance; 771 assert((bool)name); 772 instance.name = name; 773 if (description && description[0]) 774 instance.description = description; 775 instance.create_callback = create_callback; 776 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex()); 777 GetLanguageInstances().push_back(instance); 778 } 779 return false; 780 } 781 782 bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) { 783 if (create_callback) { 784 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex()); 785 LanguageInstances &instances = GetLanguageInstances(); 786 787 LanguageInstances::iterator pos, end = instances.end(); 788 for (pos = instances.begin(); pos != end; ++pos) { 789 if (pos->create_callback == create_callback) { 790 instances.erase(pos); 791 return true; 792 } 793 } 794 } 795 return false; 796 } 797 798 LanguageCreateInstance 799 PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) { 800 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex()); 801 LanguageInstances &instances = GetLanguageInstances(); 802 if (idx < instances.size()) 803 return instances[idx].create_callback; 804 return nullptr; 805 } 806 807 LanguageCreateInstance 808 PluginManager::GetLanguageCreateCallbackForPluginName(ConstString name) { 809 if (name) { 810 std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex()); 811 LanguageInstances &instances = GetLanguageInstances(); 812 813 LanguageInstances::iterator pos, end = instances.end(); 814 for (pos = instances.begin(); pos != end; ++pos) { 815 if (name == pos->name) 816 return pos->create_callback; 817 } 818 } 819 return nullptr; 820 } 821 822 #pragma mark LanguageRuntime 823 824 struct LanguageRuntimeInstance { 825 LanguageRuntimeInstance() : name(), description(), create_callback(nullptr) {} 826 827 ConstString name; 828 std::string description; 829 LanguageRuntimeCreateInstance create_callback; 830 LanguageRuntimeGetCommandObject command_callback; 831 LanguageRuntimeGetExceptionPrecondition precondition_callback; 832 }; 833 834 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances; 835 836 static std::recursive_mutex &GetLanguageRuntimeMutex() { 837 static std::recursive_mutex g_instances_mutex; 838 return g_instances_mutex; 839 } 840 841 static LanguageRuntimeInstances &GetLanguageRuntimeInstances() { 842 static LanguageRuntimeInstances g_instances; 843 return g_instances; 844 } 845 846 bool PluginManager::RegisterPlugin( 847 ConstString name, const char *description, 848 LanguageRuntimeCreateInstance create_callback, 849 LanguageRuntimeGetCommandObject command_callback, 850 LanguageRuntimeGetExceptionPrecondition precondition_callback) { 851 if (create_callback) { 852 LanguageRuntimeInstance instance; 853 assert((bool)name); 854 instance.name = name; 855 if (description && description[0]) 856 instance.description = description; 857 instance.create_callback = create_callback; 858 instance.command_callback = command_callback; 859 instance.precondition_callback = precondition_callback; 860 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 861 GetLanguageRuntimeInstances().push_back(instance); 862 } 863 return false; 864 } 865 866 bool PluginManager::UnregisterPlugin( 867 LanguageRuntimeCreateInstance create_callback) { 868 if (create_callback) { 869 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 870 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); 871 872 LanguageRuntimeInstances::iterator pos, end = instances.end(); 873 for (pos = instances.begin(); pos != end; ++pos) { 874 if (pos->create_callback == create_callback) { 875 instances.erase(pos); 876 return true; 877 } 878 } 879 } 880 return false; 881 } 882 883 LanguageRuntimeCreateInstance 884 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) { 885 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 886 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); 887 if (idx < instances.size()) 888 return instances[idx].create_callback; 889 return nullptr; 890 } 891 892 LanguageRuntimeGetCommandObject 893 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) { 894 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 895 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); 896 if (idx < instances.size()) 897 return instances[idx].command_callback; 898 return nullptr; 899 } 900 901 LanguageRuntimeGetExceptionPrecondition 902 PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) { 903 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 904 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); 905 if (idx < instances.size()) 906 return instances[idx].precondition_callback; 907 return nullptr; 908 } 909 910 LanguageRuntimeCreateInstance 911 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName( 912 ConstString name) { 913 if (name) { 914 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 915 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); 916 917 LanguageRuntimeInstances::iterator pos, end = instances.end(); 918 for (pos = instances.begin(); pos != end; ++pos) { 919 if (name == pos->name) 920 return pos->create_callback; 921 } 922 } 923 return nullptr; 924 } 925 926 #pragma mark SystemRuntime 927 928 struct SystemRuntimeInstance { 929 SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {} 930 931 ConstString name; 932 std::string description; 933 SystemRuntimeCreateInstance create_callback; 934 }; 935 936 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances; 937 938 static std::recursive_mutex &GetSystemRuntimeMutex() { 939 static std::recursive_mutex g_instances_mutex; 940 return g_instances_mutex; 941 } 942 943 static SystemRuntimeInstances &GetSystemRuntimeInstances() { 944 static SystemRuntimeInstances g_instances; 945 return g_instances; 946 } 947 948 bool PluginManager::RegisterPlugin( 949 ConstString name, const char *description, 950 SystemRuntimeCreateInstance create_callback) { 951 if (create_callback) { 952 SystemRuntimeInstance instance; 953 assert((bool)name); 954 instance.name = name; 955 if (description && description[0]) 956 instance.description = description; 957 instance.create_callback = create_callback; 958 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); 959 GetSystemRuntimeInstances().push_back(instance); 960 } 961 return false; 962 } 963 964 bool PluginManager::UnregisterPlugin( 965 SystemRuntimeCreateInstance create_callback) { 966 if (create_callback) { 967 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); 968 SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); 969 970 SystemRuntimeInstances::iterator pos, end = instances.end(); 971 for (pos = instances.begin(); pos != end; ++pos) { 972 if (pos->create_callback == create_callback) { 973 instances.erase(pos); 974 return true; 975 } 976 } 977 } 978 return false; 979 } 980 981 SystemRuntimeCreateInstance 982 PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) { 983 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); 984 SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); 985 if (idx < instances.size()) 986 return instances[idx].create_callback; 987 return nullptr; 988 } 989 990 SystemRuntimeCreateInstance 991 PluginManager::GetSystemRuntimeCreateCallbackForPluginName( 992 ConstString name) { 993 if (name) { 994 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); 995 SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); 996 997 SystemRuntimeInstances::iterator pos, end = instances.end(); 998 for (pos = instances.begin(); pos != end; ++pos) { 999 if (name == pos->name) 1000 return pos->create_callback; 1001 } 1002 } 1003 return nullptr; 1004 } 1005 1006 #pragma mark ObjectFile 1007 1008 struct ObjectFileInstance { 1009 ObjectFileInstance() 1010 : name(), description(), create_callback(nullptr), 1011 create_memory_callback(nullptr), get_module_specifications(nullptr), 1012 save_core(nullptr) {} 1013 1014 ConstString name; 1015 std::string description; 1016 ObjectFileCreateInstance create_callback; 1017 ObjectFileCreateMemoryInstance create_memory_callback; 1018 ObjectFileGetModuleSpecifications get_module_specifications; 1019 ObjectFileSaveCore save_core; 1020 }; 1021 1022 typedef std::vector<ObjectFileInstance> ObjectFileInstances; 1023 1024 static std::recursive_mutex &GetObjectFileMutex() { 1025 static std::recursive_mutex g_instances_mutex; 1026 return g_instances_mutex; 1027 } 1028 1029 static ObjectFileInstances &GetObjectFileInstances() { 1030 static ObjectFileInstances g_instances; 1031 return g_instances; 1032 } 1033 1034 bool PluginManager::RegisterPlugin( 1035 ConstString name, const char *description, 1036 ObjectFileCreateInstance create_callback, 1037 ObjectFileCreateMemoryInstance create_memory_callback, 1038 ObjectFileGetModuleSpecifications get_module_specifications, 1039 ObjectFileSaveCore save_core) { 1040 if (create_callback) { 1041 ObjectFileInstance instance; 1042 assert((bool)name); 1043 instance.name = name; 1044 if (description && description[0]) 1045 instance.description = description; 1046 instance.create_callback = create_callback; 1047 instance.create_memory_callback = create_memory_callback; 1048 instance.save_core = save_core; 1049 instance.get_module_specifications = get_module_specifications; 1050 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1051 GetObjectFileInstances().push_back(instance); 1052 } 1053 return false; 1054 } 1055 1056 bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) { 1057 if (create_callback) { 1058 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1059 ObjectFileInstances &instances = GetObjectFileInstances(); 1060 1061 ObjectFileInstances::iterator pos, end = instances.end(); 1062 for (pos = instances.begin(); pos != end; ++pos) { 1063 if (pos->create_callback == create_callback) { 1064 instances.erase(pos); 1065 return true; 1066 } 1067 } 1068 } 1069 return false; 1070 } 1071 1072 ObjectFileCreateInstance 1073 PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) { 1074 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1075 ObjectFileInstances &instances = GetObjectFileInstances(); 1076 if (idx < instances.size()) 1077 return instances[idx].create_callback; 1078 return nullptr; 1079 } 1080 1081 ObjectFileCreateMemoryInstance 1082 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) { 1083 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1084 ObjectFileInstances &instances = GetObjectFileInstances(); 1085 if (idx < instances.size()) 1086 return instances[idx].create_memory_callback; 1087 return nullptr; 1088 } 1089 1090 ObjectFileGetModuleSpecifications 1091 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex( 1092 uint32_t idx) { 1093 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1094 ObjectFileInstances &instances = GetObjectFileInstances(); 1095 if (idx < instances.size()) 1096 return instances[idx].get_module_specifications; 1097 return nullptr; 1098 } 1099 1100 ObjectFileCreateInstance 1101 PluginManager::GetObjectFileCreateCallbackForPluginName( 1102 ConstString name) { 1103 if (name) { 1104 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1105 ObjectFileInstances &instances = GetObjectFileInstances(); 1106 1107 ObjectFileInstances::iterator pos, end = instances.end(); 1108 for (pos = instances.begin(); pos != end; ++pos) { 1109 if (name == pos->name) 1110 return pos->create_callback; 1111 } 1112 } 1113 return nullptr; 1114 } 1115 1116 ObjectFileCreateMemoryInstance 1117 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( 1118 ConstString name) { 1119 if (name) { 1120 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1121 ObjectFileInstances &instances = GetObjectFileInstances(); 1122 1123 ObjectFileInstances::iterator pos, end = instances.end(); 1124 for (pos = instances.begin(); pos != end; ++pos) { 1125 if (name == pos->name) 1126 return pos->create_memory_callback; 1127 } 1128 } 1129 return nullptr; 1130 } 1131 1132 Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, 1133 const FileSpec &outfile) { 1134 Status error; 1135 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1136 ObjectFileInstances &instances = GetObjectFileInstances(); 1137 1138 ObjectFileInstances::iterator pos, end = instances.end(); 1139 for (pos = instances.begin(); pos != end; ++pos) { 1140 if (pos->save_core && pos->save_core(process_sp, outfile, error)) 1141 return error; 1142 } 1143 error.SetErrorString( 1144 "no ObjectFile plugins were able to save a core for this process"); 1145 return error; 1146 } 1147 1148 #pragma mark ObjectContainer 1149 1150 struct ObjectContainerInstance { 1151 ObjectContainerInstance() 1152 : name(), description(), create_callback(nullptr), 1153 get_module_specifications(nullptr) {} 1154 1155 ConstString name; 1156 std::string description; 1157 ObjectContainerCreateInstance create_callback; 1158 ObjectFileGetModuleSpecifications get_module_specifications; 1159 }; 1160 1161 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; 1162 1163 static std::recursive_mutex &GetObjectContainerMutex() { 1164 static std::recursive_mutex g_instances_mutex; 1165 return g_instances_mutex; 1166 } 1167 1168 static ObjectContainerInstances &GetObjectContainerInstances() { 1169 static ObjectContainerInstances g_instances; 1170 return g_instances; 1171 } 1172 1173 bool PluginManager::RegisterPlugin( 1174 ConstString name, const char *description, 1175 ObjectContainerCreateInstance create_callback, 1176 ObjectFileGetModuleSpecifications get_module_specifications) { 1177 if (create_callback) { 1178 ObjectContainerInstance instance; 1179 assert((bool)name); 1180 instance.name = name; 1181 if (description && description[0]) 1182 instance.description = description; 1183 instance.create_callback = create_callback; 1184 instance.get_module_specifications = get_module_specifications; 1185 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); 1186 GetObjectContainerInstances().push_back(instance); 1187 } 1188 return false; 1189 } 1190 1191 bool PluginManager::UnregisterPlugin( 1192 ObjectContainerCreateInstance create_callback) { 1193 if (create_callback) { 1194 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); 1195 ObjectContainerInstances &instances = GetObjectContainerInstances(); 1196 1197 ObjectContainerInstances::iterator pos, end = instances.end(); 1198 for (pos = instances.begin(); pos != end; ++pos) { 1199 if (pos->create_callback == create_callback) { 1200 instances.erase(pos); 1201 return true; 1202 } 1203 } 1204 } 1205 return false; 1206 } 1207 1208 ObjectContainerCreateInstance 1209 PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) { 1210 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); 1211 ObjectContainerInstances &instances = GetObjectContainerInstances(); 1212 if (idx < instances.size()) 1213 return instances[idx].create_callback; 1214 return nullptr; 1215 } 1216 1217 ObjectContainerCreateInstance 1218 PluginManager::GetObjectContainerCreateCallbackForPluginName( 1219 ConstString name) { 1220 if (name) { 1221 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); 1222 ObjectContainerInstances &instances = GetObjectContainerInstances(); 1223 1224 ObjectContainerInstances::iterator pos, end = instances.end(); 1225 for (pos = instances.begin(); pos != end; ++pos) { 1226 if (name == pos->name) 1227 return pos->create_callback; 1228 } 1229 } 1230 return nullptr; 1231 } 1232 1233 ObjectFileGetModuleSpecifications 1234 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex( 1235 uint32_t idx) { 1236 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); 1237 ObjectContainerInstances &instances = GetObjectContainerInstances(); 1238 if (idx < instances.size()) 1239 return instances[idx].get_module_specifications; 1240 return nullptr; 1241 } 1242 1243 #pragma mark Platform 1244 1245 struct PlatformInstance { 1246 PlatformInstance() 1247 : name(), description(), create_callback(nullptr), 1248 debugger_init_callback(nullptr) {} 1249 1250 ConstString name; 1251 std::string description; 1252 PlatformCreateInstance create_callback; 1253 DebuggerInitializeCallback debugger_init_callback; 1254 }; 1255 1256 typedef std::vector<PlatformInstance> PlatformInstances; 1257 1258 static std::recursive_mutex &GetPlatformInstancesMutex() { 1259 static std::recursive_mutex g_platform_instances_mutex; 1260 return g_platform_instances_mutex; 1261 } 1262 1263 static PlatformInstances &GetPlatformInstances() { 1264 static PlatformInstances g_platform_instances; 1265 return g_platform_instances; 1266 } 1267 1268 bool PluginManager::RegisterPlugin( 1269 ConstString name, const char *description, 1270 PlatformCreateInstance create_callback, 1271 DebuggerInitializeCallback debugger_init_callback) { 1272 if (create_callback) { 1273 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1274 1275 PlatformInstance instance; 1276 assert((bool)name); 1277 instance.name = name; 1278 if (description && description[0]) 1279 instance.description = description; 1280 instance.create_callback = create_callback; 1281 instance.debugger_init_callback = debugger_init_callback; 1282 GetPlatformInstances().push_back(instance); 1283 return true; 1284 } 1285 return false; 1286 } 1287 1288 const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { 1289 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1290 PlatformInstances &instances = GetPlatformInstances(); 1291 if (idx < instances.size()) 1292 return instances[idx].name.GetCString(); 1293 return nullptr; 1294 } 1295 1296 const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { 1297 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1298 PlatformInstances &instances = GetPlatformInstances(); 1299 if (idx < instances.size()) 1300 return instances[idx].description.c_str(); 1301 return nullptr; 1302 } 1303 1304 bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { 1305 if (create_callback) { 1306 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1307 PlatformInstances &instances = GetPlatformInstances(); 1308 1309 PlatformInstances::iterator pos, end = instances.end(); 1310 for (pos = instances.begin(); pos != end; ++pos) { 1311 if (pos->create_callback == create_callback) { 1312 instances.erase(pos); 1313 return true; 1314 } 1315 } 1316 } 1317 return false; 1318 } 1319 1320 PlatformCreateInstance 1321 PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) { 1322 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1323 PlatformInstances &instances = GetPlatformInstances(); 1324 if (idx < instances.size()) 1325 return instances[idx].create_callback; 1326 return nullptr; 1327 } 1328 1329 PlatformCreateInstance 1330 PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) { 1331 if (name) { 1332 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1333 PlatformInstances &instances = GetPlatformInstances(); 1334 1335 PlatformInstances::iterator pos, end = instances.end(); 1336 for (pos = instances.begin(); pos != end; ++pos) { 1337 if (name == pos->name) 1338 return pos->create_callback; 1339 } 1340 } 1341 return nullptr; 1342 } 1343 1344 void PluginManager::AutoCompletePlatformName(llvm::StringRef name, 1345 CompletionRequest &request) { 1346 if (name.empty()) 1347 return; 1348 1349 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1350 PlatformInstances &instances = GetPlatformInstances(); 1351 llvm::StringRef name_sref(name); 1352 1353 PlatformInstances::iterator pos, end = instances.end(); 1354 for (pos = instances.begin(); pos != end; ++pos) { 1355 llvm::StringRef plugin_name(pos->name.GetCString()); 1356 if (plugin_name.startswith(name_sref)) 1357 request.AddCompletion(plugin_name.data()); 1358 } 1359 } 1360 1361 #pragma mark Process 1362 1363 struct ProcessInstance { 1364 ProcessInstance() 1365 : name(), description(), create_callback(nullptr), 1366 debugger_init_callback(nullptr) {} 1367 1368 ConstString name; 1369 std::string description; 1370 ProcessCreateInstance create_callback; 1371 DebuggerInitializeCallback debugger_init_callback; 1372 }; 1373 1374 typedef std::vector<ProcessInstance> ProcessInstances; 1375 1376 static std::recursive_mutex &GetProcessMutex() { 1377 static std::recursive_mutex g_instances_mutex; 1378 return g_instances_mutex; 1379 } 1380 1381 static ProcessInstances &GetProcessInstances() { 1382 static ProcessInstances g_instances; 1383 return g_instances; 1384 } 1385 1386 bool PluginManager::RegisterPlugin( 1387 ConstString name, const char *description, 1388 ProcessCreateInstance create_callback, 1389 DebuggerInitializeCallback debugger_init_callback) { 1390 if (create_callback) { 1391 ProcessInstance instance; 1392 assert((bool)name); 1393 instance.name = name; 1394 if (description && description[0]) 1395 instance.description = description; 1396 instance.create_callback = create_callback; 1397 instance.debugger_init_callback = debugger_init_callback; 1398 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1399 GetProcessInstances().push_back(instance); 1400 } 1401 return false; 1402 } 1403 1404 const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { 1405 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1406 ProcessInstances &instances = GetProcessInstances(); 1407 if (idx < instances.size()) 1408 return instances[idx].name.GetCString(); 1409 return nullptr; 1410 } 1411 1412 const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { 1413 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1414 ProcessInstances &instances = GetProcessInstances(); 1415 if (idx < instances.size()) 1416 return instances[idx].description.c_str(); 1417 return nullptr; 1418 } 1419 1420 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { 1421 if (create_callback) { 1422 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1423 ProcessInstances &instances = GetProcessInstances(); 1424 1425 ProcessInstances::iterator pos, end = instances.end(); 1426 for (pos = instances.begin(); pos != end; ++pos) { 1427 if (pos->create_callback == create_callback) { 1428 instances.erase(pos); 1429 return true; 1430 } 1431 } 1432 } 1433 return false; 1434 } 1435 1436 ProcessCreateInstance 1437 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { 1438 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1439 ProcessInstances &instances = GetProcessInstances(); 1440 if (idx < instances.size()) 1441 return instances[idx].create_callback; 1442 return nullptr; 1443 } 1444 1445 ProcessCreateInstance 1446 PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) { 1447 if (name) { 1448 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1449 ProcessInstances &instances = GetProcessInstances(); 1450 1451 ProcessInstances::iterator pos, end = instances.end(); 1452 for (pos = instances.begin(); pos != end; ++pos) { 1453 if (name == pos->name) 1454 return pos->create_callback; 1455 } 1456 } 1457 return nullptr; 1458 } 1459 1460 #pragma mark ScriptInterpreter 1461 1462 struct ScriptInterpreterInstance { 1463 ScriptInterpreterInstance() 1464 : name(), language(lldb::eScriptLanguageNone), description(), 1465 create_callback(nullptr) {} 1466 1467 ConstString name; 1468 lldb::ScriptLanguage language; 1469 std::string description; 1470 ScriptInterpreterCreateInstance create_callback; 1471 }; 1472 1473 typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances; 1474 1475 static std::recursive_mutex &GetScriptInterpreterMutex() { 1476 static std::recursive_mutex g_instances_mutex; 1477 return g_instances_mutex; 1478 } 1479 1480 static ScriptInterpreterInstances &GetScriptInterpreterInstances() { 1481 static ScriptInterpreterInstances g_instances; 1482 return g_instances; 1483 } 1484 1485 bool PluginManager::RegisterPlugin( 1486 ConstString name, const char *description, 1487 lldb::ScriptLanguage script_language, 1488 ScriptInterpreterCreateInstance create_callback) { 1489 if (!create_callback) 1490 return false; 1491 ScriptInterpreterInstance instance; 1492 assert((bool)name); 1493 instance.name = name; 1494 if (description && description[0]) 1495 instance.description = description; 1496 instance.create_callback = create_callback; 1497 instance.language = script_language; 1498 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1499 GetScriptInterpreterInstances().push_back(instance); 1500 return false; 1501 } 1502 1503 bool PluginManager::UnregisterPlugin( 1504 ScriptInterpreterCreateInstance create_callback) { 1505 if (!create_callback) 1506 return false; 1507 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1508 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1509 1510 ScriptInterpreterInstances::iterator pos, end = instances.end(); 1511 for (pos = instances.begin(); pos != end; ++pos) { 1512 if (pos->create_callback != create_callback) 1513 continue; 1514 1515 instances.erase(pos); 1516 return true; 1517 } 1518 return false; 1519 } 1520 1521 ScriptInterpreterCreateInstance 1522 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) { 1523 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1524 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1525 if (idx < instances.size()) 1526 return instances[idx].create_callback; 1527 return nullptr; 1528 } 1529 1530 lldb::ScriptInterpreterSP 1531 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, 1532 Debugger &debugger) { 1533 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1534 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1535 1536 ScriptInterpreterInstances::iterator pos, end = instances.end(); 1537 ScriptInterpreterCreateInstance none_instance = nullptr; 1538 for (pos = instances.begin(); pos != end; ++pos) { 1539 if (pos->language == lldb::eScriptLanguageNone) 1540 none_instance = pos->create_callback; 1541 1542 if (script_lang == pos->language) 1543 return pos->create_callback(debugger); 1544 } 1545 1546 // If we didn't find one, return the ScriptInterpreter for the null language. 1547 assert(none_instance != nullptr); 1548 return none_instance(debugger); 1549 } 1550 1551 #pragma mark - 1552 #pragma mark StructuredDataPlugin 1553 1554 // StructuredDataPlugin 1555 1556 struct StructuredDataPluginInstance { 1557 StructuredDataPluginInstance() 1558 : name(), description(), create_callback(nullptr), 1559 debugger_init_callback(nullptr), filter_callback(nullptr) {} 1560 1561 ConstString name; 1562 std::string description; 1563 StructuredDataPluginCreateInstance create_callback; 1564 DebuggerInitializeCallback debugger_init_callback; 1565 StructuredDataFilterLaunchInfo filter_callback; 1566 }; 1567 1568 typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances; 1569 1570 static std::recursive_mutex &GetStructuredDataPluginMutex() { 1571 static std::recursive_mutex g_instances_mutex; 1572 return g_instances_mutex; 1573 } 1574 1575 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { 1576 static StructuredDataPluginInstances g_instances; 1577 return g_instances; 1578 } 1579 1580 bool PluginManager::RegisterPlugin( 1581 ConstString name, const char *description, 1582 StructuredDataPluginCreateInstance create_callback, 1583 DebuggerInitializeCallback debugger_init_callback, 1584 StructuredDataFilterLaunchInfo filter_callback) { 1585 if (create_callback) { 1586 StructuredDataPluginInstance instance; 1587 assert((bool)name); 1588 instance.name = name; 1589 if (description && description[0]) 1590 instance.description = description; 1591 instance.create_callback = create_callback; 1592 instance.debugger_init_callback = debugger_init_callback; 1593 instance.filter_callback = filter_callback; 1594 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1595 GetStructuredDataPluginInstances().push_back(instance); 1596 } 1597 return false; 1598 } 1599 1600 bool PluginManager::UnregisterPlugin( 1601 StructuredDataPluginCreateInstance create_callback) { 1602 if (create_callback) { 1603 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1604 StructuredDataPluginInstances &instances = 1605 GetStructuredDataPluginInstances(); 1606 1607 StructuredDataPluginInstances::iterator pos, end = instances.end(); 1608 for (pos = instances.begin(); pos != end; ++pos) { 1609 if (pos->create_callback == create_callback) { 1610 instances.erase(pos); 1611 return true; 1612 } 1613 } 1614 } 1615 return false; 1616 } 1617 1618 StructuredDataPluginCreateInstance 1619 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) { 1620 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1621 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); 1622 if (idx < instances.size()) 1623 return instances[idx].create_callback; 1624 return nullptr; 1625 } 1626 1627 StructuredDataPluginCreateInstance 1628 PluginManager::GetStructuredDataPluginCreateCallbackForPluginName( 1629 ConstString name) { 1630 if (name) { 1631 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1632 StructuredDataPluginInstances &instances = 1633 GetStructuredDataPluginInstances(); 1634 1635 StructuredDataPluginInstances::iterator pos, end = instances.end(); 1636 for (pos = instances.begin(); pos != end; ++pos) { 1637 if (name == pos->name) 1638 return pos->create_callback; 1639 } 1640 } 1641 return nullptr; 1642 } 1643 1644 StructuredDataFilterLaunchInfo 1645 PluginManager::GetStructuredDataFilterCallbackAtIndex( 1646 uint32_t idx, bool &iteration_complete) { 1647 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1648 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); 1649 if (idx < instances.size()) { 1650 iteration_complete = false; 1651 return instances[idx].filter_callback; 1652 } else { 1653 iteration_complete = true; 1654 } 1655 return nullptr; 1656 } 1657 1658 #pragma mark SymbolFile 1659 1660 struct SymbolFileInstance { 1661 SymbolFileInstance() 1662 : name(), description(), create_callback(nullptr), 1663 debugger_init_callback(nullptr) {} 1664 1665 ConstString name; 1666 std::string description; 1667 SymbolFileCreateInstance create_callback; 1668 DebuggerInitializeCallback debugger_init_callback; 1669 }; 1670 1671 typedef std::vector<SymbolFileInstance> SymbolFileInstances; 1672 1673 static std::recursive_mutex &GetSymbolFileMutex() { 1674 static std::recursive_mutex g_instances_mutex; 1675 return g_instances_mutex; 1676 } 1677 1678 static SymbolFileInstances &GetSymbolFileInstances() { 1679 static SymbolFileInstances g_instances; 1680 return g_instances; 1681 } 1682 1683 bool PluginManager::RegisterPlugin( 1684 ConstString name, const char *description, 1685 SymbolFileCreateInstance create_callback, 1686 DebuggerInitializeCallback debugger_init_callback) { 1687 if (create_callback) { 1688 SymbolFileInstance instance; 1689 assert((bool)name); 1690 instance.name = name; 1691 if (description && description[0]) 1692 instance.description = description; 1693 instance.create_callback = create_callback; 1694 instance.debugger_init_callback = debugger_init_callback; 1695 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1696 GetSymbolFileInstances().push_back(instance); 1697 } 1698 return false; 1699 } 1700 1701 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) { 1702 if (create_callback) { 1703 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1704 SymbolFileInstances &instances = GetSymbolFileInstances(); 1705 1706 SymbolFileInstances::iterator pos, end = instances.end(); 1707 for (pos = instances.begin(); pos != end; ++pos) { 1708 if (pos->create_callback == create_callback) { 1709 instances.erase(pos); 1710 return true; 1711 } 1712 } 1713 } 1714 return false; 1715 } 1716 1717 SymbolFileCreateInstance 1718 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) { 1719 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1720 SymbolFileInstances &instances = GetSymbolFileInstances(); 1721 if (idx < instances.size()) 1722 return instances[idx].create_callback; 1723 return nullptr; 1724 } 1725 1726 SymbolFileCreateInstance 1727 PluginManager::GetSymbolFileCreateCallbackForPluginName( 1728 ConstString name) { 1729 if (name) { 1730 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1731 SymbolFileInstances &instances = GetSymbolFileInstances(); 1732 1733 SymbolFileInstances::iterator pos, end = instances.end(); 1734 for (pos = instances.begin(); pos != end; ++pos) { 1735 if (name == pos->name) 1736 return pos->create_callback; 1737 } 1738 } 1739 return nullptr; 1740 } 1741 1742 #pragma mark SymbolVendor 1743 1744 struct SymbolVendorInstance { 1745 SymbolVendorInstance() : name(), description(), create_callback(nullptr) {} 1746 1747 ConstString name; 1748 std::string description; 1749 SymbolVendorCreateInstance create_callback; 1750 }; 1751 1752 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 1753 1754 static std::recursive_mutex &GetSymbolVendorMutex() { 1755 static std::recursive_mutex g_instances_mutex; 1756 return g_instances_mutex; 1757 } 1758 1759 static SymbolVendorInstances &GetSymbolVendorInstances() { 1760 static SymbolVendorInstances g_instances; 1761 return g_instances; 1762 } 1763 1764 bool PluginManager::RegisterPlugin(ConstString name, 1765 const char *description, 1766 SymbolVendorCreateInstance create_callback) { 1767 if (create_callback) { 1768 SymbolVendorInstance instance; 1769 assert((bool)name); 1770 instance.name = name; 1771 if (description && description[0]) 1772 instance.description = description; 1773 instance.create_callback = create_callback; 1774 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1775 GetSymbolVendorInstances().push_back(instance); 1776 } 1777 return false; 1778 } 1779 1780 bool PluginManager::UnregisterPlugin( 1781 SymbolVendorCreateInstance create_callback) { 1782 if (create_callback) { 1783 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1784 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1785 1786 SymbolVendorInstances::iterator pos, end = instances.end(); 1787 for (pos = instances.begin(); pos != end; ++pos) { 1788 if (pos->create_callback == create_callback) { 1789 instances.erase(pos); 1790 return true; 1791 } 1792 } 1793 } 1794 return false; 1795 } 1796 1797 SymbolVendorCreateInstance 1798 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { 1799 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1800 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1801 if (idx < instances.size()) 1802 return instances[idx].create_callback; 1803 return nullptr; 1804 } 1805 1806 SymbolVendorCreateInstance 1807 PluginManager::GetSymbolVendorCreateCallbackForPluginName( 1808 ConstString name) { 1809 if (name) { 1810 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1811 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1812 1813 SymbolVendorInstances::iterator pos, end = instances.end(); 1814 for (pos = instances.begin(); pos != end; ++pos) { 1815 if (name == pos->name) 1816 return pos->create_callback; 1817 } 1818 } 1819 return nullptr; 1820 } 1821 1822 #pragma mark UnwindAssembly 1823 1824 struct UnwindAssemblyInstance { 1825 UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {} 1826 1827 ConstString name; 1828 std::string description; 1829 UnwindAssemblyCreateInstance create_callback; 1830 }; 1831 1832 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances; 1833 1834 static std::recursive_mutex &GetUnwindAssemblyMutex() { 1835 static std::recursive_mutex g_instances_mutex; 1836 return g_instances_mutex; 1837 } 1838 1839 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { 1840 static UnwindAssemblyInstances g_instances; 1841 return g_instances; 1842 } 1843 1844 bool PluginManager::RegisterPlugin( 1845 ConstString name, const char *description, 1846 UnwindAssemblyCreateInstance create_callback) { 1847 if (create_callback) { 1848 UnwindAssemblyInstance instance; 1849 assert((bool)name); 1850 instance.name = name; 1851 if (description && description[0]) 1852 instance.description = description; 1853 instance.create_callback = create_callback; 1854 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1855 GetUnwindAssemblyInstances().push_back(instance); 1856 } 1857 return false; 1858 } 1859 1860 bool PluginManager::UnregisterPlugin( 1861 UnwindAssemblyCreateInstance create_callback) { 1862 if (create_callback) { 1863 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1864 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1865 1866 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1867 for (pos = instances.begin(); pos != end; ++pos) { 1868 if (pos->create_callback == create_callback) { 1869 instances.erase(pos); 1870 return true; 1871 } 1872 } 1873 } 1874 return false; 1875 } 1876 1877 UnwindAssemblyCreateInstance 1878 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) { 1879 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1880 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1881 if (idx < instances.size()) 1882 return instances[idx].create_callback; 1883 return nullptr; 1884 } 1885 1886 UnwindAssemblyCreateInstance 1887 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName( 1888 ConstString name) { 1889 if (name) { 1890 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1891 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1892 1893 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1894 for (pos = instances.begin(); pos != end; ++pos) { 1895 if (name == pos->name) 1896 return pos->create_callback; 1897 } 1898 } 1899 return nullptr; 1900 } 1901 1902 #pragma mark MemoryHistory 1903 1904 struct MemoryHistoryInstance { 1905 MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {} 1906 1907 ConstString name; 1908 std::string description; 1909 MemoryHistoryCreateInstance create_callback; 1910 }; 1911 1912 typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances; 1913 1914 static std::recursive_mutex &GetMemoryHistoryMutex() { 1915 static std::recursive_mutex g_instances_mutex; 1916 return g_instances_mutex; 1917 } 1918 1919 static MemoryHistoryInstances &GetMemoryHistoryInstances() { 1920 static MemoryHistoryInstances g_instances; 1921 return g_instances; 1922 } 1923 1924 bool PluginManager::RegisterPlugin( 1925 ConstString name, const char *description, 1926 MemoryHistoryCreateInstance create_callback) { 1927 if (create_callback) { 1928 MemoryHistoryInstance instance; 1929 assert((bool)name); 1930 instance.name = name; 1931 if (description && description[0]) 1932 instance.description = description; 1933 instance.create_callback = create_callback; 1934 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1935 GetMemoryHistoryInstances().push_back(instance); 1936 } 1937 return false; 1938 } 1939 1940 bool PluginManager::UnregisterPlugin( 1941 MemoryHistoryCreateInstance create_callback) { 1942 if (create_callback) { 1943 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1944 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1945 1946 MemoryHistoryInstances::iterator pos, end = instances.end(); 1947 for (pos = instances.begin(); pos != end; ++pos) { 1948 if (pos->create_callback == create_callback) { 1949 instances.erase(pos); 1950 return true; 1951 } 1952 } 1953 } 1954 return false; 1955 } 1956 1957 MemoryHistoryCreateInstance 1958 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { 1959 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1960 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1961 if (idx < instances.size()) 1962 return instances[idx].create_callback; 1963 return nullptr; 1964 } 1965 1966 MemoryHistoryCreateInstance 1967 PluginManager::GetMemoryHistoryCreateCallbackForPluginName( 1968 ConstString name) { 1969 if (name) { 1970 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1971 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1972 1973 MemoryHistoryInstances::iterator pos, end = instances.end(); 1974 for (pos = instances.begin(); pos != end; ++pos) { 1975 if (name == pos->name) 1976 return pos->create_callback; 1977 } 1978 } 1979 return nullptr; 1980 } 1981 1982 #pragma mark InstrumentationRuntime 1983 1984 struct InstrumentationRuntimeInstance { 1985 InstrumentationRuntimeInstance() 1986 : name(), description(), create_callback(nullptr) {} 1987 1988 ConstString name; 1989 std::string description; 1990 InstrumentationRuntimeCreateInstance create_callback; 1991 InstrumentationRuntimeGetType get_type_callback; 1992 }; 1993 1994 typedef std::vector<InstrumentationRuntimeInstance> 1995 InstrumentationRuntimeInstances; 1996 1997 static std::recursive_mutex &GetInstrumentationRuntimeMutex() { 1998 static std::recursive_mutex g_instances_mutex; 1999 return g_instances_mutex; 2000 } 2001 2002 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { 2003 static InstrumentationRuntimeInstances g_instances; 2004 return g_instances; 2005 } 2006 2007 bool PluginManager::RegisterPlugin( 2008 ConstString name, const char *description, 2009 InstrumentationRuntimeCreateInstance create_callback, 2010 InstrumentationRuntimeGetType get_type_callback) { 2011 if (create_callback) { 2012 InstrumentationRuntimeInstance instance; 2013 assert((bool)name); 2014 instance.name = name; 2015 if (description && description[0]) 2016 instance.description = description; 2017 instance.create_callback = create_callback; 2018 instance.get_type_callback = get_type_callback; 2019 std::lock_guard<std::recursive_mutex> guard( 2020 GetInstrumentationRuntimeMutex()); 2021 GetInstrumentationRuntimeInstances().push_back(instance); 2022 } 2023 return false; 2024 } 2025 2026 bool PluginManager::UnregisterPlugin( 2027 InstrumentationRuntimeCreateInstance create_callback) { 2028 if (create_callback) { 2029 std::lock_guard<std::recursive_mutex> guard( 2030 GetInstrumentationRuntimeMutex()); 2031 InstrumentationRuntimeInstances &instances = 2032 GetInstrumentationRuntimeInstances(); 2033 2034 InstrumentationRuntimeInstances::iterator pos, end = instances.end(); 2035 for (pos = instances.begin(); pos != end; ++pos) { 2036 if (pos->create_callback == create_callback) { 2037 instances.erase(pos); 2038 return true; 2039 } 2040 } 2041 } 2042 return false; 2043 } 2044 2045 InstrumentationRuntimeGetType 2046 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { 2047 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex()); 2048 InstrumentationRuntimeInstances &instances = 2049 GetInstrumentationRuntimeInstances(); 2050 if (idx < instances.size()) 2051 return instances[idx].get_type_callback; 2052 return nullptr; 2053 } 2054 2055 InstrumentationRuntimeCreateInstance 2056 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { 2057 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex()); 2058 InstrumentationRuntimeInstances &instances = 2059 GetInstrumentationRuntimeInstances(); 2060 if (idx < instances.size()) 2061 return instances[idx].create_callback; 2062 return nullptr; 2063 } 2064 2065 InstrumentationRuntimeCreateInstance 2066 PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName( 2067 ConstString name) { 2068 if (name) { 2069 std::lock_guard<std::recursive_mutex> guard( 2070 GetInstrumentationRuntimeMutex()); 2071 InstrumentationRuntimeInstances &instances = 2072 GetInstrumentationRuntimeInstances(); 2073 2074 InstrumentationRuntimeInstances::iterator pos, end = instances.end(); 2075 for (pos = instances.begin(); pos != end; ++pos) { 2076 if (name == pos->name) 2077 return pos->create_callback; 2078 } 2079 } 2080 return nullptr; 2081 } 2082 2083 #pragma mark TypeSystem 2084 2085 struct TypeSystemInstance { 2086 ConstString name; 2087 std::string description; 2088 TypeSystemCreateInstance create_callback; 2089 LanguageSet supported_languages_for_types; 2090 LanguageSet supported_languages_for_expressions; 2091 }; 2092 2093 typedef std::vector<TypeSystemInstance> TypeSystemInstances; 2094 2095 static std::recursive_mutex &GetTypeSystemMutex() { 2096 static std::recursive_mutex g_instances_mutex; 2097 return g_instances_mutex; 2098 } 2099 2100 static TypeSystemInstances &GetTypeSystemInstances() { 2101 static TypeSystemInstances g_instances; 2102 return g_instances; 2103 } 2104 2105 bool PluginManager::RegisterPlugin( 2106 ConstString name, const char *description, 2107 TypeSystemCreateInstance create_callback, 2108 LanguageSet supported_languages_for_types, 2109 LanguageSet supported_languages_for_expressions) { 2110 if (create_callback) { 2111 TypeSystemInstance instance; 2112 assert((bool)name); 2113 instance.name = name; 2114 if (description && description[0]) 2115 instance.description = description; 2116 instance.create_callback = create_callback; 2117 instance.supported_languages_for_types = supported_languages_for_types; 2118 instance.supported_languages_for_expressions = supported_languages_for_expressions; 2119 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2120 GetTypeSystemInstances().push_back(instance); 2121 } 2122 return false; 2123 } 2124 2125 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) { 2126 if (create_callback) { 2127 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2128 TypeSystemInstances &instances = GetTypeSystemInstances(); 2129 2130 TypeSystemInstances::iterator pos, end = instances.end(); 2131 for (pos = instances.begin(); pos != end; ++pos) { 2132 if (pos->create_callback == create_callback) { 2133 instances.erase(pos); 2134 return true; 2135 } 2136 } 2137 } 2138 return false; 2139 } 2140 2141 TypeSystemCreateInstance 2142 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) { 2143 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2144 TypeSystemInstances &instances = GetTypeSystemInstances(); 2145 if (idx < instances.size()) 2146 return instances[idx].create_callback; 2147 return nullptr; 2148 } 2149 2150 TypeSystemCreateInstance 2151 PluginManager::GetTypeSystemCreateCallbackForPluginName( 2152 ConstString name) { 2153 if (name) { 2154 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2155 TypeSystemInstances &instances = GetTypeSystemInstances(); 2156 2157 TypeSystemInstances::iterator pos, end = instances.end(); 2158 for (pos = instances.begin(); pos != end; ++pos) { 2159 if (name == pos->name) 2160 return pos->create_callback; 2161 } 2162 } 2163 return nullptr; 2164 } 2165 2166 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() { 2167 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2168 LanguageSet all; 2169 TypeSystemInstances &instances = GetTypeSystemInstances(); 2170 for (unsigned i = 0; i < instances.size(); ++i) 2171 all.bitvector |= instances[i].supported_languages_for_types.bitvector; 2172 return all; 2173 } 2174 2175 LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { 2176 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2177 LanguageSet all; 2178 TypeSystemInstances &instances = GetTypeSystemInstances(); 2179 for (unsigned i = 0; i < instances.size(); ++i) 2180 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector; 2181 return all; 2182 } 2183 2184 #pragma mark REPL 2185 2186 struct REPLInstance { 2187 REPLInstance() : name(), description(), create_callback(nullptr) {} 2188 2189 ConstString name; 2190 std::string description; 2191 REPLCreateInstance create_callback; 2192 LanguageSet supported_languages; 2193 }; 2194 2195 typedef std::vector<REPLInstance> REPLInstances; 2196 2197 static std::recursive_mutex &GetREPLMutex() { 2198 static std::recursive_mutex g_instances_mutex; 2199 return g_instances_mutex; 2200 } 2201 2202 static REPLInstances &GetREPLInstances() { 2203 static REPLInstances g_instances; 2204 return g_instances; 2205 } 2206 2207 bool PluginManager::RegisterPlugin(ConstString name, const char *description, 2208 REPLCreateInstance create_callback, 2209 LanguageSet supported_languages) { 2210 if (create_callback) { 2211 REPLInstance instance; 2212 assert((bool)name); 2213 instance.name = name; 2214 if (description && description[0]) 2215 instance.description = description; 2216 instance.create_callback = create_callback; 2217 instance.supported_languages = supported_languages; 2218 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2219 GetREPLInstances().push_back(instance); 2220 } 2221 return false; 2222 } 2223 2224 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) { 2225 if (create_callback) { 2226 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2227 REPLInstances &instances = GetREPLInstances(); 2228 2229 REPLInstances::iterator pos, end = instances.end(); 2230 for (pos = instances.begin(); pos != end; ++pos) { 2231 if (pos->create_callback == create_callback) { 2232 instances.erase(pos); 2233 return true; 2234 } 2235 } 2236 } 2237 return false; 2238 } 2239 2240 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) { 2241 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2242 REPLInstances &instances = GetREPLInstances(); 2243 if (idx < instances.size()) 2244 return instances[idx].create_callback; 2245 return nullptr; 2246 } 2247 2248 REPLCreateInstance 2249 PluginManager::GetREPLCreateCallbackForPluginName(ConstString name) { 2250 if (name) { 2251 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2252 REPLInstances &instances = GetREPLInstances(); 2253 2254 REPLInstances::iterator pos, end = instances.end(); 2255 for (pos = instances.begin(); pos != end; ++pos) { 2256 if (name == pos->name) 2257 return pos->create_callback; 2258 } 2259 } 2260 return nullptr; 2261 } 2262 2263 LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() { 2264 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2265 LanguageSet all; 2266 REPLInstances &instances = GetREPLInstances(); 2267 for (unsigned i = 0; i < instances.size(); ++i) 2268 all.bitvector |= instances[i].supported_languages.bitvector; 2269 return all; 2270 } 2271 2272 #pragma mark PluginManager 2273 2274 void PluginManager::DebuggerInitialize(Debugger &debugger) { 2275 // Initialize the DynamicLoader plugins 2276 { 2277 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); 2278 DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); 2279 2280 DynamicLoaderInstances::iterator pos, end = instances.end(); 2281 for (pos = instances.begin(); pos != end; ++pos) { 2282 if (pos->debugger_init_callback) 2283 pos->debugger_init_callback(debugger); 2284 } 2285 } 2286 2287 // Initialize the JITLoader plugins 2288 { 2289 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); 2290 JITLoaderInstances &instances = GetJITLoaderInstances(); 2291 2292 JITLoaderInstances::iterator pos, end = instances.end(); 2293 for (pos = instances.begin(); pos != end; ++pos) { 2294 if (pos->debugger_init_callback) 2295 pos->debugger_init_callback(debugger); 2296 } 2297 } 2298 2299 // Initialize the Platform plugins 2300 { 2301 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 2302 PlatformInstances &instances = GetPlatformInstances(); 2303 2304 PlatformInstances::iterator pos, end = instances.end(); 2305 for (pos = instances.begin(); pos != end; ++pos) { 2306 if (pos->debugger_init_callback) 2307 pos->debugger_init_callback(debugger); 2308 } 2309 } 2310 2311 // Initialize the Process plugins 2312 { 2313 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 2314 ProcessInstances &instances = GetProcessInstances(); 2315 2316 ProcessInstances::iterator pos, end = instances.end(); 2317 for (pos = instances.begin(); pos != end; ++pos) { 2318 if (pos->debugger_init_callback) 2319 pos->debugger_init_callback(debugger); 2320 } 2321 } 2322 2323 // Initialize the SymbolFile plugins 2324 { 2325 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 2326 for (auto &sym_file : GetSymbolFileInstances()) { 2327 if (sym_file.debugger_init_callback) 2328 sym_file.debugger_init_callback(debugger); 2329 } 2330 } 2331 2332 // Initialize the OperatingSystem plugins 2333 { 2334 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); 2335 for (auto &os : GetOperatingSystemInstances()) { 2336 if (os.debugger_init_callback) 2337 os.debugger_init_callback(debugger); 2338 } 2339 } 2340 2341 // Initialize the StructuredDataPlugin plugins 2342 { 2343 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 2344 for (auto &plugin : GetStructuredDataPluginInstances()) { 2345 if (plugin.debugger_init_callback) 2346 plugin.debugger_init_callback(debugger); 2347 } 2348 } 2349 } 2350 2351 // This is the preferred new way to register plugin specific settings. e.g. 2352 // This will put a plugin's settings under e.g. 2353 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 2354 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins( 2355 Debugger &debugger, ConstString plugin_type_name, 2356 ConstString plugin_type_desc, bool can_create) { 2357 lldb::OptionValuePropertiesSP parent_properties_sp( 2358 debugger.GetValueProperties()); 2359 if (parent_properties_sp) { 2360 static ConstString g_property_name("plugin"); 2361 2362 OptionValuePropertiesSP plugin_properties_sp = 2363 parent_properties_sp->GetSubProperty(nullptr, g_property_name); 2364 if (!plugin_properties_sp && can_create) { 2365 plugin_properties_sp = 2366 std::make_shared<OptionValueProperties>(g_property_name); 2367 parent_properties_sp->AppendProperty( 2368 g_property_name, ConstString("Settings specify to plugins."), true, 2369 plugin_properties_sp); 2370 } 2371 2372 if (plugin_properties_sp) { 2373 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 2374 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name); 2375 if (!plugin_type_properties_sp && can_create) { 2376 plugin_type_properties_sp = 2377 std::make_shared<OptionValueProperties>(plugin_type_name); 2378 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 2379 true, plugin_type_properties_sp); 2380 } 2381 return plugin_type_properties_sp; 2382 } 2383 } 2384 return lldb::OptionValuePropertiesSP(); 2385 } 2386 2387 // This is deprecated way to register plugin specific settings. e.g. 2388 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform 2389 // generic settings would be under "platform.SETTINGNAME". 2390 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( 2391 Debugger &debugger, ConstString plugin_type_name, 2392 ConstString plugin_type_desc, bool can_create) { 2393 static ConstString g_property_name("plugin"); 2394 lldb::OptionValuePropertiesSP parent_properties_sp( 2395 debugger.GetValueProperties()); 2396 if (parent_properties_sp) { 2397 OptionValuePropertiesSP plugin_properties_sp = 2398 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name); 2399 if (!plugin_properties_sp && can_create) { 2400 plugin_properties_sp = 2401 std::make_shared<OptionValueProperties>(plugin_type_name); 2402 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 2403 true, plugin_properties_sp); 2404 } 2405 2406 if (plugin_properties_sp) { 2407 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 2408 plugin_properties_sp->GetSubProperty(nullptr, g_property_name); 2409 if (!plugin_type_properties_sp && can_create) { 2410 plugin_type_properties_sp = 2411 std::make_shared<OptionValueProperties>(g_property_name); 2412 plugin_properties_sp->AppendProperty( 2413 g_property_name, ConstString("Settings specific to plugins"), true, 2414 plugin_type_properties_sp); 2415 } 2416 return plugin_type_properties_sp; 2417 } 2418 } 2419 return lldb::OptionValuePropertiesSP(); 2420 } 2421 2422 namespace { 2423 2424 typedef lldb::OptionValuePropertiesSP 2425 GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString , 2426 ConstString , bool can_create); 2427 2428 lldb::OptionValuePropertiesSP 2429 GetSettingForPlugin(Debugger &debugger, ConstString setting_name, 2430 ConstString plugin_type_name, 2431 GetDebuggerPropertyForPluginsPtr get_debugger_property = 2432 GetDebuggerPropertyForPlugins) { 2433 lldb::OptionValuePropertiesSP properties_sp; 2434 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property( 2435 debugger, plugin_type_name, 2436 ConstString(), // not creating to so we don't need the description 2437 false)); 2438 if (plugin_type_properties_sp) 2439 properties_sp = 2440 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 2441 return properties_sp; 2442 } 2443 2444 bool CreateSettingForPlugin( 2445 Debugger &debugger, ConstString plugin_type_name, 2446 ConstString plugin_type_desc, 2447 const lldb::OptionValuePropertiesSP &properties_sp, 2448 ConstString description, bool is_global_property, 2449 GetDebuggerPropertyForPluginsPtr get_debugger_property = 2450 GetDebuggerPropertyForPlugins) { 2451 if (properties_sp) { 2452 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2453 get_debugger_property(debugger, plugin_type_name, plugin_type_desc, 2454 true)); 2455 if (plugin_type_properties_sp) { 2456 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 2457 description, is_global_property, 2458 properties_sp); 2459 return true; 2460 } 2461 } 2462 return false; 2463 } 2464 2465 const char *kDynamicLoaderPluginName("dynamic-loader"); 2466 const char *kPlatformPluginName("platform"); 2467 const char *kProcessPluginName("process"); 2468 const char *kSymbolFilePluginName("symbol-file"); 2469 const char *kJITLoaderPluginName("jit-loader"); 2470 const char *kStructuredDataPluginName("structured-data"); 2471 2472 } // anonymous namespace 2473 2474 lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin( 2475 Debugger &debugger, ConstString setting_name) { 2476 return GetSettingForPlugin(debugger, setting_name, 2477 ConstString(kDynamicLoaderPluginName)); 2478 } 2479 2480 bool PluginManager::CreateSettingForDynamicLoaderPlugin( 2481 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2482 ConstString description, bool is_global_property) { 2483 return CreateSettingForPlugin( 2484 debugger, ConstString(kDynamicLoaderPluginName), 2485 ConstString("Settings for dynamic loader plug-ins"), properties_sp, 2486 description, is_global_property); 2487 } 2488 2489 lldb::OptionValuePropertiesSP 2490 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger, 2491 ConstString setting_name) { 2492 return GetSettingForPlugin(debugger, setting_name, 2493 ConstString(kPlatformPluginName), 2494 GetDebuggerPropertyForPluginsOldStyle); 2495 } 2496 2497 bool PluginManager::CreateSettingForPlatformPlugin( 2498 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2499 ConstString description, bool is_global_property) { 2500 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName), 2501 ConstString("Settings for platform plug-ins"), 2502 properties_sp, description, is_global_property, 2503 GetDebuggerPropertyForPluginsOldStyle); 2504 } 2505 2506 lldb::OptionValuePropertiesSP 2507 PluginManager::GetSettingForProcessPlugin(Debugger &debugger, 2508 ConstString setting_name) { 2509 return GetSettingForPlugin(debugger, setting_name, 2510 ConstString(kProcessPluginName)); 2511 } 2512 2513 bool PluginManager::CreateSettingForProcessPlugin( 2514 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2515 ConstString description, bool is_global_property) { 2516 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName), 2517 ConstString("Settings for process plug-ins"), 2518 properties_sp, description, is_global_property); 2519 } 2520 2521 lldb::OptionValuePropertiesSP 2522 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger, 2523 ConstString setting_name) { 2524 return GetSettingForPlugin(debugger, setting_name, 2525 ConstString(kSymbolFilePluginName)); 2526 } 2527 2528 bool PluginManager::CreateSettingForSymbolFilePlugin( 2529 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2530 ConstString description, bool is_global_property) { 2531 return CreateSettingForPlugin( 2532 debugger, ConstString(kSymbolFilePluginName), 2533 ConstString("Settings for symbol file plug-ins"), properties_sp, 2534 description, is_global_property); 2535 } 2536 2537 lldb::OptionValuePropertiesSP 2538 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger, 2539 ConstString setting_name) { 2540 return GetSettingForPlugin(debugger, setting_name, 2541 ConstString(kJITLoaderPluginName)); 2542 } 2543 2544 bool PluginManager::CreateSettingForJITLoaderPlugin( 2545 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2546 ConstString description, bool is_global_property) { 2547 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName), 2548 ConstString("Settings for JIT loader plug-ins"), 2549 properties_sp, description, is_global_property); 2550 } 2551 2552 static const char *kOperatingSystemPluginName("os"); 2553 2554 lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin( 2555 Debugger &debugger, ConstString setting_name) { 2556 lldb::OptionValuePropertiesSP properties_sp; 2557 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2558 GetDebuggerPropertyForPlugins( 2559 debugger, ConstString(kOperatingSystemPluginName), 2560 ConstString(), // not creating to so we don't need the description 2561 false)); 2562 if (plugin_type_properties_sp) 2563 properties_sp = 2564 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 2565 return properties_sp; 2566 } 2567 2568 bool PluginManager::CreateSettingForOperatingSystemPlugin( 2569 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2570 ConstString description, bool is_global_property) { 2571 if (properties_sp) { 2572 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2573 GetDebuggerPropertyForPlugins( 2574 debugger, ConstString(kOperatingSystemPluginName), 2575 ConstString("Settings for operating system plug-ins"), true)); 2576 if (plugin_type_properties_sp) { 2577 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 2578 description, is_global_property, 2579 properties_sp); 2580 return true; 2581 } 2582 } 2583 return false; 2584 } 2585 2586 lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin( 2587 Debugger &debugger, ConstString setting_name) { 2588 return GetSettingForPlugin(debugger, setting_name, 2589 ConstString(kStructuredDataPluginName)); 2590 } 2591 2592 bool PluginManager::CreateSettingForStructuredDataPlugin( 2593 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2594 ConstString description, bool is_global_property) { 2595 return CreateSettingForPlugin( 2596 debugger, ConstString(kStructuredDataPluginName), 2597 ConstString("Settings for structured data plug-ins"), properties_sp, 2598 description, is_global_property); 2599 } 2600