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