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