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