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