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