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