PluginManager.cpp revision 296417
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 28using namespace lldb; 29using namespace lldb_private; 30 31enum PluginAction 32{ 33 ePluginRegisterInstance, 34 ePluginUnregisterInstance, 35 ePluginGetInstanceAtIndex 36}; 37 38 39typedef bool (*PluginInitCallback) (void); 40typedef void (*PluginTermCallback) (void); 41 42struct 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 54typedef std::map<FileSpec, PluginInfo> PluginTerminateMap; 55 56static Mutex & 57GetPluginMapMutex () 58{ 59 static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive); 60 return g_plugin_map_mutex; 61} 62 63static PluginTerminateMap & 64GetPluginMap () 65{ 66 static PluginTerminateMap g_plugin_map; 67 return g_plugin_map; 68} 69 70static bool 71PluginIsLoaded (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 78static void 79SetPluginInfo (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 87template <typename FPtrTy> 88static FPtrTy 89CastToFPtr (void *VPtr) 90{ 91 return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr)); 92} 93 94static FileSpec::EnumerateDirectoryResult 95LoadPluginCallback 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 174void 175PluginManager::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 211void 212PluginManager::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 235struct 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 249typedef std::vector<ABIInstance> ABIInstances; 250 251static Mutex & 252GetABIInstancesMutex () 253{ 254 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 255 return g_instances_mutex; 256} 257 258static ABIInstances & 259GetABIInstances () 260{ 261 static ABIInstances g_instances; 262 return g_instances; 263} 264 265bool 266PluginManager::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 288bool 289PluginManager::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 309ABICreateInstance 310PluginManager::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 319ABICreateInstance 320PluginManager::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 341struct 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 355typedef std::vector<DisassemblerInstance> DisassemblerInstances; 356 357static Mutex & 358GetDisassemblerMutex () 359{ 360 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 361 return g_instances_mutex; 362} 363 364static DisassemblerInstances & 365GetDisassemblerInstances () 366{ 367 static DisassemblerInstances g_instances; 368 return g_instances; 369} 370 371bool 372PluginManager::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 394bool 395PluginManager::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 415DisassemblerCreateInstance 416PluginManager::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 425DisassemblerCreateInstance 426PluginManager::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 448struct 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 464typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances; 465 466 467static Mutex & 468GetDynamicLoaderMutex () 469{ 470 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 471 return g_instances_mutex; 472} 473 474static DynamicLoaderInstances & 475GetDynamicLoaderInstances () 476{ 477 static DynamicLoaderInstances g_instances; 478 return g_instances; 479} 480 481 482bool 483PluginManager::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 506bool 507PluginManager::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 527DynamicLoaderCreateInstance 528PluginManager::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 537DynamicLoaderCreateInstance 538PluginManager::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 558struct 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 574typedef std::vector<JITLoaderInstance> JITLoaderInstances; 575 576 577static Mutex & 578GetJITLoaderMutex () 579{ 580 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 581 return g_instances_mutex; 582} 583 584static JITLoaderInstances & 585GetJITLoaderInstances () 586{ 587 static JITLoaderInstances g_instances; 588 return g_instances; 589} 590 591 592bool 593PluginManager::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 616bool 617PluginManager::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 637JITLoaderCreateInstance 638PluginManager::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 647JITLoaderCreateInstance 648PluginManager::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 668struct 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 682typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances; 683 684static Mutex & 685GetEmulateInstructionMutex () 686{ 687 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 688 return g_instances_mutex; 689} 690 691static EmulateInstructionInstances & 692GetEmulateInstructionInstances () 693{ 694 static EmulateInstructionInstances g_instances; 695 return g_instances; 696} 697 698 699bool 700PluginManager::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 721bool 722PluginManager::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 742EmulateInstructionCreateInstance 743PluginManager::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 752EmulateInstructionCreateInstance 753PluginManager::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 772struct 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 788typedef std::vector<OperatingSystemInstance> OperatingSystemInstances; 789 790static Mutex & 791GetOperatingSystemMutex () 792{ 793 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 794 return g_instances_mutex; 795} 796 797static OperatingSystemInstances & 798GetOperatingSystemInstances () 799{ 800 static OperatingSystemInstances g_instances; 801 return g_instances; 802} 803 804bool 805PluginManager::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 824bool 825PluginManager::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 845OperatingSystemCreateInstance 846PluginManager::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 855OperatingSystemCreateInstance 856PluginManager::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 877struct 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 891typedef std::vector<LanguageInstance> LanguageInstances; 892 893static Mutex & 894GetLanguageMutex () 895{ 896 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 897 return g_instances_mutex; 898} 899 900static LanguageInstances & 901GetLanguageInstances () 902{ 903 static LanguageInstances g_instances; 904 return g_instances; 905} 906 907bool 908PluginManager::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 929bool 930PluginManager::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 950LanguageCreateInstance 951PluginManager::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 960LanguageCreateInstance 961PluginManager::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 982struct 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 997typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances; 998 999static Mutex & 1000GetLanguageRuntimeMutex () 1001{ 1002 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1003 return g_instances_mutex; 1004} 1005 1006static LanguageRuntimeInstances & 1007GetLanguageRuntimeInstances () 1008{ 1009 static LanguageRuntimeInstances g_instances; 1010 return g_instances; 1011} 1012 1013bool 1014PluginManager::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 1037bool 1038PluginManager::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 1058LanguageRuntimeCreateInstance 1059PluginManager::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 1068LanguageRuntimeGetCommandObject 1069PluginManager::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 1078LanguageRuntimeCreateInstance 1079PluginManager::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 1099struct 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 1113typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances; 1114 1115static Mutex & 1116GetSystemRuntimeMutex () 1117{ 1118 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1119 return g_instances_mutex; 1120} 1121 1122static SystemRuntimeInstances & 1123GetSystemRuntimeInstances () 1124{ 1125 static SystemRuntimeInstances g_instances; 1126 return g_instances; 1127} 1128 1129bool 1130PluginManager::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 1151bool 1152PluginManager::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 1172SystemRuntimeCreateInstance 1173PluginManager::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 1182SystemRuntimeCreateInstance 1183PluginManager::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 1203struct 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 1223typedef std::vector<ObjectFileInstance> ObjectFileInstances; 1224 1225static Mutex & 1226GetObjectFileMutex () 1227{ 1228 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1229 return g_instances_mutex; 1230} 1231 1232static ObjectFileInstances & 1233GetObjectFileInstances () 1234{ 1235 static ObjectFileInstances g_instances; 1236 return g_instances; 1237} 1238 1239 1240bool 1241PluginManager::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 1265bool 1266PluginManager::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 1286ObjectFileCreateInstance 1287PluginManager::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 1297ObjectFileCreateMemoryInstance 1298PluginManager::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 1307ObjectFileGetModuleSpecifications 1308PluginManager::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 1317ObjectFileCreateInstance 1318PluginManager::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 1336ObjectFileCreateMemoryInstance 1337PluginManager::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 1354Error 1355PluginManager::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 1373struct 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 1390typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; 1391 1392static Mutex & 1393GetObjectContainerMutex () 1394{ 1395 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1396 return g_instances_mutex; 1397} 1398 1399static ObjectContainerInstances & 1400GetObjectContainerInstances () 1401{ 1402 static ObjectContainerInstances g_instances; 1403 return g_instances; 1404} 1405 1406bool 1407PluginManager::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 1427bool 1428PluginManager::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 1448ObjectContainerCreateInstance 1449PluginManager::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 1458ObjectContainerCreateInstance 1459PluginManager::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 1476ObjectFileGetModuleSpecifications 1477PluginManager::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 1488struct 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 1502typedef std::vector<LogInstance> LogInstances; 1503 1504static Mutex & 1505GetLogMutex () 1506{ 1507 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1508 return g_instances_mutex; 1509} 1510 1511static LogInstances & 1512GetLogInstances () 1513{ 1514 static LogInstances g_instances; 1515 return g_instances; 1516} 1517 1518 1519 1520bool 1521PluginManager::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 1542bool 1543PluginManager::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 1563const char * 1564PluginManager::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 1574LogChannelCreateInstance 1575PluginManager::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 1584LogChannelCreateInstance 1585PluginManager::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 1604struct 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 1620typedef std::vector<PlatformInstance> PlatformInstances; 1621 1622static Mutex & 1623GetPlatformInstancesMutex () 1624{ 1625 static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive); 1626 return g_platform_instances_mutex; 1627} 1628 1629static PlatformInstances & 1630GetPlatformInstances () 1631{ 1632 static PlatformInstances g_platform_instances; 1633 return g_platform_instances; 1634} 1635 1636 1637bool 1638PluginManager::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 1661const char * 1662PluginManager::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 1671const char * 1672PluginManager::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 1681bool 1682PluginManager::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 1702PlatformCreateInstance 1703PluginManager::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 1712PlatformCreateInstance 1713PluginManager::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 1730size_t 1731PluginManager::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 1751struct 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 1767typedef std::vector<ProcessInstance> ProcessInstances; 1768 1769static Mutex & 1770GetProcessMutex () 1771{ 1772 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1773 return g_instances_mutex; 1774} 1775 1776static ProcessInstances & 1777GetProcessInstances () 1778{ 1779 static ProcessInstances g_instances; 1780 return g_instances; 1781} 1782 1783 1784bool 1785PluginManager::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 1805const char * 1806PluginManager::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 1815const char * 1816PluginManager::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 1825bool 1826PluginManager::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 1846ProcessCreateInstance 1847PluginManager::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 1857ProcessCreateInstance 1858PluginManager::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 1877struct 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 1893typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances; 1894 1895static Mutex & 1896GetScriptInterpreterMutex() 1897{ 1898 static Mutex g_instances_mutex(Mutex::eMutexTypeRecursive); 1899 return g_instances_mutex; 1900} 1901 1902static ScriptInterpreterInstances & 1903GetScriptInterpreterInstances() 1904{ 1905 static ScriptInterpreterInstances g_instances; 1906 return g_instances; 1907} 1908 1909bool 1910PluginManager::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 1927bool 1928PluginManager::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 1947ScriptInterpreterCreateInstance 1948PluginManager::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 1957lldb::ScriptInterpreterSP 1958PluginManager::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 1981struct 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 1997typedef std::vector<SymbolFileInstance> SymbolFileInstances; 1998 1999static Mutex & 2000GetSymbolFileMutex () 2001{ 2002 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 2003 return g_instances_mutex; 2004} 2005 2006static SymbolFileInstances & 2007GetSymbolFileInstances () 2008{ 2009 static SymbolFileInstances g_instances; 2010 return g_instances; 2011} 2012 2013 2014bool 2015PluginManager::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 2038bool 2039PluginManager::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 2059SymbolFileCreateInstance 2060PluginManager::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 2069SymbolFileCreateInstance 2070PluginManager::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 2091struct 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 2105typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 2106 2107static Mutex & 2108GetSymbolVendorMutex () 2109{ 2110 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 2111 return g_instances_mutex; 2112} 2113 2114static SymbolVendorInstances & 2115GetSymbolVendorInstances () 2116{ 2117 static SymbolVendorInstances g_instances; 2118 return g_instances; 2119} 2120 2121bool 2122PluginManager::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 2143bool 2144PluginManager::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 2164SymbolVendorCreateInstance 2165PluginManager::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 2175SymbolVendorCreateInstance 2176PluginManager::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 2196struct 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 2210typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances; 2211 2212static Mutex & 2213GetUnwindAssemblyMutex () 2214{ 2215 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 2216 return g_instances_mutex; 2217} 2218 2219static UnwindAssemblyInstances & 2220GetUnwindAssemblyInstances () 2221{ 2222 static UnwindAssemblyInstances g_instances; 2223 return g_instances; 2224} 2225 2226bool 2227PluginManager::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 2248bool 2249PluginManager::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 2269UnwindAssemblyCreateInstance 2270PluginManager::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 2280UnwindAssemblyCreateInstance 2281PluginManager::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 2300struct 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 2314typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances; 2315 2316static Mutex & 2317GetMemoryHistoryMutex () 2318{ 2319 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 2320 return g_instances_mutex; 2321} 2322 2323static MemoryHistoryInstances & 2324GetMemoryHistoryInstances () 2325{ 2326 static MemoryHistoryInstances g_instances; 2327 return g_instances; 2328} 2329 2330bool 2331PluginManager::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 2352bool 2353PluginManager::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 2373MemoryHistoryCreateInstance 2374PluginManager::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 2384MemoryHistoryCreateInstance 2385PluginManager::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 2404struct 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 2419typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances; 2420 2421static Mutex & 2422GetInstrumentationRuntimeMutex () 2423{ 2424 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 2425 return g_instances_mutex; 2426} 2427 2428static InstrumentationRuntimeInstances & 2429GetInstrumentationRuntimeInstances () 2430{ 2431 static InstrumentationRuntimeInstances g_instances; 2432 return g_instances; 2433} 2434 2435bool 2436PluginManager::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 2459bool 2460PluginManager::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 2480InstrumentationRuntimeGetType 2481PluginManager::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 2490InstrumentationRuntimeCreateInstance 2491PluginManager::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 2501InstrumentationRuntimeCreateInstance 2502PluginManager::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 2522struct TypeSystemInstance 2523{ 2524 TypeSystemInstance() : 2525 name(), 2526 description(), 2527 create_callback(NULL) 2528 { 2529 } 2530 2531 ConstString name; 2532 std::string description; 2533 TypeSystemCreateInstance create_callback; 2534 TypeSystemEnumerateSupportedLanguages enumerate_callback; 2535}; 2536 2537typedef std::vector<TypeSystemInstance> TypeSystemInstances; 2538 2539static Mutex & 2540GetTypeSystemMutex () 2541{ 2542 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 2543 return g_instances_mutex; 2544} 2545 2546static TypeSystemInstances & 2547GetTypeSystemInstances () 2548{ 2549 static TypeSystemInstances g_instances; 2550 return g_instances; 2551} 2552 2553bool 2554PluginManager::RegisterPlugin (const ConstString &name, 2555 const char *description, 2556 TypeSystemCreateInstance create_callback, 2557 TypeSystemEnumerateSupportedLanguages enumerate_supported_languages_callback) 2558{ 2559 if (create_callback) 2560 { 2561 TypeSystemInstance instance; 2562 assert ((bool)name); 2563 instance.name = name; 2564 if (description && description[0]) 2565 instance.description = description; 2566 instance.create_callback = create_callback; 2567 instance.enumerate_callback = enumerate_supported_languages_callback; 2568 Mutex::Locker locker (GetTypeSystemMutex ()); 2569 GetTypeSystemInstances ().push_back (instance); 2570 } 2571 return false; 2572} 2573 2574bool 2575PluginManager::UnregisterPlugin (TypeSystemCreateInstance create_callback) 2576{ 2577 if (create_callback) 2578 { 2579 Mutex::Locker locker (GetTypeSystemMutex ()); 2580 TypeSystemInstances &instances = GetTypeSystemInstances (); 2581 2582 TypeSystemInstances::iterator pos, end = instances.end(); 2583 for (pos = instances.begin(); pos != end; ++ pos) 2584 { 2585 if (pos->create_callback == create_callback) 2586 { 2587 instances.erase(pos); 2588 return true; 2589 } 2590 } 2591 } 2592 return false; 2593} 2594 2595TypeSystemCreateInstance 2596PluginManager::GetTypeSystemCreateCallbackAtIndex (uint32_t idx) 2597{ 2598 Mutex::Locker locker (GetTypeSystemMutex ()); 2599 TypeSystemInstances &instances = GetTypeSystemInstances (); 2600 if (idx < instances.size()) 2601 return instances[idx].create_callback; 2602 return NULL; 2603} 2604 2605TypeSystemCreateInstance 2606PluginManager::GetTypeSystemCreateCallbackForPluginName (const ConstString &name) 2607{ 2608 if (name) 2609 { 2610 Mutex::Locker locker (GetTypeSystemMutex ()); 2611 TypeSystemInstances &instances = GetTypeSystemInstances (); 2612 2613 TypeSystemInstances::iterator pos, end = instances.end(); 2614 for (pos = instances.begin(); pos != end; ++ pos) 2615 { 2616 if (name == pos->name) 2617 return pos->create_callback; 2618 } 2619 } 2620 return NULL; 2621} 2622 2623TypeSystemEnumerateSupportedLanguages 2624PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx) 2625{ 2626 Mutex::Locker locker (GetTypeSystemMutex ()); 2627 TypeSystemInstances &instances = GetTypeSystemInstances (); 2628 if (idx < instances.size()) 2629 return instances[idx].enumerate_callback; 2630 return NULL; 2631} 2632 2633TypeSystemEnumerateSupportedLanguages 2634PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name) 2635{ 2636 if (name) 2637 { 2638 Mutex::Locker locker (GetTypeSystemMutex ()); 2639 TypeSystemInstances &instances = GetTypeSystemInstances (); 2640 2641 TypeSystemInstances::iterator pos, end = instances.end(); 2642 for (pos = instances.begin(); pos != end; ++ pos) 2643 { 2644 if (name == pos->name) 2645 return pos->enumerate_callback; 2646 } 2647 } 2648 return NULL; 2649} 2650 2651#pragma mark REPL 2652 2653struct REPLInstance 2654{ 2655 REPLInstance() : 2656 name(), 2657 description(), 2658 create_callback(NULL) 2659 { 2660 } 2661 2662 ConstString name; 2663 std::string description; 2664 REPLCreateInstance create_callback; 2665 REPLEnumerateSupportedLanguages enumerate_languages_callback; 2666}; 2667 2668typedef std::vector<REPLInstance> REPLInstances; 2669 2670static Mutex & 2671GetREPLMutex () 2672{ 2673 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 2674 return g_instances_mutex; 2675} 2676 2677static REPLInstances & 2678GetREPLInstances () 2679{ 2680 static REPLInstances g_instances; 2681 return g_instances; 2682} 2683 2684bool 2685PluginManager::RegisterPlugin (const ConstString &name, 2686 const char *description, 2687 REPLCreateInstance create_callback, 2688 REPLEnumerateSupportedLanguages enumerate_languages_callback) 2689{ 2690 if (create_callback) 2691 { 2692 REPLInstance instance; 2693 assert ((bool)name); 2694 instance.name = name; 2695 if (description && description[0]) 2696 instance.description = description; 2697 instance.create_callback = create_callback; 2698 instance.enumerate_languages_callback = enumerate_languages_callback; 2699 Mutex::Locker locker (GetREPLMutex ()); 2700 GetREPLInstances ().push_back (instance); 2701 } 2702 return false; 2703} 2704 2705bool 2706PluginManager::UnregisterPlugin (REPLCreateInstance create_callback) 2707{ 2708 if (create_callback) 2709 { 2710 Mutex::Locker locker (GetREPLMutex ()); 2711 REPLInstances &instances = GetREPLInstances (); 2712 2713 REPLInstances::iterator pos, end = instances.end(); 2714 for (pos = instances.begin(); pos != end; ++ pos) 2715 { 2716 if (pos->create_callback == create_callback) 2717 { 2718 instances.erase(pos); 2719 return true; 2720 } 2721 } 2722 } 2723 return false; 2724} 2725 2726REPLCreateInstance 2727PluginManager::GetREPLCreateCallbackAtIndex (uint32_t idx) 2728{ 2729 Mutex::Locker locker (GetREPLMutex ()); 2730 REPLInstances &instances = GetREPLInstances (); 2731 if (idx < instances.size()) 2732 return instances[idx].create_callback; 2733 return NULL; 2734} 2735 2736REPLCreateInstance 2737PluginManager::GetREPLCreateCallbackForPluginName (const ConstString &name) 2738{ 2739 if (name) 2740 { 2741 Mutex::Locker locker (GetREPLMutex ()); 2742 REPLInstances &instances = GetREPLInstances (); 2743 2744 REPLInstances::iterator pos, end = instances.end(); 2745 for (pos = instances.begin(); pos != end; ++ pos) 2746 { 2747 if (name == pos->name) 2748 return pos->create_callback; 2749 } 2750 } 2751 return NULL; 2752} 2753 2754REPLEnumerateSupportedLanguages 2755PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx) 2756{ 2757 Mutex::Locker locker (GetREPLMutex ()); 2758 REPLInstances &instances = GetREPLInstances (); 2759 if (idx < instances.size()) 2760 return instances[idx].enumerate_languages_callback; 2761 return NULL; 2762} 2763 2764 2765REPLEnumerateSupportedLanguages 2766PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name) 2767{ 2768 if (name) 2769 { 2770 Mutex::Locker locker (GetREPLMutex ()); 2771 REPLInstances &instances = GetREPLInstances (); 2772 2773 REPLInstances::iterator pos, end = instances.end(); 2774 for (pos = instances.begin(); pos != end; ++ pos) 2775 { 2776 if (name == pos->name) 2777 return pos->enumerate_languages_callback; 2778 } 2779 } 2780 return NULL; 2781} 2782 2783#pragma mark PluginManager 2784 2785void 2786PluginManager::DebuggerInitialize (Debugger &debugger) 2787{ 2788 // Initialize the DynamicLoader plugins 2789 { 2790 Mutex::Locker locker (GetDynamicLoaderMutex ()); 2791 DynamicLoaderInstances &instances = GetDynamicLoaderInstances (); 2792 2793 DynamicLoaderInstances::iterator pos, end = instances.end(); 2794 for (pos = instances.begin(); pos != end; ++ pos) 2795 { 2796 if (pos->debugger_init_callback) 2797 pos->debugger_init_callback (debugger); 2798 } 2799 } 2800 2801 // Initialize the JITLoader plugins 2802 { 2803 Mutex::Locker locker (GetJITLoaderMutex ()); 2804 JITLoaderInstances &instances = GetJITLoaderInstances (); 2805 2806 JITLoaderInstances::iterator pos, end = instances.end(); 2807 for (pos = instances.begin(); pos != end; ++ pos) 2808 { 2809 if (pos->debugger_init_callback) 2810 pos->debugger_init_callback (debugger); 2811 } 2812 } 2813 2814 // Initialize the Platform plugins 2815 { 2816 Mutex::Locker locker (GetPlatformInstancesMutex ()); 2817 PlatformInstances &instances = GetPlatformInstances (); 2818 2819 PlatformInstances::iterator pos, end = instances.end(); 2820 for (pos = instances.begin(); pos != end; ++ pos) 2821 { 2822 if (pos->debugger_init_callback) 2823 pos->debugger_init_callback (debugger); 2824 } 2825 } 2826 2827 // Initialize the Process plugins 2828 { 2829 Mutex::Locker locker (GetProcessMutex()); 2830 ProcessInstances &instances = GetProcessInstances(); 2831 2832 ProcessInstances::iterator pos, end = instances.end(); 2833 for (pos = instances.begin(); pos != end; ++ pos) 2834 { 2835 if (pos->debugger_init_callback) 2836 pos->debugger_init_callback (debugger); 2837 } 2838 } 2839 2840 // Initialize the SymbolFile plugins 2841 { 2842 Mutex::Locker locker (GetSymbolFileMutex()); 2843 for (auto& sym_file: GetSymbolFileInstances()) 2844 { 2845 if (sym_file.debugger_init_callback) 2846 sym_file.debugger_init_callback (debugger); 2847 } 2848 } 2849 2850 // Initialize the OperatingSystem plugins 2851 { 2852 Mutex::Locker locker(GetOperatingSystemMutex()); 2853 for (auto &os : GetOperatingSystemInstances()) 2854 { 2855 if (os.debugger_init_callback) 2856 os.debugger_init_callback(debugger); 2857 } 2858 } 2859} 2860 2861// This is the preferred new way to register plugin specific settings. e.g. 2862// This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 2863static lldb::OptionValuePropertiesSP 2864GetDebuggerPropertyForPlugins (Debugger &debugger, 2865 const ConstString &plugin_type_name, 2866 const ConstString &plugin_type_desc, 2867 bool can_create) 2868{ 2869 lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties()); 2870 if (parent_properties_sp) 2871 { 2872 static ConstString g_property_name("plugin"); 2873 2874 OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name); 2875 if (!plugin_properties_sp && can_create) 2876 { 2877 plugin_properties_sp.reset (new OptionValueProperties (g_property_name)); 2878 parent_properties_sp->AppendProperty (g_property_name, 2879 ConstString("Settings specify to plugins."), 2880 true, 2881 plugin_properties_sp); 2882 } 2883 2884 if (plugin_properties_sp) 2885 { 2886 lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name); 2887 if (!plugin_type_properties_sp && can_create) 2888 { 2889 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name)); 2890 plugin_properties_sp->AppendProperty (plugin_type_name, 2891 plugin_type_desc, 2892 true, 2893 plugin_type_properties_sp); 2894 } 2895 return plugin_type_properties_sp; 2896 } 2897 } 2898 return lldb::OptionValuePropertiesSP(); 2899} 2900 2901// This is deprecated way to register plugin specific settings. e.g. 2902// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" 2903// and Platform generic settings would be under "platform.SETTINGNAME". 2904static lldb::OptionValuePropertiesSP 2905GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger, 2906 const ConstString &plugin_type_name, 2907 const ConstString &plugin_type_desc, 2908 bool can_create) 2909{ 2910 static ConstString g_property_name("plugin"); 2911 lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties()); 2912 if (parent_properties_sp) 2913 { 2914 OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name); 2915 if (!plugin_properties_sp && can_create) 2916 { 2917 plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name)); 2918 parent_properties_sp->AppendProperty (plugin_type_name, 2919 plugin_type_desc, 2920 true, 2921 plugin_properties_sp); 2922 } 2923 2924 if (plugin_properties_sp) 2925 { 2926 lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name); 2927 if (!plugin_type_properties_sp && can_create) 2928 { 2929 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name)); 2930 plugin_properties_sp->AppendProperty (g_property_name, 2931 ConstString("Settings specific to plugins"), 2932 true, 2933 plugin_type_properties_sp); 2934 } 2935 return plugin_type_properties_sp; 2936 } 2937 } 2938 return lldb::OptionValuePropertiesSP(); 2939} 2940 2941namespace { 2942 2943typedef lldb::OptionValuePropertiesSP 2944GetDebuggerPropertyForPluginsPtr (Debugger&, const ConstString&, const ConstString&, bool can_create); 2945 2946lldb::OptionValuePropertiesSP 2947GetSettingForPlugin (Debugger &debugger, 2948 const ConstString &setting_name, 2949 const ConstString &plugin_type_name, 2950 GetDebuggerPropertyForPluginsPtr get_debugger_property= GetDebuggerPropertyForPlugins) 2951{ 2952 lldb::OptionValuePropertiesSP properties_sp; 2953 lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (debugger, 2954 plugin_type_name, 2955 ConstString(), // not creating to so we don't need the description 2956 false)); 2957 if (plugin_type_properties_sp) 2958 properties_sp = plugin_type_properties_sp->GetSubProperty (nullptr, setting_name); 2959 return properties_sp; 2960} 2961 2962bool 2963CreateSettingForPlugin (Debugger &debugger, 2964 const ConstString &plugin_type_name, 2965 const ConstString &plugin_type_desc, 2966 const lldb::OptionValuePropertiesSP &properties_sp, 2967 const ConstString &description, 2968 bool is_global_property, 2969 GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins) 2970{ 2971 if (properties_sp) 2972 { 2973 lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property ( 2974 debugger, plugin_type_name, plugin_type_desc, true)); 2975 if (plugin_type_properties_sp) 2976 { 2977 plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), 2978 description, 2979 is_global_property, 2980 properties_sp); 2981 return true; 2982 } 2983 } 2984 return false; 2985} 2986 2987const char* kDynamicLoaderPluginName("dynamic-loader"); 2988const char* kPlatformPluginName("platform"); 2989const char* kProcessPluginName("process"); 2990const char* kSymbolFilePluginName("symbol-file"); 2991const char* kJITLoaderPluginName("jit-loader"); 2992 2993} 2994 2995lldb::OptionValuePropertiesSP 2996PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, 2997 const ConstString &setting_name) 2998{ 2999 return GetSettingForPlugin(debugger, setting_name, ConstString(kDynamicLoaderPluginName)); 3000} 3001 3002bool 3003PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger, 3004 const lldb::OptionValuePropertiesSP &properties_sp, 3005 const ConstString &description, 3006 bool is_global_property) 3007{ 3008 return CreateSettingForPlugin(debugger, 3009 ConstString(kDynamicLoaderPluginName), 3010 ConstString("Settings for dynamic loader plug-ins"), 3011 properties_sp, 3012 description, 3013 is_global_property); 3014} 3015 3016 3017lldb::OptionValuePropertiesSP 3018PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name) 3019{ 3020 return GetSettingForPlugin(debugger, 3021 setting_name, 3022 ConstString(kPlatformPluginName), 3023 GetDebuggerPropertyForPluginsOldStyle); 3024} 3025 3026bool 3027PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger, 3028 const lldb::OptionValuePropertiesSP &properties_sp, 3029 const ConstString &description, 3030 bool is_global_property) 3031{ 3032 return CreateSettingForPlugin(debugger, 3033 ConstString(kPlatformPluginName), 3034 ConstString("Settings for platform plug-ins"), 3035 properties_sp, 3036 description, 3037 is_global_property, 3038 GetDebuggerPropertyForPluginsOldStyle); 3039} 3040 3041 3042lldb::OptionValuePropertiesSP 3043PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name) 3044{ 3045 return GetSettingForPlugin(debugger, setting_name, ConstString(kProcessPluginName)); 3046} 3047 3048bool 3049PluginManager::CreateSettingForProcessPlugin (Debugger &debugger, 3050 const lldb::OptionValuePropertiesSP &properties_sp, 3051 const ConstString &description, 3052 bool is_global_property) 3053{ 3054 return CreateSettingForPlugin(debugger, 3055 ConstString(kProcessPluginName), 3056 ConstString("Settings for process plug-ins"), 3057 properties_sp, 3058 description, 3059 is_global_property); 3060} 3061 3062lldb::OptionValuePropertiesSP 3063PluginManager::GetSettingForSymbolFilePlugin (Debugger &debugger, 3064 const ConstString &setting_name) 3065{ 3066 return GetSettingForPlugin(debugger, setting_name, ConstString(kSymbolFilePluginName)); 3067} 3068 3069bool 3070PluginManager::CreateSettingForSymbolFilePlugin (Debugger &debugger, 3071 const lldb::OptionValuePropertiesSP &properties_sp, 3072 const ConstString &description, 3073 bool is_global_property) 3074{ 3075 return CreateSettingForPlugin(debugger, 3076 ConstString(kSymbolFilePluginName), 3077 ConstString("Settings for symbol file plug-ins"), 3078 properties_sp, 3079 description, 3080 is_global_property); 3081} 3082 3083lldb::OptionValuePropertiesSP 3084PluginManager::GetSettingForJITLoaderPlugin (Debugger &debugger, 3085 const ConstString &setting_name) 3086{ 3087 return GetSettingForPlugin(debugger, setting_name, ConstString(kJITLoaderPluginName)); 3088} 3089 3090bool 3091PluginManager::CreateSettingForJITLoaderPlugin (Debugger &debugger, 3092 const lldb::OptionValuePropertiesSP &properties_sp, 3093 const ConstString &description, 3094 bool is_global_property) 3095{ 3096 return CreateSettingForPlugin(debugger, 3097 ConstString(kJITLoaderPluginName), 3098 ConstString("Settings for JIT loader plug-ins"), 3099 properties_sp, 3100 description, 3101 is_global_property); 3102} 3103 3104static const char *kOperatingSystemPluginName("os"); 3105 3106lldb::OptionValuePropertiesSP 3107PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, const ConstString &setting_name) 3108{ 3109 lldb::OptionValuePropertiesSP properties_sp; 3110 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 3111 GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName), 3112 ConstString(), // not creating to so we don't need the description 3113 false)); 3114 if (plugin_type_properties_sp) 3115 properties_sp = plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 3116 return properties_sp; 3117} 3118 3119bool 3120PluginManager::CreateSettingForOperatingSystemPlugin(Debugger &debugger, 3121 const lldb::OptionValuePropertiesSP &properties_sp, 3122 const ConstString &description, bool is_global_property) 3123{ 3124 if (properties_sp) 3125 { 3126 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 3127 GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName), 3128 ConstString("Settings for operating system plug-ins"), true)); 3129 if (plugin_type_properties_sp) 3130 { 3131 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), description, is_global_property, 3132 properties_sp); 3133 return true; 3134 } 3135 } 3136 return false; 3137} 3138