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 }; 2535 2536 typedef std::vector<TypeSystemInstance> TypeSystemInstances; 2537 2538 static Mutex & 2539 GetTypeSystemMutex () 2540 { 2541 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 2542 return g_instances_mutex; 2543 } 2544 2545 static TypeSystemInstances & 2546 GetTypeSystemInstances () 2547 { 2548 static TypeSystemInstances g_instances; 2549 return g_instances; 2550 } 2551 2552 bool 2553 PluginManager::RegisterPlugin (const ConstString &name, 2554 const char *description, 2555 TypeSystemCreateInstance create_callback) 2556 { 2557 if (create_callback) 2558 { 2559 TypeSystemInstance instance; 2560 assert ((bool)name); 2561 instance.name = name; 2562 if (description && description[0]) 2563 instance.description = description; 2564 instance.create_callback = create_callback; 2565 Mutex::Locker locker (GetTypeSystemMutex ()); 2566 GetTypeSystemInstances ().push_back (instance); 2567 } 2568 return false; 2569 } 2570 2571 bool 2572 PluginManager::UnregisterPlugin (TypeSystemCreateInstance create_callback) 2573 { 2574 if (create_callback) 2575 { 2576 Mutex::Locker locker (GetTypeSystemMutex ()); 2577 TypeSystemInstances &instances = GetTypeSystemInstances (); 2578 2579 TypeSystemInstances::iterator pos, end = instances.end(); 2580 for (pos = instances.begin(); pos != end; ++ pos) 2581 { 2582 if (pos->create_callback == create_callback) 2583 { 2584 instances.erase(pos); 2585 return true; 2586 } 2587 } 2588 } 2589 return false; 2590 } 2591 2592 TypeSystemCreateInstance 2593 PluginManager::GetTypeSystemCreateCallbackAtIndex (uint32_t idx) 2594 { 2595 Mutex::Locker locker (GetTypeSystemMutex ()); 2596 TypeSystemInstances &instances = GetTypeSystemInstances (); 2597 if (idx < instances.size()) 2598 return instances[idx].create_callback; 2599 return NULL; 2600 } 2601 2602 TypeSystemCreateInstance 2603 PluginManager::GetTypeSystemCreateCallbackForPluginName (const ConstString &name) 2604 { 2605 if (name) 2606 { 2607 Mutex::Locker locker (GetTypeSystemMutex ()); 2608 TypeSystemInstances &instances = GetTypeSystemInstances (); 2609 2610 TypeSystemInstances::iterator pos, end = instances.end(); 2611 for (pos = instances.begin(); pos != end; ++ pos) 2612 { 2613 if (name == pos->name) 2614 return pos->create_callback; 2615 } 2616 } 2617 return NULL; 2618 } 2619 2620 2621 #pragma mark PluginManager 2622 2623 void 2624 PluginManager::DebuggerInitialize (Debugger &debugger) 2625 { 2626 // Initialize the DynamicLoader plugins 2627 { 2628 Mutex::Locker locker (GetDynamicLoaderMutex ()); 2629 DynamicLoaderInstances &instances = GetDynamicLoaderInstances (); 2630 2631 DynamicLoaderInstances::iterator pos, end = instances.end(); 2632 for (pos = instances.begin(); pos != end; ++ pos) 2633 { 2634 if (pos->debugger_init_callback) 2635 pos->debugger_init_callback (debugger); 2636 } 2637 } 2638 2639 // Initialize the JITLoader plugins 2640 { 2641 Mutex::Locker locker (GetJITLoaderMutex ()); 2642 JITLoaderInstances &instances = GetJITLoaderInstances (); 2643 2644 JITLoaderInstances::iterator pos, end = instances.end(); 2645 for (pos = instances.begin(); pos != end; ++ pos) 2646 { 2647 if (pos->debugger_init_callback) 2648 pos->debugger_init_callback (debugger); 2649 } 2650 } 2651 2652 // Initialize the Platform plugins 2653 { 2654 Mutex::Locker locker (GetPlatformInstancesMutex ()); 2655 PlatformInstances &instances = GetPlatformInstances (); 2656 2657 PlatformInstances::iterator pos, end = instances.end(); 2658 for (pos = instances.begin(); pos != end; ++ pos) 2659 { 2660 if (pos->debugger_init_callback) 2661 pos->debugger_init_callback (debugger); 2662 } 2663 } 2664 2665 // Initialize the Process plugins 2666 { 2667 Mutex::Locker locker (GetProcessMutex()); 2668 ProcessInstances &instances = GetProcessInstances(); 2669 2670 ProcessInstances::iterator pos, end = instances.end(); 2671 for (pos = instances.begin(); pos != end; ++ pos) 2672 { 2673 if (pos->debugger_init_callback) 2674 pos->debugger_init_callback (debugger); 2675 } 2676 } 2677 2678 // Initialize the SymbolFile plugins 2679 { 2680 Mutex::Locker locker (GetSymbolFileMutex()); 2681 for (auto& sym_file: GetSymbolFileInstances()) 2682 { 2683 if (sym_file.debugger_init_callback) 2684 sym_file.debugger_init_callback (debugger); 2685 } 2686 } 2687 2688 // Initialize the OperatingSystem plugins 2689 { 2690 Mutex::Locker locker(GetOperatingSystemMutex()); 2691 for (auto &os : GetOperatingSystemInstances()) 2692 { 2693 if (os.debugger_init_callback) 2694 os.debugger_init_callback(debugger); 2695 } 2696 } 2697 } 2698 2699 // This is the preferred new way to register plugin specific settings. e.g. 2700 // This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 2701 static lldb::OptionValuePropertiesSP 2702 GetDebuggerPropertyForPlugins (Debugger &debugger, 2703 const ConstString &plugin_type_name, 2704 const ConstString &plugin_type_desc, 2705 bool can_create) 2706 { 2707 lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties()); 2708 if (parent_properties_sp) 2709 { 2710 static ConstString g_property_name("plugin"); 2711 2712 OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name); 2713 if (!plugin_properties_sp && can_create) 2714 { 2715 plugin_properties_sp.reset (new OptionValueProperties (g_property_name)); 2716 parent_properties_sp->AppendProperty (g_property_name, 2717 ConstString("Settings specify to plugins."), 2718 true, 2719 plugin_properties_sp); 2720 } 2721 2722 if (plugin_properties_sp) 2723 { 2724 lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name); 2725 if (!plugin_type_properties_sp && can_create) 2726 { 2727 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name)); 2728 plugin_properties_sp->AppendProperty (plugin_type_name, 2729 plugin_type_desc, 2730 true, 2731 plugin_type_properties_sp); 2732 } 2733 return plugin_type_properties_sp; 2734 } 2735 } 2736 return lldb::OptionValuePropertiesSP(); 2737 } 2738 2739 // This is deprecated way to register plugin specific settings. e.g. 2740 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" 2741 // and Platform generic settings would be under "platform.SETTINGNAME". 2742 static lldb::OptionValuePropertiesSP 2743 GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger, 2744 const ConstString &plugin_type_name, 2745 const ConstString &plugin_type_desc, 2746 bool can_create) 2747 { 2748 static ConstString g_property_name("plugin"); 2749 lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties()); 2750 if (parent_properties_sp) 2751 { 2752 OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name); 2753 if (!plugin_properties_sp && can_create) 2754 { 2755 plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name)); 2756 parent_properties_sp->AppendProperty (plugin_type_name, 2757 plugin_type_desc, 2758 true, 2759 plugin_properties_sp); 2760 } 2761 2762 if (plugin_properties_sp) 2763 { 2764 lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name); 2765 if (!plugin_type_properties_sp && can_create) 2766 { 2767 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name)); 2768 plugin_properties_sp->AppendProperty (g_property_name, 2769 ConstString("Settings specific to plugins"), 2770 true, 2771 plugin_type_properties_sp); 2772 } 2773 return plugin_type_properties_sp; 2774 } 2775 } 2776 return lldb::OptionValuePropertiesSP(); 2777 } 2778 2779 namespace { 2780 2781 typedef lldb::OptionValuePropertiesSP 2782 GetDebuggerPropertyForPluginsPtr (Debugger&, const ConstString&, const ConstString&, bool can_create); 2783 2784 lldb::OptionValuePropertiesSP 2785 GetSettingForPlugin (Debugger &debugger, 2786 const ConstString &setting_name, 2787 const ConstString &plugin_type_name, 2788 GetDebuggerPropertyForPluginsPtr get_debugger_property= GetDebuggerPropertyForPlugins) 2789 { 2790 lldb::OptionValuePropertiesSP properties_sp; 2791 lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (debugger, 2792 plugin_type_name, 2793 ConstString(), // not creating to so we don't need the description 2794 false)); 2795 if (plugin_type_properties_sp) 2796 properties_sp = plugin_type_properties_sp->GetSubProperty (nullptr, setting_name); 2797 return properties_sp; 2798 } 2799 2800 bool 2801 CreateSettingForPlugin (Debugger &debugger, 2802 const ConstString &plugin_type_name, 2803 const ConstString &plugin_type_desc, 2804 const lldb::OptionValuePropertiesSP &properties_sp, 2805 const ConstString &description, 2806 bool is_global_property, 2807 GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins) 2808 { 2809 if (properties_sp) 2810 { 2811 lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property ( 2812 debugger, plugin_type_name, plugin_type_desc, true)); 2813 if (plugin_type_properties_sp) 2814 { 2815 plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), 2816 description, 2817 is_global_property, 2818 properties_sp); 2819 return true; 2820 } 2821 } 2822 return false; 2823 } 2824 2825 const char* kDynamicLoaderPluginName("dynamic-loader"); 2826 const char* kPlatformPluginName("platform"); 2827 const char* kProcessPluginName("process"); 2828 const char* kSymbolFilePluginName("symbol-file"); 2829 const char* kJITLoaderPluginName("jit-loader"); 2830 2831 } 2832 2833 lldb::OptionValuePropertiesSP 2834 PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, 2835 const ConstString &setting_name) 2836 { 2837 return GetSettingForPlugin(debugger, setting_name, ConstString(kDynamicLoaderPluginName)); 2838 } 2839 2840 bool 2841 PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger, 2842 const lldb::OptionValuePropertiesSP &properties_sp, 2843 const ConstString &description, 2844 bool is_global_property) 2845 { 2846 return CreateSettingForPlugin(debugger, 2847 ConstString(kDynamicLoaderPluginName), 2848 ConstString("Settings for dynamic loader plug-ins"), 2849 properties_sp, 2850 description, 2851 is_global_property); 2852 } 2853 2854 2855 lldb::OptionValuePropertiesSP 2856 PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name) 2857 { 2858 return GetSettingForPlugin(debugger, 2859 setting_name, 2860 ConstString(kPlatformPluginName), 2861 GetDebuggerPropertyForPluginsOldStyle); 2862 } 2863 2864 bool 2865 PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger, 2866 const lldb::OptionValuePropertiesSP &properties_sp, 2867 const ConstString &description, 2868 bool is_global_property) 2869 { 2870 return CreateSettingForPlugin(debugger, 2871 ConstString(kPlatformPluginName), 2872 ConstString("Settings for platform plug-ins"), 2873 properties_sp, 2874 description, 2875 is_global_property, 2876 GetDebuggerPropertyForPluginsOldStyle); 2877 } 2878 2879 2880 lldb::OptionValuePropertiesSP 2881 PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name) 2882 { 2883 return GetSettingForPlugin(debugger, setting_name, ConstString(kProcessPluginName)); 2884 } 2885 2886 bool 2887 PluginManager::CreateSettingForProcessPlugin (Debugger &debugger, 2888 const lldb::OptionValuePropertiesSP &properties_sp, 2889 const ConstString &description, 2890 bool is_global_property) 2891 { 2892 return CreateSettingForPlugin(debugger, 2893 ConstString(kProcessPluginName), 2894 ConstString("Settings for process plug-ins"), 2895 properties_sp, 2896 description, 2897 is_global_property); 2898 } 2899 2900 lldb::OptionValuePropertiesSP 2901 PluginManager::GetSettingForSymbolFilePlugin (Debugger &debugger, 2902 const ConstString &setting_name) 2903 { 2904 return GetSettingForPlugin(debugger, setting_name, ConstString(kSymbolFilePluginName)); 2905 } 2906 2907 bool 2908 PluginManager::CreateSettingForSymbolFilePlugin (Debugger &debugger, 2909 const lldb::OptionValuePropertiesSP &properties_sp, 2910 const ConstString &description, 2911 bool is_global_property) 2912 { 2913 return CreateSettingForPlugin(debugger, 2914 ConstString(kSymbolFilePluginName), 2915 ConstString("Settings for symbol file plug-ins"), 2916 properties_sp, 2917 description, 2918 is_global_property); 2919 } 2920 2921 lldb::OptionValuePropertiesSP 2922 PluginManager::GetSettingForJITLoaderPlugin (Debugger &debugger, 2923 const ConstString &setting_name) 2924 { 2925 return GetSettingForPlugin(debugger, setting_name, ConstString(kJITLoaderPluginName)); 2926 } 2927 2928 bool 2929 PluginManager::CreateSettingForJITLoaderPlugin (Debugger &debugger, 2930 const lldb::OptionValuePropertiesSP &properties_sp, 2931 const ConstString &description, 2932 bool is_global_property) 2933 { 2934 return CreateSettingForPlugin(debugger, 2935 ConstString(kJITLoaderPluginName), 2936 ConstString("Settings for JIT loader plug-ins"), 2937 properties_sp, 2938 description, 2939 is_global_property); 2940 } 2941 2942 static const char *kOperatingSystemPluginName("os"); 2943 2944 lldb::OptionValuePropertiesSP 2945 PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, const ConstString &setting_name) 2946 { 2947 lldb::OptionValuePropertiesSP properties_sp; 2948 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2949 GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName), 2950 ConstString(), // not creating to so we don't need the description 2951 false)); 2952 if (plugin_type_properties_sp) 2953 properties_sp = plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 2954 return properties_sp; 2955 } 2956 2957 bool 2958 PluginManager::CreateSettingForOperatingSystemPlugin(Debugger &debugger, 2959 const lldb::OptionValuePropertiesSP &properties_sp, 2960 const ConstString &description, bool is_global_property) 2961 { 2962 if (properties_sp) 2963 { 2964 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2965 GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName), 2966 ConstString("Settings for operating system plug-ins"), true)); 2967 if (plugin_type_properties_sp) 2968 { 2969 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), description, is_global_property, 2970 properties_sp); 2971 return true; 2972 } 2973 } 2974 return false; 2975 } 2976