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>(reinterpret_cast<intptr_t>(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 size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name, 1345 StringList &matches) { 1346 if (name.empty()) 1347 return matches.GetSize(); 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 matches.AppendString(plugin_name.data()); 1358 } 1359 return matches.GetSize(); 1360 } 1361 1362 #pragma mark Process 1363 1364 struct ProcessInstance { 1365 ProcessInstance() 1366 : name(), description(), create_callback(nullptr), 1367 debugger_init_callback(nullptr) {} 1368 1369 ConstString name; 1370 std::string description; 1371 ProcessCreateInstance create_callback; 1372 DebuggerInitializeCallback debugger_init_callback; 1373 }; 1374 1375 typedef std::vector<ProcessInstance> ProcessInstances; 1376 1377 static std::recursive_mutex &GetProcessMutex() { 1378 static std::recursive_mutex g_instances_mutex; 1379 return g_instances_mutex; 1380 } 1381 1382 static ProcessInstances &GetProcessInstances() { 1383 static ProcessInstances g_instances; 1384 return g_instances; 1385 } 1386 1387 bool PluginManager::RegisterPlugin( 1388 ConstString name, const char *description, 1389 ProcessCreateInstance create_callback, 1390 DebuggerInitializeCallback debugger_init_callback) { 1391 if (create_callback) { 1392 ProcessInstance instance; 1393 assert((bool)name); 1394 instance.name = name; 1395 if (description && description[0]) 1396 instance.description = description; 1397 instance.create_callback = create_callback; 1398 instance.debugger_init_callback = debugger_init_callback; 1399 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1400 GetProcessInstances().push_back(instance); 1401 } 1402 return false; 1403 } 1404 1405 const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { 1406 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1407 ProcessInstances &instances = GetProcessInstances(); 1408 if (idx < instances.size()) 1409 return instances[idx].name.GetCString(); 1410 return nullptr; 1411 } 1412 1413 const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { 1414 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1415 ProcessInstances &instances = GetProcessInstances(); 1416 if (idx < instances.size()) 1417 return instances[idx].description.c_str(); 1418 return nullptr; 1419 } 1420 1421 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { 1422 if (create_callback) { 1423 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1424 ProcessInstances &instances = GetProcessInstances(); 1425 1426 ProcessInstances::iterator pos, end = instances.end(); 1427 for (pos = instances.begin(); pos != end; ++pos) { 1428 if (pos->create_callback == create_callback) { 1429 instances.erase(pos); 1430 return true; 1431 } 1432 } 1433 } 1434 return false; 1435 } 1436 1437 ProcessCreateInstance 1438 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { 1439 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1440 ProcessInstances &instances = GetProcessInstances(); 1441 if (idx < instances.size()) 1442 return instances[idx].create_callback; 1443 return nullptr; 1444 } 1445 1446 ProcessCreateInstance 1447 PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) { 1448 if (name) { 1449 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1450 ProcessInstances &instances = GetProcessInstances(); 1451 1452 ProcessInstances::iterator pos, end = instances.end(); 1453 for (pos = instances.begin(); pos != end; ++pos) { 1454 if (name == pos->name) 1455 return pos->create_callback; 1456 } 1457 } 1458 return nullptr; 1459 } 1460 1461 #pragma mark ScriptInterpreter 1462 1463 struct ScriptInterpreterInstance { 1464 ScriptInterpreterInstance() 1465 : name(), language(lldb::eScriptLanguageNone), description(), 1466 create_callback(nullptr) {} 1467 1468 ConstString name; 1469 lldb::ScriptLanguage language; 1470 std::string description; 1471 ScriptInterpreterCreateInstance create_callback; 1472 }; 1473 1474 typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances; 1475 1476 static std::recursive_mutex &GetScriptInterpreterMutex() { 1477 static std::recursive_mutex g_instances_mutex; 1478 return g_instances_mutex; 1479 } 1480 1481 static ScriptInterpreterInstances &GetScriptInterpreterInstances() { 1482 static ScriptInterpreterInstances g_instances; 1483 return g_instances; 1484 } 1485 1486 bool PluginManager::RegisterPlugin( 1487 ConstString name, const char *description, 1488 lldb::ScriptLanguage script_language, 1489 ScriptInterpreterCreateInstance create_callback) { 1490 if (!create_callback) 1491 return false; 1492 ScriptInterpreterInstance instance; 1493 assert((bool)name); 1494 instance.name = name; 1495 if (description && description[0]) 1496 instance.description = description; 1497 instance.create_callback = create_callback; 1498 instance.language = script_language; 1499 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1500 GetScriptInterpreterInstances().push_back(instance); 1501 return false; 1502 } 1503 1504 bool PluginManager::UnregisterPlugin( 1505 ScriptInterpreterCreateInstance create_callback) { 1506 if (!create_callback) 1507 return false; 1508 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1509 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1510 1511 ScriptInterpreterInstances::iterator pos, end = instances.end(); 1512 for (pos = instances.begin(); pos != end; ++pos) { 1513 if (pos->create_callback != create_callback) 1514 continue; 1515 1516 instances.erase(pos); 1517 return true; 1518 } 1519 return false; 1520 } 1521 1522 ScriptInterpreterCreateInstance 1523 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) { 1524 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1525 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1526 if (idx < instances.size()) 1527 return instances[idx].create_callback; 1528 return nullptr; 1529 } 1530 1531 lldb::ScriptInterpreterSP 1532 PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, 1533 Debugger &debugger) { 1534 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1535 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1536 1537 ScriptInterpreterInstances::iterator pos, end = instances.end(); 1538 ScriptInterpreterCreateInstance none_instance = nullptr; 1539 for (pos = instances.begin(); pos != end; ++pos) { 1540 if (pos->language == lldb::eScriptLanguageNone) 1541 none_instance = pos->create_callback; 1542 1543 if (script_lang == pos->language) 1544 return pos->create_callback(debugger); 1545 } 1546 1547 // If we didn't find one, return the ScriptInterpreter for the null language. 1548 assert(none_instance != nullptr); 1549 return none_instance(debugger); 1550 } 1551 1552 #pragma mark - 1553 #pragma mark StructuredDataPlugin 1554 1555 // StructuredDataPlugin 1556 1557 struct StructuredDataPluginInstance { 1558 StructuredDataPluginInstance() 1559 : name(), description(), create_callback(nullptr), 1560 debugger_init_callback(nullptr), filter_callback(nullptr) {} 1561 1562 ConstString name; 1563 std::string description; 1564 StructuredDataPluginCreateInstance create_callback; 1565 DebuggerInitializeCallback debugger_init_callback; 1566 StructuredDataFilterLaunchInfo filter_callback; 1567 }; 1568 1569 typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances; 1570 1571 static std::recursive_mutex &GetStructuredDataPluginMutex() { 1572 static std::recursive_mutex g_instances_mutex; 1573 return g_instances_mutex; 1574 } 1575 1576 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { 1577 static StructuredDataPluginInstances g_instances; 1578 return g_instances; 1579 } 1580 1581 bool PluginManager::RegisterPlugin( 1582 ConstString name, const char *description, 1583 StructuredDataPluginCreateInstance create_callback, 1584 DebuggerInitializeCallback debugger_init_callback, 1585 StructuredDataFilterLaunchInfo filter_callback) { 1586 if (create_callback) { 1587 StructuredDataPluginInstance instance; 1588 assert((bool)name); 1589 instance.name = name; 1590 if (description && description[0]) 1591 instance.description = description; 1592 instance.create_callback = create_callback; 1593 instance.debugger_init_callback = debugger_init_callback; 1594 instance.filter_callback = filter_callback; 1595 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1596 GetStructuredDataPluginInstances().push_back(instance); 1597 } 1598 return false; 1599 } 1600 1601 bool PluginManager::UnregisterPlugin( 1602 StructuredDataPluginCreateInstance create_callback) { 1603 if (create_callback) { 1604 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1605 StructuredDataPluginInstances &instances = 1606 GetStructuredDataPluginInstances(); 1607 1608 StructuredDataPluginInstances::iterator pos, end = instances.end(); 1609 for (pos = instances.begin(); pos != end; ++pos) { 1610 if (pos->create_callback == create_callback) { 1611 instances.erase(pos); 1612 return true; 1613 } 1614 } 1615 } 1616 return false; 1617 } 1618 1619 StructuredDataPluginCreateInstance 1620 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) { 1621 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1622 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); 1623 if (idx < instances.size()) 1624 return instances[idx].create_callback; 1625 return nullptr; 1626 } 1627 1628 StructuredDataPluginCreateInstance 1629 PluginManager::GetStructuredDataPluginCreateCallbackForPluginName( 1630 ConstString name) { 1631 if (name) { 1632 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1633 StructuredDataPluginInstances &instances = 1634 GetStructuredDataPluginInstances(); 1635 1636 StructuredDataPluginInstances::iterator pos, end = instances.end(); 1637 for (pos = instances.begin(); pos != end; ++pos) { 1638 if (name == pos->name) 1639 return pos->create_callback; 1640 } 1641 } 1642 return nullptr; 1643 } 1644 1645 StructuredDataFilterLaunchInfo 1646 PluginManager::GetStructuredDataFilterCallbackAtIndex( 1647 uint32_t idx, bool &iteration_complete) { 1648 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1649 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); 1650 if (idx < instances.size()) { 1651 iteration_complete = false; 1652 return instances[idx].filter_callback; 1653 } else { 1654 iteration_complete = true; 1655 } 1656 return nullptr; 1657 } 1658 1659 #pragma mark SymbolFile 1660 1661 struct SymbolFileInstance { 1662 SymbolFileInstance() 1663 : name(), description(), create_callback(nullptr), 1664 debugger_init_callback(nullptr) {} 1665 1666 ConstString name; 1667 std::string description; 1668 SymbolFileCreateInstance create_callback; 1669 DebuggerInitializeCallback debugger_init_callback; 1670 }; 1671 1672 typedef std::vector<SymbolFileInstance> SymbolFileInstances; 1673 1674 static std::recursive_mutex &GetSymbolFileMutex() { 1675 static std::recursive_mutex g_instances_mutex; 1676 return g_instances_mutex; 1677 } 1678 1679 static SymbolFileInstances &GetSymbolFileInstances() { 1680 static SymbolFileInstances g_instances; 1681 return g_instances; 1682 } 1683 1684 bool PluginManager::RegisterPlugin( 1685 ConstString name, const char *description, 1686 SymbolFileCreateInstance create_callback, 1687 DebuggerInitializeCallback debugger_init_callback) { 1688 if (create_callback) { 1689 SymbolFileInstance instance; 1690 assert((bool)name); 1691 instance.name = name; 1692 if (description && description[0]) 1693 instance.description = description; 1694 instance.create_callback = create_callback; 1695 instance.debugger_init_callback = debugger_init_callback; 1696 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1697 GetSymbolFileInstances().push_back(instance); 1698 } 1699 return false; 1700 } 1701 1702 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) { 1703 if (create_callback) { 1704 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1705 SymbolFileInstances &instances = GetSymbolFileInstances(); 1706 1707 SymbolFileInstances::iterator pos, end = instances.end(); 1708 for (pos = instances.begin(); pos != end; ++pos) { 1709 if (pos->create_callback == create_callback) { 1710 instances.erase(pos); 1711 return true; 1712 } 1713 } 1714 } 1715 return false; 1716 } 1717 1718 SymbolFileCreateInstance 1719 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) { 1720 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1721 SymbolFileInstances &instances = GetSymbolFileInstances(); 1722 if (idx < instances.size()) 1723 return instances[idx].create_callback; 1724 return nullptr; 1725 } 1726 1727 SymbolFileCreateInstance 1728 PluginManager::GetSymbolFileCreateCallbackForPluginName( 1729 ConstString name) { 1730 if (name) { 1731 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1732 SymbolFileInstances &instances = GetSymbolFileInstances(); 1733 1734 SymbolFileInstances::iterator pos, end = instances.end(); 1735 for (pos = instances.begin(); pos != end; ++pos) { 1736 if (name == pos->name) 1737 return pos->create_callback; 1738 } 1739 } 1740 return nullptr; 1741 } 1742 1743 #pragma mark SymbolVendor 1744 1745 struct SymbolVendorInstance { 1746 SymbolVendorInstance() : name(), description(), create_callback(nullptr) {} 1747 1748 ConstString name; 1749 std::string description; 1750 SymbolVendorCreateInstance create_callback; 1751 }; 1752 1753 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 1754 1755 static std::recursive_mutex &GetSymbolVendorMutex() { 1756 static std::recursive_mutex g_instances_mutex; 1757 return g_instances_mutex; 1758 } 1759 1760 static SymbolVendorInstances &GetSymbolVendorInstances() { 1761 static SymbolVendorInstances g_instances; 1762 return g_instances; 1763 } 1764 1765 bool PluginManager::RegisterPlugin(ConstString name, 1766 const char *description, 1767 SymbolVendorCreateInstance create_callback) { 1768 if (create_callback) { 1769 SymbolVendorInstance instance; 1770 assert((bool)name); 1771 instance.name = name; 1772 if (description && description[0]) 1773 instance.description = description; 1774 instance.create_callback = create_callback; 1775 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1776 GetSymbolVendorInstances().push_back(instance); 1777 } 1778 return false; 1779 } 1780 1781 bool PluginManager::UnregisterPlugin( 1782 SymbolVendorCreateInstance create_callback) { 1783 if (create_callback) { 1784 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1785 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1786 1787 SymbolVendorInstances::iterator pos, end = instances.end(); 1788 for (pos = instances.begin(); pos != end; ++pos) { 1789 if (pos->create_callback == create_callback) { 1790 instances.erase(pos); 1791 return true; 1792 } 1793 } 1794 } 1795 return false; 1796 } 1797 1798 SymbolVendorCreateInstance 1799 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { 1800 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1801 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1802 if (idx < instances.size()) 1803 return instances[idx].create_callback; 1804 return nullptr; 1805 } 1806 1807 SymbolVendorCreateInstance 1808 PluginManager::GetSymbolVendorCreateCallbackForPluginName( 1809 ConstString name) { 1810 if (name) { 1811 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1812 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1813 1814 SymbolVendorInstances::iterator pos, end = instances.end(); 1815 for (pos = instances.begin(); pos != end; ++pos) { 1816 if (name == pos->name) 1817 return pos->create_callback; 1818 } 1819 } 1820 return nullptr; 1821 } 1822 1823 #pragma mark UnwindAssembly 1824 1825 struct UnwindAssemblyInstance { 1826 UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {} 1827 1828 ConstString name; 1829 std::string description; 1830 UnwindAssemblyCreateInstance create_callback; 1831 }; 1832 1833 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances; 1834 1835 static std::recursive_mutex &GetUnwindAssemblyMutex() { 1836 static std::recursive_mutex g_instances_mutex; 1837 return g_instances_mutex; 1838 } 1839 1840 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { 1841 static UnwindAssemblyInstances g_instances; 1842 return g_instances; 1843 } 1844 1845 bool PluginManager::RegisterPlugin( 1846 ConstString name, const char *description, 1847 UnwindAssemblyCreateInstance create_callback) { 1848 if (create_callback) { 1849 UnwindAssemblyInstance instance; 1850 assert((bool)name); 1851 instance.name = name; 1852 if (description && description[0]) 1853 instance.description = description; 1854 instance.create_callback = create_callback; 1855 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1856 GetUnwindAssemblyInstances().push_back(instance); 1857 } 1858 return false; 1859 } 1860 1861 bool PluginManager::UnregisterPlugin( 1862 UnwindAssemblyCreateInstance create_callback) { 1863 if (create_callback) { 1864 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1865 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1866 1867 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1868 for (pos = instances.begin(); pos != end; ++pos) { 1869 if (pos->create_callback == create_callback) { 1870 instances.erase(pos); 1871 return true; 1872 } 1873 } 1874 } 1875 return false; 1876 } 1877 1878 UnwindAssemblyCreateInstance 1879 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) { 1880 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1881 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1882 if (idx < instances.size()) 1883 return instances[idx].create_callback; 1884 return nullptr; 1885 } 1886 1887 UnwindAssemblyCreateInstance 1888 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName( 1889 ConstString name) { 1890 if (name) { 1891 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1892 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1893 1894 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1895 for (pos = instances.begin(); pos != end; ++pos) { 1896 if (name == pos->name) 1897 return pos->create_callback; 1898 } 1899 } 1900 return nullptr; 1901 } 1902 1903 #pragma mark MemoryHistory 1904 1905 struct MemoryHistoryInstance { 1906 MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {} 1907 1908 ConstString name; 1909 std::string description; 1910 MemoryHistoryCreateInstance create_callback; 1911 }; 1912 1913 typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances; 1914 1915 static std::recursive_mutex &GetMemoryHistoryMutex() { 1916 static std::recursive_mutex g_instances_mutex; 1917 return g_instances_mutex; 1918 } 1919 1920 static MemoryHistoryInstances &GetMemoryHistoryInstances() { 1921 static MemoryHistoryInstances g_instances; 1922 return g_instances; 1923 } 1924 1925 bool PluginManager::RegisterPlugin( 1926 ConstString name, const char *description, 1927 MemoryHistoryCreateInstance create_callback) { 1928 if (create_callback) { 1929 MemoryHistoryInstance instance; 1930 assert((bool)name); 1931 instance.name = name; 1932 if (description && description[0]) 1933 instance.description = description; 1934 instance.create_callback = create_callback; 1935 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1936 GetMemoryHistoryInstances().push_back(instance); 1937 } 1938 return false; 1939 } 1940 1941 bool PluginManager::UnregisterPlugin( 1942 MemoryHistoryCreateInstance create_callback) { 1943 if (create_callback) { 1944 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1945 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1946 1947 MemoryHistoryInstances::iterator pos, end = instances.end(); 1948 for (pos = instances.begin(); pos != end; ++pos) { 1949 if (pos->create_callback == create_callback) { 1950 instances.erase(pos); 1951 return true; 1952 } 1953 } 1954 } 1955 return false; 1956 } 1957 1958 MemoryHistoryCreateInstance 1959 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { 1960 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1961 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1962 if (idx < instances.size()) 1963 return instances[idx].create_callback; 1964 return nullptr; 1965 } 1966 1967 MemoryHistoryCreateInstance 1968 PluginManager::GetMemoryHistoryCreateCallbackForPluginName( 1969 ConstString name) { 1970 if (name) { 1971 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1972 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1973 1974 MemoryHistoryInstances::iterator pos, end = instances.end(); 1975 for (pos = instances.begin(); pos != end; ++pos) { 1976 if (name == pos->name) 1977 return pos->create_callback; 1978 } 1979 } 1980 return nullptr; 1981 } 1982 1983 #pragma mark InstrumentationRuntime 1984 1985 struct InstrumentationRuntimeInstance { 1986 InstrumentationRuntimeInstance() 1987 : name(), description(), create_callback(nullptr) {} 1988 1989 ConstString name; 1990 std::string description; 1991 InstrumentationRuntimeCreateInstance create_callback; 1992 InstrumentationRuntimeGetType get_type_callback; 1993 }; 1994 1995 typedef std::vector<InstrumentationRuntimeInstance> 1996 InstrumentationRuntimeInstances; 1997 1998 static std::recursive_mutex &GetInstrumentationRuntimeMutex() { 1999 static std::recursive_mutex g_instances_mutex; 2000 return g_instances_mutex; 2001 } 2002 2003 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { 2004 static InstrumentationRuntimeInstances g_instances; 2005 return g_instances; 2006 } 2007 2008 bool PluginManager::RegisterPlugin( 2009 ConstString name, const char *description, 2010 InstrumentationRuntimeCreateInstance create_callback, 2011 InstrumentationRuntimeGetType get_type_callback) { 2012 if (create_callback) { 2013 InstrumentationRuntimeInstance instance; 2014 assert((bool)name); 2015 instance.name = name; 2016 if (description && description[0]) 2017 instance.description = description; 2018 instance.create_callback = create_callback; 2019 instance.get_type_callback = get_type_callback; 2020 std::lock_guard<std::recursive_mutex> guard( 2021 GetInstrumentationRuntimeMutex()); 2022 GetInstrumentationRuntimeInstances().push_back(instance); 2023 } 2024 return false; 2025 } 2026 2027 bool PluginManager::UnregisterPlugin( 2028 InstrumentationRuntimeCreateInstance create_callback) { 2029 if (create_callback) { 2030 std::lock_guard<std::recursive_mutex> guard( 2031 GetInstrumentationRuntimeMutex()); 2032 InstrumentationRuntimeInstances &instances = 2033 GetInstrumentationRuntimeInstances(); 2034 2035 InstrumentationRuntimeInstances::iterator pos, end = instances.end(); 2036 for (pos = instances.begin(); pos != end; ++pos) { 2037 if (pos->create_callback == create_callback) { 2038 instances.erase(pos); 2039 return true; 2040 } 2041 } 2042 } 2043 return false; 2044 } 2045 2046 InstrumentationRuntimeGetType 2047 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { 2048 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex()); 2049 InstrumentationRuntimeInstances &instances = 2050 GetInstrumentationRuntimeInstances(); 2051 if (idx < instances.size()) 2052 return instances[idx].get_type_callback; 2053 return nullptr; 2054 } 2055 2056 InstrumentationRuntimeCreateInstance 2057 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { 2058 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex()); 2059 InstrumentationRuntimeInstances &instances = 2060 GetInstrumentationRuntimeInstances(); 2061 if (idx < instances.size()) 2062 return instances[idx].create_callback; 2063 return nullptr; 2064 } 2065 2066 InstrumentationRuntimeCreateInstance 2067 PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName( 2068 ConstString name) { 2069 if (name) { 2070 std::lock_guard<std::recursive_mutex> guard( 2071 GetInstrumentationRuntimeMutex()); 2072 InstrumentationRuntimeInstances &instances = 2073 GetInstrumentationRuntimeInstances(); 2074 2075 InstrumentationRuntimeInstances::iterator pos, end = instances.end(); 2076 for (pos = instances.begin(); pos != end; ++pos) { 2077 if (name == pos->name) 2078 return pos->create_callback; 2079 } 2080 } 2081 return nullptr; 2082 } 2083 2084 #pragma mark TypeSystem 2085 2086 struct TypeSystemInstance { 2087 TypeSystemInstance() : name(), description(), create_callback(nullptr) {} 2088 2089 ConstString name; 2090 std::string description; 2091 TypeSystemCreateInstance create_callback; 2092 TypeSystemEnumerateSupportedLanguages enumerate_callback; 2093 }; 2094 2095 typedef std::vector<TypeSystemInstance> TypeSystemInstances; 2096 2097 static std::recursive_mutex &GetTypeSystemMutex() { 2098 static std::recursive_mutex g_instances_mutex; 2099 return g_instances_mutex; 2100 } 2101 2102 static TypeSystemInstances &GetTypeSystemInstances() { 2103 static TypeSystemInstances g_instances; 2104 return g_instances; 2105 } 2106 2107 bool PluginManager::RegisterPlugin(ConstString name, 2108 const char *description, 2109 TypeSystemCreateInstance create_callback, 2110 TypeSystemEnumerateSupportedLanguages 2111 enumerate_supported_languages_callback) { 2112 if (create_callback) { 2113 TypeSystemInstance instance; 2114 assert((bool)name); 2115 instance.name = name; 2116 if (description && description[0]) 2117 instance.description = description; 2118 instance.create_callback = create_callback; 2119 instance.enumerate_callback = enumerate_supported_languages_callback; 2120 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2121 GetTypeSystemInstances().push_back(instance); 2122 } 2123 return false; 2124 } 2125 2126 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) { 2127 if (create_callback) { 2128 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2129 TypeSystemInstances &instances = GetTypeSystemInstances(); 2130 2131 TypeSystemInstances::iterator pos, end = instances.end(); 2132 for (pos = instances.begin(); pos != end; ++pos) { 2133 if (pos->create_callback == create_callback) { 2134 instances.erase(pos); 2135 return true; 2136 } 2137 } 2138 } 2139 return false; 2140 } 2141 2142 TypeSystemCreateInstance 2143 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) { 2144 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2145 TypeSystemInstances &instances = GetTypeSystemInstances(); 2146 if (idx < instances.size()) 2147 return instances[idx].create_callback; 2148 return nullptr; 2149 } 2150 2151 TypeSystemCreateInstance 2152 PluginManager::GetTypeSystemCreateCallbackForPluginName( 2153 ConstString name) { 2154 if (name) { 2155 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2156 TypeSystemInstances &instances = GetTypeSystemInstances(); 2157 2158 TypeSystemInstances::iterator pos, end = instances.end(); 2159 for (pos = instances.begin(); pos != end; ++pos) { 2160 if (name == pos->name) 2161 return pos->create_callback; 2162 } 2163 } 2164 return nullptr; 2165 } 2166 2167 TypeSystemEnumerateSupportedLanguages 2168 PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex( 2169 uint32_t idx) { 2170 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2171 TypeSystemInstances &instances = GetTypeSystemInstances(); 2172 if (idx < instances.size()) 2173 return instances[idx].enumerate_callback; 2174 return nullptr; 2175 } 2176 2177 TypeSystemEnumerateSupportedLanguages 2178 PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName( 2179 ConstString name) { 2180 if (name) { 2181 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2182 TypeSystemInstances &instances = GetTypeSystemInstances(); 2183 2184 TypeSystemInstances::iterator pos, end = instances.end(); 2185 for (pos = instances.begin(); pos != end; ++pos) { 2186 if (name == pos->name) 2187 return pos->enumerate_callback; 2188 } 2189 } 2190 return nullptr; 2191 } 2192 2193 #pragma mark REPL 2194 2195 struct REPLInstance { 2196 REPLInstance() : name(), description(), create_callback(nullptr) {} 2197 2198 ConstString name; 2199 std::string description; 2200 REPLCreateInstance create_callback; 2201 REPLEnumerateSupportedLanguages enumerate_languages_callback; 2202 }; 2203 2204 typedef std::vector<REPLInstance> REPLInstances; 2205 2206 static std::recursive_mutex &GetREPLMutex() { 2207 static std::recursive_mutex g_instances_mutex; 2208 return g_instances_mutex; 2209 } 2210 2211 static REPLInstances &GetREPLInstances() { 2212 static REPLInstances g_instances; 2213 return g_instances; 2214 } 2215 2216 bool PluginManager::RegisterPlugin( 2217 ConstString name, const char *description, 2218 REPLCreateInstance create_callback, 2219 REPLEnumerateSupportedLanguages enumerate_languages_callback) { 2220 if (create_callback) { 2221 REPLInstance instance; 2222 assert((bool)name); 2223 instance.name = name; 2224 if (description && description[0]) 2225 instance.description = description; 2226 instance.create_callback = create_callback; 2227 instance.enumerate_languages_callback = enumerate_languages_callback; 2228 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2229 GetREPLInstances().push_back(instance); 2230 } 2231 return false; 2232 } 2233 2234 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) { 2235 if (create_callback) { 2236 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2237 REPLInstances &instances = GetREPLInstances(); 2238 2239 REPLInstances::iterator pos, end = instances.end(); 2240 for (pos = instances.begin(); pos != end; ++pos) { 2241 if (pos->create_callback == create_callback) { 2242 instances.erase(pos); 2243 return true; 2244 } 2245 } 2246 } 2247 return false; 2248 } 2249 2250 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) { 2251 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2252 REPLInstances &instances = GetREPLInstances(); 2253 if (idx < instances.size()) 2254 return instances[idx].create_callback; 2255 return nullptr; 2256 } 2257 2258 REPLCreateInstance 2259 PluginManager::GetREPLCreateCallbackForPluginName(ConstString name) { 2260 if (name) { 2261 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2262 REPLInstances &instances = GetREPLInstances(); 2263 2264 REPLInstances::iterator pos, end = instances.end(); 2265 for (pos = instances.begin(); pos != end; ++pos) { 2266 if (name == pos->name) 2267 return pos->create_callback; 2268 } 2269 } 2270 return nullptr; 2271 } 2272 2273 REPLEnumerateSupportedLanguages 2274 PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) { 2275 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2276 REPLInstances &instances = GetREPLInstances(); 2277 if (idx < instances.size()) 2278 return instances[idx].enumerate_languages_callback; 2279 return nullptr; 2280 } 2281 2282 REPLEnumerateSupportedLanguages 2283 PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName( 2284 ConstString name) { 2285 if (name) { 2286 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2287 REPLInstances &instances = GetREPLInstances(); 2288 2289 REPLInstances::iterator pos, end = instances.end(); 2290 for (pos = instances.begin(); pos != end; ++pos) { 2291 if (name == pos->name) 2292 return pos->enumerate_languages_callback; 2293 } 2294 } 2295 return nullptr; 2296 } 2297 2298 #pragma mark PluginManager 2299 2300 void PluginManager::DebuggerInitialize(Debugger &debugger) { 2301 // Initialize the DynamicLoader plugins 2302 { 2303 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); 2304 DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); 2305 2306 DynamicLoaderInstances::iterator pos, end = instances.end(); 2307 for (pos = instances.begin(); pos != end; ++pos) { 2308 if (pos->debugger_init_callback) 2309 pos->debugger_init_callback(debugger); 2310 } 2311 } 2312 2313 // Initialize the JITLoader plugins 2314 { 2315 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); 2316 JITLoaderInstances &instances = GetJITLoaderInstances(); 2317 2318 JITLoaderInstances::iterator pos, end = instances.end(); 2319 for (pos = instances.begin(); pos != end; ++pos) { 2320 if (pos->debugger_init_callback) 2321 pos->debugger_init_callback(debugger); 2322 } 2323 } 2324 2325 // Initialize the Platform plugins 2326 { 2327 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 2328 PlatformInstances &instances = GetPlatformInstances(); 2329 2330 PlatformInstances::iterator pos, end = instances.end(); 2331 for (pos = instances.begin(); pos != end; ++pos) { 2332 if (pos->debugger_init_callback) 2333 pos->debugger_init_callback(debugger); 2334 } 2335 } 2336 2337 // Initialize the Process plugins 2338 { 2339 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 2340 ProcessInstances &instances = GetProcessInstances(); 2341 2342 ProcessInstances::iterator pos, end = instances.end(); 2343 for (pos = instances.begin(); pos != end; ++pos) { 2344 if (pos->debugger_init_callback) 2345 pos->debugger_init_callback(debugger); 2346 } 2347 } 2348 2349 // Initialize the SymbolFile plugins 2350 { 2351 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 2352 for (auto &sym_file : GetSymbolFileInstances()) { 2353 if (sym_file.debugger_init_callback) 2354 sym_file.debugger_init_callback(debugger); 2355 } 2356 } 2357 2358 // Initialize the OperatingSystem plugins 2359 { 2360 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); 2361 for (auto &os : GetOperatingSystemInstances()) { 2362 if (os.debugger_init_callback) 2363 os.debugger_init_callback(debugger); 2364 } 2365 } 2366 2367 // Initialize the StructuredDataPlugin plugins 2368 { 2369 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 2370 for (auto &plugin : GetStructuredDataPluginInstances()) { 2371 if (plugin.debugger_init_callback) 2372 plugin.debugger_init_callback(debugger); 2373 } 2374 } 2375 } 2376 2377 // This is the preferred new way to register plugin specific settings. e.g. 2378 // This will put a plugin's settings under e.g. 2379 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 2380 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins( 2381 Debugger &debugger, ConstString plugin_type_name, 2382 ConstString plugin_type_desc, bool can_create) { 2383 lldb::OptionValuePropertiesSP parent_properties_sp( 2384 debugger.GetValueProperties()); 2385 if (parent_properties_sp) { 2386 static ConstString g_property_name("plugin"); 2387 2388 OptionValuePropertiesSP plugin_properties_sp = 2389 parent_properties_sp->GetSubProperty(nullptr, g_property_name); 2390 if (!plugin_properties_sp && can_create) { 2391 plugin_properties_sp = 2392 std::make_shared<OptionValueProperties>(g_property_name); 2393 parent_properties_sp->AppendProperty( 2394 g_property_name, ConstString("Settings specify to plugins."), true, 2395 plugin_properties_sp); 2396 } 2397 2398 if (plugin_properties_sp) { 2399 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 2400 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name); 2401 if (!plugin_type_properties_sp && can_create) { 2402 plugin_type_properties_sp = 2403 std::make_shared<OptionValueProperties>(plugin_type_name); 2404 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 2405 true, plugin_type_properties_sp); 2406 } 2407 return plugin_type_properties_sp; 2408 } 2409 } 2410 return lldb::OptionValuePropertiesSP(); 2411 } 2412 2413 // This is deprecated way to register plugin specific settings. e.g. 2414 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform 2415 // generic settings would be under "platform.SETTINGNAME". 2416 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( 2417 Debugger &debugger, ConstString plugin_type_name, 2418 ConstString plugin_type_desc, bool can_create) { 2419 static ConstString g_property_name("plugin"); 2420 lldb::OptionValuePropertiesSP parent_properties_sp( 2421 debugger.GetValueProperties()); 2422 if (parent_properties_sp) { 2423 OptionValuePropertiesSP plugin_properties_sp = 2424 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name); 2425 if (!plugin_properties_sp && can_create) { 2426 plugin_properties_sp = 2427 std::make_shared<OptionValueProperties>(plugin_type_name); 2428 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 2429 true, plugin_properties_sp); 2430 } 2431 2432 if (plugin_properties_sp) { 2433 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 2434 plugin_properties_sp->GetSubProperty(nullptr, g_property_name); 2435 if (!plugin_type_properties_sp && can_create) { 2436 plugin_type_properties_sp = 2437 std::make_shared<OptionValueProperties>(g_property_name); 2438 plugin_properties_sp->AppendProperty( 2439 g_property_name, ConstString("Settings specific to plugins"), true, 2440 plugin_type_properties_sp); 2441 } 2442 return plugin_type_properties_sp; 2443 } 2444 } 2445 return lldb::OptionValuePropertiesSP(); 2446 } 2447 2448 namespace { 2449 2450 typedef lldb::OptionValuePropertiesSP 2451 GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString , 2452 ConstString , bool can_create); 2453 2454 lldb::OptionValuePropertiesSP 2455 GetSettingForPlugin(Debugger &debugger, ConstString setting_name, 2456 ConstString plugin_type_name, 2457 GetDebuggerPropertyForPluginsPtr get_debugger_property = 2458 GetDebuggerPropertyForPlugins) { 2459 lldb::OptionValuePropertiesSP properties_sp; 2460 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property( 2461 debugger, plugin_type_name, 2462 ConstString(), // not creating to so we don't need the description 2463 false)); 2464 if (plugin_type_properties_sp) 2465 properties_sp = 2466 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 2467 return properties_sp; 2468 } 2469 2470 bool CreateSettingForPlugin( 2471 Debugger &debugger, ConstString plugin_type_name, 2472 ConstString plugin_type_desc, 2473 const lldb::OptionValuePropertiesSP &properties_sp, 2474 ConstString description, bool is_global_property, 2475 GetDebuggerPropertyForPluginsPtr get_debugger_property = 2476 GetDebuggerPropertyForPlugins) { 2477 if (properties_sp) { 2478 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2479 get_debugger_property(debugger, plugin_type_name, plugin_type_desc, 2480 true)); 2481 if (plugin_type_properties_sp) { 2482 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 2483 description, is_global_property, 2484 properties_sp); 2485 return true; 2486 } 2487 } 2488 return false; 2489 } 2490 2491 const char *kDynamicLoaderPluginName("dynamic-loader"); 2492 const char *kPlatformPluginName("platform"); 2493 const char *kProcessPluginName("process"); 2494 const char *kSymbolFilePluginName("symbol-file"); 2495 const char *kJITLoaderPluginName("jit-loader"); 2496 const char *kStructuredDataPluginName("structured-data"); 2497 2498 } // anonymous namespace 2499 2500 lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin( 2501 Debugger &debugger, ConstString setting_name) { 2502 return GetSettingForPlugin(debugger, setting_name, 2503 ConstString(kDynamicLoaderPluginName)); 2504 } 2505 2506 bool PluginManager::CreateSettingForDynamicLoaderPlugin( 2507 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2508 ConstString description, bool is_global_property) { 2509 return CreateSettingForPlugin( 2510 debugger, ConstString(kDynamicLoaderPluginName), 2511 ConstString("Settings for dynamic loader plug-ins"), properties_sp, 2512 description, is_global_property); 2513 } 2514 2515 lldb::OptionValuePropertiesSP 2516 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger, 2517 ConstString setting_name) { 2518 return GetSettingForPlugin(debugger, setting_name, 2519 ConstString(kPlatformPluginName), 2520 GetDebuggerPropertyForPluginsOldStyle); 2521 } 2522 2523 bool PluginManager::CreateSettingForPlatformPlugin( 2524 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2525 ConstString description, bool is_global_property) { 2526 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName), 2527 ConstString("Settings for platform plug-ins"), 2528 properties_sp, description, is_global_property, 2529 GetDebuggerPropertyForPluginsOldStyle); 2530 } 2531 2532 lldb::OptionValuePropertiesSP 2533 PluginManager::GetSettingForProcessPlugin(Debugger &debugger, 2534 ConstString setting_name) { 2535 return GetSettingForPlugin(debugger, setting_name, 2536 ConstString(kProcessPluginName)); 2537 } 2538 2539 bool PluginManager::CreateSettingForProcessPlugin( 2540 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2541 ConstString description, bool is_global_property) { 2542 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName), 2543 ConstString("Settings for process plug-ins"), 2544 properties_sp, description, is_global_property); 2545 } 2546 2547 lldb::OptionValuePropertiesSP 2548 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger, 2549 ConstString setting_name) { 2550 return GetSettingForPlugin(debugger, setting_name, 2551 ConstString(kSymbolFilePluginName)); 2552 } 2553 2554 bool PluginManager::CreateSettingForSymbolFilePlugin( 2555 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2556 ConstString description, bool is_global_property) { 2557 return CreateSettingForPlugin( 2558 debugger, ConstString(kSymbolFilePluginName), 2559 ConstString("Settings for symbol file plug-ins"), properties_sp, 2560 description, is_global_property); 2561 } 2562 2563 lldb::OptionValuePropertiesSP 2564 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger, 2565 ConstString setting_name) { 2566 return GetSettingForPlugin(debugger, setting_name, 2567 ConstString(kJITLoaderPluginName)); 2568 } 2569 2570 bool PluginManager::CreateSettingForJITLoaderPlugin( 2571 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2572 ConstString description, bool is_global_property) { 2573 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName), 2574 ConstString("Settings for JIT loader plug-ins"), 2575 properties_sp, description, is_global_property); 2576 } 2577 2578 static const char *kOperatingSystemPluginName("os"); 2579 2580 lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin( 2581 Debugger &debugger, ConstString setting_name) { 2582 lldb::OptionValuePropertiesSP properties_sp; 2583 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2584 GetDebuggerPropertyForPlugins( 2585 debugger, ConstString(kOperatingSystemPluginName), 2586 ConstString(), // not creating to so we don't need the description 2587 false)); 2588 if (plugin_type_properties_sp) 2589 properties_sp = 2590 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 2591 return properties_sp; 2592 } 2593 2594 bool PluginManager::CreateSettingForOperatingSystemPlugin( 2595 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2596 ConstString description, bool is_global_property) { 2597 if (properties_sp) { 2598 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2599 GetDebuggerPropertyForPlugins( 2600 debugger, ConstString(kOperatingSystemPluginName), 2601 ConstString("Settings for operating system plug-ins"), true)); 2602 if (plugin_type_properties_sp) { 2603 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 2604 description, is_global_property, 2605 properties_sp); 2606 return true; 2607 } 2608 } 2609 return false; 2610 } 2611 2612 lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin( 2613 Debugger &debugger, ConstString setting_name) { 2614 return GetSettingForPlugin(debugger, setting_name, 2615 ConstString(kStructuredDataPluginName)); 2616 } 2617 2618 bool PluginManager::CreateSettingForStructuredDataPlugin( 2619 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2620 ConstString description, bool is_global_property) { 2621 return CreateSettingForPlugin( 2622 debugger, ConstString(kStructuredDataPluginName), 2623 ConstString("Settings for structured data plug-ins"), properties_sp, 2624 description, is_global_property); 2625 } 2626