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 }; 869 870 typedef std::vector<ObjectFileInstance> ObjectFileInstances; 871 872 static Mutex & 873 GetObjectFileMutex () 874 { 875 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 876 return g_instances_mutex; 877 } 878 879 static ObjectFileInstances & 880 GetObjectFileInstances () 881 { 882 static ObjectFileInstances g_instances; 883 return g_instances; 884 } 885 886 887 bool 888 PluginManager::RegisterPlugin 889 ( 890 const char *name, 891 const char *description, 892 ObjectFileCreateInstance create_callback 893 ) 894 { 895 if (create_callback) 896 { 897 ObjectFileInstance instance; 898 assert (name && name[0]); 899 instance.name = name; 900 if (description && description[0]) 901 instance.description = description; 902 instance.create_callback = create_callback; 903 Mutex::Locker locker (GetObjectFileMutex ()); 904 GetObjectFileInstances ().push_back (instance); 905 } 906 return false; 907 } 908 909 bool 910 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback) 911 { 912 if (create_callback) 913 { 914 Mutex::Locker locker (GetObjectFileMutex ()); 915 ObjectFileInstances &instances = GetObjectFileInstances (); 916 917 ObjectFileInstances::iterator pos, end = instances.end(); 918 for (pos = instances.begin(); pos != end; ++ pos) 919 { 920 if (pos->create_callback == create_callback) 921 { 922 instances.erase(pos); 923 return true; 924 } 925 } 926 } 927 return false; 928 } 929 930 ObjectFileCreateInstance 931 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx) 932 { 933 Mutex::Locker locker (GetObjectFileMutex ()); 934 ObjectFileInstances &instances = GetObjectFileInstances (); 935 if (idx < instances.size()) 936 return instances[idx].create_callback; 937 return NULL; 938 } 939 940 ObjectFileCreateInstance 941 PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name) 942 { 943 if (name && name[0]) 944 { 945 llvm::StringRef name_sref(name); 946 Mutex::Locker locker (GetObjectFileMutex ()); 947 ObjectFileInstances &instances = GetObjectFileInstances (); 948 949 ObjectFileInstances::iterator pos, end = instances.end(); 950 for (pos = instances.begin(); pos != end; ++ pos) 951 { 952 if (name_sref.equals (pos->name)) 953 return pos->create_callback; 954 } 955 } 956 return NULL; 957 } 958 959 960 961 #pragma mark ObjectContainer 962 963 struct ObjectContainerInstance 964 { 965 ObjectContainerInstance() : 966 name(), 967 description(), 968 create_callback(NULL) 969 { 970 } 971 972 std::string name; 973 std::string description; 974 ObjectContainerCreateInstance create_callback; 975 }; 976 977 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; 978 979 static Mutex & 980 GetObjectContainerMutex () 981 { 982 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 983 return g_instances_mutex; 984 } 985 986 static ObjectContainerInstances & 987 GetObjectContainerInstances () 988 { 989 static ObjectContainerInstances g_instances; 990 return g_instances; 991 } 992 993 bool 994 PluginManager::RegisterPlugin 995 ( 996 const char *name, 997 const char *description, 998 ObjectContainerCreateInstance create_callback 999 ) 1000 { 1001 if (create_callback) 1002 { 1003 ObjectContainerInstance instance; 1004 assert (name && name[0]); 1005 instance.name = name; 1006 if (description && description[0]) 1007 instance.description = description; 1008 instance.create_callback = create_callback; 1009 Mutex::Locker locker (GetObjectContainerMutex ()); 1010 GetObjectContainerInstances ().push_back (instance); 1011 } 1012 return false; 1013 } 1014 1015 bool 1016 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback) 1017 { 1018 if (create_callback) 1019 { 1020 Mutex::Locker locker (GetObjectContainerMutex ()); 1021 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1022 1023 ObjectContainerInstances::iterator pos, end = instances.end(); 1024 for (pos = instances.begin(); pos != end; ++ pos) 1025 { 1026 if (pos->create_callback == create_callback) 1027 { 1028 instances.erase(pos); 1029 return true; 1030 } 1031 } 1032 } 1033 return false; 1034 } 1035 1036 ObjectContainerCreateInstance 1037 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx) 1038 { 1039 Mutex::Locker locker (GetObjectContainerMutex ()); 1040 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1041 if (idx < instances.size()) 1042 return instances[idx].create_callback; 1043 return NULL; 1044 } 1045 1046 ObjectContainerCreateInstance 1047 PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name) 1048 { 1049 if (name && name[0]) 1050 { 1051 llvm::StringRef name_sref(name); 1052 Mutex::Locker locker (GetObjectContainerMutex ()); 1053 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1054 1055 ObjectContainerInstances::iterator pos, end = instances.end(); 1056 for (pos = instances.begin(); pos != end; ++ pos) 1057 { 1058 if (name_sref.equals (pos->name)) 1059 return pos->create_callback; 1060 } 1061 } 1062 return NULL; 1063 } 1064 1065 #pragma mark LogChannel 1066 1067 struct LogInstance 1068 { 1069 LogInstance() : 1070 name(), 1071 description(), 1072 create_callback(NULL) 1073 { 1074 } 1075 1076 std::string name; 1077 std::string description; 1078 LogChannelCreateInstance create_callback; 1079 }; 1080 1081 typedef std::vector<LogInstance> LogInstances; 1082 1083 static Mutex & 1084 GetLogMutex () 1085 { 1086 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1087 return g_instances_mutex; 1088 } 1089 1090 static LogInstances & 1091 GetLogInstances () 1092 { 1093 static LogInstances g_instances; 1094 return g_instances; 1095 } 1096 1097 1098 1099 bool 1100 PluginManager::RegisterPlugin 1101 ( 1102 const char *name, 1103 const char *description, 1104 LogChannelCreateInstance create_callback 1105 ) 1106 { 1107 if (create_callback) 1108 { 1109 LogInstance instance; 1110 assert (name && name[0]); 1111 instance.name = name; 1112 if (description && description[0]) 1113 instance.description = description; 1114 instance.create_callback = create_callback; 1115 Mutex::Locker locker (GetLogMutex ()); 1116 GetLogInstances ().push_back (instance); 1117 } 1118 return false; 1119 } 1120 1121 bool 1122 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback) 1123 { 1124 if (create_callback) 1125 { 1126 Mutex::Locker locker (GetLogMutex ()); 1127 LogInstances &instances = GetLogInstances (); 1128 1129 LogInstances::iterator pos, end = instances.end(); 1130 for (pos = instances.begin(); pos != end; ++ pos) 1131 { 1132 if (pos->create_callback == create_callback) 1133 { 1134 instances.erase(pos); 1135 return true; 1136 } 1137 } 1138 } 1139 return false; 1140 } 1141 1142 const char * 1143 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx) 1144 { 1145 Mutex::Locker locker (GetLogMutex ()); 1146 LogInstances &instances = GetLogInstances (); 1147 if (idx < instances.size()) 1148 return instances[idx].name.c_str(); 1149 return NULL; 1150 } 1151 1152 1153 LogChannelCreateInstance 1154 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx) 1155 { 1156 Mutex::Locker locker (GetLogMutex ()); 1157 LogInstances &instances = GetLogInstances (); 1158 if (idx < instances.size()) 1159 return instances[idx].create_callback; 1160 return NULL; 1161 } 1162 1163 LogChannelCreateInstance 1164 PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name) 1165 { 1166 if (name && name[0]) 1167 { 1168 llvm::StringRef name_sref(name); 1169 Mutex::Locker locker (GetLogMutex ()); 1170 LogInstances &instances = GetLogInstances (); 1171 1172 LogInstances::iterator pos, end = instances.end(); 1173 for (pos = instances.begin(); pos != end; ++ pos) 1174 { 1175 if (name_sref.equals (pos->name)) 1176 return pos->create_callback; 1177 } 1178 } 1179 return NULL; 1180 } 1181 1182 #pragma mark Platform 1183 1184 struct PlatformInstance 1185 { 1186 PlatformInstance() : 1187 name(), 1188 description(), 1189 create_callback(NULL) 1190 { 1191 } 1192 1193 std::string name; 1194 std::string description; 1195 PlatformCreateInstance create_callback; 1196 }; 1197 1198 typedef std::vector<PlatformInstance> PlatformInstances; 1199 1200 static Mutex & 1201 GetPlatformInstancesMutex () 1202 { 1203 static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive); 1204 return g_platform_instances_mutex; 1205 } 1206 1207 static PlatformInstances & 1208 GetPlatformInstances () 1209 { 1210 static PlatformInstances g_platform_instances; 1211 return g_platform_instances; 1212 } 1213 1214 1215 bool 1216 PluginManager::RegisterPlugin (const char *name, 1217 const char *description, 1218 PlatformCreateInstance create_callback) 1219 { 1220 if (create_callback) 1221 { 1222 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1223 1224 PlatformInstance instance; 1225 assert (name && name[0]); 1226 instance.name = name; 1227 if (description && description[0]) 1228 instance.description = description; 1229 instance.create_callback = create_callback; 1230 GetPlatformInstances ().push_back (instance); 1231 return true; 1232 } 1233 return false; 1234 } 1235 1236 const char * 1237 PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx) 1238 { 1239 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1240 PlatformInstances &instances = GetPlatformInstances (); 1241 if (idx < instances.size()) 1242 return instances[idx].name.c_str(); 1243 return NULL; 1244 } 1245 1246 const char * 1247 PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx) 1248 { 1249 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1250 PlatformInstances &instances = GetPlatformInstances (); 1251 if (idx < instances.size()) 1252 return instances[idx].description.c_str(); 1253 return NULL; 1254 } 1255 1256 bool 1257 PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback) 1258 { 1259 if (create_callback) 1260 { 1261 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1262 PlatformInstances &instances = GetPlatformInstances (); 1263 1264 PlatformInstances::iterator pos, end = instances.end(); 1265 for (pos = instances.begin(); pos != end; ++ pos) 1266 { 1267 if (pos->create_callback == create_callback) 1268 { 1269 instances.erase(pos); 1270 return true; 1271 } 1272 } 1273 } 1274 return false; 1275 } 1276 1277 PlatformCreateInstance 1278 PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx) 1279 { 1280 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1281 PlatformInstances &instances = GetPlatformInstances (); 1282 if (idx < instances.size()) 1283 return instances[idx].create_callback; 1284 return NULL; 1285 } 1286 1287 PlatformCreateInstance 1288 PluginManager::GetPlatformCreateCallbackForPluginName (const char *name) 1289 { 1290 if (name && name[0]) 1291 { 1292 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1293 PlatformInstances &instances = GetPlatformInstances (); 1294 llvm::StringRef name_sref(name); 1295 1296 PlatformInstances::iterator pos, end = instances.end(); 1297 for (pos = instances.begin(); pos != end; ++ pos) 1298 { 1299 if (name_sref.equals (pos->name)) 1300 return pos->create_callback; 1301 } 1302 } 1303 return NULL; 1304 } 1305 1306 uint32_t 1307 PluginManager::AutoCompletePlatformName (const char *name, StringList &matches) 1308 { 1309 if (name && name[0]) 1310 { 1311 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1312 PlatformInstances &instances = GetPlatformInstances (); 1313 llvm::StringRef name_sref(name); 1314 1315 PlatformInstances::iterator pos, end = instances.end(); 1316 for (pos = instances.begin(); pos != end; ++ pos) 1317 { 1318 llvm::StringRef plugin_name (pos->name); 1319 if (plugin_name.startswith(name_sref)) 1320 matches.AppendString (plugin_name.data()); 1321 } 1322 } 1323 return matches.GetSize(); 1324 } 1325 1326 #pragma mark Process 1327 1328 struct ProcessInstance 1329 { 1330 ProcessInstance() : 1331 name(), 1332 description(), 1333 create_callback(NULL) 1334 { 1335 } 1336 1337 std::string name; 1338 std::string description; 1339 ProcessCreateInstance create_callback; 1340 }; 1341 1342 typedef std::vector<ProcessInstance> ProcessInstances; 1343 1344 static Mutex & 1345 GetProcessMutex () 1346 { 1347 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1348 return g_instances_mutex; 1349 } 1350 1351 static ProcessInstances & 1352 GetProcessInstances () 1353 { 1354 static ProcessInstances g_instances; 1355 return g_instances; 1356 } 1357 1358 1359 bool 1360 PluginManager::RegisterPlugin 1361 ( 1362 const char *name, 1363 const char *description, 1364 ProcessCreateInstance create_callback 1365 ) 1366 { 1367 if (create_callback) 1368 { 1369 ProcessInstance instance; 1370 assert (name && name[0]); 1371 instance.name = name; 1372 if (description && description[0]) 1373 instance.description = description; 1374 instance.create_callback = create_callback; 1375 Mutex::Locker locker (GetProcessMutex ()); 1376 GetProcessInstances ().push_back (instance); 1377 } 1378 return false; 1379 } 1380 1381 const char * 1382 PluginManager::GetProcessPluginNameAtIndex (uint32_t idx) 1383 { 1384 Mutex::Locker locker (GetProcessMutex ()); 1385 ProcessInstances &instances = GetProcessInstances (); 1386 if (idx < instances.size()) 1387 return instances[idx].name.c_str(); 1388 return NULL; 1389 } 1390 1391 const char * 1392 PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx) 1393 { 1394 Mutex::Locker locker (GetProcessMutex ()); 1395 ProcessInstances &instances = GetProcessInstances (); 1396 if (idx < instances.size()) 1397 return instances[idx].description.c_str(); 1398 return NULL; 1399 } 1400 1401 bool 1402 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback) 1403 { 1404 if (create_callback) 1405 { 1406 Mutex::Locker locker (GetProcessMutex ()); 1407 ProcessInstances &instances = GetProcessInstances (); 1408 1409 ProcessInstances::iterator pos, end = instances.end(); 1410 for (pos = instances.begin(); pos != end; ++ pos) 1411 { 1412 if (pos->create_callback == create_callback) 1413 { 1414 instances.erase(pos); 1415 return true; 1416 } 1417 } 1418 } 1419 return false; 1420 } 1421 1422 ProcessCreateInstance 1423 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx) 1424 { 1425 Mutex::Locker locker (GetProcessMutex ()); 1426 ProcessInstances &instances = GetProcessInstances (); 1427 if (idx < instances.size()) 1428 return instances[idx].create_callback; 1429 return NULL; 1430 } 1431 1432 1433 ProcessCreateInstance 1434 PluginManager::GetProcessCreateCallbackForPluginName (const char *name) 1435 { 1436 if (name && name[0]) 1437 { 1438 llvm::StringRef name_sref(name); 1439 Mutex::Locker locker (GetProcessMutex ()); 1440 ProcessInstances &instances = GetProcessInstances (); 1441 1442 ProcessInstances::iterator pos, end = instances.end(); 1443 for (pos = instances.begin(); pos != end; ++ pos) 1444 { 1445 if (name_sref.equals (pos->name)) 1446 return pos->create_callback; 1447 } 1448 } 1449 return NULL; 1450 } 1451 1452 #pragma mark SymbolFile 1453 1454 struct SymbolFileInstance 1455 { 1456 SymbolFileInstance() : 1457 name(), 1458 description(), 1459 create_callback(NULL) 1460 { 1461 } 1462 1463 std::string name; 1464 std::string description; 1465 SymbolFileCreateInstance create_callback; 1466 }; 1467 1468 typedef std::vector<SymbolFileInstance> SymbolFileInstances; 1469 1470 static Mutex & 1471 GetSymbolFileMutex () 1472 { 1473 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1474 return g_instances_mutex; 1475 } 1476 1477 static SymbolFileInstances & 1478 GetSymbolFileInstances () 1479 { 1480 static SymbolFileInstances g_instances; 1481 return g_instances; 1482 } 1483 1484 1485 bool 1486 PluginManager::RegisterPlugin 1487 ( 1488 const char *name, 1489 const char *description, 1490 SymbolFileCreateInstance create_callback 1491 ) 1492 { 1493 if (create_callback) 1494 { 1495 SymbolFileInstance instance; 1496 assert (name && name[0]); 1497 instance.name = name; 1498 if (description && description[0]) 1499 instance.description = description; 1500 instance.create_callback = create_callback; 1501 Mutex::Locker locker (GetSymbolFileMutex ()); 1502 GetSymbolFileInstances ().push_back (instance); 1503 } 1504 return false; 1505 } 1506 1507 bool 1508 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback) 1509 { 1510 if (create_callback) 1511 { 1512 Mutex::Locker locker (GetSymbolFileMutex ()); 1513 SymbolFileInstances &instances = GetSymbolFileInstances (); 1514 1515 SymbolFileInstances::iterator pos, end = instances.end(); 1516 for (pos = instances.begin(); pos != end; ++ pos) 1517 { 1518 if (pos->create_callback == create_callback) 1519 { 1520 instances.erase(pos); 1521 return true; 1522 } 1523 } 1524 } 1525 return false; 1526 } 1527 1528 SymbolFileCreateInstance 1529 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx) 1530 { 1531 Mutex::Locker locker (GetSymbolFileMutex ()); 1532 SymbolFileInstances &instances = GetSymbolFileInstances (); 1533 if (idx < instances.size()) 1534 return instances[idx].create_callback; 1535 return NULL; 1536 } 1537 1538 SymbolFileCreateInstance 1539 PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name) 1540 { 1541 if (name && name[0]) 1542 { 1543 llvm::StringRef name_sref(name); 1544 Mutex::Locker locker (GetSymbolFileMutex ()); 1545 SymbolFileInstances &instances = GetSymbolFileInstances (); 1546 1547 SymbolFileInstances::iterator pos, end = instances.end(); 1548 for (pos = instances.begin(); pos != end; ++ pos) 1549 { 1550 if (name_sref.equals (pos->name)) 1551 return pos->create_callback; 1552 } 1553 } 1554 return NULL; 1555 } 1556 1557 1558 1559 #pragma mark SymbolVendor 1560 1561 struct SymbolVendorInstance 1562 { 1563 SymbolVendorInstance() : 1564 name(), 1565 description(), 1566 create_callback(NULL) 1567 { 1568 } 1569 1570 std::string name; 1571 std::string description; 1572 SymbolVendorCreateInstance create_callback; 1573 }; 1574 1575 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 1576 1577 static Mutex & 1578 GetSymbolVendorMutex () 1579 { 1580 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1581 return g_instances_mutex; 1582 } 1583 1584 static SymbolVendorInstances & 1585 GetSymbolVendorInstances () 1586 { 1587 static SymbolVendorInstances g_instances; 1588 return g_instances; 1589 } 1590 1591 bool 1592 PluginManager::RegisterPlugin 1593 ( 1594 const char *name, 1595 const char *description, 1596 SymbolVendorCreateInstance create_callback 1597 ) 1598 { 1599 if (create_callback) 1600 { 1601 SymbolVendorInstance instance; 1602 assert (name && name[0]); 1603 instance.name = name; 1604 if (description && description[0]) 1605 instance.description = description; 1606 instance.create_callback = create_callback; 1607 Mutex::Locker locker (GetSymbolVendorMutex ()); 1608 GetSymbolVendorInstances ().push_back (instance); 1609 } 1610 return false; 1611 } 1612 1613 bool 1614 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback) 1615 { 1616 if (create_callback) 1617 { 1618 Mutex::Locker locker (GetSymbolVendorMutex ()); 1619 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1620 1621 SymbolVendorInstances::iterator pos, end = instances.end(); 1622 for (pos = instances.begin(); pos != end; ++ pos) 1623 { 1624 if (pos->create_callback == create_callback) 1625 { 1626 instances.erase(pos); 1627 return true; 1628 } 1629 } 1630 } 1631 return false; 1632 } 1633 1634 SymbolVendorCreateInstance 1635 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx) 1636 { 1637 Mutex::Locker locker (GetSymbolVendorMutex ()); 1638 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1639 if (idx < instances.size()) 1640 return instances[idx].create_callback; 1641 return NULL; 1642 } 1643 1644 1645 SymbolVendorCreateInstance 1646 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name) 1647 { 1648 if (name && name[0]) 1649 { 1650 llvm::StringRef name_sref(name); 1651 Mutex::Locker locker (GetSymbolVendorMutex ()); 1652 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1653 1654 SymbolVendorInstances::iterator pos, end = instances.end(); 1655 for (pos = instances.begin(); pos != end; ++ pos) 1656 { 1657 if (name_sref.equals (pos->name)) 1658 return pos->create_callback; 1659 } 1660 } 1661 return NULL; 1662 } 1663 1664 1665 #pragma mark UnwindAssembly 1666 1667 struct UnwindAssemblyInstance 1668 { 1669 UnwindAssemblyInstance() : 1670 name(), 1671 description(), 1672 create_callback(NULL) 1673 { 1674 } 1675 1676 std::string name; 1677 std::string description; 1678 UnwindAssemblyCreateInstance create_callback; 1679 }; 1680 1681 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances; 1682 1683 static Mutex & 1684 GetUnwindAssemblyMutex () 1685 { 1686 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1687 return g_instances_mutex; 1688 } 1689 1690 static UnwindAssemblyInstances & 1691 GetUnwindAssemblyInstances () 1692 { 1693 static UnwindAssemblyInstances g_instances; 1694 return g_instances; 1695 } 1696 1697 bool 1698 PluginManager::RegisterPlugin 1699 ( 1700 const char *name, 1701 const char *description, 1702 UnwindAssemblyCreateInstance create_callback 1703 ) 1704 { 1705 if (create_callback) 1706 { 1707 UnwindAssemblyInstance instance; 1708 assert (name && name[0]); 1709 instance.name = name; 1710 if (description && description[0]) 1711 instance.description = description; 1712 instance.create_callback = create_callback; 1713 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 1714 GetUnwindAssemblyInstances ().push_back (instance); 1715 } 1716 return false; 1717 } 1718 1719 bool 1720 PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback) 1721 { 1722 if (create_callback) 1723 { 1724 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 1725 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances (); 1726 1727 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1728 for (pos = instances.begin(); pos != end; ++ pos) 1729 { 1730 if (pos->create_callback == create_callback) 1731 { 1732 instances.erase(pos); 1733 return true; 1734 } 1735 } 1736 } 1737 return false; 1738 } 1739 1740 UnwindAssemblyCreateInstance 1741 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx) 1742 { 1743 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 1744 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances (); 1745 if (idx < instances.size()) 1746 return instances[idx].create_callback; 1747 return NULL; 1748 } 1749 1750 1751 UnwindAssemblyCreateInstance 1752 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const char *name) 1753 { 1754 if (name && name[0]) 1755 { 1756 llvm::StringRef name_sref(name); 1757 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 1758 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances (); 1759 1760 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1761 for (pos = instances.begin(); pos != end; ++ pos) 1762 { 1763 if (name_sref.equals (pos->name)) 1764 return pos->create_callback; 1765 } 1766 } 1767 return NULL; 1768 } 1769 1770