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 JITLoader 548 549 550 struct JITLoaderInstance 551 { 552 JITLoaderInstance() : 553 name(), 554 description(), 555 create_callback(NULL), 556 debugger_init_callback (NULL) 557 { 558 } 559 560 ConstString name; 561 std::string description; 562 JITLoaderCreateInstance create_callback; 563 DebuggerInitializeCallback debugger_init_callback; 564 }; 565 566 typedef std::vector<JITLoaderInstance> JITLoaderInstances; 567 568 569 static Mutex & 570 GetJITLoaderMutex () 571 { 572 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 573 return g_instances_mutex; 574 } 575 576 static JITLoaderInstances & 577 GetJITLoaderInstances () 578 { 579 static JITLoaderInstances g_instances; 580 return g_instances; 581 } 582 583 584 bool 585 PluginManager::RegisterPlugin 586 ( 587 const ConstString &name, 588 const char *description, 589 JITLoaderCreateInstance create_callback, 590 DebuggerInitializeCallback debugger_init_callback 591 ) 592 { 593 if (create_callback) 594 { 595 JITLoaderInstance instance; 596 assert ((bool)name); 597 instance.name = name; 598 if (description && description[0]) 599 instance.description = description; 600 instance.create_callback = create_callback; 601 instance.debugger_init_callback = debugger_init_callback; 602 Mutex::Locker locker (GetJITLoaderMutex ()); 603 GetJITLoaderInstances ().push_back (instance); 604 } 605 return false; 606 } 607 608 bool 609 PluginManager::UnregisterPlugin (JITLoaderCreateInstance create_callback) 610 { 611 if (create_callback) 612 { 613 Mutex::Locker locker (GetJITLoaderMutex ()); 614 JITLoaderInstances &instances = GetJITLoaderInstances (); 615 616 JITLoaderInstances::iterator pos, end = instances.end(); 617 for (pos = instances.begin(); pos != end; ++ pos) 618 { 619 if (pos->create_callback == create_callback) 620 { 621 instances.erase(pos); 622 return true; 623 } 624 } 625 } 626 return false; 627 } 628 629 JITLoaderCreateInstance 630 PluginManager::GetJITLoaderCreateCallbackAtIndex (uint32_t idx) 631 { 632 Mutex::Locker locker (GetJITLoaderMutex ()); 633 JITLoaderInstances &instances = GetJITLoaderInstances (); 634 if (idx < instances.size()) 635 return instances[idx].create_callback; 636 return NULL; 637 } 638 639 JITLoaderCreateInstance 640 PluginManager::GetJITLoaderCreateCallbackForPluginName (const ConstString &name) 641 { 642 if (name) 643 { 644 Mutex::Locker locker (GetJITLoaderMutex ()); 645 JITLoaderInstances &instances = GetJITLoaderInstances (); 646 647 JITLoaderInstances::iterator pos, end = instances.end(); 648 for (pos = instances.begin(); pos != end; ++ pos) 649 { 650 if (name == pos->name) 651 return pos->create_callback; 652 } 653 } 654 return NULL; 655 } 656 657 #pragma mark EmulateInstruction 658 659 660 struct EmulateInstructionInstance 661 { 662 EmulateInstructionInstance() : 663 name(), 664 description(), 665 create_callback(NULL) 666 { 667 } 668 669 ConstString name; 670 std::string description; 671 EmulateInstructionCreateInstance create_callback; 672 }; 673 674 typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances; 675 676 static Mutex & 677 GetEmulateInstructionMutex () 678 { 679 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 680 return g_instances_mutex; 681 } 682 683 static EmulateInstructionInstances & 684 GetEmulateInstructionInstances () 685 { 686 static EmulateInstructionInstances g_instances; 687 return g_instances; 688 } 689 690 691 bool 692 PluginManager::RegisterPlugin 693 ( 694 const ConstString &name, 695 const char *description, 696 EmulateInstructionCreateInstance create_callback 697 ) 698 { 699 if (create_callback) 700 { 701 EmulateInstructionInstance instance; 702 assert ((bool)name); 703 instance.name = name; 704 if (description && description[0]) 705 instance.description = description; 706 instance.create_callback = create_callback; 707 Mutex::Locker locker (GetEmulateInstructionMutex ()); 708 GetEmulateInstructionInstances ().push_back (instance); 709 } 710 return false; 711 } 712 713 bool 714 PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback) 715 { 716 if (create_callback) 717 { 718 Mutex::Locker locker (GetEmulateInstructionMutex ()); 719 EmulateInstructionInstances &instances = GetEmulateInstructionInstances (); 720 721 EmulateInstructionInstances::iterator pos, end = instances.end(); 722 for (pos = instances.begin(); pos != end; ++ pos) 723 { 724 if (pos->create_callback == create_callback) 725 { 726 instances.erase(pos); 727 return true; 728 } 729 } 730 } 731 return false; 732 } 733 734 EmulateInstructionCreateInstance 735 PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx) 736 { 737 Mutex::Locker locker (GetEmulateInstructionMutex ()); 738 EmulateInstructionInstances &instances = GetEmulateInstructionInstances (); 739 if (idx < instances.size()) 740 return instances[idx].create_callback; 741 return NULL; 742 } 743 744 EmulateInstructionCreateInstance 745 PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name) 746 { 747 if (name) 748 { 749 Mutex::Locker locker (GetEmulateInstructionMutex ()); 750 EmulateInstructionInstances &instances = GetEmulateInstructionInstances (); 751 752 EmulateInstructionInstances::iterator pos, end = instances.end(); 753 for (pos = instances.begin(); pos != end; ++ pos) 754 { 755 if (name == pos->name) 756 return pos->create_callback; 757 } 758 } 759 return NULL; 760 } 761 #pragma mark OperatingSystem 762 763 764 struct OperatingSystemInstance 765 { 766 OperatingSystemInstance() : 767 name(), 768 description(), 769 create_callback(NULL) 770 { 771 } 772 773 ConstString name; 774 std::string description; 775 OperatingSystemCreateInstance create_callback; 776 }; 777 778 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances; 779 780 static Mutex & 781 GetOperatingSystemMutex () 782 { 783 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 784 return g_instances_mutex; 785 } 786 787 static OperatingSystemInstances & 788 GetOperatingSystemInstances () 789 { 790 static OperatingSystemInstances g_instances; 791 return g_instances; 792 } 793 794 bool 795 PluginManager::RegisterPlugin (const ConstString &name, 796 const char *description, 797 OperatingSystemCreateInstance create_callback) 798 { 799 if (create_callback) 800 { 801 OperatingSystemInstance instance; 802 assert ((bool)name); 803 instance.name = name; 804 if (description && description[0]) 805 instance.description = description; 806 instance.create_callback = create_callback; 807 Mutex::Locker locker (GetOperatingSystemMutex ()); 808 GetOperatingSystemInstances ().push_back (instance); 809 } 810 return false; 811 } 812 813 bool 814 PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback) 815 { 816 if (create_callback) 817 { 818 Mutex::Locker locker (GetOperatingSystemMutex ()); 819 OperatingSystemInstances &instances = GetOperatingSystemInstances (); 820 821 OperatingSystemInstances::iterator pos, end = instances.end(); 822 for (pos = instances.begin(); pos != end; ++ pos) 823 { 824 if (pos->create_callback == create_callback) 825 { 826 instances.erase(pos); 827 return true; 828 } 829 } 830 } 831 return false; 832 } 833 834 OperatingSystemCreateInstance 835 PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx) 836 { 837 Mutex::Locker locker (GetOperatingSystemMutex ()); 838 OperatingSystemInstances &instances = GetOperatingSystemInstances (); 839 if (idx < instances.size()) 840 return instances[idx].create_callback; 841 return NULL; 842 } 843 844 OperatingSystemCreateInstance 845 PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name) 846 { 847 if (name) 848 { 849 Mutex::Locker locker (GetOperatingSystemMutex ()); 850 OperatingSystemInstances &instances = GetOperatingSystemInstances (); 851 852 OperatingSystemInstances::iterator pos, end = instances.end(); 853 for (pos = instances.begin(); pos != end; ++ pos) 854 { 855 if (name == pos->name) 856 return pos->create_callback; 857 } 858 } 859 return NULL; 860 } 861 862 863 #pragma mark LanguageRuntime 864 865 866 struct LanguageRuntimeInstance 867 { 868 LanguageRuntimeInstance() : 869 name(), 870 description(), 871 create_callback(NULL) 872 { 873 } 874 875 ConstString name; 876 std::string description; 877 LanguageRuntimeCreateInstance create_callback; 878 }; 879 880 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances; 881 882 static Mutex & 883 GetLanguageRuntimeMutex () 884 { 885 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 886 return g_instances_mutex; 887 } 888 889 static LanguageRuntimeInstances & 890 GetLanguageRuntimeInstances () 891 { 892 static LanguageRuntimeInstances g_instances; 893 return g_instances; 894 } 895 896 bool 897 PluginManager::RegisterPlugin 898 ( 899 const ConstString &name, 900 const char *description, 901 LanguageRuntimeCreateInstance create_callback 902 ) 903 { 904 if (create_callback) 905 { 906 LanguageRuntimeInstance instance; 907 assert ((bool)name); 908 instance.name = name; 909 if (description && description[0]) 910 instance.description = description; 911 instance.create_callback = create_callback; 912 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 913 GetLanguageRuntimeInstances ().push_back (instance); 914 } 915 return false; 916 } 917 918 bool 919 PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback) 920 { 921 if (create_callback) 922 { 923 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 924 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances (); 925 926 LanguageRuntimeInstances::iterator pos, end = instances.end(); 927 for (pos = instances.begin(); pos != end; ++ pos) 928 { 929 if (pos->create_callback == create_callback) 930 { 931 instances.erase(pos); 932 return true; 933 } 934 } 935 } 936 return false; 937 } 938 939 LanguageRuntimeCreateInstance 940 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx) 941 { 942 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 943 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances (); 944 if (idx < instances.size()) 945 return instances[idx].create_callback; 946 return NULL; 947 } 948 949 LanguageRuntimeCreateInstance 950 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name) 951 { 952 if (name) 953 { 954 Mutex::Locker locker (GetLanguageRuntimeMutex ()); 955 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances (); 956 957 LanguageRuntimeInstances::iterator pos, end = instances.end(); 958 for (pos = instances.begin(); pos != end; ++ pos) 959 { 960 if (name == pos->name) 961 return pos->create_callback; 962 } 963 } 964 return NULL; 965 } 966 967 #pragma mark SystemRuntime 968 969 970 struct SystemRuntimeInstance 971 { 972 SystemRuntimeInstance() : 973 name(), 974 description(), 975 create_callback(NULL) 976 { 977 } 978 979 ConstString name; 980 std::string description; 981 SystemRuntimeCreateInstance create_callback; 982 }; 983 984 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances; 985 986 static Mutex & 987 GetSystemRuntimeMutex () 988 { 989 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 990 return g_instances_mutex; 991 } 992 993 static SystemRuntimeInstances & 994 GetSystemRuntimeInstances () 995 { 996 static SystemRuntimeInstances g_instances; 997 return g_instances; 998 } 999 1000 bool 1001 PluginManager::RegisterPlugin 1002 ( 1003 const ConstString &name, 1004 const char *description, 1005 SystemRuntimeCreateInstance create_callback 1006 ) 1007 { 1008 if (create_callback) 1009 { 1010 SystemRuntimeInstance instance; 1011 assert ((bool)name); 1012 instance.name = name; 1013 if (description && description[0]) 1014 instance.description = description; 1015 instance.create_callback = create_callback; 1016 Mutex::Locker locker (GetSystemRuntimeMutex ()); 1017 GetSystemRuntimeInstances ().push_back (instance); 1018 } 1019 return false; 1020 } 1021 1022 bool 1023 PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback) 1024 { 1025 if (create_callback) 1026 { 1027 Mutex::Locker locker (GetSystemRuntimeMutex ()); 1028 SystemRuntimeInstances &instances = GetSystemRuntimeInstances (); 1029 1030 SystemRuntimeInstances::iterator pos, end = instances.end(); 1031 for (pos = instances.begin(); pos != end; ++ pos) 1032 { 1033 if (pos->create_callback == create_callback) 1034 { 1035 instances.erase(pos); 1036 return true; 1037 } 1038 } 1039 } 1040 return false; 1041 } 1042 1043 SystemRuntimeCreateInstance 1044 PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx) 1045 { 1046 Mutex::Locker locker (GetSystemRuntimeMutex ()); 1047 SystemRuntimeInstances &instances = GetSystemRuntimeInstances (); 1048 if (idx < instances.size()) 1049 return instances[idx].create_callback; 1050 return NULL; 1051 } 1052 1053 SystemRuntimeCreateInstance 1054 PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name) 1055 { 1056 if (name) 1057 { 1058 Mutex::Locker locker (GetSystemRuntimeMutex ()); 1059 SystemRuntimeInstances &instances = GetSystemRuntimeInstances (); 1060 1061 SystemRuntimeInstances::iterator pos, end = instances.end(); 1062 for (pos = instances.begin(); pos != end; ++ pos) 1063 { 1064 if (name == pos->name) 1065 return pos->create_callback; 1066 } 1067 } 1068 return NULL; 1069 } 1070 1071 1072 #pragma mark ObjectFile 1073 1074 struct ObjectFileInstance 1075 { 1076 ObjectFileInstance() : 1077 name(), 1078 description(), 1079 create_callback(NULL), 1080 create_memory_callback (NULL), 1081 get_module_specifications (NULL), 1082 save_core (NULL) 1083 { 1084 } 1085 1086 ConstString name; 1087 std::string description; 1088 ObjectFileCreateInstance create_callback; 1089 ObjectFileCreateMemoryInstance create_memory_callback; 1090 ObjectFileGetModuleSpecifications get_module_specifications; 1091 ObjectFileSaveCore save_core; 1092 }; 1093 1094 typedef std::vector<ObjectFileInstance> ObjectFileInstances; 1095 1096 static Mutex & 1097 GetObjectFileMutex () 1098 { 1099 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1100 return g_instances_mutex; 1101 } 1102 1103 static ObjectFileInstances & 1104 GetObjectFileInstances () 1105 { 1106 static ObjectFileInstances g_instances; 1107 return g_instances; 1108 } 1109 1110 1111 bool 1112 PluginManager::RegisterPlugin (const ConstString &name, 1113 const char *description, 1114 ObjectFileCreateInstance create_callback, 1115 ObjectFileCreateMemoryInstance create_memory_callback, 1116 ObjectFileGetModuleSpecifications get_module_specifications, 1117 ObjectFileSaveCore save_core) 1118 { 1119 if (create_callback) 1120 { 1121 ObjectFileInstance instance; 1122 assert ((bool)name); 1123 instance.name = name; 1124 if (description && description[0]) 1125 instance.description = description; 1126 instance.create_callback = create_callback; 1127 instance.create_memory_callback = create_memory_callback; 1128 instance.save_core = save_core; 1129 instance.get_module_specifications = get_module_specifications; 1130 Mutex::Locker locker (GetObjectFileMutex ()); 1131 GetObjectFileInstances ().push_back (instance); 1132 } 1133 return false; 1134 } 1135 1136 bool 1137 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback) 1138 { 1139 if (create_callback) 1140 { 1141 Mutex::Locker locker (GetObjectFileMutex ()); 1142 ObjectFileInstances &instances = GetObjectFileInstances (); 1143 1144 ObjectFileInstances::iterator pos, end = instances.end(); 1145 for (pos = instances.begin(); pos != end; ++ pos) 1146 { 1147 if (pos->create_callback == create_callback) 1148 { 1149 instances.erase(pos); 1150 return true; 1151 } 1152 } 1153 } 1154 return false; 1155 } 1156 1157 ObjectFileCreateInstance 1158 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx) 1159 { 1160 Mutex::Locker locker (GetObjectFileMutex ()); 1161 ObjectFileInstances &instances = GetObjectFileInstances (); 1162 if (idx < instances.size()) 1163 return instances[idx].create_callback; 1164 return NULL; 1165 } 1166 1167 1168 ObjectFileCreateMemoryInstance 1169 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx) 1170 { 1171 Mutex::Locker locker (GetObjectFileMutex ()); 1172 ObjectFileInstances &instances = GetObjectFileInstances (); 1173 if (idx < instances.size()) 1174 return instances[idx].create_memory_callback; 1175 return NULL; 1176 } 1177 1178 ObjectFileGetModuleSpecifications 1179 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx) 1180 { 1181 Mutex::Locker locker (GetObjectFileMutex ()); 1182 ObjectFileInstances &instances = GetObjectFileInstances (); 1183 if (idx < instances.size()) 1184 return instances[idx].get_module_specifications; 1185 return NULL; 1186 } 1187 1188 ObjectFileCreateInstance 1189 PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name) 1190 { 1191 if (name) 1192 { 1193 Mutex::Locker locker (GetObjectFileMutex ()); 1194 ObjectFileInstances &instances = GetObjectFileInstances (); 1195 1196 ObjectFileInstances::iterator pos, end = instances.end(); 1197 for (pos = instances.begin(); pos != end; ++ pos) 1198 { 1199 if (name == pos->name) 1200 return pos->create_callback; 1201 } 1202 } 1203 return NULL; 1204 } 1205 1206 1207 ObjectFileCreateMemoryInstance 1208 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name) 1209 { 1210 if (name) 1211 { 1212 Mutex::Locker locker (GetObjectFileMutex ()); 1213 ObjectFileInstances &instances = GetObjectFileInstances (); 1214 1215 ObjectFileInstances::iterator pos, end = instances.end(); 1216 for (pos = instances.begin(); pos != end; ++ pos) 1217 { 1218 if (name == pos->name) 1219 return pos->create_memory_callback; 1220 } 1221 } 1222 return NULL; 1223 } 1224 1225 Error 1226 PluginManager::SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile) 1227 { 1228 Error error; 1229 Mutex::Locker locker (GetObjectFileMutex ()); 1230 ObjectFileInstances &instances = GetObjectFileInstances (); 1231 1232 ObjectFileInstances::iterator pos, end = instances.end(); 1233 for (pos = instances.begin(); pos != end; ++ pos) 1234 { 1235 if (pos->save_core && pos->save_core (process_sp, outfile, error)) 1236 return error; 1237 } 1238 error.SetErrorString("no ObjectFile plugins were able to save a core for this process"); 1239 return error; 1240 } 1241 1242 #pragma mark ObjectContainer 1243 1244 struct ObjectContainerInstance 1245 { 1246 ObjectContainerInstance() : 1247 name(), 1248 description(), 1249 create_callback (NULL), 1250 get_module_specifications (NULL) 1251 { 1252 } 1253 1254 ConstString name; 1255 std::string description; 1256 ObjectContainerCreateInstance create_callback; 1257 ObjectFileGetModuleSpecifications get_module_specifications; 1258 1259 }; 1260 1261 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; 1262 1263 static Mutex & 1264 GetObjectContainerMutex () 1265 { 1266 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1267 return g_instances_mutex; 1268 } 1269 1270 static ObjectContainerInstances & 1271 GetObjectContainerInstances () 1272 { 1273 static ObjectContainerInstances g_instances; 1274 return g_instances; 1275 } 1276 1277 bool 1278 PluginManager::RegisterPlugin (const ConstString &name, 1279 const char *description, 1280 ObjectContainerCreateInstance create_callback, 1281 ObjectFileGetModuleSpecifications get_module_specifications) 1282 { 1283 if (create_callback) 1284 { 1285 ObjectContainerInstance instance; 1286 assert ((bool)name); 1287 instance.name = name; 1288 if (description && description[0]) 1289 instance.description = description; 1290 instance.create_callback = create_callback; 1291 instance.get_module_specifications = get_module_specifications; 1292 Mutex::Locker locker (GetObjectContainerMutex ()); 1293 GetObjectContainerInstances ().push_back (instance); 1294 } 1295 return false; 1296 } 1297 1298 bool 1299 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback) 1300 { 1301 if (create_callback) 1302 { 1303 Mutex::Locker locker (GetObjectContainerMutex ()); 1304 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1305 1306 ObjectContainerInstances::iterator pos, end = instances.end(); 1307 for (pos = instances.begin(); pos != end; ++ pos) 1308 { 1309 if (pos->create_callback == create_callback) 1310 { 1311 instances.erase(pos); 1312 return true; 1313 } 1314 } 1315 } 1316 return false; 1317 } 1318 1319 ObjectContainerCreateInstance 1320 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx) 1321 { 1322 Mutex::Locker locker (GetObjectContainerMutex ()); 1323 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1324 if (idx < instances.size()) 1325 return instances[idx].create_callback; 1326 return NULL; 1327 } 1328 1329 ObjectContainerCreateInstance 1330 PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name) 1331 { 1332 if (name) 1333 { 1334 Mutex::Locker locker (GetObjectContainerMutex ()); 1335 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1336 1337 ObjectContainerInstances::iterator pos, end = instances.end(); 1338 for (pos = instances.begin(); pos != end; ++ pos) 1339 { 1340 if (name == pos->name) 1341 return pos->create_callback; 1342 } 1343 } 1344 return NULL; 1345 } 1346 1347 ObjectFileGetModuleSpecifications 1348 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx) 1349 { 1350 Mutex::Locker locker (GetObjectContainerMutex ()); 1351 ObjectContainerInstances &instances = GetObjectContainerInstances (); 1352 if (idx < instances.size()) 1353 return instances[idx].get_module_specifications; 1354 return NULL; 1355 } 1356 1357 #pragma mark LogChannel 1358 1359 struct LogInstance 1360 { 1361 LogInstance() : 1362 name(), 1363 description(), 1364 create_callback(NULL) 1365 { 1366 } 1367 1368 ConstString name; 1369 std::string description; 1370 LogChannelCreateInstance create_callback; 1371 }; 1372 1373 typedef std::vector<LogInstance> LogInstances; 1374 1375 static Mutex & 1376 GetLogMutex () 1377 { 1378 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1379 return g_instances_mutex; 1380 } 1381 1382 static LogInstances & 1383 GetLogInstances () 1384 { 1385 static LogInstances g_instances; 1386 return g_instances; 1387 } 1388 1389 1390 1391 bool 1392 PluginManager::RegisterPlugin 1393 ( 1394 const ConstString &name, 1395 const char *description, 1396 LogChannelCreateInstance create_callback 1397 ) 1398 { 1399 if (create_callback) 1400 { 1401 LogInstance instance; 1402 assert ((bool)name); 1403 instance.name = name; 1404 if (description && description[0]) 1405 instance.description = description; 1406 instance.create_callback = create_callback; 1407 Mutex::Locker locker (GetLogMutex ()); 1408 GetLogInstances ().push_back (instance); 1409 } 1410 return false; 1411 } 1412 1413 bool 1414 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback) 1415 { 1416 if (create_callback) 1417 { 1418 Mutex::Locker locker (GetLogMutex ()); 1419 LogInstances &instances = GetLogInstances (); 1420 1421 LogInstances::iterator pos, end = instances.end(); 1422 for (pos = instances.begin(); pos != end; ++ pos) 1423 { 1424 if (pos->create_callback == create_callback) 1425 { 1426 instances.erase(pos); 1427 return true; 1428 } 1429 } 1430 } 1431 return false; 1432 } 1433 1434 const char * 1435 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx) 1436 { 1437 Mutex::Locker locker (GetLogMutex ()); 1438 LogInstances &instances = GetLogInstances (); 1439 if (idx < instances.size()) 1440 return instances[idx].name.GetCString(); 1441 return NULL; 1442 } 1443 1444 1445 LogChannelCreateInstance 1446 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx) 1447 { 1448 Mutex::Locker locker (GetLogMutex ()); 1449 LogInstances &instances = GetLogInstances (); 1450 if (idx < instances.size()) 1451 return instances[idx].create_callback; 1452 return NULL; 1453 } 1454 1455 LogChannelCreateInstance 1456 PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name) 1457 { 1458 if (name) 1459 { 1460 Mutex::Locker locker (GetLogMutex ()); 1461 LogInstances &instances = GetLogInstances (); 1462 1463 LogInstances::iterator pos, end = instances.end(); 1464 for (pos = instances.begin(); pos != end; ++ pos) 1465 { 1466 if (name == pos->name) 1467 return pos->create_callback; 1468 } 1469 } 1470 return NULL; 1471 } 1472 1473 #pragma mark Platform 1474 1475 struct PlatformInstance 1476 { 1477 PlatformInstance() : 1478 name(), 1479 description(), 1480 create_callback(NULL), 1481 debugger_init_callback (NULL) 1482 { 1483 } 1484 1485 ConstString name; 1486 std::string description; 1487 PlatformCreateInstance create_callback; 1488 DebuggerInitializeCallback debugger_init_callback; 1489 }; 1490 1491 typedef std::vector<PlatformInstance> PlatformInstances; 1492 1493 static Mutex & 1494 GetPlatformInstancesMutex () 1495 { 1496 static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive); 1497 return g_platform_instances_mutex; 1498 } 1499 1500 static PlatformInstances & 1501 GetPlatformInstances () 1502 { 1503 static PlatformInstances g_platform_instances; 1504 return g_platform_instances; 1505 } 1506 1507 1508 bool 1509 PluginManager::RegisterPlugin (const ConstString &name, 1510 const char *description, 1511 PlatformCreateInstance create_callback, 1512 DebuggerInitializeCallback debugger_init_callback) 1513 { 1514 if (create_callback) 1515 { 1516 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1517 1518 PlatformInstance instance; 1519 assert ((bool)name); 1520 instance.name = name; 1521 if (description && description[0]) 1522 instance.description = description; 1523 instance.create_callback = create_callback; 1524 instance.debugger_init_callback = debugger_init_callback; 1525 GetPlatformInstances ().push_back (instance); 1526 return true; 1527 } 1528 return false; 1529 } 1530 1531 1532 const char * 1533 PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx) 1534 { 1535 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1536 PlatformInstances &instances = GetPlatformInstances (); 1537 if (idx < instances.size()) 1538 return instances[idx].name.GetCString(); 1539 return NULL; 1540 } 1541 1542 const char * 1543 PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx) 1544 { 1545 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1546 PlatformInstances &instances = GetPlatformInstances (); 1547 if (idx < instances.size()) 1548 return instances[idx].description.c_str(); 1549 return NULL; 1550 } 1551 1552 bool 1553 PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback) 1554 { 1555 if (create_callback) 1556 { 1557 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1558 PlatformInstances &instances = GetPlatformInstances (); 1559 1560 PlatformInstances::iterator pos, end = instances.end(); 1561 for (pos = instances.begin(); pos != end; ++ pos) 1562 { 1563 if (pos->create_callback == create_callback) 1564 { 1565 instances.erase(pos); 1566 return true; 1567 } 1568 } 1569 } 1570 return false; 1571 } 1572 1573 PlatformCreateInstance 1574 PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx) 1575 { 1576 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1577 PlatformInstances &instances = GetPlatformInstances (); 1578 if (idx < instances.size()) 1579 return instances[idx].create_callback; 1580 return NULL; 1581 } 1582 1583 PlatformCreateInstance 1584 PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name) 1585 { 1586 if (name) 1587 { 1588 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1589 PlatformInstances &instances = GetPlatformInstances (); 1590 1591 PlatformInstances::iterator pos, end = instances.end(); 1592 for (pos = instances.begin(); pos != end; ++ pos) 1593 { 1594 if (name == pos->name) 1595 return pos->create_callback; 1596 } 1597 } 1598 return NULL; 1599 } 1600 1601 size_t 1602 PluginManager::AutoCompletePlatformName (const char *name, StringList &matches) 1603 { 1604 if (name) 1605 { 1606 Mutex::Locker locker (GetPlatformInstancesMutex ()); 1607 PlatformInstances &instances = GetPlatformInstances (); 1608 llvm::StringRef name_sref(name); 1609 1610 PlatformInstances::iterator pos, end = instances.end(); 1611 for (pos = instances.begin(); pos != end; ++ pos) 1612 { 1613 llvm::StringRef plugin_name (pos->name.GetCString()); 1614 if (plugin_name.startswith(name_sref)) 1615 matches.AppendString (plugin_name.data()); 1616 } 1617 } 1618 return matches.GetSize(); 1619 } 1620 #pragma mark Process 1621 1622 struct ProcessInstance 1623 { 1624 ProcessInstance() : 1625 name(), 1626 description(), 1627 create_callback(NULL), 1628 debugger_init_callback(NULL) 1629 { 1630 } 1631 1632 ConstString name; 1633 std::string description; 1634 ProcessCreateInstance create_callback; 1635 DebuggerInitializeCallback debugger_init_callback; 1636 }; 1637 1638 typedef std::vector<ProcessInstance> ProcessInstances; 1639 1640 static Mutex & 1641 GetProcessMutex () 1642 { 1643 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1644 return g_instances_mutex; 1645 } 1646 1647 static ProcessInstances & 1648 GetProcessInstances () 1649 { 1650 static ProcessInstances g_instances; 1651 return g_instances; 1652 } 1653 1654 1655 bool 1656 PluginManager::RegisterPlugin (const ConstString &name, 1657 const char *description, 1658 ProcessCreateInstance create_callback, 1659 DebuggerInitializeCallback debugger_init_callback) 1660 { 1661 if (create_callback) 1662 { 1663 ProcessInstance instance; 1664 assert ((bool)name); 1665 instance.name = name; 1666 if (description && description[0]) 1667 instance.description = description; 1668 instance.create_callback = create_callback; 1669 instance.debugger_init_callback = debugger_init_callback; 1670 Mutex::Locker locker (GetProcessMutex ()); 1671 GetProcessInstances ().push_back (instance); 1672 } 1673 return false; 1674 } 1675 1676 const char * 1677 PluginManager::GetProcessPluginNameAtIndex (uint32_t idx) 1678 { 1679 Mutex::Locker locker (GetProcessMutex ()); 1680 ProcessInstances &instances = GetProcessInstances (); 1681 if (idx < instances.size()) 1682 return instances[idx].name.GetCString(); 1683 return NULL; 1684 } 1685 1686 const char * 1687 PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx) 1688 { 1689 Mutex::Locker locker (GetProcessMutex ()); 1690 ProcessInstances &instances = GetProcessInstances (); 1691 if (idx < instances.size()) 1692 return instances[idx].description.c_str(); 1693 return NULL; 1694 } 1695 1696 bool 1697 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback) 1698 { 1699 if (create_callback) 1700 { 1701 Mutex::Locker locker (GetProcessMutex ()); 1702 ProcessInstances &instances = GetProcessInstances (); 1703 1704 ProcessInstances::iterator pos, end = instances.end(); 1705 for (pos = instances.begin(); pos != end; ++ pos) 1706 { 1707 if (pos->create_callback == create_callback) 1708 { 1709 instances.erase(pos); 1710 return true; 1711 } 1712 } 1713 } 1714 return false; 1715 } 1716 1717 ProcessCreateInstance 1718 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx) 1719 { 1720 Mutex::Locker locker (GetProcessMutex ()); 1721 ProcessInstances &instances = GetProcessInstances (); 1722 if (idx < instances.size()) 1723 return instances[idx].create_callback; 1724 return NULL; 1725 } 1726 1727 1728 ProcessCreateInstance 1729 PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name) 1730 { 1731 if (name) 1732 { 1733 Mutex::Locker locker (GetProcessMutex ()); 1734 ProcessInstances &instances = GetProcessInstances (); 1735 1736 ProcessInstances::iterator pos, end = instances.end(); 1737 for (pos = instances.begin(); pos != end; ++ pos) 1738 { 1739 if (name == pos->name) 1740 return pos->create_callback; 1741 } 1742 } 1743 return NULL; 1744 } 1745 1746 #pragma mark SymbolFile 1747 1748 struct SymbolFileInstance 1749 { 1750 SymbolFileInstance() : 1751 name(), 1752 description(), 1753 create_callback(NULL) 1754 { 1755 } 1756 1757 ConstString name; 1758 std::string description; 1759 SymbolFileCreateInstance create_callback; 1760 }; 1761 1762 typedef std::vector<SymbolFileInstance> SymbolFileInstances; 1763 1764 static Mutex & 1765 GetSymbolFileMutex () 1766 { 1767 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1768 return g_instances_mutex; 1769 } 1770 1771 static SymbolFileInstances & 1772 GetSymbolFileInstances () 1773 { 1774 static SymbolFileInstances g_instances; 1775 return g_instances; 1776 } 1777 1778 1779 bool 1780 PluginManager::RegisterPlugin 1781 ( 1782 const ConstString &name, 1783 const char *description, 1784 SymbolFileCreateInstance create_callback 1785 ) 1786 { 1787 if (create_callback) 1788 { 1789 SymbolFileInstance instance; 1790 assert ((bool)name); 1791 instance.name = name; 1792 if (description && description[0]) 1793 instance.description = description; 1794 instance.create_callback = create_callback; 1795 Mutex::Locker locker (GetSymbolFileMutex ()); 1796 GetSymbolFileInstances ().push_back (instance); 1797 } 1798 return false; 1799 } 1800 1801 bool 1802 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback) 1803 { 1804 if (create_callback) 1805 { 1806 Mutex::Locker locker (GetSymbolFileMutex ()); 1807 SymbolFileInstances &instances = GetSymbolFileInstances (); 1808 1809 SymbolFileInstances::iterator pos, end = instances.end(); 1810 for (pos = instances.begin(); pos != end; ++ pos) 1811 { 1812 if (pos->create_callback == create_callback) 1813 { 1814 instances.erase(pos); 1815 return true; 1816 } 1817 } 1818 } 1819 return false; 1820 } 1821 1822 SymbolFileCreateInstance 1823 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx) 1824 { 1825 Mutex::Locker locker (GetSymbolFileMutex ()); 1826 SymbolFileInstances &instances = GetSymbolFileInstances (); 1827 if (idx < instances.size()) 1828 return instances[idx].create_callback; 1829 return NULL; 1830 } 1831 1832 SymbolFileCreateInstance 1833 PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name) 1834 { 1835 if (name) 1836 { 1837 Mutex::Locker locker (GetSymbolFileMutex ()); 1838 SymbolFileInstances &instances = GetSymbolFileInstances (); 1839 1840 SymbolFileInstances::iterator pos, end = instances.end(); 1841 for (pos = instances.begin(); pos != end; ++ pos) 1842 { 1843 if (name == pos->name) 1844 return pos->create_callback; 1845 } 1846 } 1847 return NULL; 1848 } 1849 1850 1851 1852 #pragma mark SymbolVendor 1853 1854 struct SymbolVendorInstance 1855 { 1856 SymbolVendorInstance() : 1857 name(), 1858 description(), 1859 create_callback(NULL) 1860 { 1861 } 1862 1863 ConstString name; 1864 std::string description; 1865 SymbolVendorCreateInstance create_callback; 1866 }; 1867 1868 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 1869 1870 static Mutex & 1871 GetSymbolVendorMutex () 1872 { 1873 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1874 return g_instances_mutex; 1875 } 1876 1877 static SymbolVendorInstances & 1878 GetSymbolVendorInstances () 1879 { 1880 static SymbolVendorInstances g_instances; 1881 return g_instances; 1882 } 1883 1884 bool 1885 PluginManager::RegisterPlugin 1886 ( 1887 const ConstString &name, 1888 const char *description, 1889 SymbolVendorCreateInstance create_callback 1890 ) 1891 { 1892 if (create_callback) 1893 { 1894 SymbolVendorInstance instance; 1895 assert ((bool)name); 1896 instance.name = name; 1897 if (description && description[0]) 1898 instance.description = description; 1899 instance.create_callback = create_callback; 1900 Mutex::Locker locker (GetSymbolVendorMutex ()); 1901 GetSymbolVendorInstances ().push_back (instance); 1902 } 1903 return false; 1904 } 1905 1906 bool 1907 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback) 1908 { 1909 if (create_callback) 1910 { 1911 Mutex::Locker locker (GetSymbolVendorMutex ()); 1912 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1913 1914 SymbolVendorInstances::iterator pos, end = instances.end(); 1915 for (pos = instances.begin(); pos != end; ++ pos) 1916 { 1917 if (pos->create_callback == create_callback) 1918 { 1919 instances.erase(pos); 1920 return true; 1921 } 1922 } 1923 } 1924 return false; 1925 } 1926 1927 SymbolVendorCreateInstance 1928 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx) 1929 { 1930 Mutex::Locker locker (GetSymbolVendorMutex ()); 1931 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1932 if (idx < instances.size()) 1933 return instances[idx].create_callback; 1934 return NULL; 1935 } 1936 1937 1938 SymbolVendorCreateInstance 1939 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name) 1940 { 1941 if (name) 1942 { 1943 Mutex::Locker locker (GetSymbolVendorMutex ()); 1944 SymbolVendorInstances &instances = GetSymbolVendorInstances (); 1945 1946 SymbolVendorInstances::iterator pos, end = instances.end(); 1947 for (pos = instances.begin(); pos != end; ++ pos) 1948 { 1949 if (name == pos->name) 1950 return pos->create_callback; 1951 } 1952 } 1953 return NULL; 1954 } 1955 1956 1957 #pragma mark UnwindAssembly 1958 1959 struct UnwindAssemblyInstance 1960 { 1961 UnwindAssemblyInstance() : 1962 name(), 1963 description(), 1964 create_callback(NULL) 1965 { 1966 } 1967 1968 ConstString name; 1969 std::string description; 1970 UnwindAssemblyCreateInstance create_callback; 1971 }; 1972 1973 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances; 1974 1975 static Mutex & 1976 GetUnwindAssemblyMutex () 1977 { 1978 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); 1979 return g_instances_mutex; 1980 } 1981 1982 static UnwindAssemblyInstances & 1983 GetUnwindAssemblyInstances () 1984 { 1985 static UnwindAssemblyInstances g_instances; 1986 return g_instances; 1987 } 1988 1989 bool 1990 PluginManager::RegisterPlugin 1991 ( 1992 const ConstString &name, 1993 const char *description, 1994 UnwindAssemblyCreateInstance create_callback 1995 ) 1996 { 1997 if (create_callback) 1998 { 1999 UnwindAssemblyInstance instance; 2000 assert ((bool)name); 2001 instance.name = name; 2002 if (description && description[0]) 2003 instance.description = description; 2004 instance.create_callback = create_callback; 2005 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 2006 GetUnwindAssemblyInstances ().push_back (instance); 2007 } 2008 return false; 2009 } 2010 2011 bool 2012 PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback) 2013 { 2014 if (create_callback) 2015 { 2016 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 2017 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances (); 2018 2019 UnwindAssemblyInstances::iterator pos, end = instances.end(); 2020 for (pos = instances.begin(); pos != end; ++ pos) 2021 { 2022 if (pos->create_callback == create_callback) 2023 { 2024 instances.erase(pos); 2025 return true; 2026 } 2027 } 2028 } 2029 return false; 2030 } 2031 2032 UnwindAssemblyCreateInstance 2033 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx) 2034 { 2035 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 2036 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances (); 2037 if (idx < instances.size()) 2038 return instances[idx].create_callback; 2039 return NULL; 2040 } 2041 2042 2043 UnwindAssemblyCreateInstance 2044 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name) 2045 { 2046 if (name) 2047 { 2048 Mutex::Locker locker (GetUnwindAssemblyMutex ()); 2049 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances (); 2050 2051 UnwindAssemblyInstances::iterator pos, end = instances.end(); 2052 for (pos = instances.begin(); pos != end; ++ pos) 2053 { 2054 if (name == pos->name) 2055 return pos->create_callback; 2056 } 2057 } 2058 return NULL; 2059 } 2060 2061 void 2062 PluginManager::DebuggerInitialize (Debugger &debugger) 2063 { 2064 // Initialize the DynamicLoader plugins 2065 { 2066 Mutex::Locker locker (GetDynamicLoaderMutex ()); 2067 DynamicLoaderInstances &instances = GetDynamicLoaderInstances (); 2068 2069 DynamicLoaderInstances::iterator pos, end = instances.end(); 2070 for (pos = instances.begin(); pos != end; ++ pos) 2071 { 2072 if (pos->debugger_init_callback) 2073 pos->debugger_init_callback (debugger); 2074 } 2075 } 2076 2077 // Initialize the JITLoader plugins 2078 { 2079 Mutex::Locker locker (GetJITLoaderMutex ()); 2080 JITLoaderInstances &instances = GetJITLoaderInstances (); 2081 2082 JITLoaderInstances::iterator pos, end = instances.end(); 2083 for (pos = instances.begin(); pos != end; ++ pos) 2084 { 2085 if (pos->debugger_init_callback) 2086 pos->debugger_init_callback (debugger); 2087 } 2088 } 2089 2090 // Initialize the Platform plugins 2091 { 2092 Mutex::Locker locker (GetPlatformInstancesMutex ()); 2093 PlatformInstances &instances = GetPlatformInstances (); 2094 2095 PlatformInstances::iterator pos, end = instances.end(); 2096 for (pos = instances.begin(); pos != end; ++ pos) 2097 { 2098 if (pos->debugger_init_callback) 2099 pos->debugger_init_callback (debugger); 2100 } 2101 } 2102 2103 // Initialize the Process plugins 2104 { 2105 Mutex::Locker locker (GetProcessMutex()); 2106 ProcessInstances &instances = GetProcessInstances(); 2107 2108 ProcessInstances::iterator pos, end = instances.end(); 2109 for (pos = instances.begin(); pos != end; ++ pos) 2110 { 2111 if (pos->debugger_init_callback) 2112 pos->debugger_init_callback (debugger); 2113 } 2114 } 2115 2116 } 2117 2118 // This is the preferred new way to register plugin specific settings. e.g. 2119 // This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 2120 static lldb::OptionValuePropertiesSP 2121 GetDebuggerPropertyForPlugins (Debugger &debugger, 2122 const ConstString &plugin_type_name, 2123 const ConstString &plugin_type_desc, 2124 bool can_create) 2125 { 2126 lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties()); 2127 if (parent_properties_sp) 2128 { 2129 static ConstString g_property_name("plugin"); 2130 2131 OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name); 2132 if (!plugin_properties_sp && can_create) 2133 { 2134 plugin_properties_sp.reset (new OptionValueProperties (g_property_name)); 2135 parent_properties_sp->AppendProperty (g_property_name, 2136 ConstString("Settings specify to plugins."), 2137 true, 2138 plugin_properties_sp); 2139 } 2140 2141 if (plugin_properties_sp) 2142 { 2143 lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name); 2144 if (!plugin_type_properties_sp && can_create) 2145 { 2146 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name)); 2147 plugin_properties_sp->AppendProperty (plugin_type_name, 2148 plugin_type_desc, 2149 true, 2150 plugin_type_properties_sp); 2151 } 2152 return plugin_type_properties_sp; 2153 } 2154 } 2155 return lldb::OptionValuePropertiesSP(); 2156 } 2157 2158 // This is deprecated way to register plugin specific settings. e.g. 2159 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" 2160 // and Platform generic settings would be under "platform.SETTINGNAME". 2161 static lldb::OptionValuePropertiesSP 2162 GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger, 2163 const ConstString &plugin_type_name, 2164 const ConstString &plugin_type_desc, 2165 bool can_create) 2166 { 2167 static ConstString g_property_name("plugin"); 2168 lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties()); 2169 if (parent_properties_sp) 2170 { 2171 OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name); 2172 if (!plugin_properties_sp && can_create) 2173 { 2174 plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name)); 2175 parent_properties_sp->AppendProperty (plugin_type_name, 2176 plugin_type_desc, 2177 true, 2178 plugin_properties_sp); 2179 } 2180 2181 if (plugin_properties_sp) 2182 { 2183 lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name); 2184 if (!plugin_type_properties_sp && can_create) 2185 { 2186 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name)); 2187 plugin_properties_sp->AppendProperty (g_property_name, 2188 ConstString("Settings specific to plugins"), 2189 true, 2190 plugin_type_properties_sp); 2191 } 2192 return plugin_type_properties_sp; 2193 } 2194 } 2195 return lldb::OptionValuePropertiesSP(); 2196 } 2197 2198 2199 lldb::OptionValuePropertiesSP 2200 PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name) 2201 { 2202 lldb::OptionValuePropertiesSP properties_sp; 2203 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, 2204 ConstString("dynamic-loader"), 2205 ConstString(), // not creating to so we don't need the description 2206 false)); 2207 if (plugin_type_properties_sp) 2208 properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name); 2209 return properties_sp; 2210 } 2211 2212 bool 2213 PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger, 2214 const lldb::OptionValuePropertiesSP &properties_sp, 2215 const ConstString &description, 2216 bool is_global_property) 2217 { 2218 if (properties_sp) 2219 { 2220 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, 2221 ConstString("dynamic-loader"), 2222 ConstString("Settings for dynamic loader plug-ins"), 2223 true)); 2224 if (plugin_type_properties_sp) 2225 { 2226 plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), 2227 description, 2228 is_global_property, 2229 properties_sp); 2230 return true; 2231 } 2232 } 2233 return false; 2234 } 2235 2236 2237 lldb::OptionValuePropertiesSP 2238 PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name) 2239 { 2240 lldb::OptionValuePropertiesSP properties_sp; 2241 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger, 2242 ConstString("platform"), 2243 ConstString(), // not creating to so we don't need the description 2244 false)); 2245 if (plugin_type_properties_sp) 2246 properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name); 2247 return properties_sp; 2248 } 2249 2250 bool 2251 PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger, 2252 const lldb::OptionValuePropertiesSP &properties_sp, 2253 const ConstString &description, 2254 bool is_global_property) 2255 { 2256 if (properties_sp) 2257 { 2258 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger, 2259 ConstString("platform"), 2260 ConstString("Settings for platform plug-ins"), 2261 true)); 2262 if (plugin_type_properties_sp) 2263 { 2264 plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), 2265 description, 2266 is_global_property, 2267 properties_sp); 2268 return true; 2269 } 2270 } 2271 return false; 2272 } 2273 2274 2275 lldb::OptionValuePropertiesSP 2276 PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name) 2277 { 2278 lldb::OptionValuePropertiesSP properties_sp; 2279 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, 2280 ConstString("process"), 2281 ConstString(), // not creating to so we don't need the description 2282 false)); 2283 if (plugin_type_properties_sp) 2284 properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name); 2285 return properties_sp; 2286 } 2287 2288 bool 2289 PluginManager::CreateSettingForProcessPlugin (Debugger &debugger, 2290 const lldb::OptionValuePropertiesSP &properties_sp, 2291 const ConstString &description, 2292 bool is_global_property) 2293 { 2294 if (properties_sp) 2295 { 2296 lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, 2297 ConstString("process"), 2298 ConstString("Settings for process plug-ins"), 2299 true)); 2300 if (plugin_type_properties_sp) 2301 { 2302 plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), 2303 description, 2304 is_global_property, 2305 properties_sp); 2306 return true; 2307 } 2308 } 2309 return false; 2310 } 2311 2312