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