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/lldb-python.h" 11 12 #include "lldb/Core/PluginManager.h" 13 14 #include <limits.h> 15 16 #include <string> 17 #include <vector> 18 19 #include "lldb/Core/Debugger.h" 20 #include "lldb/Core/Error.h" 21 #include "lldb/Host/FileSpec.h" 22 #include "lldb/Host/Host.h" 23 #include "lldb/Host/Mutex.h" 24 #include "lldb/Interpreter/OptionValueProperties.h" 25 26 #include "llvm/ADT/StringRef.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 void *plugin_handle; 45 PluginInitCallback plugin_init_callback; 46 PluginTermCallback plugin_term_callback; 47 }; 48 49 typedef std::map<FileSpec, PluginInfo> PluginTerminateMap; 50 51 static Mutex & 52 GetPluginMapMutex () 53 { 54 static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive); 55 return g_plugin_map_mutex; 56 } 57 58 static PluginTerminateMap & 59 GetPluginMap () 60 { 61 static PluginTerminateMap g_plugin_map; 62 return g_plugin_map; 63 } 64 65 static bool 66 PluginIsLoaded (const FileSpec &plugin_file_spec) 67 { 68 Mutex::Locker locker (GetPluginMapMutex ()); 69 PluginTerminateMap &plugin_map = GetPluginMap (); 70 return plugin_map.find (plugin_file_spec) != plugin_map.end(); 71 } 72 73 static void 74 SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info) 75 { 76 Mutex::Locker locker (GetPluginMapMutex ()); 77 PluginTerminateMap &plugin_map = GetPluginMap (); 78 assert (plugin_map.find (plugin_file_spec) == plugin_map.end()); 79 plugin_map[plugin_file_spec] = plugin_info; 80 } 81 82 83 static FileSpec::EnumerateDirectoryResult 84 LoadPluginCallback 85 ( 86 void *baton, 87 FileSpec::FileType file_type, 88 const FileSpec &file_spec 89 ) 90 { 91 // PluginManager *plugin_manager = (PluginManager *)baton; 92 Error error; 93 94 // If we have a regular file, a symbolic link or unknown file type, try 95 // and process the file. We must handle unknown as sometimes the directory 96 // enumeration might be enumerating a file system that doesn't have correct 97 // file type information. 98 if (file_type == FileSpec::eFileTypeRegular || 99 file_type == FileSpec::eFileTypeSymbolicLink || 100 file_type == FileSpec::eFileTypeUnknown ) 101 { 102 FileSpec plugin_file_spec (file_spec); 103 plugin_file_spec.ResolvePath(); 104 105 if (PluginIsLoaded (plugin_file_spec)) 106 return FileSpec::eEnumerateDirectoryResultNext; 107 else 108 { 109 PluginInfo plugin_info = { NULL, NULL, NULL }; 110 uint32_t flags = Host::eDynamicLibraryOpenOptionLazy | 111 Host::eDynamicLibraryOpenOptionLocal | 112 Host::eDynamicLibraryOpenOptionLimitGetSymbol; 113 114 plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, flags, error); 115 if (plugin_info.plugin_handle) 116 { 117 bool success = false; 118 plugin_info.plugin_init_callback = (PluginInitCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error); 119 if (plugin_info.plugin_init_callback) 120 { 121 // Call the plug-in "bool LLDBPluginInitialize(void)" function 122 success = plugin_info.plugin_init_callback(); 123 } 124 125 if (success) 126 { 127 // It is ok for the "LLDBPluginTerminate" symbol to be NULL 128 plugin_info.plugin_term_callback = (PluginTermCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error); 129 } 130 else 131 { 132 // The initialize function returned FALSE which means the 133 // plug-in might not be compatible, or might be too new or 134 // too old, or might not want to run on this machine. 135 Host::DynamicLibraryClose (plugin_info.plugin_handle); 136 plugin_info.plugin_handle = NULL; 137 plugin_info.plugin_init_callback = NULL; 138 } 139 140 // Regardless of success or failure, cache the plug-in load 141 // in our plug-in info so we don't try to load it again and 142 // again. 143 SetPluginInfo (plugin_file_spec, plugin_info); 144 145 return FileSpec::eEnumerateDirectoryResultNext; 146 } 147 } 148 } 149 150 if (file_type == FileSpec::eFileTypeUnknown || 151 file_type == FileSpec::eFileTypeDirectory || 152 file_type == FileSpec::eFileTypeSymbolicLink ) 153 { 154 // Try and recurse into anything that a directory or symbolic link. 155 // We must also do this for unknown as sometimes the directory enumeration 156 // might be enurating a file system that doesn't have correct file type 157 // information. 158 return FileSpec::eEnumerateDirectoryResultEnter; 159 } 160 161 return FileSpec::eEnumerateDirectoryResultNext; 162 } 163 164 165 void 166 PluginManager::Initialize () 167 { 168 #if 1 169 FileSpec dir_spec; 170 const bool find_directories = true; 171 const bool find_files = true; 172 const bool find_other = true; 173 char dir_path[PATH_MAX]; 174 if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) 175 { 176 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 177 { 178 FileSpec::EnumerateDirectory (dir_path, 179 find_directories, 180 find_files, 181 find_other, 182 LoadPluginCallback, 183 NULL); 184 } 185 } 186 187 if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) 188 { 189 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 190 { 191 FileSpec::EnumerateDirectory (dir_path, 192 find_directories, 193 find_files, 194 find_other, 195 LoadPluginCallback, 196 NULL); 197 } 198 } 199 #endif 200 } 201 202 void 203 PluginManager::Terminate () 204 { 205 Mutex::Locker locker (GetPluginMapMutex ()); 206 PluginTerminateMap &plugin_map = GetPluginMap (); 207 208 PluginTerminateMap::const_iterator pos, end = plugin_map.end(); 209 for (pos = plugin_map.begin(); pos != end; ++pos) 210 { 211 // Call the plug-in "void LLDBPluginTerminate (void)" function if there 212 // is one (if the symbol was not NULL). 213 if (pos->second.plugin_handle) 214 { 215 if (pos->second.plugin_term_callback) 216 pos->second.plugin_term_callback(); 217 Host::DynamicLibraryClose (pos->second.plugin_handle); 218 } 219 } 220 plugin_map.clear(); 221 } 222 223 224 #pragma mark ABI 225 226 227 struct ABIInstance 228 { 229 ABIInstance() : 230 name(), 231 description(), 232 create_callback(NULL) 233 { 234 } 235 236 ConstString name; 237 std::string description; 238 ABICreateInstance create_callback; 239 }; 240 241 typedef std::vector<ABIInstance> ABIInstances; 242 243 static Mutex & 244 GetABIInstancesMutex () 245 { 246 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 247 return g_instances_mutex; 248 } 249 250 static ABIInstances & 251 GetABIInstances () 252 { 253 static ABIInstances g_instances; 254 return g_instances; 255 } 256 257 bool 258 PluginManager::RegisterPlugin 259 ( 260 const ConstString &name, 261 const char *description, 262 ABICreateInstance create_callback 263 ) 264 { 265 if (create_callback) 266 { 267 ABIInstance instance; 268 assert ((bool)name); 269 instance.name = name; 270 if (description && description[0]) 271 instance.description = description; 272 instance.create_callback = create_callback; 273 Mutex::Locker locker (GetABIInstancesMutex ()); 274 GetABIInstances ().push_back (instance); 275 return true; 276 } 277 return false; 278 } 279 280 bool 281 PluginManager::UnregisterPlugin (ABICreateInstance create_callback) 282 { 283 if (create_callback) 284 { 285 Mutex::Locker locker (GetABIInstancesMutex ()); 286 ABIInstances &instances = GetABIInstances (); 287 288 ABIInstances::iterator pos, end = instances.end(); 289 for (pos = instances.begin(); pos != end; ++ pos) 290 { 291 if (pos->create_callback == create_callback) 292 { 293 instances.erase(pos); 294 return true; 295 } 296 } 297 } 298 return false; 299 } 300 301 ABICreateInstance 302 PluginManager::GetABICreateCallbackAtIndex (uint32_t idx) 303 { 304 Mutex::Locker locker (GetABIInstancesMutex ()); 305 ABIInstances &instances = GetABIInstances (); 306 if (idx < instances.size()) 307 return instances[idx].create_callback; 308 return NULL; 309 } 310 311 ABICreateInstance 312 PluginManager::GetABICreateCallbackForPluginName (const ConstString &name) 313 { 314 if (name) 315 { 316 Mutex::Locker locker (GetABIInstancesMutex ()); 317 ABIInstances &instances = GetABIInstances (); 318 319 ABIInstances::iterator pos, end = instances.end(); 320 for (pos = instances.begin(); pos != end; ++ pos) 321 { 322 if (name == pos->name) 323 return pos->create_callback; 324 } 325 } 326 return NULL; 327 } 328 329 330 #pragma mark Disassembler 331 332 333 struct DisassemblerInstance 334 { 335 DisassemblerInstance() : 336 name(), 337 description(), 338 create_callback(NULL) 339 { 340 } 341 342 ConstString name; 343 std::string description; 344 DisassemblerCreateInstance create_callback; 345 }; 346 347 typedef std::vector<DisassemblerInstance> DisassemblerInstances; 348 349 static Mutex & 350 GetDisassemblerMutex () 351 { 352 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 353 return g_instances_mutex; 354 } 355 356 static DisassemblerInstances & 357 GetDisassemblerInstances () 358 { 359 static DisassemblerInstances g_instances; 360 return g_instances; 361 } 362 363 bool 364 PluginManager::RegisterPlugin 365 ( 366 const ConstString &name, 367 const char *description, 368 DisassemblerCreateInstance create_callback 369 ) 370 { 371 if (create_callback) 372 { 373 DisassemblerInstance instance; 374 assert ((bool)name); 375 instance.name = name; 376 if (description && description[0]) 377 instance.description = description; 378 instance.create_callback = create_callback; 379 Mutex::Locker locker (GetDisassemblerMutex ()); 380 GetDisassemblerInstances ().push_back (instance); 381 return true; 382 } 383 return false; 384 } 385 386 bool 387 PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback) 388 { 389 if (create_callback) 390 { 391 Mutex::Locker locker (GetDisassemblerMutex ()); 392 DisassemblerInstances &instances = GetDisassemblerInstances (); 393 394 DisassemblerInstances::iterator pos, end = instances.end(); 395 for (pos = instances.begin(); pos != end; ++ pos) 396 { 397 if (pos->create_callback == create_callback) 398 { 399 instances.erase(pos); 400 return true; 401 } 402 } 403 } 404 return false; 405 } 406 407 DisassemblerCreateInstance 408 PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx) 409 { 410 Mutex::Locker locker (GetDisassemblerMutex ()); 411 DisassemblerInstances &instances = GetDisassemblerInstances (); 412 if (idx < instances.size()) 413 return instances[idx].create_callback; 414 return NULL; 415 } 416 417 DisassemblerCreateInstance 418 PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &name) 419 { 420 if (name) 421 { 422 Mutex::Locker locker (GetDisassemblerMutex ()); 423 DisassemblerInstances &instances = GetDisassemblerInstances (); 424 425 DisassemblerInstances::iterator pos, end = instances.end(); 426 for (pos = instances.begin(); pos != end; ++ pos) 427 { 428 if (name == pos->name) 429 return pos->create_callback; 430 } 431 } 432 return NULL; 433 } 434 435 436 437 #pragma mark DynamicLoader 438 439 440 struct DynamicLoaderInstance 441 { 442 DynamicLoaderInstance() : 443 name(), 444 description(), 445 create_callback(NULL), 446 debugger_init_callback (NULL) 447 { 448 } 449 450 ConstString name; 451 std::string description; 452 DynamicLoaderCreateInstance create_callback; 453 DebuggerInitializeCallback debugger_init_callback; 454 }; 455 456 typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances; 457 458 459 static Mutex & 460 GetDynamicLoaderMutex () 461 { 462 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 463 return g_instances_mutex; 464 } 465 466 static DynamicLoaderInstances & 467 GetDynamicLoaderInstances () 468 { 469 static DynamicLoaderInstances g_instances; 470 return g_instances; 471 } 472 473 474 bool 475 PluginManager::RegisterPlugin 476 ( 477 const ConstString &name, 478 const char *description, 479 DynamicLoaderCreateInstance create_callback, 480 DebuggerInitializeCallback debugger_init_callback 481 ) 482 { 483 if (create_callback) 484 { 485 DynamicLoaderInstance instance; 486 assert ((bool)name); 487 instance.name = name; 488 if (description && description[0]) 489 instance.description = description; 490 instance.create_callback = create_callback; 491 instance.debugger_init_callback = debugger_init_callback; 492 Mutex::Locker locker (GetDynamicLoaderMutex ()); 493 GetDynamicLoaderInstances ().push_back (instance); 494 } 495 return false; 496 } 497 498 bool 499 PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback) 500 { 501 if (create_callback) 502 { 503 Mutex::Locker locker (GetDynamicLoaderMutex ()); 504 DynamicLoaderInstances &instances = GetDynamicLoaderInstances (); 505 506 DynamicLoaderInstances::iterator pos, end = instances.end(); 507 for (pos = instances.begin(); pos != end; ++ pos) 508 { 509 if (pos->create_callback == create_callback) 510 { 511 instances.erase(pos); 512 return true; 513 } 514 } 515 } 516 return false; 517 } 518 519 DynamicLoaderCreateInstance 520 PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx) 521 { 522 Mutex::Locker locker (GetDynamicLoaderMutex ()); 523 DynamicLoaderInstances &instances = GetDynamicLoaderInstances (); 524 if (idx < instances.size()) 525 return instances[idx].create_callback; 526 return NULL; 527 } 528 529 DynamicLoaderCreateInstance 530 PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name) 531 { 532 if (name) 533 { 534 Mutex::Locker locker (GetDynamicLoaderMutex ()); 535 DynamicLoaderInstances &instances = GetDynamicLoaderInstances (); 536 537 DynamicLoaderInstances::iterator pos, end = instances.end(); 538 for (pos = instances.begin(); pos != end; ++ pos) 539 { 540 if (name == pos->name) 541 return pos->create_callback; 542 } 543 } 544 return NULL; 545 } 546 547 #pragma mark EmulateInstruction 548 549 550 struct EmulateInstructionInstance 551 { 552 EmulateInstructionInstance() : 553 name(), 554 description(), 555 create_callback(NULL) 556 { 557 } 558 559 ConstString name; 560 std::string description; 561 EmulateInstructionCreateInstance create_callback; 562 }; 563 564 typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances; 565 566 static Mutex & 567 GetEmulateInstructionMutex () 568 { 569 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 570 return g_instances_mutex; 571 } 572 573 static EmulateInstructionInstances & 574 GetEmulateInstructionInstances () 575 { 576 static EmulateInstructionInstances g_instances; 577 return g_instances; 578 } 579 580 581 bool 582 PluginManager::RegisterPlugin 583 ( 584 const ConstString &name, 585 const char *description, 586 EmulateInstructionCreateInstance create_callback 587 ) 588 { 589 if (create_callback) 590 { 591 EmulateInstructionInstance instance; 592 assert ((bool)name); 593 instance.name = name; 594 if (description && description[0]) 595 instance.description = description; 596 instance.create_callback = create_callback; 597 Mutex::Locker locker (GetEmulateInstructionMutex ()); 598 GetEmulateInstructionInstances ().push_back (instance); 599 } 600 return false; 601 } 602 603 bool 604 PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback) 605 { 606 if (create_callback) 607 { 608 Mutex::Locker locker (GetEmulateInstructionMutex ()); 609 EmulateInstructionInstances &instances = GetEmulateInstructionInstances (); 610 611 EmulateInstructionInstances::iterator pos, end = instances.end(); 612 for (pos = instances.begin(); pos != end; ++ pos) 613 { 614 if (pos->create_callback == create_callback) 615 { 616 instances.erase(pos); 617 return true; 618 } 619 } 620 } 621 return false; 622 } 623 624 EmulateInstructionCreateInstance 625 PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx) 626 { 627 Mutex::Locker locker (GetEmulateInstructionMutex ()); 628 EmulateInstructionInstances &instances = GetEmulateInstructionInstances (); 629 if (idx < instances.size()) 630 return instances[idx].create_callback; 631 return NULL; 632 } 633 634 EmulateInstructionCreateInstance 635 PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name) 636 { 637 if (name) 638 { 639 Mutex::Locker locker (GetEmulateInstructionMutex ()); 640 EmulateInstructionInstances &instances = GetEmulateInstructionInstances (); 641 642 EmulateInstructionInstances::iterator pos, end = instances.end(); 643 for (pos = instances.begin(); pos != end; ++ pos) 644 { 645 if (name == pos->name) 646 return pos->create_callback; 647 } 648 } 649 return NULL; 650 } 651 #pragma mark OperatingSystem 652 653 654 struct OperatingSystemInstance 655 { 656 OperatingSystemInstance() : 657 name(), 658 description(), 659 create_callback(NULL) 660 { 661 } 662 663 ConstString name; 664 std::string description; 665 OperatingSystemCreateInstance create_callback; 666 }; 667 668 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances; 669 670 static Mutex & 671 GetOperatingSystemMutex () 672 { 673 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 674 return g_instances_mutex; 675 } 676 677 static OperatingSystemInstances & 678 GetOperatingSystemInstances () 679 { 680 static OperatingSystemInstances g_instances; 681 return g_instances; 682 } 683 684 bool 685 PluginManager::RegisterPlugin (const ConstString &name, 686 const char *description, 687 OperatingSystemCreateInstance create_callback) 688 { 689 if (create_callback) 690 { 691 OperatingSystemInstance instance; 692 assert ((bool)name); 693 instance.name = name; 694 if (description && description[0]) 695 instance.description = description; 696 instance.create_callback = create_callback; 697 Mutex::Locker locker (GetOperatingSystemMutex ()); 698 GetOperatingSystemInstances ().push_back (instance); 699 } 700 return false; 701 } 702 703 bool 704 PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback) 705 { 706 if (create_callback) 707 { 708 Mutex::Locker locker (GetOperatingSystemMutex ()); 709 OperatingSystemInstances &instances = GetOperatingSystemInstances (); 710 711 OperatingSystemInstances::iterator pos, end = instances.end(); 712 for (pos = instances.begin(); pos != end; ++ pos) 713 { 714 if (pos->create_callback == create_callback) 715 { 716 instances.erase(pos); 717 return true; 718 } 719 } 720 } 721 return false; 722 } 723 724 OperatingSystemCreateInstance 725 PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx) 726 { 727 Mutex::Locker locker (GetOperatingSystemMutex ()); 728 OperatingSystemInstances &instances = GetOperatingSystemInstances (); 729 if (idx < instances.size()) 730 return instances[idx].create_callback; 731 return NULL; 732 } 733 734 OperatingSystemCreateInstance 735 PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name) 736 { 737 if (name) 738 { 739 Mutex::Locker locker (GetOperatingSystemMutex ()); 740 OperatingSystemInstances &instances = GetOperatingSystemInstances (); 741 742 OperatingSystemInstances::iterator pos, end = instances.end(); 743 for (pos = instances.begin(); pos != end; ++ pos) 744 { 745 if (name == pos->name) 746 return pos->create_callback; 747 } 748 } 749 return NULL; 750 } 751 752 753 #pragma mark LanguageRuntime 754 755 756 struct LanguageRuntimeInstance 757 { 758 LanguageRuntimeInstance() : 759 name(), 760 description(), 761 create_callback(NULL) 762 { 763 } 764 765 ConstString name; 766 std::string description; 767 LanguageRuntimeCreateInstance create_callback; 768 }; 769 770 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances; 771 772 static Mutex & 773 GetLanguageRuntimeMutex () 774 { 775 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 776 return g_instances_mutex; 777 } 778 779 static LanguageRuntimeInstances & 780 GetLanguageRuntimeInstances () 781 { 782 static LanguageRuntimeInstances g_instances; 783 return g_instances; 784 } 785 786 bool 787 PluginManager::RegisterPlugin 788 ( 789 const ConstString &name, 790 const char *description, 791 LanguageRuntimeCreateInstance create_callback 792 ) 793 { 794 if (create_callback) 795 { 796 LanguageRuntimeInstance instance; 797 assert ((bool)name); 798 instance.name = name; 799 if (description && description[0]) 800 instance.description = description; 801 instance.create_callback = create_callback; 802 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 803 GetLanguageRuntimeInstances ().push_back (instance); 804 } 805 return false; 806 } 807 808 bool 809 PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback) 810 { 811 if (create_callback) 812 { 813 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 814 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances (); 815 816 LanguageRuntimeInstances::iterator pos, end = instances.end(); 817 for (pos = instances.begin(); pos != end; ++ pos) 818 { 819 if (pos->create_callback == create_callback) 820 { 821 instances.erase(pos); 822 return true; 823 } 824 } 825 } 826 return false; 827 } 828 829 LanguageRuntimeCreateInstance 830 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx) 831 { 832 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 833 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances (); 834 if (idx < instances.size()) 835 return instances[idx].create_callback; 836 return NULL; 837 } 838 839 LanguageRuntimeCreateInstance 840 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name) 841 { 842 if (name) 843 { 844 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 845 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances (); 846 847 LanguageRuntimeInstances::iterator pos, end = instances.end(); 848 for (pos = instances.begin(); pos != end; ++ pos) 849 { 850 if (name == pos->name) 851 return pos->create_callback; 852 } 853 } 854 return NULL; 855 } 856 857 #pragma mark SystemRuntime 858 859 860 struct SystemRuntimeInstance 861 { 862 SystemRuntimeInstance() : 863 name(), 864 description(), 865 create_callback(NULL) 866 { 867 } 868 869 ConstString name; 870 std::string description; 871 SystemRuntimeCreateInstance create_callback; 872 }; 873 874 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances; 875 876 static Mutex & 877 GetSystemRuntimeMutex () 878 { 879 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 880 return g_instances_mutex; 881 } 882 883 static SystemRuntimeInstances & 884 GetSystemRuntimeInstances () 885 { 886 static SystemRuntimeInstances g_instances; 887 return g_instances; 888 } 889 890 bool 891 PluginManager::RegisterPlugin 892 ( 893 const ConstString &name, 894 const char *description, 895 SystemRuntimeCreateInstance create_callback 896 ) 897 { 898 if (create_callback) 899 { 900 SystemRuntimeInstance instance; 901 assert ((bool)name); 902 instance.name = name; 903 if (description && description[0]) 904 instance.description = description; 905 instance.create_callback = create_callback; 906 Mutex::Locker locker (GetSystemRuntimeMutex ()); 907 GetSystemRuntimeInstances ().push_back (instance); 908 } 909 return false; 910 } 911 912 bool 913 PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback) 914 { 915 if (create_callback) 916 { 917 Mutex::Locker locker (GetSystemRuntimeMutex ()); 918 SystemRuntimeInstances &instances = GetSystemRuntimeInstances (); 919 920 SystemRuntimeInstances::iterator pos, end = instances.end(); 921 for (pos = instances.begin(); pos != end; ++ pos) 922 { 923 if (pos->create_callback == create_callback) 924 { 925 instances.erase(pos); 926 return true; 927 } 928 } 929 } 930 return false; 931 } 932 933 SystemRuntimeCreateInstance 934 PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx) 935 { 936 Mutex::Locker locker (GetSystemRuntimeMutex ()); 937 SystemRuntimeInstances &instances = GetSystemRuntimeInstances (); 938 if (idx < instances.size()) 939 return instances[idx].create_callback; 940 return NULL; 941 } 942 943 SystemRuntimeCreateInstance 944 PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name) 945 { 946 if (name) 947 { 948 Mutex::Locker locker (GetSystemRuntimeMutex ()); 949 SystemRuntimeInstances &instances = GetSystemRuntimeInstances (); 950 951 SystemRuntimeInstances::iterator pos, end = instances.end(); 952 for (pos = instances.begin(); pos != end; ++ pos) 953 { 954 if (name == pos->name) 955 return pos->create_callback; 956 } 957 } 958 return NULL; 959 } 960 961 962 #pragma mark ObjectFile 963 964 struct ObjectFileInstance 965 { 966 ObjectFileInstance() : 967 name(), 968 description(), 969 create_callback(NULL), 970 create_memory_callback (NULL), 971 get_module_specifications (NULL) 972 { 973 } 974 975 ConstString name; 976 std::string description; 977 ObjectFileCreateInstance create_callback; 978 ObjectFileCreateMemoryInstance create_memory_callback; 979 ObjectFileGetModuleSpecifications get_module_specifications; 980 }; 981 982 typedef std::vector<ObjectFileInstance> ObjectFileInstances; 983 984 static Mutex & 985 GetObjectFileMutex () 986 { 987 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 988 return g_instances_mutex; 989 } 990 991 static ObjectFileInstances & 992 GetObjectFileInstances () 993 { 994 static ObjectFileInstances g_instances; 995 return g_instances; 996 } 997 998 999 bool 1000 PluginManager::RegisterPlugin (const ConstString &name, 1001 const char *description, 1002 ObjectFileCreateInstance create_callback, 1003 ObjectFileCreateMemoryInstance create_memory_callback, 1004 ObjectFileGetModuleSpecifications get_module_specifications) 1005 { 1006 if (create_callback) 1007 { 1008 ObjectFileInstance instance; 1009 assert ((bool)name); 1010 instance.name = name; 1011 if (description && description[0]) 1012 instance.description = description; 1013 instance.create_callback = create_callback; 1014 instance.create_memory_callback = create_memory_callback; 1015 instance.get_module_specifications = get_module_specifications; 1016 Mutex::Locker locker (GetObjectFileMutex ()); 1017 GetObjectFileInstances ().push_back (instance); 1018 } 1019 return false; 1020 } 1021 1022 bool 1023 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback) 1024 { 1025 if (create_callback) 1026 { 1027 Mutex::Locker locker (GetObjectFileMutex ()); 1028 ObjectFileInstances &instances = GetObjectFileInstances (); 1029 1030 ObjectFileInstances::iterator pos, end = instances.end(); 1031 for (pos = instances.begin(); pos != end; ++ pos) 1032 { 1033 if (pos->create_callback == create_callback) 1034 { 1035 instances.erase(pos); 1036 return true; 1037 } 1038 } 1039 } 1040 return false; 1041 } 1042 1043 ObjectFileCreateInstance 1044 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx) 1045 { 1046 Mutex::Locker locker (GetObjectFileMutex ()); 1047 ObjectFileInstances &instances = GetObjectFileInstances (); 1048 if (idx < instances.size()) 1049 return instances[idx].create_callback; 1050 return NULL; 1051 } 1052 1053 1054 ObjectFileCreateMemoryInstance 1055 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx) 1056 { 1057 Mutex::Locker locker (GetObjectFileMutex ()); 1058 ObjectFileInstances &instances = GetObjectFileInstances (); 1059 if (idx < instances.size()) 1060 return instances[idx].create_memory_callback; 1061 return NULL; 1062 } 1063 1064 ObjectFileGetModuleSpecifications 1065 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx) 1066 { 1067 Mutex::Locker locker (GetObjectFileMutex ()); 1068 ObjectFileInstances &instances = GetObjectFileInstances (); 1069 if (idx < instances.size()) 1070 return instances[idx].get_module_specifications; 1071 return NULL; 1072 } 1073 1074 ObjectFileCreateInstance 1075 PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name) 1076 { 1077 if (name) 1078 { 1079 Mutex::Locker locker (GetObjectFileMutex ()); 1080 ObjectFileInstances &instances = GetObjectFileInstances (); 1081 1082 ObjectFileInstances::iterator pos, end = instances.end(); 1083 for (pos = instances.begin(); pos != end; ++ pos) 1084 { 1085 if (name == pos->name) 1086 return pos->create_callback; 1087 } 1088 } 1089 return NULL; 1090 } 1091 1092 1093 ObjectFileCreateMemoryInstance 1094 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name) 1095 { 1096 if (name) 1097 { 1098 Mutex::Locker locker (GetObjectFileMutex ()); 1099 ObjectFileInstances &instances = GetObjectFileInstances (); 1100 1101 ObjectFileInstances::iterator pos, end = instances.end(); 1102 for (pos = instances.begin(); pos != end; ++ pos) 1103 { 1104 if (name == pos->name) 1105 return pos->create_memory_callback; 1106 } 1107 } 1108 return NULL; 1109 } 1110 1111 1112 1113 #pragma mark ObjectContainer 1114 1115 struct ObjectContainerInstance 1116 { 1117 ObjectContainerInstance() : 1118 name(), 1119 description(), 1120 create_callback (NULL), 1121 get_module_specifications (NULL) 1122 { 1123 } 1124 1125 ConstString name; 1126 std::string description; 1127 ObjectContainerCreateInstance create_callback; 1128 ObjectFileGetModuleSpecifications get_module_specifications; 1129 1130 }; 1131 1132 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; 1133 1134 static Mutex & 1135 GetObjectContainerMutex () 1136 { 1137 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1138 return g_instances_mutex; 1139 } 1140 1141 static ObjectContainerInstances & 1142 GetObjectContainerInstances () 1143 { 1144 static ObjectContainerInstances g_instances; 1145 return g_instances; 1146 } 1147 1148 bool 1149 PluginManager::RegisterPlugin (const ConstString &name, 1150 const char *description, 1151 ObjectContainerCreateInstance create_callback, 1152 ObjectFileGetModuleSpecifications get_module_specifications) 1153 { 1154 if (create_callback) 1155 { 1156 ObjectContainerInstance instance; 1157 assert ((bool)name); 1158 instance.name = name; 1159 if (description && description[0]) 1160 instance.description = description; 1161 instance.create_callback = create_callback; 1162 instance.get_module_specifications = get_module_specifications; 1163 Mutex::Locker locker (GetObjectContainerMutex ()); 1164 GetObjectContainerInstances ().push_back (instance); 1165 } 1166 return false; 1167 } 1168 1169 bool 1170 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback) 1171 { 1172 if (create_callback) 1173 { 1174 Mutex::Locker locker (GetObjectContainerMutex ()); 1175 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1176 1177 ObjectContainerInstances::iterator pos, end = instances.end(); 1178 for (pos = instances.begin(); pos != end; ++ pos) 1179 { 1180 if (pos->create_callback == create_callback) 1181 { 1182 instances.erase(pos); 1183 return true; 1184 } 1185 } 1186 } 1187 return false; 1188 } 1189 1190 ObjectContainerCreateInstance 1191 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx) 1192 { 1193 Mutex::Locker locker (GetObjectContainerMutex ()); 1194 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1195 if (idx < instances.size()) 1196 return instances[idx].create_callback; 1197 return NULL; 1198 } 1199 1200 ObjectContainerCreateInstance 1201 PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name) 1202 { 1203 if (name) 1204 { 1205 Mutex::Locker locker (GetObjectContainerMutex ()); 1206 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1207 1208 ObjectContainerInstances::iterator pos, end = instances.end(); 1209 for (pos = instances.begin(); pos != end; ++ pos) 1210 { 1211 if (name == pos->name) 1212 return pos->create_callback; 1213 } 1214 } 1215 return NULL; 1216 } 1217 1218 ObjectFileGetModuleSpecifications 1219 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx) 1220 { 1221 Mutex::Locker locker (GetObjectContainerMutex ()); 1222 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1223 if (idx < instances.size()) 1224 return instances[idx].get_module_specifications; 1225 return NULL; 1226 } 1227 1228 #pragma mark LogChannel 1229 1230 struct LogInstance 1231 { 1232 LogInstance() : 1233 name(), 1234 description(), 1235 create_callback(NULL) 1236 { 1237 } 1238 1239 ConstString name; 1240 std::string description; 1241 LogChannelCreateInstance create_callback; 1242 }; 1243 1244 typedef std::vector<LogInstance> LogInstances; 1245 1246 static Mutex & 1247 GetLogMutex () 1248 { 1249 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1250 return g_instances_mutex; 1251 } 1252 1253 static LogInstances & 1254 GetLogInstances () 1255 { 1256 static LogInstances g_instances; 1257 return g_instances; 1258 } 1259 1260 1261 1262 bool 1263 PluginManager::RegisterPlugin 1264 ( 1265 const ConstString &name, 1266 const char *description, 1267 LogChannelCreateInstance create_callback 1268 ) 1269 { 1270 if (create_callback) 1271 { 1272 LogInstance instance; 1273 assert ((bool)name); 1274 instance.name = name; 1275 if (description && description[0]) 1276 instance.description = description; 1277 instance.create_callback = create_callback; 1278 Mutex::Locker locker (GetLogMutex ()); 1279 GetLogInstances ().push_back (instance); 1280 } 1281 return false; 1282 } 1283 1284 bool 1285 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback) 1286 { 1287 if (create_callback) 1288 { 1289 Mutex::Locker locker (GetLogMutex ()); 1290 LogInstances &instances = GetLogInstances (); 1291 1292 LogInstances::iterator pos, end = instances.end(); 1293 for (pos = instances.begin(); pos != end; ++ pos) 1294 { 1295 if (pos->create_callback == create_callback) 1296 { 1297 instances.erase(pos); 1298 return true; 1299 } 1300 } 1301 } 1302 return false; 1303 } 1304 1305 const char * 1306 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx) 1307 { 1308 Mutex::Locker locker (GetLogMutex ()); 1309 LogInstances &instances = GetLogInstances (); 1310 if (idx < instances.size()) 1311 return instances[idx].name.GetCString(); 1312 return NULL; 1313 } 1314 1315 1316 LogChannelCreateInstance 1317 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx) 1318 { 1319 Mutex::Locker locker (GetLogMutex ()); 1320 LogInstances &instances = GetLogInstances (); 1321 if (idx < instances.size()) 1322 return instances[idx].create_callback; 1323 return NULL; 1324 } 1325 1326 LogChannelCreateInstance 1327 PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name) 1328 { 1329 if (name) 1330 { 1331 Mutex::Locker locker (GetLogMutex ()); 1332 LogInstances &instances = GetLogInstances (); 1333 1334 LogInstances::iterator pos, end = instances.end(); 1335 for (pos = instances.begin(); pos != end; ++ pos) 1336 { 1337 if (name == pos->name) 1338 return pos->create_callback; 1339 } 1340 } 1341 return NULL; 1342 } 1343 1344 #pragma mark Platform 1345 1346 struct PlatformInstance 1347 { 1348 PlatformInstance() : 1349 name(), 1350 description(), 1351 create_callback(NULL), 1352 debugger_init_callback (NULL) 1353 { 1354 } 1355 1356 ConstString name; 1357 std::string description; 1358 PlatformCreateInstance create_callback; 1359 DebuggerInitializeCallback debugger_init_callback; 1360 }; 1361 1362 typedef std::vector<PlatformInstance> PlatformInstances; 1363 1364 static Mutex & 1365 GetPlatformInstancesMutex () 1366 { 1367 static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive); 1368 return g_platform_instances_mutex; 1369 } 1370 1371 static PlatformInstances & 1372 GetPlatformInstances () 1373 { 1374 static PlatformInstances g_platform_instances; 1375 return g_platform_instances; 1376 } 1377 1378 1379 bool 1380 PluginManager::RegisterPlugin (const ConstString &name, 1381 const char *description, 1382 PlatformCreateInstance create_callback, 1383 DebuggerInitializeCallback debugger_init_callback) 1384 { 1385 if (create_callback) 1386 { 1387 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1388 1389 PlatformInstance instance; 1390 assert ((bool)name); 1391 instance.name = name; 1392 if (description && description[0]) 1393 instance.description = description; 1394 instance.create_callback = create_callback; 1395 instance.debugger_init_callback = debugger_init_callback; 1396 GetPlatformInstances ().push_back (instance); 1397 return true; 1398 } 1399 return false; 1400 } 1401 1402 1403 const char * 1404 PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx) 1405 { 1406 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1407 PlatformInstances &instances = GetPlatformInstances (); 1408 if (idx < instances.size()) 1409 return instances[idx].name.GetCString(); 1410 return NULL; 1411 } 1412 1413 const char * 1414 PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx) 1415 { 1416 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1417 PlatformInstances &instances = GetPlatformInstances (); 1418 if (idx < instances.size()) 1419 return instances[idx].description.c_str(); 1420 return NULL; 1421 } 1422 1423 bool 1424 PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback) 1425 { 1426 if (create_callback) 1427 { 1428 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1429 PlatformInstances &instances = GetPlatformInstances (); 1430 1431 PlatformInstances::iterator pos, end = instances.end(); 1432 for (pos = instances.begin(); pos != end; ++ pos) 1433 { 1434 if (pos->create_callback == create_callback) 1435 { 1436 instances.erase(pos); 1437 return true; 1438 } 1439 } 1440 } 1441 return false; 1442 } 1443 1444 PlatformCreateInstance 1445 PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx) 1446 { 1447 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1448 PlatformInstances &instances = GetPlatformInstances (); 1449 if (idx < instances.size()) 1450 return instances[idx].create_callback; 1451 return NULL; 1452 } 1453 1454 PlatformCreateInstance 1455 PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name) 1456 { 1457 if (name) 1458 { 1459 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1460 PlatformInstances &instances = GetPlatformInstances (); 1461 1462 PlatformInstances::iterator pos, end = instances.end(); 1463 for (pos = instances.begin(); pos != end; ++ pos) 1464 { 1465 if (name == pos->name) 1466 return pos->create_callback; 1467 } 1468 } 1469 return NULL; 1470 } 1471 1472 size_t 1473 PluginManager::AutoCompletePlatformName (const char *name, StringList &matches) 1474 { 1475 if (name) 1476 { 1477 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1478 PlatformInstances &instances = GetPlatformInstances (); 1479 llvm::StringRef name_sref(name); 1480 1481 PlatformInstances::iterator pos, end = instances.end(); 1482 for (pos = instances.begin(); pos != end; ++ pos) 1483 { 1484 llvm::StringRef plugin_name (pos->name.GetCString()); 1485 if (plugin_name.startswith(name_sref)) 1486 matches.AppendString (plugin_name.data()); 1487 } 1488 } 1489 return matches.GetSize(); 1490 } 1491 #pragma mark Process 1492 1493 struct ProcessInstance 1494 { 1495 ProcessInstance() : 1496 name(), 1497 description(), 1498 create_callback(NULL), 1499 debugger_init_callback(NULL) 1500 { 1501 } 1502 1503 ConstString name; 1504 std::string description; 1505 ProcessCreateInstance create_callback; 1506 DebuggerInitializeCallback debugger_init_callback; 1507 }; 1508 1509 typedef std::vector<ProcessInstance> ProcessInstances; 1510 1511 static Mutex & 1512 GetProcessMutex () 1513 { 1514 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1515 return g_instances_mutex; 1516 } 1517 1518 static ProcessInstances & 1519 GetProcessInstances () 1520 { 1521 static ProcessInstances g_instances; 1522 return g_instances; 1523 } 1524 1525 1526 bool 1527 PluginManager::RegisterPlugin (const ConstString &name, 1528 const char *description, 1529 ProcessCreateInstance create_callback, 1530 DebuggerInitializeCallback debugger_init_callback) 1531 { 1532 if (create_callback) 1533 { 1534 ProcessInstance instance; 1535 assert ((bool)name); 1536 instance.name = name; 1537 if (description && description[0]) 1538 instance.description = description; 1539 instance.create_callback = create_callback; 1540 instance.debugger_init_callback = debugger_init_callback; 1541 Mutex::Locker locker (GetProcessMutex ()); 1542 GetProcessInstances ().push_back (instance); 1543 } 1544 return false; 1545 } 1546 1547 const char * 1548 PluginManager::GetProcessPluginNameAtIndex (uint32_t idx) 1549 { 1550 Mutex::Locker locker (GetProcessMutex ()); 1551 ProcessInstances &instances = GetProcessInstances (); 1552 if (idx < instances.size()) 1553 return instances[idx].name.GetCString(); 1554 return NULL; 1555 } 1556 1557 const char * 1558 PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx) 1559 { 1560 Mutex::Locker locker (GetProcessMutex ()); 1561 ProcessInstances &instances = GetProcessInstances (); 1562 if (idx < instances.size()) 1563 return instances[idx].description.c_str(); 1564 return NULL; 1565 } 1566 1567 bool 1568 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback) 1569 { 1570 if (create_callback) 1571 { 1572 Mutex::Locker locker (GetProcessMutex ()); 1573 ProcessInstances &instances = GetProcessInstances (); 1574 1575 ProcessInstances::iterator pos, end = instances.end(); 1576 for (pos = instances.begin(); pos != end; ++ pos) 1577 { 1578 if (pos->create_callback == create_callback) 1579 { 1580 instances.erase(pos); 1581 return true; 1582 } 1583 } 1584 } 1585 return false; 1586 } 1587 1588 ProcessCreateInstance 1589 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx) 1590 { 1591 Mutex::Locker locker (GetProcessMutex ()); 1592 ProcessInstances &instances = GetProcessInstances (); 1593 if (idx < instances.size()) 1594 return instances[idx].create_callback; 1595 return NULL; 1596 } 1597 1598 1599 ProcessCreateInstance 1600 PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name) 1601 { 1602 if (name) 1603 { 1604 Mutex::Locker locker (GetProcessMutex ()); 1605 ProcessInstances &instances = GetProcessInstances (); 1606 1607 ProcessInstances::iterator pos, end = instances.end(); 1608 for (pos = instances.begin(); pos != end; ++ pos) 1609 { 1610 if (name == pos->name) 1611 return pos->create_callback; 1612 } 1613 } 1614 return NULL; 1615 } 1616 1617 #pragma mark SymbolFile 1618 1619 struct SymbolFileInstance 1620 { 1621 SymbolFileInstance() : 1622 name(), 1623 description(), 1624 create_callback(NULL) 1625 { 1626 } 1627 1628 ConstString name; 1629 std::string description; 1630 SymbolFileCreateInstance create_callback; 1631 }; 1632 1633 typedef std::vector<SymbolFileInstance> SymbolFileInstances; 1634 1635 static Mutex & 1636 GetSymbolFileMutex () 1637 { 1638 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1639 return g_instances_mutex; 1640 } 1641 1642 static SymbolFileInstances & 1643 GetSymbolFileInstances () 1644 { 1645 static SymbolFileInstances g_instances; 1646 return g_instances; 1647 } 1648 1649 1650 bool 1651 PluginManager::RegisterPlugin 1652 ( 1653 const ConstString &name, 1654 const char *description, 1655 SymbolFileCreateInstance create_callback 1656 ) 1657 { 1658 if (create_callback) 1659 { 1660 SymbolFileInstance instance; 1661 assert ((bool)name); 1662 instance.name = name; 1663 if (description && description[0]) 1664 instance.description = description; 1665 instance.create_callback = create_callback; 1666 Mutex::Locker locker (GetSymbolFileMutex ()); 1667 GetSymbolFileInstances ().push_back (instance); 1668 } 1669 return false; 1670 } 1671 1672 bool 1673 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback) 1674 { 1675 if (create_callback) 1676 { 1677 Mutex::Locker locker (GetSymbolFileMutex ()); 1678 SymbolFileInstances &instances = GetSymbolFileInstances (); 1679 1680 SymbolFileInstances::iterator pos, end = instances.end(); 1681 for (pos = instances.begin(); pos != end; ++ pos) 1682 { 1683 if (pos->create_callback == create_callback) 1684 { 1685 instances.erase(pos); 1686 return true; 1687 } 1688 } 1689 } 1690 return false; 1691 } 1692 1693 SymbolFileCreateInstance 1694 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx) 1695 { 1696 Mutex::Locker locker (GetSymbolFileMutex ()); 1697 SymbolFileInstances &instances = GetSymbolFileInstances (); 1698 if (idx < instances.size()) 1699 return instances[idx].create_callback; 1700 return NULL; 1701 } 1702 1703 SymbolFileCreateInstance 1704 PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name) 1705 { 1706 if (name) 1707 { 1708 Mutex::Locker locker (GetSymbolFileMutex ()); 1709 SymbolFileInstances &instances = GetSymbolFileInstances (); 1710 1711 SymbolFileInstances::iterator pos, end = instances.end(); 1712 for (pos = instances.begin(); pos != end; ++ pos) 1713 { 1714 if (name == pos->name) 1715 return pos->create_callback; 1716 } 1717 } 1718 return NULL; 1719 } 1720 1721 1722 1723 #pragma mark SymbolVendor 1724 1725 struct SymbolVendorInstance 1726 { 1727 SymbolVendorInstance() : 1728 name(), 1729 description(), 1730 create_callback(NULL) 1731 { 1732 } 1733 1734 ConstString name; 1735 std::string description; 1736 SymbolVendorCreateInstance create_callback; 1737 }; 1738 1739 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 1740 1741 static Mutex & 1742 GetSymbolVendorMutex () 1743 { 1744 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1745 return g_instances_mutex; 1746 } 1747 1748 static SymbolVendorInstances & 1749 GetSymbolVendorInstances () 1750 { 1751 static SymbolVendorInstances g_instances; 1752 return g_instances; 1753 } 1754 1755 bool 1756 PluginManager::RegisterPlugin 1757 ( 1758 const ConstString &name, 1759 const char *description, 1760 SymbolVendorCreateInstance create_callback 1761 ) 1762 { 1763 if (create_callback) 1764 { 1765 SymbolVendorInstance instance; 1766 assert ((bool)name); 1767 instance.name = name; 1768 if (description && description[0]) 1769 instance.description = description; 1770 instance.create_callback = create_callback; 1771 Mutex::Locker locker (GetSymbolVendorMutex ()); 1772 GetSymbolVendorInstances ().push_back (instance); 1773 } 1774 return false; 1775 } 1776 1777 bool 1778 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback) 1779 { 1780 if (create_callback) 1781 { 1782 Mutex::Locker locker (GetSymbolVendorMutex ()); 1783 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1784 1785 SymbolVendorInstances::iterator pos, end = instances.end(); 1786 for (pos = instances.begin(); pos != end; ++ pos) 1787 { 1788 if (pos->create_callback == create_callback) 1789 { 1790 instances.erase(pos); 1791 return true; 1792 } 1793 } 1794 } 1795 return false; 1796 } 1797 1798 SymbolVendorCreateInstance 1799 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx) 1800 { 1801 Mutex::Locker locker (GetSymbolVendorMutex ()); 1802 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1803 if (idx < instances.size()) 1804 return instances[idx].create_callback; 1805 return NULL; 1806 } 1807 1808 1809 SymbolVendorCreateInstance 1810 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name) 1811 { 1812 if (name) 1813 { 1814 Mutex::Locker locker (GetSymbolVendorMutex ()); 1815 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1816 1817 SymbolVendorInstances::iterator pos, end = instances.end(); 1818 for (pos = instances.begin(); pos != end; ++ pos) 1819 { 1820 if (name == pos->name) 1821 return pos->create_callback; 1822 } 1823 } 1824 return NULL; 1825 } 1826 1827 1828 #pragma mark UnwindAssembly 1829 1830 struct UnwindAssemblyInstance 1831 { 1832 UnwindAssemblyInstance() : 1833 name(), 1834 description(), 1835 create_callback(NULL) 1836 { 1837 } 1838 1839 ConstString name; 1840 std::string description; 1841 UnwindAssemblyCreateInstance create_callback; 1842 }; 1843 1844 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances; 1845 1846 static Mutex & 1847 GetUnwindAssemblyMutex () 1848 { 1849 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1850 return g_instances_mutex; 1851 } 1852 1853 static UnwindAssemblyInstances & 1854 GetUnwindAssemblyInstances () 1855 { 1856 static UnwindAssemblyInstances g_instances; 1857 return g_instances; 1858 } 1859 1860 bool 1861 PluginManager::RegisterPlugin 1862 ( 1863 const ConstString &name, 1864 const char *description, 1865 UnwindAssemblyCreateInstance create_callback 1866 ) 1867 { 1868 if (create_callback) 1869 { 1870 UnwindAssemblyInstance instance; 1871 assert ((bool)name); 1872 instance.name = name; 1873 if (description && description[0]) 1874 instance.description = description; 1875 instance.create_callback = create_callback; 1876 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 1877 GetUnwindAssemblyInstances ().push_back (instance); 1878 } 1879 return false; 1880 } 1881 1882 bool 1883 PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback) 1884 { 1885 if (create_callback) 1886 { 1887 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 1888 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances (); 1889 1890 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1891 for (pos = instances.begin(); pos != end; ++ pos) 1892 { 1893 if (pos->create_callback == create_callback) 1894 { 1895 instances.erase(pos); 1896 return true; 1897 } 1898 } 1899 } 1900 return false; 1901 } 1902 1903 UnwindAssemblyCreateInstance 1904 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx) 1905 { 1906 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 1907 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances (); 1908 if (idx < instances.size()) 1909 return instances[idx].create_callback; 1910 return NULL; 1911 } 1912 1913 1914 UnwindAssemblyCreateInstance 1915 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name) 1916 { 1917 if (name) 1918 { 1919 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 1920 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances (); 1921 1922 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1923 for (pos = instances.begin(); pos != end; ++ pos) 1924 { 1925 if (name == pos->name) 1926 return pos->create_callback; 1927 } 1928 } 1929 return NULL; 1930 } 1931 1932 void 1933 PluginManager::DebuggerInitialize (Debugger &debugger) 1934 { 1935 // Initialize the DynamicLoader plugins 1936 { 1937 Mutex::Locker locker (GetDynamicLoaderMutex ()); 1938 DynamicLoaderInstances &instances = GetDynamicLoaderInstances (); 1939 1940 DynamicLoaderInstances::iterator pos, end = instances.end(); 1941 for (pos = instances.begin(); pos != end; ++ pos) 1942 { 1943 if (pos->debugger_init_callback) 1944 pos->debugger_init_callback (debugger); 1945 } 1946 } 1947 1948 // Initialize the Platform plugins 1949 { 1950 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1951 PlatformInstances &instances = GetPlatformInstances (); 1952 1953 PlatformInstances::iterator pos, end = instances.end(); 1954 for (pos = instances.begin(); pos != end; ++ pos) 1955 { 1956 if (pos->debugger_init_callback) 1957 pos->debugger_init_callback (debugger); 1958 } 1959 } 1960 1961 // Initialize the Process plugins 1962 { 1963 Mutex::Locker locker (GetProcessMutex()); 1964 ProcessInstances &instances = GetProcessInstances(); 1965 1966 ProcessInstances::iterator pos, end = instances.end(); 1967 for (pos = instances.begin(); pos != end; ++ pos) 1968 { 1969 if (pos->debugger_init_callback) 1970 pos->debugger_init_callback (debugger); 1971 } 1972 } 1973 1974 } 1975 1976 // This is the preferred new way to register plugin specific settings. e.g. 1977 // This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 1978 static lldb::OptionValuePropertiesSP 1979 GetDebuggerPropertyForPlugins (Debugger &debugger, 1980 const ConstString &plugin_type_name, 1981 const ConstString &plugin_type_desc, 1982 bool can_create) 1983 { 1984 lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties()); 1985 if (parent_properties_sp) 1986 { 1987 static ConstString g_property_name("plugin"); 1988 1989 OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name); 1990 if (!plugin_properties_sp && can_create) 1991 { 1992 plugin_properties_sp.reset (new OptionValueProperties (g_property_name)); 1993 parent_properties_sp->AppendProperty (g_property_name, 1994 ConstString("Settings specify to plugins."), 1995 true, 1996 plugin_properties_sp); 1997 } 1998 1999 if (plugin_properties_sp) 2000 { 2001 lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name); 2002 if (!plugin_type_properties_sp && can_create) 2003 { 2004 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name)); 2005 plugin_properties_sp->AppendProperty (plugin_type_name, 2006 plugin_type_desc, 2007 true, 2008 plugin_type_properties_sp); 2009 } 2010 return plugin_type_properties_sp; 2011 } 2012 } 2013 return lldb::OptionValuePropertiesSP(); 2014 } 2015 2016 // This is deprecated way to register plugin specific settings. e.g. 2017 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" 2018 // and Platform generic settings would be under "platform.SETTINGNAME". 2019 static lldb::OptionValuePropertiesSP 2020 GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger, 2021 const ConstString &plugin_type_name, 2022 const ConstString &plugin_type_desc, 2023 bool can_create) 2024 { 2025 static ConstString g_property_name("plugin"); 2026 lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties()); 2027 if (parent_properties_sp) 2028 { 2029 OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name); 2030 if (!plugin_properties_sp && can_create) 2031 { 2032 plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name)); 2033 parent_properties_sp->AppendProperty (plugin_type_name, 2034 plugin_type_desc, 2035 true, 2036 plugin_properties_sp); 2037 } 2038 2039 if (plugin_properties_sp) 2040 { 2041 lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name); 2042 if (!plugin_type_properties_sp && can_create) 2043 { 2044 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name)); 2045 plugin_properties_sp->AppendProperty (g_property_name, 2046 ConstString("Settings specific to plugins"), 2047 true, 2048 plugin_type_properties_sp); 2049 } 2050 return plugin_type_properties_sp; 2051 } 2052 } 2053 return lldb::OptionValuePropertiesSP(); 2054 } 2055 2056 2057 lldb::OptionValuePropertiesSP 2058 PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name) 2059 { 2060 lldb::OptionValuePropertiesSP properties_sp; 2061 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, 2062 ConstString("dynamic-loader"), 2063 ConstString(), // not creating to so we don't need the description 2064 false)); 2065 if (plugin_type_properties_sp) 2066 properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name); 2067 return properties_sp; 2068 } 2069 2070 bool 2071 PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger, 2072 const lldb::OptionValuePropertiesSP &properties_sp, 2073 const ConstString &description, 2074 bool is_global_property) 2075 { 2076 if (properties_sp) 2077 { 2078 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, 2079 ConstString("dynamic-loader"), 2080 ConstString("Settings for dynamic loader plug-ins"), 2081 true)); 2082 if (plugin_type_properties_sp) 2083 { 2084 plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), 2085 description, 2086 is_global_property, 2087 properties_sp); 2088 return true; 2089 } 2090 } 2091 return false; 2092 } 2093 2094 2095 lldb::OptionValuePropertiesSP 2096 PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name) 2097 { 2098 lldb::OptionValuePropertiesSP properties_sp; 2099 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger, 2100 ConstString("platform"), 2101 ConstString(), // not creating to so we don't need the description 2102 false)); 2103 if (plugin_type_properties_sp) 2104 properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name); 2105 return properties_sp; 2106 } 2107 2108 bool 2109 PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger, 2110 const lldb::OptionValuePropertiesSP &properties_sp, 2111 const ConstString &description, 2112 bool is_global_property) 2113 { 2114 if (properties_sp) 2115 { 2116 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger, 2117 ConstString("platform"), 2118 ConstString("Settings for platform plug-ins"), 2119 true)); 2120 if (plugin_type_properties_sp) 2121 { 2122 plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), 2123 description, 2124 is_global_property, 2125 properties_sp); 2126 return true; 2127 } 2128 } 2129 return false; 2130 } 2131 2132 2133 lldb::OptionValuePropertiesSP 2134 PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name) 2135 { 2136 lldb::OptionValuePropertiesSP properties_sp; 2137 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, 2138 ConstString("process"), 2139 ConstString(), // not creating to so we don't need the description 2140 false)); 2141 if (plugin_type_properties_sp) 2142 properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name); 2143 return properties_sp; 2144 } 2145 2146 bool 2147 PluginManager::CreateSettingForProcessPlugin (Debugger &debugger, 2148 const lldb::OptionValuePropertiesSP &properties_sp, 2149 const ConstString &description, 2150 bool is_global_property) 2151 { 2152 if (properties_sp) 2153 { 2154 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, 2155 ConstString("process"), 2156 ConstString("Settings for process plug-ins"), 2157 true)); 2158 if (plugin_type_properties_sp) 2159 { 2160 plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), 2161 description, 2162 is_global_property, 2163 properties_sp); 2164 return true; 2165 } 2166 } 2167 return false; 2168 } 2169 2170