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 }; 832 833 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances; 834 835 static std::recursive_mutex &GetLanguageRuntimeMutex() { 836 static std::recursive_mutex g_instances_mutex; 837 return g_instances_mutex; 838 } 839 840 static LanguageRuntimeInstances &GetLanguageRuntimeInstances() { 841 static LanguageRuntimeInstances g_instances; 842 return g_instances; 843 } 844 845 bool PluginManager::RegisterPlugin( 846 ConstString name, const char *description, 847 LanguageRuntimeCreateInstance create_callback, 848 LanguageRuntimeGetCommandObject command_callback) { 849 if (create_callback) { 850 LanguageRuntimeInstance instance; 851 assert((bool)name); 852 instance.name = name; 853 if (description && description[0]) 854 instance.description = description; 855 instance.create_callback = create_callback; 856 instance.command_callback = command_callback; 857 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 858 GetLanguageRuntimeInstances().push_back(instance); 859 } 860 return false; 861 } 862 863 bool PluginManager::UnregisterPlugin( 864 LanguageRuntimeCreateInstance create_callback) { 865 if (create_callback) { 866 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 867 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); 868 869 LanguageRuntimeInstances::iterator pos, end = instances.end(); 870 for (pos = instances.begin(); pos != end; ++pos) { 871 if (pos->create_callback == create_callback) { 872 instances.erase(pos); 873 return true; 874 } 875 } 876 } 877 return false; 878 } 879 880 LanguageRuntimeCreateInstance 881 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) { 882 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 883 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); 884 if (idx < instances.size()) 885 return instances[idx].create_callback; 886 return nullptr; 887 } 888 889 LanguageRuntimeGetCommandObject 890 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) { 891 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 892 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); 893 if (idx < instances.size()) 894 return instances[idx].command_callback; 895 return nullptr; 896 } 897 898 LanguageRuntimeCreateInstance 899 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName( 900 ConstString name) { 901 if (name) { 902 std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); 903 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); 904 905 LanguageRuntimeInstances::iterator pos, end = instances.end(); 906 for (pos = instances.begin(); pos != end; ++pos) { 907 if (name == pos->name) 908 return pos->create_callback; 909 } 910 } 911 return nullptr; 912 } 913 914 #pragma mark SystemRuntime 915 916 struct SystemRuntimeInstance { 917 SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {} 918 919 ConstString name; 920 std::string description; 921 SystemRuntimeCreateInstance create_callback; 922 }; 923 924 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances; 925 926 static std::recursive_mutex &GetSystemRuntimeMutex() { 927 static std::recursive_mutex g_instances_mutex; 928 return g_instances_mutex; 929 } 930 931 static SystemRuntimeInstances &GetSystemRuntimeInstances() { 932 static SystemRuntimeInstances g_instances; 933 return g_instances; 934 } 935 936 bool PluginManager::RegisterPlugin( 937 ConstString name, const char *description, 938 SystemRuntimeCreateInstance create_callback) { 939 if (create_callback) { 940 SystemRuntimeInstance instance; 941 assert((bool)name); 942 instance.name = name; 943 if (description && description[0]) 944 instance.description = description; 945 instance.create_callback = create_callback; 946 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); 947 GetSystemRuntimeInstances().push_back(instance); 948 } 949 return false; 950 } 951 952 bool PluginManager::UnregisterPlugin( 953 SystemRuntimeCreateInstance create_callback) { 954 if (create_callback) { 955 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); 956 SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); 957 958 SystemRuntimeInstances::iterator pos, end = instances.end(); 959 for (pos = instances.begin(); pos != end; ++pos) { 960 if (pos->create_callback == create_callback) { 961 instances.erase(pos); 962 return true; 963 } 964 } 965 } 966 return false; 967 } 968 969 SystemRuntimeCreateInstance 970 PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) { 971 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); 972 SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); 973 if (idx < instances.size()) 974 return instances[idx].create_callback; 975 return nullptr; 976 } 977 978 SystemRuntimeCreateInstance 979 PluginManager::GetSystemRuntimeCreateCallbackForPluginName( 980 ConstString name) { 981 if (name) { 982 std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); 983 SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); 984 985 SystemRuntimeInstances::iterator pos, end = instances.end(); 986 for (pos = instances.begin(); pos != end; ++pos) { 987 if (name == pos->name) 988 return pos->create_callback; 989 } 990 } 991 return nullptr; 992 } 993 994 #pragma mark ObjectFile 995 996 struct ObjectFileInstance { 997 ObjectFileInstance() 998 : name(), description(), create_callback(nullptr), 999 create_memory_callback(nullptr), get_module_specifications(nullptr), 1000 save_core(nullptr) {} 1001 1002 ConstString name; 1003 std::string description; 1004 ObjectFileCreateInstance create_callback; 1005 ObjectFileCreateMemoryInstance create_memory_callback; 1006 ObjectFileGetModuleSpecifications get_module_specifications; 1007 ObjectFileSaveCore save_core; 1008 }; 1009 1010 typedef std::vector<ObjectFileInstance> ObjectFileInstances; 1011 1012 static std::recursive_mutex &GetObjectFileMutex() { 1013 static std::recursive_mutex g_instances_mutex; 1014 return g_instances_mutex; 1015 } 1016 1017 static ObjectFileInstances &GetObjectFileInstances() { 1018 static ObjectFileInstances g_instances; 1019 return g_instances; 1020 } 1021 1022 bool PluginManager::RegisterPlugin( 1023 ConstString name, const char *description, 1024 ObjectFileCreateInstance create_callback, 1025 ObjectFileCreateMemoryInstance create_memory_callback, 1026 ObjectFileGetModuleSpecifications get_module_specifications, 1027 ObjectFileSaveCore save_core) { 1028 if (create_callback) { 1029 ObjectFileInstance instance; 1030 assert((bool)name); 1031 instance.name = name; 1032 if (description && description[0]) 1033 instance.description = description; 1034 instance.create_callback = create_callback; 1035 instance.create_memory_callback = create_memory_callback; 1036 instance.save_core = save_core; 1037 instance.get_module_specifications = get_module_specifications; 1038 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1039 GetObjectFileInstances().push_back(instance); 1040 } 1041 return false; 1042 } 1043 1044 bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) { 1045 if (create_callback) { 1046 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1047 ObjectFileInstances &instances = GetObjectFileInstances(); 1048 1049 ObjectFileInstances::iterator pos, end = instances.end(); 1050 for (pos = instances.begin(); pos != end; ++pos) { 1051 if (pos->create_callback == create_callback) { 1052 instances.erase(pos); 1053 return true; 1054 } 1055 } 1056 } 1057 return false; 1058 } 1059 1060 ObjectFileCreateInstance 1061 PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) { 1062 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1063 ObjectFileInstances &instances = GetObjectFileInstances(); 1064 if (idx < instances.size()) 1065 return instances[idx].create_callback; 1066 return nullptr; 1067 } 1068 1069 ObjectFileCreateMemoryInstance 1070 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) { 1071 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1072 ObjectFileInstances &instances = GetObjectFileInstances(); 1073 if (idx < instances.size()) 1074 return instances[idx].create_memory_callback; 1075 return nullptr; 1076 } 1077 1078 ObjectFileGetModuleSpecifications 1079 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex( 1080 uint32_t idx) { 1081 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1082 ObjectFileInstances &instances = GetObjectFileInstances(); 1083 if (idx < instances.size()) 1084 return instances[idx].get_module_specifications; 1085 return nullptr; 1086 } 1087 1088 ObjectFileCreateInstance 1089 PluginManager::GetObjectFileCreateCallbackForPluginName( 1090 ConstString name) { 1091 if (name) { 1092 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1093 ObjectFileInstances &instances = GetObjectFileInstances(); 1094 1095 ObjectFileInstances::iterator pos, end = instances.end(); 1096 for (pos = instances.begin(); pos != end; ++pos) { 1097 if (name == pos->name) 1098 return pos->create_callback; 1099 } 1100 } 1101 return nullptr; 1102 } 1103 1104 ObjectFileCreateMemoryInstance 1105 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( 1106 ConstString name) { 1107 if (name) { 1108 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1109 ObjectFileInstances &instances = GetObjectFileInstances(); 1110 1111 ObjectFileInstances::iterator pos, end = instances.end(); 1112 for (pos = instances.begin(); pos != end; ++pos) { 1113 if (name == pos->name) 1114 return pos->create_memory_callback; 1115 } 1116 } 1117 return nullptr; 1118 } 1119 1120 Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, 1121 const FileSpec &outfile) { 1122 Status error; 1123 std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); 1124 ObjectFileInstances &instances = GetObjectFileInstances(); 1125 1126 ObjectFileInstances::iterator pos, end = instances.end(); 1127 for (pos = instances.begin(); pos != end; ++pos) { 1128 if (pos->save_core && pos->save_core(process_sp, outfile, error)) 1129 return error; 1130 } 1131 error.SetErrorString( 1132 "no ObjectFile plugins were able to save a core for this process"); 1133 return error; 1134 } 1135 1136 #pragma mark ObjectContainer 1137 1138 struct ObjectContainerInstance { 1139 ObjectContainerInstance() 1140 : name(), description(), create_callback(nullptr), 1141 get_module_specifications(nullptr) {} 1142 1143 ConstString name; 1144 std::string description; 1145 ObjectContainerCreateInstance create_callback; 1146 ObjectFileGetModuleSpecifications get_module_specifications; 1147 }; 1148 1149 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; 1150 1151 static std::recursive_mutex &GetObjectContainerMutex() { 1152 static std::recursive_mutex g_instances_mutex; 1153 return g_instances_mutex; 1154 } 1155 1156 static ObjectContainerInstances &GetObjectContainerInstances() { 1157 static ObjectContainerInstances g_instances; 1158 return g_instances; 1159 } 1160 1161 bool PluginManager::RegisterPlugin( 1162 ConstString name, const char *description, 1163 ObjectContainerCreateInstance create_callback, 1164 ObjectFileGetModuleSpecifications get_module_specifications) { 1165 if (create_callback) { 1166 ObjectContainerInstance instance; 1167 assert((bool)name); 1168 instance.name = name; 1169 if (description && description[0]) 1170 instance.description = description; 1171 instance.create_callback = create_callback; 1172 instance.get_module_specifications = get_module_specifications; 1173 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); 1174 GetObjectContainerInstances().push_back(instance); 1175 } 1176 return false; 1177 } 1178 1179 bool PluginManager::UnregisterPlugin( 1180 ObjectContainerCreateInstance create_callback) { 1181 if (create_callback) { 1182 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); 1183 ObjectContainerInstances &instances = GetObjectContainerInstances(); 1184 1185 ObjectContainerInstances::iterator pos, end = instances.end(); 1186 for (pos = instances.begin(); pos != end; ++pos) { 1187 if (pos->create_callback == create_callback) { 1188 instances.erase(pos); 1189 return true; 1190 } 1191 } 1192 } 1193 return false; 1194 } 1195 1196 ObjectContainerCreateInstance 1197 PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) { 1198 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); 1199 ObjectContainerInstances &instances = GetObjectContainerInstances(); 1200 if (idx < instances.size()) 1201 return instances[idx].create_callback; 1202 return nullptr; 1203 } 1204 1205 ObjectContainerCreateInstance 1206 PluginManager::GetObjectContainerCreateCallbackForPluginName( 1207 ConstString name) { 1208 if (name) { 1209 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); 1210 ObjectContainerInstances &instances = GetObjectContainerInstances(); 1211 1212 ObjectContainerInstances::iterator pos, end = instances.end(); 1213 for (pos = instances.begin(); pos != end; ++pos) { 1214 if (name == pos->name) 1215 return pos->create_callback; 1216 } 1217 } 1218 return nullptr; 1219 } 1220 1221 ObjectFileGetModuleSpecifications 1222 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex( 1223 uint32_t idx) { 1224 std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); 1225 ObjectContainerInstances &instances = GetObjectContainerInstances(); 1226 if (idx < instances.size()) 1227 return instances[idx].get_module_specifications; 1228 return nullptr; 1229 } 1230 1231 #pragma mark Platform 1232 1233 struct PlatformInstance { 1234 PlatformInstance() 1235 : name(), description(), create_callback(nullptr), 1236 debugger_init_callback(nullptr) {} 1237 1238 ConstString name; 1239 std::string description; 1240 PlatformCreateInstance create_callback; 1241 DebuggerInitializeCallback debugger_init_callback; 1242 }; 1243 1244 typedef std::vector<PlatformInstance> PlatformInstances; 1245 1246 static std::recursive_mutex &GetPlatformInstancesMutex() { 1247 static std::recursive_mutex g_platform_instances_mutex; 1248 return g_platform_instances_mutex; 1249 } 1250 1251 static PlatformInstances &GetPlatformInstances() { 1252 static PlatformInstances g_platform_instances; 1253 return g_platform_instances; 1254 } 1255 1256 bool PluginManager::RegisterPlugin( 1257 ConstString name, const char *description, 1258 PlatformCreateInstance create_callback, 1259 DebuggerInitializeCallback debugger_init_callback) { 1260 if (create_callback) { 1261 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1262 1263 PlatformInstance instance; 1264 assert((bool)name); 1265 instance.name = name; 1266 if (description && description[0]) 1267 instance.description = description; 1268 instance.create_callback = create_callback; 1269 instance.debugger_init_callback = debugger_init_callback; 1270 GetPlatformInstances().push_back(instance); 1271 return true; 1272 } 1273 return false; 1274 } 1275 1276 const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { 1277 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1278 PlatformInstances &instances = GetPlatformInstances(); 1279 if (idx < instances.size()) 1280 return instances[idx].name.GetCString(); 1281 return nullptr; 1282 } 1283 1284 const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { 1285 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1286 PlatformInstances &instances = GetPlatformInstances(); 1287 if (idx < instances.size()) 1288 return instances[idx].description.c_str(); 1289 return nullptr; 1290 } 1291 1292 bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { 1293 if (create_callback) { 1294 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1295 PlatformInstances &instances = GetPlatformInstances(); 1296 1297 PlatformInstances::iterator pos, end = instances.end(); 1298 for (pos = instances.begin(); pos != end; ++pos) { 1299 if (pos->create_callback == create_callback) { 1300 instances.erase(pos); 1301 return true; 1302 } 1303 } 1304 } 1305 return false; 1306 } 1307 1308 PlatformCreateInstance 1309 PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) { 1310 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1311 PlatformInstances &instances = GetPlatformInstances(); 1312 if (idx < instances.size()) 1313 return instances[idx].create_callback; 1314 return nullptr; 1315 } 1316 1317 PlatformCreateInstance 1318 PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) { 1319 if (name) { 1320 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1321 PlatformInstances &instances = GetPlatformInstances(); 1322 1323 PlatformInstances::iterator pos, end = instances.end(); 1324 for (pos = instances.begin(); pos != end; ++pos) { 1325 if (name == pos->name) 1326 return pos->create_callback; 1327 } 1328 } 1329 return nullptr; 1330 } 1331 1332 size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name, 1333 StringList &matches) { 1334 if (name.empty()) 1335 return matches.GetSize(); 1336 1337 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1338 PlatformInstances &instances = GetPlatformInstances(); 1339 llvm::StringRef name_sref(name); 1340 1341 PlatformInstances::iterator pos, end = instances.end(); 1342 for (pos = instances.begin(); pos != end; ++pos) { 1343 llvm::StringRef plugin_name(pos->name.GetCString()); 1344 if (plugin_name.startswith(name_sref)) 1345 matches.AppendString(plugin_name.data()); 1346 } 1347 return matches.GetSize(); 1348 } 1349 1350 #pragma mark Process 1351 1352 struct ProcessInstance { 1353 ProcessInstance() 1354 : name(), description(), create_callback(nullptr), 1355 debugger_init_callback(nullptr) {} 1356 1357 ConstString name; 1358 std::string description; 1359 ProcessCreateInstance create_callback; 1360 DebuggerInitializeCallback debugger_init_callback; 1361 }; 1362 1363 typedef std::vector<ProcessInstance> ProcessInstances; 1364 1365 static std::recursive_mutex &GetProcessMutex() { 1366 static std::recursive_mutex g_instances_mutex; 1367 return g_instances_mutex; 1368 } 1369 1370 static ProcessInstances &GetProcessInstances() { 1371 static ProcessInstances g_instances; 1372 return g_instances; 1373 } 1374 1375 bool PluginManager::RegisterPlugin( 1376 ConstString name, const char *description, 1377 ProcessCreateInstance create_callback, 1378 DebuggerInitializeCallback debugger_init_callback) { 1379 if (create_callback) { 1380 ProcessInstance instance; 1381 assert((bool)name); 1382 instance.name = name; 1383 if (description && description[0]) 1384 instance.description = description; 1385 instance.create_callback = create_callback; 1386 instance.debugger_init_callback = debugger_init_callback; 1387 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1388 GetProcessInstances().push_back(instance); 1389 } 1390 return false; 1391 } 1392 1393 const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { 1394 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1395 ProcessInstances &instances = GetProcessInstances(); 1396 if (idx < instances.size()) 1397 return instances[idx].name.GetCString(); 1398 return nullptr; 1399 } 1400 1401 const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { 1402 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1403 ProcessInstances &instances = GetProcessInstances(); 1404 if (idx < instances.size()) 1405 return instances[idx].description.c_str(); 1406 return nullptr; 1407 } 1408 1409 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { 1410 if (create_callback) { 1411 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1412 ProcessInstances &instances = GetProcessInstances(); 1413 1414 ProcessInstances::iterator pos, end = instances.end(); 1415 for (pos = instances.begin(); pos != end; ++pos) { 1416 if (pos->create_callback == create_callback) { 1417 instances.erase(pos); 1418 return true; 1419 } 1420 } 1421 } 1422 return false; 1423 } 1424 1425 ProcessCreateInstance 1426 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { 1427 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1428 ProcessInstances &instances = GetProcessInstances(); 1429 if (idx < instances.size()) 1430 return instances[idx].create_callback; 1431 return nullptr; 1432 } 1433 1434 ProcessCreateInstance 1435 PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) { 1436 if (name) { 1437 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1438 ProcessInstances &instances = GetProcessInstances(); 1439 1440 ProcessInstances::iterator pos, end = instances.end(); 1441 for (pos = instances.begin(); pos != end; ++pos) { 1442 if (name == pos->name) 1443 return pos->create_callback; 1444 } 1445 } 1446 return nullptr; 1447 } 1448 1449 #pragma mark ScriptInterpreter 1450 1451 struct ScriptInterpreterInstance { 1452 ScriptInterpreterInstance() 1453 : name(), language(lldb::eScriptLanguageNone), description(), 1454 create_callback(nullptr) {} 1455 1456 ConstString name; 1457 lldb::ScriptLanguage language; 1458 std::string description; 1459 ScriptInterpreterCreateInstance create_callback; 1460 }; 1461 1462 typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances; 1463 1464 static std::recursive_mutex &GetScriptInterpreterMutex() { 1465 static std::recursive_mutex g_instances_mutex; 1466 return g_instances_mutex; 1467 } 1468 1469 static ScriptInterpreterInstances &GetScriptInterpreterInstances() { 1470 static ScriptInterpreterInstances g_instances; 1471 return g_instances; 1472 } 1473 1474 bool PluginManager::RegisterPlugin( 1475 ConstString name, const char *description, 1476 lldb::ScriptLanguage script_language, 1477 ScriptInterpreterCreateInstance create_callback) { 1478 if (!create_callback) 1479 return false; 1480 ScriptInterpreterInstance instance; 1481 assert((bool)name); 1482 instance.name = name; 1483 if (description && description[0]) 1484 instance.description = description; 1485 instance.create_callback = create_callback; 1486 instance.language = script_language; 1487 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1488 GetScriptInterpreterInstances().push_back(instance); 1489 return false; 1490 } 1491 1492 bool PluginManager::UnregisterPlugin( 1493 ScriptInterpreterCreateInstance create_callback) { 1494 if (!create_callback) 1495 return false; 1496 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1497 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1498 1499 ScriptInterpreterInstances::iterator pos, end = instances.end(); 1500 for (pos = instances.begin(); pos != end; ++pos) { 1501 if (pos->create_callback != create_callback) 1502 continue; 1503 1504 instances.erase(pos); 1505 return true; 1506 } 1507 return false; 1508 } 1509 1510 ScriptInterpreterCreateInstance 1511 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) { 1512 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1513 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1514 if (idx < instances.size()) 1515 return instances[idx].create_callback; 1516 return nullptr; 1517 } 1518 1519 lldb::ScriptInterpreterSP PluginManager::GetScriptInterpreterForLanguage( 1520 lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter) { 1521 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1522 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1523 1524 ScriptInterpreterInstances::iterator pos, end = instances.end(); 1525 ScriptInterpreterCreateInstance none_instance = nullptr; 1526 for (pos = instances.begin(); pos != end; ++pos) { 1527 if (pos->language == lldb::eScriptLanguageNone) 1528 none_instance = pos->create_callback; 1529 1530 if (script_lang == pos->language) 1531 return pos->create_callback(interpreter); 1532 } 1533 1534 // If we didn't find one, return the ScriptInterpreter for the null language. 1535 assert(none_instance != nullptr); 1536 return none_instance(interpreter); 1537 } 1538 1539 #pragma mark - 1540 #pragma mark StructuredDataPlugin 1541 1542 // StructuredDataPlugin 1543 1544 struct StructuredDataPluginInstance { 1545 StructuredDataPluginInstance() 1546 : name(), description(), create_callback(nullptr), 1547 debugger_init_callback(nullptr), filter_callback(nullptr) {} 1548 1549 ConstString name; 1550 std::string description; 1551 StructuredDataPluginCreateInstance create_callback; 1552 DebuggerInitializeCallback debugger_init_callback; 1553 StructuredDataFilterLaunchInfo filter_callback; 1554 }; 1555 1556 typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances; 1557 1558 static std::recursive_mutex &GetStructuredDataPluginMutex() { 1559 static std::recursive_mutex g_instances_mutex; 1560 return g_instances_mutex; 1561 } 1562 1563 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { 1564 static StructuredDataPluginInstances g_instances; 1565 return g_instances; 1566 } 1567 1568 bool PluginManager::RegisterPlugin( 1569 ConstString name, const char *description, 1570 StructuredDataPluginCreateInstance create_callback, 1571 DebuggerInitializeCallback debugger_init_callback, 1572 StructuredDataFilterLaunchInfo filter_callback) { 1573 if (create_callback) { 1574 StructuredDataPluginInstance instance; 1575 assert((bool)name); 1576 instance.name = name; 1577 if (description && description[0]) 1578 instance.description = description; 1579 instance.create_callback = create_callback; 1580 instance.debugger_init_callback = debugger_init_callback; 1581 instance.filter_callback = filter_callback; 1582 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1583 GetStructuredDataPluginInstances().push_back(instance); 1584 } 1585 return false; 1586 } 1587 1588 bool PluginManager::UnregisterPlugin( 1589 StructuredDataPluginCreateInstance create_callback) { 1590 if (create_callback) { 1591 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1592 StructuredDataPluginInstances &instances = 1593 GetStructuredDataPluginInstances(); 1594 1595 StructuredDataPluginInstances::iterator pos, end = instances.end(); 1596 for (pos = instances.begin(); pos != end; ++pos) { 1597 if (pos->create_callback == create_callback) { 1598 instances.erase(pos); 1599 return true; 1600 } 1601 } 1602 } 1603 return false; 1604 } 1605 1606 StructuredDataPluginCreateInstance 1607 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) { 1608 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1609 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); 1610 if (idx < instances.size()) 1611 return instances[idx].create_callback; 1612 return nullptr; 1613 } 1614 1615 StructuredDataPluginCreateInstance 1616 PluginManager::GetStructuredDataPluginCreateCallbackForPluginName( 1617 ConstString name) { 1618 if (name) { 1619 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1620 StructuredDataPluginInstances &instances = 1621 GetStructuredDataPluginInstances(); 1622 1623 StructuredDataPluginInstances::iterator pos, end = instances.end(); 1624 for (pos = instances.begin(); pos != end; ++pos) { 1625 if (name == pos->name) 1626 return pos->create_callback; 1627 } 1628 } 1629 return nullptr; 1630 } 1631 1632 StructuredDataFilterLaunchInfo 1633 PluginManager::GetStructuredDataFilterCallbackAtIndex( 1634 uint32_t idx, bool &iteration_complete) { 1635 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1636 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); 1637 if (idx < instances.size()) { 1638 iteration_complete = false; 1639 return instances[idx].filter_callback; 1640 } else { 1641 iteration_complete = true; 1642 } 1643 return nullptr; 1644 } 1645 1646 #pragma mark SymbolFile 1647 1648 struct SymbolFileInstance { 1649 SymbolFileInstance() 1650 : name(), description(), create_callback(nullptr), 1651 debugger_init_callback(nullptr) {} 1652 1653 ConstString name; 1654 std::string description; 1655 SymbolFileCreateInstance create_callback; 1656 DebuggerInitializeCallback debugger_init_callback; 1657 }; 1658 1659 typedef std::vector<SymbolFileInstance> SymbolFileInstances; 1660 1661 static std::recursive_mutex &GetSymbolFileMutex() { 1662 static std::recursive_mutex g_instances_mutex; 1663 return g_instances_mutex; 1664 } 1665 1666 static SymbolFileInstances &GetSymbolFileInstances() { 1667 static SymbolFileInstances g_instances; 1668 return g_instances; 1669 } 1670 1671 bool PluginManager::RegisterPlugin( 1672 ConstString name, const char *description, 1673 SymbolFileCreateInstance create_callback, 1674 DebuggerInitializeCallback debugger_init_callback) { 1675 if (create_callback) { 1676 SymbolFileInstance instance; 1677 assert((bool)name); 1678 instance.name = name; 1679 if (description && description[0]) 1680 instance.description = description; 1681 instance.create_callback = create_callback; 1682 instance.debugger_init_callback = debugger_init_callback; 1683 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1684 GetSymbolFileInstances().push_back(instance); 1685 } 1686 return false; 1687 } 1688 1689 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) { 1690 if (create_callback) { 1691 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1692 SymbolFileInstances &instances = GetSymbolFileInstances(); 1693 1694 SymbolFileInstances::iterator pos, end = instances.end(); 1695 for (pos = instances.begin(); pos != end; ++pos) { 1696 if (pos->create_callback == create_callback) { 1697 instances.erase(pos); 1698 return true; 1699 } 1700 } 1701 } 1702 return false; 1703 } 1704 1705 SymbolFileCreateInstance 1706 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) { 1707 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1708 SymbolFileInstances &instances = GetSymbolFileInstances(); 1709 if (idx < instances.size()) 1710 return instances[idx].create_callback; 1711 return nullptr; 1712 } 1713 1714 SymbolFileCreateInstance 1715 PluginManager::GetSymbolFileCreateCallbackForPluginName( 1716 ConstString name) { 1717 if (name) { 1718 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1719 SymbolFileInstances &instances = GetSymbolFileInstances(); 1720 1721 SymbolFileInstances::iterator pos, end = instances.end(); 1722 for (pos = instances.begin(); pos != end; ++pos) { 1723 if (name == pos->name) 1724 return pos->create_callback; 1725 } 1726 } 1727 return nullptr; 1728 } 1729 1730 #pragma mark SymbolVendor 1731 1732 struct SymbolVendorInstance { 1733 SymbolVendorInstance() : name(), description(), create_callback(nullptr) {} 1734 1735 ConstString name; 1736 std::string description; 1737 SymbolVendorCreateInstance create_callback; 1738 }; 1739 1740 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 1741 1742 static std::recursive_mutex &GetSymbolVendorMutex() { 1743 static std::recursive_mutex g_instances_mutex; 1744 return g_instances_mutex; 1745 } 1746 1747 static SymbolVendorInstances &GetSymbolVendorInstances() { 1748 static SymbolVendorInstances g_instances; 1749 return g_instances; 1750 } 1751 1752 bool PluginManager::RegisterPlugin(ConstString name, 1753 const char *description, 1754 SymbolVendorCreateInstance create_callback) { 1755 if (create_callback) { 1756 SymbolVendorInstance instance; 1757 assert((bool)name); 1758 instance.name = name; 1759 if (description && description[0]) 1760 instance.description = description; 1761 instance.create_callback = create_callback; 1762 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1763 GetSymbolVendorInstances().push_back(instance); 1764 } 1765 return false; 1766 } 1767 1768 bool PluginManager::UnregisterPlugin( 1769 SymbolVendorCreateInstance create_callback) { 1770 if (create_callback) { 1771 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1772 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1773 1774 SymbolVendorInstances::iterator pos, end = instances.end(); 1775 for (pos = instances.begin(); pos != end; ++pos) { 1776 if (pos->create_callback == create_callback) { 1777 instances.erase(pos); 1778 return true; 1779 } 1780 } 1781 } 1782 return false; 1783 } 1784 1785 SymbolVendorCreateInstance 1786 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { 1787 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1788 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1789 if (idx < instances.size()) 1790 return instances[idx].create_callback; 1791 return nullptr; 1792 } 1793 1794 SymbolVendorCreateInstance 1795 PluginManager::GetSymbolVendorCreateCallbackForPluginName( 1796 ConstString name) { 1797 if (name) { 1798 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1799 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1800 1801 SymbolVendorInstances::iterator pos, end = instances.end(); 1802 for (pos = instances.begin(); pos != end; ++pos) { 1803 if (name == pos->name) 1804 return pos->create_callback; 1805 } 1806 } 1807 return nullptr; 1808 } 1809 1810 #pragma mark UnwindAssembly 1811 1812 struct UnwindAssemblyInstance { 1813 UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {} 1814 1815 ConstString name; 1816 std::string description; 1817 UnwindAssemblyCreateInstance create_callback; 1818 }; 1819 1820 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances; 1821 1822 static std::recursive_mutex &GetUnwindAssemblyMutex() { 1823 static std::recursive_mutex g_instances_mutex; 1824 return g_instances_mutex; 1825 } 1826 1827 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { 1828 static UnwindAssemblyInstances g_instances; 1829 return g_instances; 1830 } 1831 1832 bool PluginManager::RegisterPlugin( 1833 ConstString name, const char *description, 1834 UnwindAssemblyCreateInstance create_callback) { 1835 if (create_callback) { 1836 UnwindAssemblyInstance instance; 1837 assert((bool)name); 1838 instance.name = name; 1839 if (description && description[0]) 1840 instance.description = description; 1841 instance.create_callback = create_callback; 1842 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1843 GetUnwindAssemblyInstances().push_back(instance); 1844 } 1845 return false; 1846 } 1847 1848 bool PluginManager::UnregisterPlugin( 1849 UnwindAssemblyCreateInstance create_callback) { 1850 if (create_callback) { 1851 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1852 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1853 1854 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1855 for (pos = instances.begin(); pos != end; ++pos) { 1856 if (pos->create_callback == create_callback) { 1857 instances.erase(pos); 1858 return true; 1859 } 1860 } 1861 } 1862 return false; 1863 } 1864 1865 UnwindAssemblyCreateInstance 1866 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) { 1867 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1868 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1869 if (idx < instances.size()) 1870 return instances[idx].create_callback; 1871 return nullptr; 1872 } 1873 1874 UnwindAssemblyCreateInstance 1875 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName( 1876 ConstString name) { 1877 if (name) { 1878 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1879 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1880 1881 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1882 for (pos = instances.begin(); pos != end; ++pos) { 1883 if (name == pos->name) 1884 return pos->create_callback; 1885 } 1886 } 1887 return nullptr; 1888 } 1889 1890 #pragma mark MemoryHistory 1891 1892 struct MemoryHistoryInstance { 1893 MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {} 1894 1895 ConstString name; 1896 std::string description; 1897 MemoryHistoryCreateInstance create_callback; 1898 }; 1899 1900 typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances; 1901 1902 static std::recursive_mutex &GetMemoryHistoryMutex() { 1903 static std::recursive_mutex g_instances_mutex; 1904 return g_instances_mutex; 1905 } 1906 1907 static MemoryHistoryInstances &GetMemoryHistoryInstances() { 1908 static MemoryHistoryInstances g_instances; 1909 return g_instances; 1910 } 1911 1912 bool PluginManager::RegisterPlugin( 1913 ConstString name, const char *description, 1914 MemoryHistoryCreateInstance create_callback) { 1915 if (create_callback) { 1916 MemoryHistoryInstance instance; 1917 assert((bool)name); 1918 instance.name = name; 1919 if (description && description[0]) 1920 instance.description = description; 1921 instance.create_callback = create_callback; 1922 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1923 GetMemoryHistoryInstances().push_back(instance); 1924 } 1925 return false; 1926 } 1927 1928 bool PluginManager::UnregisterPlugin( 1929 MemoryHistoryCreateInstance create_callback) { 1930 if (create_callback) { 1931 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1932 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1933 1934 MemoryHistoryInstances::iterator pos, end = instances.end(); 1935 for (pos = instances.begin(); pos != end; ++pos) { 1936 if (pos->create_callback == create_callback) { 1937 instances.erase(pos); 1938 return true; 1939 } 1940 } 1941 } 1942 return false; 1943 } 1944 1945 MemoryHistoryCreateInstance 1946 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { 1947 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1948 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1949 if (idx < instances.size()) 1950 return instances[idx].create_callback; 1951 return nullptr; 1952 } 1953 1954 MemoryHistoryCreateInstance 1955 PluginManager::GetMemoryHistoryCreateCallbackForPluginName( 1956 ConstString name) { 1957 if (name) { 1958 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1959 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1960 1961 MemoryHistoryInstances::iterator pos, end = instances.end(); 1962 for (pos = instances.begin(); pos != end; ++pos) { 1963 if (name == pos->name) 1964 return pos->create_callback; 1965 } 1966 } 1967 return nullptr; 1968 } 1969 1970 #pragma mark InstrumentationRuntime 1971 1972 struct InstrumentationRuntimeInstance { 1973 InstrumentationRuntimeInstance() 1974 : name(), description(), create_callback(nullptr) {} 1975 1976 ConstString name; 1977 std::string description; 1978 InstrumentationRuntimeCreateInstance create_callback; 1979 InstrumentationRuntimeGetType get_type_callback; 1980 }; 1981 1982 typedef std::vector<InstrumentationRuntimeInstance> 1983 InstrumentationRuntimeInstances; 1984 1985 static std::recursive_mutex &GetInstrumentationRuntimeMutex() { 1986 static std::recursive_mutex g_instances_mutex; 1987 return g_instances_mutex; 1988 } 1989 1990 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { 1991 static InstrumentationRuntimeInstances g_instances; 1992 return g_instances; 1993 } 1994 1995 bool PluginManager::RegisterPlugin( 1996 ConstString name, const char *description, 1997 InstrumentationRuntimeCreateInstance create_callback, 1998 InstrumentationRuntimeGetType get_type_callback) { 1999 if (create_callback) { 2000 InstrumentationRuntimeInstance instance; 2001 assert((bool)name); 2002 instance.name = name; 2003 if (description && description[0]) 2004 instance.description = description; 2005 instance.create_callback = create_callback; 2006 instance.get_type_callback = get_type_callback; 2007 std::lock_guard<std::recursive_mutex> guard( 2008 GetInstrumentationRuntimeMutex()); 2009 GetInstrumentationRuntimeInstances().push_back(instance); 2010 } 2011 return false; 2012 } 2013 2014 bool PluginManager::UnregisterPlugin( 2015 InstrumentationRuntimeCreateInstance create_callback) { 2016 if (create_callback) { 2017 std::lock_guard<std::recursive_mutex> guard( 2018 GetInstrumentationRuntimeMutex()); 2019 InstrumentationRuntimeInstances &instances = 2020 GetInstrumentationRuntimeInstances(); 2021 2022 InstrumentationRuntimeInstances::iterator pos, end = instances.end(); 2023 for (pos = instances.begin(); pos != end; ++pos) { 2024 if (pos->create_callback == create_callback) { 2025 instances.erase(pos); 2026 return true; 2027 } 2028 } 2029 } 2030 return false; 2031 } 2032 2033 InstrumentationRuntimeGetType 2034 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { 2035 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex()); 2036 InstrumentationRuntimeInstances &instances = 2037 GetInstrumentationRuntimeInstances(); 2038 if (idx < instances.size()) 2039 return instances[idx].get_type_callback; 2040 return nullptr; 2041 } 2042 2043 InstrumentationRuntimeCreateInstance 2044 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { 2045 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex()); 2046 InstrumentationRuntimeInstances &instances = 2047 GetInstrumentationRuntimeInstances(); 2048 if (idx < instances.size()) 2049 return instances[idx].create_callback; 2050 return nullptr; 2051 } 2052 2053 InstrumentationRuntimeCreateInstance 2054 PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName( 2055 ConstString name) { 2056 if (name) { 2057 std::lock_guard<std::recursive_mutex> guard( 2058 GetInstrumentationRuntimeMutex()); 2059 InstrumentationRuntimeInstances &instances = 2060 GetInstrumentationRuntimeInstances(); 2061 2062 InstrumentationRuntimeInstances::iterator pos, end = instances.end(); 2063 for (pos = instances.begin(); pos != end; ++pos) { 2064 if (name == pos->name) 2065 return pos->create_callback; 2066 } 2067 } 2068 return nullptr; 2069 } 2070 2071 #pragma mark TypeSystem 2072 2073 struct TypeSystemInstance { 2074 TypeSystemInstance() : name(), description(), create_callback(nullptr) {} 2075 2076 ConstString name; 2077 std::string description; 2078 TypeSystemCreateInstance create_callback; 2079 TypeSystemEnumerateSupportedLanguages enumerate_callback; 2080 }; 2081 2082 typedef std::vector<TypeSystemInstance> TypeSystemInstances; 2083 2084 static std::recursive_mutex &GetTypeSystemMutex() { 2085 static std::recursive_mutex g_instances_mutex; 2086 return g_instances_mutex; 2087 } 2088 2089 static TypeSystemInstances &GetTypeSystemInstances() { 2090 static TypeSystemInstances g_instances; 2091 return g_instances; 2092 } 2093 2094 bool PluginManager::RegisterPlugin(ConstString name, 2095 const char *description, 2096 TypeSystemCreateInstance create_callback, 2097 TypeSystemEnumerateSupportedLanguages 2098 enumerate_supported_languages_callback) { 2099 if (create_callback) { 2100 TypeSystemInstance instance; 2101 assert((bool)name); 2102 instance.name = name; 2103 if (description && description[0]) 2104 instance.description = description; 2105 instance.create_callback = create_callback; 2106 instance.enumerate_callback = enumerate_supported_languages_callback; 2107 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2108 GetTypeSystemInstances().push_back(instance); 2109 } 2110 return false; 2111 } 2112 2113 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) { 2114 if (create_callback) { 2115 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2116 TypeSystemInstances &instances = GetTypeSystemInstances(); 2117 2118 TypeSystemInstances::iterator pos, end = instances.end(); 2119 for (pos = instances.begin(); pos != end; ++pos) { 2120 if (pos->create_callback == create_callback) { 2121 instances.erase(pos); 2122 return true; 2123 } 2124 } 2125 } 2126 return false; 2127 } 2128 2129 TypeSystemCreateInstance 2130 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) { 2131 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2132 TypeSystemInstances &instances = GetTypeSystemInstances(); 2133 if (idx < instances.size()) 2134 return instances[idx].create_callback; 2135 return nullptr; 2136 } 2137 2138 TypeSystemCreateInstance 2139 PluginManager::GetTypeSystemCreateCallbackForPluginName( 2140 ConstString name) { 2141 if (name) { 2142 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2143 TypeSystemInstances &instances = GetTypeSystemInstances(); 2144 2145 TypeSystemInstances::iterator pos, end = instances.end(); 2146 for (pos = instances.begin(); pos != end; ++pos) { 2147 if (name == pos->name) 2148 return pos->create_callback; 2149 } 2150 } 2151 return nullptr; 2152 } 2153 2154 TypeSystemEnumerateSupportedLanguages 2155 PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex( 2156 uint32_t idx) { 2157 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2158 TypeSystemInstances &instances = GetTypeSystemInstances(); 2159 if (idx < instances.size()) 2160 return instances[idx].enumerate_callback; 2161 return nullptr; 2162 } 2163 2164 TypeSystemEnumerateSupportedLanguages 2165 PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName( 2166 ConstString name) { 2167 if (name) { 2168 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2169 TypeSystemInstances &instances = GetTypeSystemInstances(); 2170 2171 TypeSystemInstances::iterator pos, end = instances.end(); 2172 for (pos = instances.begin(); pos != end; ++pos) { 2173 if (name == pos->name) 2174 return pos->enumerate_callback; 2175 } 2176 } 2177 return nullptr; 2178 } 2179 2180 #pragma mark REPL 2181 2182 struct REPLInstance { 2183 REPLInstance() : name(), description(), create_callback(nullptr) {} 2184 2185 ConstString name; 2186 std::string description; 2187 REPLCreateInstance create_callback; 2188 REPLEnumerateSupportedLanguages enumerate_languages_callback; 2189 }; 2190 2191 typedef std::vector<REPLInstance> REPLInstances; 2192 2193 static std::recursive_mutex &GetREPLMutex() { 2194 static std::recursive_mutex g_instances_mutex; 2195 return g_instances_mutex; 2196 } 2197 2198 static REPLInstances &GetREPLInstances() { 2199 static REPLInstances g_instances; 2200 return g_instances; 2201 } 2202 2203 bool PluginManager::RegisterPlugin( 2204 ConstString name, const char *description, 2205 REPLCreateInstance create_callback, 2206 REPLEnumerateSupportedLanguages enumerate_languages_callback) { 2207 if (create_callback) { 2208 REPLInstance instance; 2209 assert((bool)name); 2210 instance.name = name; 2211 if (description && description[0]) 2212 instance.description = description; 2213 instance.create_callback = create_callback; 2214 instance.enumerate_languages_callback = enumerate_languages_callback; 2215 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2216 GetREPLInstances().push_back(instance); 2217 } 2218 return false; 2219 } 2220 2221 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) { 2222 if (create_callback) { 2223 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2224 REPLInstances &instances = GetREPLInstances(); 2225 2226 REPLInstances::iterator pos, end = instances.end(); 2227 for (pos = instances.begin(); pos != end; ++pos) { 2228 if (pos->create_callback == create_callback) { 2229 instances.erase(pos); 2230 return true; 2231 } 2232 } 2233 } 2234 return false; 2235 } 2236 2237 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) { 2238 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2239 REPLInstances &instances = GetREPLInstances(); 2240 if (idx < instances.size()) 2241 return instances[idx].create_callback; 2242 return nullptr; 2243 } 2244 2245 REPLCreateInstance 2246 PluginManager::GetREPLCreateCallbackForPluginName(ConstString name) { 2247 if (name) { 2248 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2249 REPLInstances &instances = GetREPLInstances(); 2250 2251 REPLInstances::iterator pos, end = instances.end(); 2252 for (pos = instances.begin(); pos != end; ++pos) { 2253 if (name == pos->name) 2254 return pos->create_callback; 2255 } 2256 } 2257 return nullptr; 2258 } 2259 2260 REPLEnumerateSupportedLanguages 2261 PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) { 2262 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2263 REPLInstances &instances = GetREPLInstances(); 2264 if (idx < instances.size()) 2265 return instances[idx].enumerate_languages_callback; 2266 return nullptr; 2267 } 2268 2269 REPLEnumerateSupportedLanguages 2270 PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName( 2271 ConstString name) { 2272 if (name) { 2273 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2274 REPLInstances &instances = GetREPLInstances(); 2275 2276 REPLInstances::iterator pos, end = instances.end(); 2277 for (pos = instances.begin(); pos != end; ++pos) { 2278 if (name == pos->name) 2279 return pos->enumerate_languages_callback; 2280 } 2281 } 2282 return nullptr; 2283 } 2284 2285 #pragma mark PluginManager 2286 2287 void PluginManager::DebuggerInitialize(Debugger &debugger) { 2288 // Initialize the DynamicLoader plugins 2289 { 2290 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); 2291 DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); 2292 2293 DynamicLoaderInstances::iterator pos, end = instances.end(); 2294 for (pos = instances.begin(); pos != end; ++pos) { 2295 if (pos->debugger_init_callback) 2296 pos->debugger_init_callback(debugger); 2297 } 2298 } 2299 2300 // Initialize the JITLoader plugins 2301 { 2302 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); 2303 JITLoaderInstances &instances = GetJITLoaderInstances(); 2304 2305 JITLoaderInstances::iterator pos, end = instances.end(); 2306 for (pos = instances.begin(); pos != end; ++pos) { 2307 if (pos->debugger_init_callback) 2308 pos->debugger_init_callback(debugger); 2309 } 2310 } 2311 2312 // Initialize the Platform plugins 2313 { 2314 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 2315 PlatformInstances &instances = GetPlatformInstances(); 2316 2317 PlatformInstances::iterator pos, end = instances.end(); 2318 for (pos = instances.begin(); pos != end; ++pos) { 2319 if (pos->debugger_init_callback) 2320 pos->debugger_init_callback(debugger); 2321 } 2322 } 2323 2324 // Initialize the Process plugins 2325 { 2326 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 2327 ProcessInstances &instances = GetProcessInstances(); 2328 2329 ProcessInstances::iterator pos, end = instances.end(); 2330 for (pos = instances.begin(); pos != end; ++pos) { 2331 if (pos->debugger_init_callback) 2332 pos->debugger_init_callback(debugger); 2333 } 2334 } 2335 2336 // Initialize the SymbolFile plugins 2337 { 2338 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 2339 for (auto &sym_file : GetSymbolFileInstances()) { 2340 if (sym_file.debugger_init_callback) 2341 sym_file.debugger_init_callback(debugger); 2342 } 2343 } 2344 2345 // Initialize the OperatingSystem plugins 2346 { 2347 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); 2348 for (auto &os : GetOperatingSystemInstances()) { 2349 if (os.debugger_init_callback) 2350 os.debugger_init_callback(debugger); 2351 } 2352 } 2353 2354 // Initialize the StructuredDataPlugin plugins 2355 { 2356 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 2357 for (auto &plugin : GetStructuredDataPluginInstances()) { 2358 if (plugin.debugger_init_callback) 2359 plugin.debugger_init_callback(debugger); 2360 } 2361 } 2362 } 2363 2364 // This is the preferred new way to register plugin specific settings. e.g. 2365 // This will put a plugin's settings under e.g. 2366 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 2367 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins( 2368 Debugger &debugger, ConstString plugin_type_name, 2369 ConstString plugin_type_desc, bool can_create) { 2370 lldb::OptionValuePropertiesSP parent_properties_sp( 2371 debugger.GetValueProperties()); 2372 if (parent_properties_sp) { 2373 static ConstString g_property_name("plugin"); 2374 2375 OptionValuePropertiesSP plugin_properties_sp = 2376 parent_properties_sp->GetSubProperty(nullptr, g_property_name); 2377 if (!plugin_properties_sp && can_create) { 2378 plugin_properties_sp = 2379 std::make_shared<OptionValueProperties>(g_property_name); 2380 parent_properties_sp->AppendProperty( 2381 g_property_name, ConstString("Settings specify to plugins."), true, 2382 plugin_properties_sp); 2383 } 2384 2385 if (plugin_properties_sp) { 2386 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 2387 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name); 2388 if (!plugin_type_properties_sp && can_create) { 2389 plugin_type_properties_sp = 2390 std::make_shared<OptionValueProperties>(plugin_type_name); 2391 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 2392 true, plugin_type_properties_sp); 2393 } 2394 return plugin_type_properties_sp; 2395 } 2396 } 2397 return lldb::OptionValuePropertiesSP(); 2398 } 2399 2400 // This is deprecated way to register plugin specific settings. e.g. 2401 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform 2402 // generic settings would be under "platform.SETTINGNAME". 2403 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( 2404 Debugger &debugger, ConstString plugin_type_name, 2405 ConstString plugin_type_desc, bool can_create) { 2406 static ConstString g_property_name("plugin"); 2407 lldb::OptionValuePropertiesSP parent_properties_sp( 2408 debugger.GetValueProperties()); 2409 if (parent_properties_sp) { 2410 OptionValuePropertiesSP plugin_properties_sp = 2411 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name); 2412 if (!plugin_properties_sp && can_create) { 2413 plugin_properties_sp = 2414 std::make_shared<OptionValueProperties>(plugin_type_name); 2415 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 2416 true, plugin_properties_sp); 2417 } 2418 2419 if (plugin_properties_sp) { 2420 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 2421 plugin_properties_sp->GetSubProperty(nullptr, g_property_name); 2422 if (!plugin_type_properties_sp && can_create) { 2423 plugin_type_properties_sp = 2424 std::make_shared<OptionValueProperties>(g_property_name); 2425 plugin_properties_sp->AppendProperty( 2426 g_property_name, ConstString("Settings specific to plugins"), true, 2427 plugin_type_properties_sp); 2428 } 2429 return plugin_type_properties_sp; 2430 } 2431 } 2432 return lldb::OptionValuePropertiesSP(); 2433 } 2434 2435 namespace { 2436 2437 typedef lldb::OptionValuePropertiesSP 2438 GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString , 2439 ConstString , bool can_create); 2440 2441 lldb::OptionValuePropertiesSP 2442 GetSettingForPlugin(Debugger &debugger, ConstString setting_name, 2443 ConstString plugin_type_name, 2444 GetDebuggerPropertyForPluginsPtr get_debugger_property = 2445 GetDebuggerPropertyForPlugins) { 2446 lldb::OptionValuePropertiesSP properties_sp; 2447 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property( 2448 debugger, plugin_type_name, 2449 ConstString(), // not creating to so we don't need the description 2450 false)); 2451 if (plugin_type_properties_sp) 2452 properties_sp = 2453 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 2454 return properties_sp; 2455 } 2456 2457 bool CreateSettingForPlugin( 2458 Debugger &debugger, ConstString plugin_type_name, 2459 ConstString plugin_type_desc, 2460 const lldb::OptionValuePropertiesSP &properties_sp, 2461 ConstString description, bool is_global_property, 2462 GetDebuggerPropertyForPluginsPtr get_debugger_property = 2463 GetDebuggerPropertyForPlugins) { 2464 if (properties_sp) { 2465 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2466 get_debugger_property(debugger, plugin_type_name, plugin_type_desc, 2467 true)); 2468 if (plugin_type_properties_sp) { 2469 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 2470 description, is_global_property, 2471 properties_sp); 2472 return true; 2473 } 2474 } 2475 return false; 2476 } 2477 2478 const char *kDynamicLoaderPluginName("dynamic-loader"); 2479 const char *kPlatformPluginName("platform"); 2480 const char *kProcessPluginName("process"); 2481 const char *kSymbolFilePluginName("symbol-file"); 2482 const char *kJITLoaderPluginName("jit-loader"); 2483 const char *kStructuredDataPluginName("structured-data"); 2484 2485 } // anonymous namespace 2486 2487 lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin( 2488 Debugger &debugger, ConstString setting_name) { 2489 return GetSettingForPlugin(debugger, setting_name, 2490 ConstString(kDynamicLoaderPluginName)); 2491 } 2492 2493 bool PluginManager::CreateSettingForDynamicLoaderPlugin( 2494 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2495 ConstString description, bool is_global_property) { 2496 return CreateSettingForPlugin( 2497 debugger, ConstString(kDynamicLoaderPluginName), 2498 ConstString("Settings for dynamic loader plug-ins"), properties_sp, 2499 description, is_global_property); 2500 } 2501 2502 lldb::OptionValuePropertiesSP 2503 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger, 2504 ConstString setting_name) { 2505 return GetSettingForPlugin(debugger, setting_name, 2506 ConstString(kPlatformPluginName), 2507 GetDebuggerPropertyForPluginsOldStyle); 2508 } 2509 2510 bool PluginManager::CreateSettingForPlatformPlugin( 2511 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2512 ConstString description, bool is_global_property) { 2513 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName), 2514 ConstString("Settings for platform plug-ins"), 2515 properties_sp, description, is_global_property, 2516 GetDebuggerPropertyForPluginsOldStyle); 2517 } 2518 2519 lldb::OptionValuePropertiesSP 2520 PluginManager::GetSettingForProcessPlugin(Debugger &debugger, 2521 ConstString setting_name) { 2522 return GetSettingForPlugin(debugger, setting_name, 2523 ConstString(kProcessPluginName)); 2524 } 2525 2526 bool PluginManager::CreateSettingForProcessPlugin( 2527 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2528 ConstString description, bool is_global_property) { 2529 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName), 2530 ConstString("Settings for process plug-ins"), 2531 properties_sp, description, is_global_property); 2532 } 2533 2534 lldb::OptionValuePropertiesSP 2535 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger, 2536 ConstString setting_name) { 2537 return GetSettingForPlugin(debugger, setting_name, 2538 ConstString(kSymbolFilePluginName)); 2539 } 2540 2541 bool PluginManager::CreateSettingForSymbolFilePlugin( 2542 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2543 ConstString description, bool is_global_property) { 2544 return CreateSettingForPlugin( 2545 debugger, ConstString(kSymbolFilePluginName), 2546 ConstString("Settings for symbol file plug-ins"), properties_sp, 2547 description, is_global_property); 2548 } 2549 2550 lldb::OptionValuePropertiesSP 2551 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger, 2552 ConstString setting_name) { 2553 return GetSettingForPlugin(debugger, setting_name, 2554 ConstString(kJITLoaderPluginName)); 2555 } 2556 2557 bool PluginManager::CreateSettingForJITLoaderPlugin( 2558 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2559 ConstString description, bool is_global_property) { 2560 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName), 2561 ConstString("Settings for JIT loader plug-ins"), 2562 properties_sp, description, is_global_property); 2563 } 2564 2565 static const char *kOperatingSystemPluginName("os"); 2566 2567 lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin( 2568 Debugger &debugger, ConstString setting_name) { 2569 lldb::OptionValuePropertiesSP properties_sp; 2570 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2571 GetDebuggerPropertyForPlugins( 2572 debugger, ConstString(kOperatingSystemPluginName), 2573 ConstString(), // not creating to so we don't need the description 2574 false)); 2575 if (plugin_type_properties_sp) 2576 properties_sp = 2577 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 2578 return properties_sp; 2579 } 2580 2581 bool PluginManager::CreateSettingForOperatingSystemPlugin( 2582 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2583 ConstString description, bool is_global_property) { 2584 if (properties_sp) { 2585 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2586 GetDebuggerPropertyForPlugins( 2587 debugger, ConstString(kOperatingSystemPluginName), 2588 ConstString("Settings for operating system plug-ins"), true)); 2589 if (plugin_type_properties_sp) { 2590 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 2591 description, is_global_property, 2592 properties_sp); 2593 return true; 2594 } 2595 } 2596 return false; 2597 } 2598 2599 lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin( 2600 Debugger &debugger, ConstString setting_name) { 2601 return GetSettingForPlugin(debugger, setting_name, 2602 ConstString(kStructuredDataPluginName)); 2603 } 2604 2605 bool PluginManager::CreateSettingForStructuredDataPlugin( 2606 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2607 ConstString description, bool is_global_property) { 2608 return CreateSettingForPlugin( 2609 debugger, ConstString(kStructuredDataPluginName), 2610 ConstString("Settings for structured data plug-ins"), properties_sp, 2611 description, is_global_property); 2612 } 2613