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