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