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 644 645 #pragma mark LanguageRuntime 646 647 648 struct LanguageRuntimeInstance 649 { 650 LanguageRuntimeInstance() : 651 name(), 652 description(), 653 create_callback(NULL) 654 { 655 } 656 657 std::string name; 658 std::string description; 659 LanguageRuntimeCreateInstance create_callback; 660 }; 661 662 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances; 663 664 static Mutex & 665 GetLanguageRuntimeMutex () 666 { 667 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 668 return g_instances_mutex; 669 } 670 671 static LanguageRuntimeInstances & 672 GetLanguageRuntimeInstances () 673 { 674 static LanguageRuntimeInstances g_instances; 675 return g_instances; 676 } 677 678 bool 679 PluginManager::RegisterPlugin 680 ( 681 const char *name, 682 const char *description, 683 LanguageRuntimeCreateInstance create_callback 684 ) 685 { 686 if (create_callback) 687 { 688 LanguageRuntimeInstance instance; 689 assert (name && name[0]); 690 instance.name = name; 691 if (description && description[0]) 692 instance.description = description; 693 instance.create_callback = create_callback; 694 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 695 GetLanguageRuntimeInstances ().push_back (instance); 696 } 697 return false; 698 } 699 700 bool 701 PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback) 702 { 703 if (create_callback) 704 { 705 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 706 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances (); 707 708 LanguageRuntimeInstances::iterator pos, end = instances.end(); 709 for (pos = instances.begin(); pos != end; ++ pos) 710 { 711 if (pos->create_callback == create_callback) 712 { 713 instances.erase(pos); 714 return true; 715 } 716 } 717 } 718 return false; 719 } 720 721 LanguageRuntimeCreateInstance 722 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx) 723 { 724 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 725 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances (); 726 if (idx < instances.size()) 727 return instances[idx].create_callback; 728 return NULL; 729 } 730 731 LanguageRuntimeCreateInstance 732 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const char *name) 733 { 734 if (name && name[0]) 735 { 736 llvm::StringRef name_sref(name); 737 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 738 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances (); 739 740 LanguageRuntimeInstances::iterator pos, end = instances.end(); 741 for (pos = instances.begin(); pos != end; ++ pos) 742 { 743 if (name_sref.equals (pos->name)) 744 return pos->create_callback; 745 } 746 } 747 return NULL; 748 } 749 750 #pragma mark ObjectFile 751 752 struct ObjectFileInstance 753 { 754 ObjectFileInstance() : 755 name(), 756 description(), 757 create_callback(NULL) 758 { 759 } 760 761 std::string name; 762 std::string description; 763 ObjectFileCreateInstance create_callback; 764 }; 765 766 typedef std::vector<ObjectFileInstance> ObjectFileInstances; 767 768 static Mutex & 769 GetObjectFileMutex () 770 { 771 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 772 return g_instances_mutex; 773 } 774 775 static ObjectFileInstances & 776 GetObjectFileInstances () 777 { 778 static ObjectFileInstances g_instances; 779 return g_instances; 780 } 781 782 783 bool 784 PluginManager::RegisterPlugin 785 ( 786 const char *name, 787 const char *description, 788 ObjectFileCreateInstance create_callback 789 ) 790 { 791 if (create_callback) 792 { 793 ObjectFileInstance instance; 794 assert (name && name[0]); 795 instance.name = name; 796 if (description && description[0]) 797 instance.description = description; 798 instance.create_callback = create_callback; 799 Mutex::Locker locker (GetObjectFileMutex ()); 800 GetObjectFileInstances ().push_back (instance); 801 } 802 return false; 803 } 804 805 bool 806 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback) 807 { 808 if (create_callback) 809 { 810 Mutex::Locker locker (GetObjectFileMutex ()); 811 ObjectFileInstances &instances = GetObjectFileInstances (); 812 813 ObjectFileInstances::iterator pos, end = instances.end(); 814 for (pos = instances.begin(); pos != end; ++ pos) 815 { 816 if (pos->create_callback == create_callback) 817 { 818 instances.erase(pos); 819 return true; 820 } 821 } 822 } 823 return false; 824 } 825 826 ObjectFileCreateInstance 827 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx) 828 { 829 Mutex::Locker locker (GetObjectFileMutex ()); 830 ObjectFileInstances &instances = GetObjectFileInstances (); 831 if (idx < instances.size()) 832 return instances[idx].create_callback; 833 return NULL; 834 } 835 836 ObjectFileCreateInstance 837 PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name) 838 { 839 if (name && name[0]) 840 { 841 llvm::StringRef name_sref(name); 842 Mutex::Locker locker (GetObjectFileMutex ()); 843 ObjectFileInstances &instances = GetObjectFileInstances (); 844 845 ObjectFileInstances::iterator pos, end = instances.end(); 846 for (pos = instances.begin(); pos != end; ++ pos) 847 { 848 if (name_sref.equals (pos->name)) 849 return pos->create_callback; 850 } 851 } 852 return NULL; 853 } 854 855 856 857 #pragma mark ObjectContainer 858 859 struct ObjectContainerInstance 860 { 861 ObjectContainerInstance() : 862 name(), 863 description(), 864 create_callback(NULL) 865 { 866 } 867 868 std::string name; 869 std::string description; 870 ObjectContainerCreateInstance create_callback; 871 }; 872 873 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; 874 875 static Mutex & 876 GetObjectContainerMutex () 877 { 878 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 879 return g_instances_mutex; 880 } 881 882 static ObjectContainerInstances & 883 GetObjectContainerInstances () 884 { 885 static ObjectContainerInstances g_instances; 886 return g_instances; 887 } 888 889 bool 890 PluginManager::RegisterPlugin 891 ( 892 const char *name, 893 const char *description, 894 ObjectContainerCreateInstance create_callback 895 ) 896 { 897 if (create_callback) 898 { 899 ObjectContainerInstance instance; 900 assert (name && name[0]); 901 instance.name = name; 902 if (description && description[0]) 903 instance.description = description; 904 instance.create_callback = create_callback; 905 Mutex::Locker locker (GetObjectContainerMutex ()); 906 GetObjectContainerInstances ().push_back (instance); 907 } 908 return false; 909 } 910 911 bool 912 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback) 913 { 914 if (create_callback) 915 { 916 Mutex::Locker locker (GetObjectContainerMutex ()); 917 ObjectContainerInstances &instances = GetObjectContainerInstances (); 918 919 ObjectContainerInstances::iterator pos, end = instances.end(); 920 for (pos = instances.begin(); pos != end; ++ pos) 921 { 922 if (pos->create_callback == create_callback) 923 { 924 instances.erase(pos); 925 return true; 926 } 927 } 928 } 929 return false; 930 } 931 932 ObjectContainerCreateInstance 933 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx) 934 { 935 Mutex::Locker locker (GetObjectContainerMutex ()); 936 ObjectContainerInstances &instances = GetObjectContainerInstances (); 937 if (idx < instances.size()) 938 return instances[idx].create_callback; 939 return NULL; 940 } 941 942 ObjectContainerCreateInstance 943 PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name) 944 { 945 if (name && name[0]) 946 { 947 llvm::StringRef name_sref(name); 948 Mutex::Locker locker (GetObjectContainerMutex ()); 949 ObjectContainerInstances &instances = GetObjectContainerInstances (); 950 951 ObjectContainerInstances::iterator pos, end = instances.end(); 952 for (pos = instances.begin(); pos != end; ++ pos) 953 { 954 if (name_sref.equals (pos->name)) 955 return pos->create_callback; 956 } 957 } 958 return NULL; 959 } 960 961 #pragma mark LogChannel 962 963 struct LogInstance 964 { 965 LogInstance() : 966 name(), 967 description(), 968 create_callback(NULL) 969 { 970 } 971 972 std::string name; 973 std::string description; 974 LogChannelCreateInstance create_callback; 975 }; 976 977 typedef std::vector<LogInstance> LogInstances; 978 979 static Mutex & 980 GetLogMutex () 981 { 982 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 983 return g_instances_mutex; 984 } 985 986 static LogInstances & 987 GetLogInstances () 988 { 989 static LogInstances g_instances; 990 return g_instances; 991 } 992 993 994 995 bool 996 PluginManager::RegisterPlugin 997 ( 998 const char *name, 999 const char *description, 1000 LogChannelCreateInstance create_callback 1001 ) 1002 { 1003 if (create_callback) 1004 { 1005 LogInstance instance; 1006 assert (name && name[0]); 1007 instance.name = name; 1008 if (description && description[0]) 1009 instance.description = description; 1010 instance.create_callback = create_callback; 1011 Mutex::Locker locker (GetLogMutex ()); 1012 GetLogInstances ().push_back (instance); 1013 } 1014 return false; 1015 } 1016 1017 bool 1018 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback) 1019 { 1020 if (create_callback) 1021 { 1022 Mutex::Locker locker (GetLogMutex ()); 1023 LogInstances &instances = GetLogInstances (); 1024 1025 LogInstances::iterator pos, end = instances.end(); 1026 for (pos = instances.begin(); pos != end; ++ pos) 1027 { 1028 if (pos->create_callback == create_callback) 1029 { 1030 instances.erase(pos); 1031 return true; 1032 } 1033 } 1034 } 1035 return false; 1036 } 1037 1038 const char * 1039 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx) 1040 { 1041 Mutex::Locker locker (GetLogMutex ()); 1042 LogInstances &instances = GetLogInstances (); 1043 if (idx < instances.size()) 1044 return instances[idx].name.c_str(); 1045 return NULL; 1046 } 1047 1048 1049 LogChannelCreateInstance 1050 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx) 1051 { 1052 Mutex::Locker locker (GetLogMutex ()); 1053 LogInstances &instances = GetLogInstances (); 1054 if (idx < instances.size()) 1055 return instances[idx].create_callback; 1056 return NULL; 1057 } 1058 1059 LogChannelCreateInstance 1060 PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name) 1061 { 1062 if (name && name[0]) 1063 { 1064 llvm::StringRef name_sref(name); 1065 Mutex::Locker locker (GetLogMutex ()); 1066 LogInstances &instances = GetLogInstances (); 1067 1068 LogInstances::iterator pos, end = instances.end(); 1069 for (pos = instances.begin(); pos != end; ++ pos) 1070 { 1071 if (name_sref.equals (pos->name)) 1072 return pos->create_callback; 1073 } 1074 } 1075 return NULL; 1076 } 1077 1078 #pragma mark Platform 1079 1080 struct PlatformInstance 1081 { 1082 PlatformInstance() : 1083 name(), 1084 description(), 1085 create_callback(NULL) 1086 { 1087 } 1088 1089 std::string name; 1090 std::string description; 1091 PlatformCreateInstance create_callback; 1092 }; 1093 1094 typedef std::vector<PlatformInstance> PlatformInstances; 1095 1096 static Mutex & 1097 GetPlatformInstancesMutex () 1098 { 1099 static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive); 1100 return g_platform_instances_mutex; 1101 } 1102 1103 static PlatformInstances & 1104 GetPlatformInstances () 1105 { 1106 static PlatformInstances g_platform_instances; 1107 return g_platform_instances; 1108 } 1109 1110 1111 bool 1112 PluginManager::RegisterPlugin (const char *name, 1113 const char *description, 1114 PlatformCreateInstance create_callback) 1115 { 1116 if (create_callback) 1117 { 1118 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1119 1120 PlatformInstance instance; 1121 assert (name && name[0]); 1122 instance.name = name; 1123 if (description && description[0]) 1124 instance.description = description; 1125 instance.create_callback = create_callback; 1126 GetPlatformInstances ().push_back (instance); 1127 return true; 1128 } 1129 return false; 1130 } 1131 1132 const char * 1133 PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx) 1134 { 1135 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1136 PlatformInstances &instances = GetPlatformInstances (); 1137 if (idx < instances.size()) 1138 return instances[idx].name.c_str(); 1139 return NULL; 1140 } 1141 1142 const char * 1143 PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx) 1144 { 1145 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1146 PlatformInstances &instances = GetPlatformInstances (); 1147 if (idx < instances.size()) 1148 return instances[idx].description.c_str(); 1149 return NULL; 1150 } 1151 1152 bool 1153 PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback) 1154 { 1155 if (create_callback) 1156 { 1157 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1158 PlatformInstances &instances = GetPlatformInstances (); 1159 1160 PlatformInstances::iterator pos, end = instances.end(); 1161 for (pos = instances.begin(); pos != end; ++ pos) 1162 { 1163 if (pos->create_callback == create_callback) 1164 { 1165 instances.erase(pos); 1166 return true; 1167 } 1168 } 1169 } 1170 return false; 1171 } 1172 1173 PlatformCreateInstance 1174 PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx) 1175 { 1176 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1177 PlatformInstances &instances = GetPlatformInstances (); 1178 if (idx < instances.size()) 1179 return instances[idx].create_callback; 1180 return NULL; 1181 } 1182 1183 PlatformCreateInstance 1184 PluginManager::GetPlatformCreateCallbackForPluginName (const char *name) 1185 { 1186 if (name && name[0]) 1187 { 1188 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1189 PlatformInstances &instances = GetPlatformInstances (); 1190 llvm::StringRef name_sref(name); 1191 1192 PlatformInstances::iterator pos, end = instances.end(); 1193 for (pos = instances.begin(); pos != end; ++ pos) 1194 { 1195 if (name_sref.equals (name)) 1196 return pos->create_callback; 1197 } 1198 } 1199 return NULL; 1200 } 1201 1202 uint32_t 1203 PluginManager::AutoCompletePlatformName (const char *name, StringList &matches) 1204 { 1205 if (name && name[0]) 1206 { 1207 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1208 PlatformInstances &instances = GetPlatformInstances (); 1209 llvm::StringRef name_sref(name); 1210 1211 PlatformInstances::iterator pos, end = instances.end(); 1212 for (pos = instances.begin(); pos != end; ++ pos) 1213 { 1214 const char *plugin_name = pos->name.c_str(); 1215 if (name_sref.startswith(plugin_name)) 1216 matches.AppendString (plugin_name); 1217 } 1218 } 1219 return matches.GetSize(); 1220 } 1221 1222 #pragma mark Process 1223 1224 struct ProcessInstance 1225 { 1226 ProcessInstance() : 1227 name(), 1228 description(), 1229 create_callback(NULL) 1230 { 1231 } 1232 1233 std::string name; 1234 std::string description; 1235 ProcessCreateInstance create_callback; 1236 }; 1237 1238 typedef std::vector<ProcessInstance> ProcessInstances; 1239 1240 static Mutex & 1241 GetProcessMutex () 1242 { 1243 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1244 return g_instances_mutex; 1245 } 1246 1247 static ProcessInstances & 1248 GetProcessInstances () 1249 { 1250 static ProcessInstances g_instances; 1251 return g_instances; 1252 } 1253 1254 1255 bool 1256 PluginManager::RegisterPlugin 1257 ( 1258 const char *name, 1259 const char *description, 1260 ProcessCreateInstance create_callback 1261 ) 1262 { 1263 if (create_callback) 1264 { 1265 ProcessInstance instance; 1266 assert (name && name[0]); 1267 instance.name = name; 1268 if (description && description[0]) 1269 instance.description = description; 1270 instance.create_callback = create_callback; 1271 Mutex::Locker locker (GetProcessMutex ()); 1272 GetProcessInstances ().push_back (instance); 1273 } 1274 return false; 1275 } 1276 1277 const char * 1278 PluginManager::GetProcessPluginNameAtIndex (uint32_t idx) 1279 { 1280 Mutex::Locker locker (GetProcessMutex ()); 1281 ProcessInstances &instances = GetProcessInstances (); 1282 if (idx < instances.size()) 1283 return instances[idx].name.c_str(); 1284 return NULL; 1285 } 1286 1287 const char * 1288 PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx) 1289 { 1290 Mutex::Locker locker (GetProcessMutex ()); 1291 ProcessInstances &instances = GetProcessInstances (); 1292 if (idx < instances.size()) 1293 return instances[idx].description.c_str(); 1294 return NULL; 1295 } 1296 1297 bool 1298 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback) 1299 { 1300 if (create_callback) 1301 { 1302 Mutex::Locker locker (GetProcessMutex ()); 1303 ProcessInstances &instances = GetProcessInstances (); 1304 1305 ProcessInstances::iterator pos, end = instances.end(); 1306 for (pos = instances.begin(); pos != end; ++ pos) 1307 { 1308 if (pos->create_callback == create_callback) 1309 { 1310 instances.erase(pos); 1311 return true; 1312 } 1313 } 1314 } 1315 return false; 1316 } 1317 1318 ProcessCreateInstance 1319 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx) 1320 { 1321 Mutex::Locker locker (GetProcessMutex ()); 1322 ProcessInstances &instances = GetProcessInstances (); 1323 if (idx < instances.size()) 1324 return instances[idx].create_callback; 1325 return NULL; 1326 } 1327 1328 1329 ProcessCreateInstance 1330 PluginManager::GetProcessCreateCallbackForPluginName (const char *name) 1331 { 1332 if (name && name[0]) 1333 { 1334 llvm::StringRef name_sref(name); 1335 Mutex::Locker locker (GetProcessMutex ()); 1336 ProcessInstances &instances = GetProcessInstances (); 1337 1338 ProcessInstances::iterator pos, end = instances.end(); 1339 for (pos = instances.begin(); pos != end; ++ pos) 1340 { 1341 if (name_sref.equals (pos->name)) 1342 return pos->create_callback; 1343 } 1344 } 1345 return NULL; 1346 } 1347 1348 #pragma mark SymbolFile 1349 1350 struct SymbolFileInstance 1351 { 1352 SymbolFileInstance() : 1353 name(), 1354 description(), 1355 create_callback(NULL) 1356 { 1357 } 1358 1359 std::string name; 1360 std::string description; 1361 SymbolFileCreateInstance create_callback; 1362 }; 1363 1364 typedef std::vector<SymbolFileInstance> SymbolFileInstances; 1365 1366 static Mutex & 1367 GetSymbolFileMutex () 1368 { 1369 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1370 return g_instances_mutex; 1371 } 1372 1373 static SymbolFileInstances & 1374 GetSymbolFileInstances () 1375 { 1376 static SymbolFileInstances g_instances; 1377 return g_instances; 1378 } 1379 1380 1381 bool 1382 PluginManager::RegisterPlugin 1383 ( 1384 const char *name, 1385 const char *description, 1386 SymbolFileCreateInstance create_callback 1387 ) 1388 { 1389 if (create_callback) 1390 { 1391 SymbolFileInstance instance; 1392 assert (name && name[0]); 1393 instance.name = name; 1394 if (description && description[0]) 1395 instance.description = description; 1396 instance.create_callback = create_callback; 1397 Mutex::Locker locker (GetSymbolFileMutex ()); 1398 GetSymbolFileInstances ().push_back (instance); 1399 } 1400 return false; 1401 } 1402 1403 bool 1404 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback) 1405 { 1406 if (create_callback) 1407 { 1408 Mutex::Locker locker (GetSymbolFileMutex ()); 1409 SymbolFileInstances &instances = GetSymbolFileInstances (); 1410 1411 SymbolFileInstances::iterator pos, end = instances.end(); 1412 for (pos = instances.begin(); pos != end; ++ pos) 1413 { 1414 if (pos->create_callback == create_callback) 1415 { 1416 instances.erase(pos); 1417 return true; 1418 } 1419 } 1420 } 1421 return false; 1422 } 1423 1424 SymbolFileCreateInstance 1425 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx) 1426 { 1427 Mutex::Locker locker (GetSymbolFileMutex ()); 1428 SymbolFileInstances &instances = GetSymbolFileInstances (); 1429 if (idx < instances.size()) 1430 return instances[idx].create_callback; 1431 return NULL; 1432 } 1433 1434 SymbolFileCreateInstance 1435 PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name) 1436 { 1437 if (name && name[0]) 1438 { 1439 llvm::StringRef name_sref(name); 1440 Mutex::Locker locker (GetSymbolFileMutex ()); 1441 SymbolFileInstances &instances = GetSymbolFileInstances (); 1442 1443 SymbolFileInstances::iterator pos, end = instances.end(); 1444 for (pos = instances.begin(); pos != end; ++ pos) 1445 { 1446 if (name_sref.equals (pos->name)) 1447 return pos->create_callback; 1448 } 1449 } 1450 return NULL; 1451 } 1452 1453 1454 1455 #pragma mark SymbolVendor 1456 1457 struct SymbolVendorInstance 1458 { 1459 SymbolVendorInstance() : 1460 name(), 1461 description(), 1462 create_callback(NULL) 1463 { 1464 } 1465 1466 std::string name; 1467 std::string description; 1468 SymbolVendorCreateInstance create_callback; 1469 }; 1470 1471 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 1472 1473 static Mutex & 1474 GetSymbolVendorMutex () 1475 { 1476 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1477 return g_instances_mutex; 1478 } 1479 1480 static SymbolVendorInstances & 1481 GetSymbolVendorInstances () 1482 { 1483 static SymbolVendorInstances g_instances; 1484 return g_instances; 1485 } 1486 1487 bool 1488 PluginManager::RegisterPlugin 1489 ( 1490 const char *name, 1491 const char *description, 1492 SymbolVendorCreateInstance create_callback 1493 ) 1494 { 1495 if (create_callback) 1496 { 1497 SymbolVendorInstance instance; 1498 assert (name && name[0]); 1499 instance.name = name; 1500 if (description && description[0]) 1501 instance.description = description; 1502 instance.create_callback = create_callback; 1503 Mutex::Locker locker (GetSymbolVendorMutex ()); 1504 GetSymbolVendorInstances ().push_back (instance); 1505 } 1506 return false; 1507 } 1508 1509 bool 1510 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback) 1511 { 1512 if (create_callback) 1513 { 1514 Mutex::Locker locker (GetSymbolVendorMutex ()); 1515 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1516 1517 SymbolVendorInstances::iterator pos, end = instances.end(); 1518 for (pos = instances.begin(); pos != end; ++ pos) 1519 { 1520 if (pos->create_callback == create_callback) 1521 { 1522 instances.erase(pos); 1523 return true; 1524 } 1525 } 1526 } 1527 return false; 1528 } 1529 1530 SymbolVendorCreateInstance 1531 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx) 1532 { 1533 Mutex::Locker locker (GetSymbolVendorMutex ()); 1534 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1535 if (idx < instances.size()) 1536 return instances[idx].create_callback; 1537 return NULL; 1538 } 1539 1540 1541 SymbolVendorCreateInstance 1542 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name) 1543 { 1544 if (name && name[0]) 1545 { 1546 llvm::StringRef name_sref(name); 1547 Mutex::Locker locker (GetSymbolVendorMutex ()); 1548 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1549 1550 SymbolVendorInstances::iterator pos, end = instances.end(); 1551 for (pos = instances.begin(); pos != end; ++ pos) 1552 { 1553 if (name_sref.equals (pos->name)) 1554 return pos->create_callback; 1555 } 1556 } 1557 return NULL; 1558 } 1559 1560 1561 #pragma mark UnwindAssemblyProfiler 1562 1563 struct UnwindAssemblyProfilerInstance 1564 { 1565 UnwindAssemblyProfilerInstance() : 1566 name(), 1567 description(), 1568 create_callback(NULL) 1569 { 1570 } 1571 1572 std::string name; 1573 std::string description; 1574 UnwindAssemblyProfilerCreateInstance create_callback; 1575 }; 1576 1577 typedef std::vector<UnwindAssemblyProfilerInstance> UnwindAssemblyProfilerInstances; 1578 1579 static Mutex & 1580 GetUnwindAssemblyProfilerMutex () 1581 { 1582 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1583 return g_instances_mutex; 1584 } 1585 1586 static UnwindAssemblyProfilerInstances & 1587 GetUnwindAssemblyProfilerInstances () 1588 { 1589 static UnwindAssemblyProfilerInstances g_instances; 1590 return g_instances; 1591 } 1592 1593 bool 1594 PluginManager::RegisterPlugin 1595 ( 1596 const char *name, 1597 const char *description, 1598 UnwindAssemblyProfilerCreateInstance create_callback 1599 ) 1600 { 1601 if (create_callback) 1602 { 1603 UnwindAssemblyProfilerInstance instance; 1604 assert (name && name[0]); 1605 instance.name = name; 1606 if (description && description[0]) 1607 instance.description = description; 1608 instance.create_callback = create_callback; 1609 Mutex::Locker locker (GetUnwindAssemblyProfilerMutex ()); 1610 GetUnwindAssemblyProfilerInstances ().push_back (instance); 1611 } 1612 return false; 1613 } 1614 1615 bool 1616 PluginManager::UnregisterPlugin (UnwindAssemblyProfilerCreateInstance create_callback) 1617 { 1618 if (create_callback) 1619 { 1620 Mutex::Locker locker (GetUnwindAssemblyProfilerMutex ()); 1621 UnwindAssemblyProfilerInstances &instances = GetUnwindAssemblyProfilerInstances (); 1622 1623 UnwindAssemblyProfilerInstances::iterator pos, end = instances.end(); 1624 for (pos = instances.begin(); pos != end; ++ pos) 1625 { 1626 if (pos->create_callback == create_callback) 1627 { 1628 instances.erase(pos); 1629 return true; 1630 } 1631 } 1632 } 1633 return false; 1634 } 1635 1636 UnwindAssemblyProfilerCreateInstance 1637 PluginManager::GetUnwindAssemblyProfilerCreateCallbackAtIndex (uint32_t idx) 1638 { 1639 Mutex::Locker locker (GetUnwindAssemblyProfilerMutex ()); 1640 UnwindAssemblyProfilerInstances &instances = GetUnwindAssemblyProfilerInstances (); 1641 if (idx < instances.size()) 1642 return instances[idx].create_callback; 1643 return NULL; 1644 } 1645 1646 1647 UnwindAssemblyProfilerCreateInstance 1648 PluginManager::GetUnwindAssemblyProfilerCreateCallbackForPluginName (const char *name) 1649 { 1650 if (name && name[0]) 1651 { 1652 llvm::StringRef name_sref(name); 1653 Mutex::Locker locker (GetUnwindAssemblyProfilerMutex ()); 1654 UnwindAssemblyProfilerInstances &instances = GetUnwindAssemblyProfilerInstances (); 1655 1656 UnwindAssemblyProfilerInstances::iterator pos, end = instances.end(); 1657 for (pos = instances.begin(); pos != end; ++ pos) 1658 { 1659 if (name_sref.equals (pos->name)) 1660 return pos->create_callback; 1661 } 1662 } 1663 return NULL; 1664 } 1665 1666 #pragma mark ArchDefaultUnwindPlan 1667 1668 struct ArchDefaultUnwindPlanInstance 1669 { 1670 ArchDefaultUnwindPlanInstance() : 1671 name(), 1672 description(), 1673 create_callback(NULL) 1674 { 1675 } 1676 1677 std::string name; 1678 std::string description; 1679 ArchDefaultUnwindPlanCreateInstance create_callback; 1680 }; 1681 1682 typedef std::vector<ArchDefaultUnwindPlanInstance> ArchDefaultUnwindPlanInstances; 1683 1684 static Mutex & 1685 GetArchDefaultUnwindPlanMutex () 1686 { 1687 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1688 return g_instances_mutex; 1689 } 1690 1691 static ArchDefaultUnwindPlanInstances & 1692 GetArchDefaultUnwindPlanInstances () 1693 { 1694 static ArchDefaultUnwindPlanInstances g_instances; 1695 return g_instances; 1696 } 1697 1698 1699 bool 1700 PluginManager::RegisterPlugin 1701 ( 1702 const char *name, 1703 const char *description, 1704 ArchDefaultUnwindPlanCreateInstance create_callback 1705 ) 1706 { 1707 if (create_callback) 1708 { 1709 ArchDefaultUnwindPlanInstance instance; 1710 assert (name && name[0]); 1711 instance.name = name; 1712 if (description && description[0]) 1713 instance.description = description; 1714 instance.create_callback = create_callback; 1715 Mutex::Locker locker (GetArchDefaultUnwindPlanMutex ()); 1716 GetArchDefaultUnwindPlanInstances ().push_back (instance); 1717 } 1718 return false; 1719 } 1720 1721 bool 1722 PluginManager::UnregisterPlugin (ArchDefaultUnwindPlanCreateInstance create_callback) 1723 { 1724 if (create_callback) 1725 { 1726 Mutex::Locker locker (GetArchDefaultUnwindPlanMutex ()); 1727 ArchDefaultUnwindPlanInstances &instances = GetArchDefaultUnwindPlanInstances (); 1728 1729 ArchDefaultUnwindPlanInstances::iterator pos, end = instances.end(); 1730 for (pos = instances.begin(); pos != end; ++ pos) 1731 { 1732 if (pos->create_callback == create_callback) 1733 { 1734 instances.erase(pos); 1735 return true; 1736 } 1737 } 1738 } 1739 return false; 1740 } 1741 1742 ArchDefaultUnwindPlanCreateInstance 1743 PluginManager::GetArchDefaultUnwindPlanCreateCallbackAtIndex (uint32_t idx) 1744 { 1745 Mutex::Locker locker (GetArchDefaultUnwindPlanMutex ()); 1746 ArchDefaultUnwindPlanInstances &instances = GetArchDefaultUnwindPlanInstances (); 1747 if (idx < instances.size()) 1748 return instances[idx].create_callback; 1749 return NULL; 1750 } 1751 1752 1753 ArchDefaultUnwindPlanCreateInstance 1754 PluginManager::GetArchDefaultUnwindPlanCreateCallbackForPluginName (const char *name) 1755 { 1756 if (name && name[0]) 1757 { 1758 llvm::StringRef name_sref(name); 1759 Mutex::Locker locker (GetArchDefaultUnwindPlanMutex ()); 1760 ArchDefaultUnwindPlanInstances &instances = GetArchDefaultUnwindPlanInstances (); 1761 1762 ArchDefaultUnwindPlanInstances::iterator pos, end = instances.end(); 1763 for (pos = instances.begin(); pos != end; ++ pos) 1764 { 1765 if (name_sref.equals (pos->name)) 1766 return pos->create_callback; 1767 } 1768 } 1769 return NULL; 1770 } 1771 1772 #pragma mark ArchVolatileRegs 1773 1774 struct ArchVolatileRegsInstance 1775 { 1776 ArchVolatileRegsInstance() : 1777 name(), 1778 description(), 1779 create_callback(NULL) 1780 { 1781 } 1782 1783 std::string name; 1784 std::string description; 1785 ArchVolatileRegsCreateInstance create_callback; 1786 }; 1787 1788 typedef std::vector<ArchVolatileRegsInstance> ArchVolatileRegsInstances; 1789 1790 static Mutex & 1791 GetArchVolatileRegsMutex () 1792 { 1793 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1794 return g_instances_mutex; 1795 } 1796 1797 static ArchVolatileRegsInstances & 1798 GetArchVolatileRegsInstances () 1799 { 1800 static ArchVolatileRegsInstances g_instances; 1801 return g_instances; 1802 } 1803 1804 bool 1805 PluginManager::RegisterPlugin 1806 ( 1807 const char *name, 1808 const char *description, 1809 ArchVolatileRegsCreateInstance create_callback 1810 ) 1811 { 1812 if (create_callback) 1813 { 1814 ArchVolatileRegsInstance instance; 1815 assert (name && name[0]); 1816 instance.name = name; 1817 if (description && description[0]) 1818 instance.description = description; 1819 instance.create_callback = create_callback; 1820 Mutex::Locker locker (GetArchVolatileRegsMutex ()); 1821 GetArchVolatileRegsInstances ().push_back (instance); 1822 } 1823 return false; 1824 } 1825 1826 bool 1827 PluginManager::UnregisterPlugin (ArchVolatileRegsCreateInstance create_callback) 1828 { 1829 if (create_callback) 1830 { 1831 Mutex::Locker locker (GetArchVolatileRegsMutex ()); 1832 ArchVolatileRegsInstances &instances = GetArchVolatileRegsInstances (); 1833 1834 ArchVolatileRegsInstances::iterator pos, end = instances.end(); 1835 for (pos = instances.begin(); pos != end; ++ pos) 1836 { 1837 if (pos->create_callback == create_callback) 1838 { 1839 instances.erase(pos); 1840 return true; 1841 } 1842 } 1843 } 1844 return false; 1845 } 1846 1847 ArchVolatileRegsCreateInstance 1848 PluginManager::GetArchVolatileRegsCreateCallbackAtIndex (uint32_t idx) 1849 { 1850 Mutex::Locker locker (GetArchVolatileRegsMutex ()); 1851 ArchVolatileRegsInstances &instances = GetArchVolatileRegsInstances (); 1852 if (idx < instances.size()) 1853 return instances[idx].create_callback; 1854 return NULL; 1855 } 1856 1857 ArchVolatileRegsCreateInstance 1858 PluginManager::GetArchVolatileRegsCreateCallbackForPluginName (const char *name) 1859 { 1860 if (name && name[0]) 1861 { 1862 llvm::StringRef name_sref(name); 1863 Mutex::Locker locker (GetArchVolatileRegsMutex ()); 1864 ArchVolatileRegsInstances &instances = GetArchVolatileRegsInstances (); 1865 1866 ArchVolatileRegsInstances::iterator pos, end = instances.end(); 1867 for (pos = instances.begin(); pos != end; ++ pos) 1868 { 1869 if (name_sref.equals (pos->name)) 1870 return pos->create_callback; 1871 } 1872 } 1873 return NULL; 1874 } 1875 1876