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