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