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/Core/PluginManager.h" 11 12 #include <string> 13 #include <vector> 14 15 using namespace lldb_private; 16 17 enum PluginAction 18 { 19 ePluginRegisterInstance, 20 ePluginUnregisterInstance, 21 ePluginGetInstanceAtIndex 22 }; 23 24 25 #pragma mark ABI 26 27 28 struct ABIInstance 29 { 30 ABIInstance() : 31 name(), 32 description(), 33 create_callback(NULL) 34 { 35 } 36 37 std::string name; 38 std::string description; 39 ABICreateInstance create_callback; 40 }; 41 42 typedef std::vector<ABIInstance> ABIInstances; 43 44 static bool 45 AccessABIInstances (PluginAction action, ABIInstance &instance, uint32_t index) 46 { 47 static ABIInstances g_plugin_instances; 48 49 switch (action) 50 { 51 case ePluginRegisterInstance: 52 if (instance.create_callback) 53 { 54 g_plugin_instances.push_back (instance); 55 return true; 56 } 57 break; 58 59 case ePluginUnregisterInstance: 60 if (instance.create_callback) 61 { 62 ABIInstances::iterator pos, end = g_plugin_instances.end(); 63 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 64 { 65 if (pos->create_callback == instance.create_callback) 66 { 67 g_plugin_instances.erase(pos); 68 return true; 69 } 70 } 71 } 72 break; 73 74 case ePluginGetInstanceAtIndex: 75 if (index < g_plugin_instances.size()) 76 { 77 instance = g_plugin_instances[index]; 78 return true; 79 } 80 break; 81 82 default: 83 break; 84 } 85 return false; 86 } 87 88 89 bool 90 PluginManager::RegisterPlugin 91 ( 92 const char *name, 93 const char *description, 94 ABICreateInstance create_callback 95 ) 96 { 97 if (create_callback) 98 { 99 ABIInstance instance; 100 assert (name && name[0]); 101 instance.name = name; 102 if (description && description[0]) 103 instance.description = description; 104 instance.create_callback = create_callback; 105 return AccessABIInstances (ePluginRegisterInstance, instance, 0); 106 } 107 return false; 108 } 109 110 bool 111 PluginManager::UnregisterPlugin (ABICreateInstance create_callback) 112 { 113 if (create_callback) 114 { 115 ABIInstance instance; 116 instance.create_callback = create_callback; 117 return AccessABIInstances (ePluginUnregisterInstance, instance, 0); 118 } 119 return false; 120 } 121 122 ABICreateInstance 123 PluginManager::GetABICreateCallbackAtIndex (uint32_t idx) 124 { 125 ABIInstance instance; 126 if (AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx)) 127 return instance.create_callback; 128 return NULL; 129 } 130 131 ABICreateInstance 132 PluginManager::GetABICreateCallbackForPluginName (const char *name) 133 { 134 if (name && name[0]) 135 { 136 ABIInstance instance; 137 std::string ss_name(name); 138 for (uint32_t idx = 0; AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 139 { 140 if (instance.name == ss_name) 141 return instance.create_callback; 142 } 143 } 144 return NULL; 145 } 146 147 148 #pragma mark Disassembler 149 150 151 struct DisassemblerInstance 152 { 153 DisassemblerInstance() : 154 name(), 155 description(), 156 create_callback(NULL) 157 { 158 } 159 160 std::string name; 161 std::string description; 162 DisassemblerCreateInstance create_callback; 163 }; 164 165 typedef std::vector<DisassemblerInstance> DisassemblerInstances; 166 167 static bool 168 AccessDisassemblerInstances (PluginAction action, DisassemblerInstance &instance, uint32_t index) 169 { 170 static DisassemblerInstances g_plugin_instances; 171 172 switch (action) 173 { 174 case ePluginRegisterInstance: 175 if (instance.create_callback) 176 { 177 g_plugin_instances.push_back (instance); 178 return true; 179 } 180 break; 181 182 case ePluginUnregisterInstance: 183 if (instance.create_callback) 184 { 185 DisassemblerInstances::iterator pos, end = g_plugin_instances.end(); 186 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 187 { 188 if (pos->create_callback == instance.create_callback) 189 { 190 g_plugin_instances.erase(pos); 191 return true; 192 } 193 } 194 } 195 break; 196 197 case ePluginGetInstanceAtIndex: 198 if (index < g_plugin_instances.size()) 199 { 200 instance = g_plugin_instances[index]; 201 return true; 202 } 203 break; 204 205 default: 206 break; 207 } 208 return false; 209 } 210 211 212 bool 213 PluginManager::RegisterPlugin 214 ( 215 const char *name, 216 const char *description, 217 DisassemblerCreateInstance create_callback 218 ) 219 { 220 if (create_callback) 221 { 222 DisassemblerInstance instance; 223 assert (name && name[0]); 224 instance.name = name; 225 if (description && description[0]) 226 instance.description = description; 227 instance.create_callback = create_callback; 228 return AccessDisassemblerInstances (ePluginRegisterInstance, instance, 0); 229 } 230 return false; 231 } 232 233 bool 234 PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback) 235 { 236 if (create_callback) 237 { 238 DisassemblerInstance instance; 239 instance.create_callback = create_callback; 240 return AccessDisassemblerInstances (ePluginUnregisterInstance, instance, 0); 241 } 242 return false; 243 } 244 245 DisassemblerCreateInstance 246 PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx) 247 { 248 DisassemblerInstance instance; 249 if (AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx)) 250 return instance.create_callback; 251 return NULL; 252 } 253 254 DisassemblerCreateInstance 255 PluginManager::GetDisassemblerCreateCallbackForPluginName (const char *name) 256 { 257 if (name && name[0]) 258 { 259 DisassemblerInstance instance; 260 std::string ss_name(name); 261 for (uint32_t idx = 0; AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 262 { 263 if (instance.name == ss_name) 264 return instance.create_callback; 265 } 266 } 267 return NULL; 268 } 269 270 271 272 #pragma mark DynamicLoader 273 274 275 struct DynamicLoaderInstance 276 { 277 DynamicLoaderInstance() : 278 name(), 279 description(), 280 create_callback(NULL) 281 { 282 } 283 284 std::string name; 285 std::string description; 286 DynamicLoaderCreateInstance create_callback; 287 }; 288 289 typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances; 290 291 static bool 292 AccessDynamicLoaderInstances (PluginAction action, DynamicLoaderInstance &instance, uint32_t index) 293 { 294 static DynamicLoaderInstances g_plugin_instances; 295 296 switch (action) 297 { 298 case ePluginRegisterInstance: 299 if (instance.create_callback) 300 { 301 g_plugin_instances.push_back (instance); 302 return true; 303 } 304 break; 305 306 case ePluginUnregisterInstance: 307 if (instance.create_callback) 308 { 309 DynamicLoaderInstances::iterator pos, end = g_plugin_instances.end(); 310 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 311 { 312 if (pos->create_callback == instance.create_callback) 313 { 314 g_plugin_instances.erase(pos); 315 return true; 316 } 317 } 318 } 319 break; 320 321 case ePluginGetInstanceAtIndex: 322 if (index < g_plugin_instances.size()) 323 { 324 instance = g_plugin_instances[index]; 325 return true; 326 } 327 break; 328 329 default: 330 break; 331 } 332 return false; 333 } 334 335 336 bool 337 PluginManager::RegisterPlugin 338 ( 339 const char *name, 340 const char *description, 341 DynamicLoaderCreateInstance create_callback 342 ) 343 { 344 if (create_callback) 345 { 346 DynamicLoaderInstance instance; 347 assert (name && name[0]); 348 instance.name = name; 349 if (description && description[0]) 350 instance.description = description; 351 instance.create_callback = create_callback; 352 return AccessDynamicLoaderInstances (ePluginRegisterInstance, instance, 0); 353 } 354 return false; 355 } 356 357 bool 358 PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback) 359 { 360 if (create_callback) 361 { 362 DynamicLoaderInstance instance; 363 instance.create_callback = create_callback; 364 return AccessDynamicLoaderInstances (ePluginUnregisterInstance, instance, 0); 365 } 366 return false; 367 } 368 369 DynamicLoaderCreateInstance 370 PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx) 371 { 372 DynamicLoaderInstance instance; 373 if (AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx)) 374 return instance.create_callback; 375 return NULL; 376 } 377 378 DynamicLoaderCreateInstance 379 PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const char *name) 380 { 381 if (name && name[0]) 382 { 383 DynamicLoaderInstance instance; 384 std::string ss_name(name); 385 for (uint32_t idx = 0; AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 386 { 387 if (instance.name == ss_name) 388 return instance.create_callback; 389 } 390 } 391 return NULL; 392 } 393 394 395 #pragma mark LanguageRuntime 396 397 398 struct LanguageRuntimeInstance 399 { 400 LanguageRuntimeInstance() : 401 name(), 402 description(), 403 create_callback(NULL) 404 { 405 } 406 407 std::string name; 408 std::string description; 409 LanguageRuntimeCreateInstance create_callback; 410 }; 411 412 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances; 413 414 static bool 415 AccessLanguageRuntimeInstances (PluginAction action, LanguageRuntimeInstance &instance, uint32_t index) 416 { 417 static LanguageRuntimeInstances g_plugin_instances; 418 419 switch (action) 420 { 421 case ePluginRegisterInstance: 422 if (instance.create_callback) 423 { 424 g_plugin_instances.push_back (instance); 425 return true; 426 } 427 break; 428 429 case ePluginUnregisterInstance: 430 if (instance.create_callback) 431 { 432 LanguageRuntimeInstances::iterator pos, end = g_plugin_instances.end(); 433 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 434 { 435 if (pos->create_callback == instance.create_callback) 436 { 437 g_plugin_instances.erase(pos); 438 return true; 439 } 440 } 441 } 442 break; 443 444 case ePluginGetInstanceAtIndex: 445 if (index < g_plugin_instances.size()) 446 { 447 instance = g_plugin_instances[index]; 448 return true; 449 } 450 break; 451 452 default: 453 break; 454 } 455 return false; 456 } 457 458 459 bool 460 PluginManager::RegisterPlugin 461 ( 462 const char *name, 463 const char *description, 464 LanguageRuntimeCreateInstance create_callback 465 ) 466 { 467 if (create_callback) 468 { 469 LanguageRuntimeInstance instance; 470 assert (name && name[0]); 471 instance.name = name; 472 if (description && description[0]) 473 instance.description = description; 474 instance.create_callback = create_callback; 475 return AccessLanguageRuntimeInstances (ePluginRegisterInstance, instance, 0); 476 } 477 return false; 478 } 479 480 bool 481 PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback) 482 { 483 if (create_callback) 484 { 485 LanguageRuntimeInstance instance; 486 instance.create_callback = create_callback; 487 return AccessLanguageRuntimeInstances (ePluginUnregisterInstance, instance, 0); 488 } 489 return false; 490 } 491 492 LanguageRuntimeCreateInstance 493 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx) 494 { 495 LanguageRuntimeInstance instance; 496 if (AccessLanguageRuntimeInstances (ePluginGetInstanceAtIndex, instance, idx)) 497 return instance.create_callback; 498 return NULL; 499 } 500 501 LanguageRuntimeCreateInstance 502 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const char *name) 503 { 504 if (name && name[0]) 505 { 506 LanguageRuntimeInstance instance; 507 std::string ss_name(name); 508 for (uint32_t idx = 0; AccessLanguageRuntimeInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 509 { 510 if (instance.name == ss_name) 511 return instance.create_callback; 512 } 513 } 514 return NULL; 515 } 516 517 #pragma mark ObjectFile 518 519 struct ObjectFileInstance 520 { 521 ObjectFileInstance() : 522 name(), 523 description(), 524 create_callback(NULL) 525 { 526 } 527 528 std::string name; 529 std::string description; 530 ObjectFileCreateInstance create_callback; 531 }; 532 533 typedef std::vector<ObjectFileInstance> ObjectFileInstances; 534 535 static bool 536 AccessObjectFileInstances (PluginAction action, ObjectFileInstance &instance, uint32_t index) 537 { 538 static ObjectFileInstances g_plugin_instances; 539 540 switch (action) 541 { 542 case ePluginRegisterInstance: 543 if (instance.create_callback) 544 { 545 g_plugin_instances.push_back (instance); 546 return true; 547 } 548 break; 549 550 case ePluginUnregisterInstance: 551 if (instance.create_callback) 552 { 553 ObjectFileInstances::iterator pos, end = g_plugin_instances.end(); 554 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 555 { 556 if (pos->create_callback == instance.create_callback) 557 { 558 g_plugin_instances.erase(pos); 559 return true; 560 } 561 } 562 } 563 break; 564 565 case ePluginGetInstanceAtIndex: 566 if (index < g_plugin_instances.size()) 567 { 568 instance = g_plugin_instances[index]; 569 return true; 570 } 571 break; 572 573 default: 574 break; 575 } 576 return false; 577 } 578 579 580 bool 581 PluginManager::RegisterPlugin 582 ( 583 const char *name, 584 const char *description, 585 ObjectFileCreateInstance create_callback 586 ) 587 { 588 if (create_callback) 589 { 590 ObjectFileInstance instance; 591 assert (name && name[0]); 592 instance.name = name; 593 if (description && description[0]) 594 instance.description = description; 595 instance.create_callback = create_callback; 596 return AccessObjectFileInstances (ePluginRegisterInstance, instance, 0); 597 } 598 return false; 599 } 600 601 bool 602 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback) 603 { 604 if (create_callback) 605 { 606 ObjectFileInstance instance; 607 instance.create_callback = create_callback; 608 return AccessObjectFileInstances (ePluginUnregisterInstance, instance, 0); 609 } 610 return false; 611 } 612 613 ObjectFileCreateInstance 614 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx) 615 { 616 ObjectFileInstance instance; 617 if (AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx)) 618 return instance.create_callback; 619 return NULL; 620 } 621 ObjectFileCreateInstance 622 PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name) 623 { 624 if (name && name[0]) 625 { 626 ObjectFileInstance instance; 627 std::string ss_name(name); 628 for (uint32_t idx = 0; AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 629 { 630 if (instance.name == ss_name) 631 return instance.create_callback; 632 } 633 } 634 return NULL; 635 } 636 637 638 639 #pragma mark ObjectContainer 640 641 struct ObjectContainerInstance 642 { 643 ObjectContainerInstance() : 644 name(), 645 description(), 646 create_callback(NULL) 647 { 648 } 649 650 std::string name; 651 std::string description; 652 ObjectContainerCreateInstance create_callback; 653 }; 654 655 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; 656 657 static bool 658 AccessObjectContainerInstances (PluginAction action, ObjectContainerInstance &instance, uint32_t index) 659 { 660 static ObjectContainerInstances g_plugin_instances; 661 662 switch (action) 663 { 664 case ePluginRegisterInstance: 665 if (instance.create_callback) 666 { 667 g_plugin_instances.push_back (instance); 668 return true; 669 } 670 break; 671 672 case ePluginUnregisterInstance: 673 if (instance.create_callback) 674 { 675 ObjectContainerInstances::iterator pos, end = g_plugin_instances.end(); 676 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 677 { 678 if (pos->create_callback == instance.create_callback) 679 { 680 g_plugin_instances.erase(pos); 681 return true; 682 } 683 } 684 } 685 break; 686 687 case ePluginGetInstanceAtIndex: 688 if (index < g_plugin_instances.size()) 689 { 690 instance = g_plugin_instances[index]; 691 return true; 692 } 693 break; 694 695 default: 696 break; 697 } 698 return false; 699 } 700 701 702 bool 703 PluginManager::RegisterPlugin 704 ( 705 const char *name, 706 const char *description, 707 ObjectContainerCreateInstance create_callback 708 ) 709 { 710 if (create_callback) 711 { 712 ObjectContainerInstance instance; 713 assert (name && name[0]); 714 instance.name = name; 715 if (description && description[0]) 716 instance.description = description; 717 instance.create_callback = create_callback; 718 return AccessObjectContainerInstances (ePluginRegisterInstance, instance, 0); 719 } 720 return false; 721 } 722 723 bool 724 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback) 725 { 726 if (create_callback) 727 { 728 ObjectContainerInstance instance; 729 instance.create_callback = create_callback; 730 return AccessObjectContainerInstances (ePluginUnregisterInstance, instance, 0); 731 } 732 return false; 733 } 734 735 ObjectContainerCreateInstance 736 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx) 737 { 738 ObjectContainerInstance instance; 739 if (AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx)) 740 return instance.create_callback; 741 return NULL; 742 } 743 ObjectContainerCreateInstance 744 PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name) 745 { 746 if (name && name[0]) 747 { 748 ObjectContainerInstance instance; 749 std::string ss_name(name); 750 for (uint32_t idx = 0; AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 751 { 752 if (instance.name == ss_name) 753 return instance.create_callback; 754 } 755 } 756 return NULL; 757 } 758 759 #pragma mark LogChannel 760 761 struct LogChannelInstance 762 { 763 LogChannelInstance() : 764 name(), 765 description(), 766 create_callback(NULL) 767 { 768 } 769 770 std::string name; 771 std::string description; 772 LogChannelCreateInstance create_callback; 773 }; 774 775 typedef std::vector<LogChannelInstance> LogChannelInstances; 776 777 static bool 778 AccessLogChannelInstances (PluginAction action, LogChannelInstance &instance, uint32_t index) 779 { 780 static LogChannelInstances g_plugin_instances; 781 782 switch (action) 783 { 784 case ePluginRegisterInstance: 785 if (instance.create_callback) 786 { 787 g_plugin_instances.push_back (instance); 788 return true; 789 } 790 break; 791 792 case ePluginUnregisterInstance: 793 if (instance.create_callback) 794 { 795 LogChannelInstances::iterator pos, end = g_plugin_instances.end(); 796 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 797 { 798 if (pos->create_callback == instance.create_callback) 799 { 800 g_plugin_instances.erase(pos); 801 return true; 802 } 803 } 804 } 805 break; 806 807 case ePluginGetInstanceAtIndex: 808 if (index < g_plugin_instances.size()) 809 { 810 instance = g_plugin_instances[index]; 811 return true; 812 } 813 break; 814 815 default: 816 break; 817 } 818 return false; 819 } 820 821 822 bool 823 PluginManager::RegisterPlugin 824 ( 825 const char *name, 826 const char *description, 827 LogChannelCreateInstance create_callback 828 ) 829 { 830 if (create_callback) 831 { 832 LogChannelInstance instance; 833 assert (name && name[0]); 834 instance.name = name; 835 if (description && description[0]) 836 instance.description = description; 837 instance.create_callback = create_callback; 838 return AccessLogChannelInstances (ePluginRegisterInstance, instance, 0); 839 } 840 return false; 841 } 842 843 bool 844 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback) 845 { 846 if (create_callback) 847 { 848 LogChannelInstance instance; 849 instance.create_callback = create_callback; 850 return AccessLogChannelInstances (ePluginUnregisterInstance, instance, 0); 851 } 852 return false; 853 } 854 855 const char * 856 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx) 857 { 858 LogChannelInstance instance; 859 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx)) 860 return instance.name.c_str(); 861 return NULL; 862 } 863 864 865 LogChannelCreateInstance 866 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx) 867 { 868 LogChannelInstance instance; 869 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx)) 870 return instance.create_callback; 871 return NULL; 872 } 873 874 LogChannelCreateInstance 875 PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name) 876 { 877 if (name && name[0]) 878 { 879 LogChannelInstance instance; 880 std::string ss_name(name); 881 for (uint32_t idx = 0; AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 882 { 883 if (instance.name == ss_name) 884 return instance.create_callback; 885 } 886 } 887 return NULL; 888 } 889 890 #pragma mark Process 891 892 struct ProcessInstance 893 { 894 ProcessInstance() : 895 name(), 896 description(), 897 create_callback(NULL) 898 { 899 } 900 901 std::string name; 902 std::string description; 903 ProcessCreateInstance create_callback; 904 }; 905 906 typedef std::vector<ProcessInstance> ProcessInstances; 907 908 static bool 909 AccessProcessInstances (PluginAction action, ProcessInstance &instance, uint32_t index) 910 { 911 static ProcessInstances g_plugin_instances; 912 913 switch (action) 914 { 915 case ePluginRegisterInstance: 916 if (instance.create_callback) 917 { 918 g_plugin_instances.push_back (instance); 919 return true; 920 } 921 break; 922 923 case ePluginUnregisterInstance: 924 if (instance.create_callback) 925 { 926 ProcessInstances::iterator pos, end = g_plugin_instances.end(); 927 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 928 { 929 if (pos->create_callback == instance.create_callback) 930 { 931 g_plugin_instances.erase(pos); 932 return true; 933 } 934 } 935 } 936 break; 937 938 case ePluginGetInstanceAtIndex: 939 if (index < g_plugin_instances.size()) 940 { 941 instance = g_plugin_instances[index]; 942 return true; 943 } 944 break; 945 946 default: 947 break; 948 } 949 return false; 950 } 951 952 953 bool 954 PluginManager::RegisterPlugin 955 ( 956 const char *name, 957 const char *description, 958 ProcessCreateInstance create_callback 959 ) 960 { 961 if (create_callback) 962 { 963 ProcessInstance instance; 964 assert (name && name[0]); 965 instance.name = name; 966 if (description && description[0]) 967 instance.description = description; 968 instance.create_callback = create_callback; 969 return AccessProcessInstances (ePluginRegisterInstance, instance, 0); 970 } 971 return false; 972 } 973 974 bool 975 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback) 976 { 977 if (create_callback) 978 { 979 ProcessInstance instance; 980 instance.create_callback = create_callback; 981 return AccessProcessInstances (ePluginUnregisterInstance, instance, 0); 982 } 983 return false; 984 } 985 986 ProcessCreateInstance 987 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx) 988 { 989 ProcessInstance instance; 990 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx)) 991 return instance.create_callback; 992 return NULL; 993 } 994 995 ProcessCreateInstance 996 PluginManager::GetProcessCreateCallbackForPluginName (const char *name) 997 { 998 if (name && name[0]) 999 { 1000 ProcessInstance instance; 1001 std::string ss_name(name); 1002 for (uint32_t idx = 0; AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 1003 { 1004 if (instance.name == ss_name) 1005 return instance.create_callback; 1006 } 1007 } 1008 return NULL; 1009 } 1010 1011 #pragma mark SymbolFile 1012 1013 struct SymbolFileInstance 1014 { 1015 SymbolFileInstance() : 1016 name(), 1017 description(), 1018 create_callback(NULL) 1019 { 1020 } 1021 1022 std::string name; 1023 std::string description; 1024 SymbolFileCreateInstance create_callback; 1025 }; 1026 1027 typedef std::vector<SymbolFileInstance> SymbolFileInstances; 1028 1029 static bool 1030 AccessSymbolFileInstances (PluginAction action, SymbolFileInstance &instance, uint32_t index) 1031 { 1032 static SymbolFileInstances g_plugin_instances; 1033 1034 switch (action) 1035 { 1036 case ePluginRegisterInstance: 1037 if (instance.create_callback) 1038 { 1039 g_plugin_instances.push_back (instance); 1040 return true; 1041 } 1042 break; 1043 1044 case ePluginUnregisterInstance: 1045 if (instance.create_callback) 1046 { 1047 SymbolFileInstances::iterator pos, end = g_plugin_instances.end(); 1048 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 1049 { 1050 if (pos->create_callback == instance.create_callback) 1051 { 1052 g_plugin_instances.erase(pos); 1053 return true; 1054 } 1055 } 1056 } 1057 break; 1058 1059 case ePluginGetInstanceAtIndex: 1060 if (index < g_plugin_instances.size()) 1061 { 1062 instance = g_plugin_instances[index]; 1063 return true; 1064 } 1065 break; 1066 1067 default: 1068 break; 1069 } 1070 return false; 1071 } 1072 1073 1074 bool 1075 PluginManager::RegisterPlugin 1076 ( 1077 const char *name, 1078 const char *description, 1079 SymbolFileCreateInstance create_callback 1080 ) 1081 { 1082 if (create_callback) 1083 { 1084 SymbolFileInstance instance; 1085 assert (name && name[0]); 1086 instance.name = name; 1087 if (description && description[0]) 1088 instance.description = description; 1089 instance.create_callback = create_callback; 1090 return AccessSymbolFileInstances (ePluginRegisterInstance, instance, 0); 1091 } 1092 return false; 1093 } 1094 1095 bool 1096 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback) 1097 { 1098 if (create_callback) 1099 { 1100 SymbolFileInstance instance; 1101 instance.create_callback = create_callback; 1102 return AccessSymbolFileInstances (ePluginUnregisterInstance, instance, 0); 1103 } 1104 return false; 1105 } 1106 1107 SymbolFileCreateInstance 1108 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx) 1109 { 1110 SymbolFileInstance instance; 1111 if (AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx)) 1112 return instance.create_callback; 1113 return NULL; 1114 } 1115 SymbolFileCreateInstance 1116 PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name) 1117 { 1118 if (name && name[0]) 1119 { 1120 SymbolFileInstance instance; 1121 std::string ss_name(name); 1122 for (uint32_t idx = 0; AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 1123 { 1124 if (instance.name == ss_name) 1125 return instance.create_callback; 1126 } 1127 } 1128 return NULL; 1129 } 1130 1131 1132 1133 #pragma mark SymbolVendor 1134 1135 struct SymbolVendorInstance 1136 { 1137 SymbolVendorInstance() : 1138 name(), 1139 description(), 1140 create_callback(NULL) 1141 { 1142 } 1143 1144 std::string name; 1145 std::string description; 1146 SymbolVendorCreateInstance create_callback; 1147 }; 1148 1149 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 1150 1151 static bool 1152 AccessSymbolVendorInstances (PluginAction action, SymbolVendorInstance &instance, uint32_t index) 1153 { 1154 static SymbolVendorInstances g_plugin_instances; 1155 1156 switch (action) 1157 { 1158 case ePluginRegisterInstance: 1159 if (instance.create_callback) 1160 { 1161 g_plugin_instances.push_back (instance); 1162 return true; 1163 } 1164 break; 1165 1166 case ePluginUnregisterInstance: 1167 if (instance.create_callback) 1168 { 1169 SymbolVendorInstances::iterator pos, end = g_plugin_instances.end(); 1170 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 1171 { 1172 if (pos->create_callback == instance.create_callback) 1173 { 1174 g_plugin_instances.erase(pos); 1175 return true; 1176 } 1177 } 1178 } 1179 break; 1180 1181 case ePluginGetInstanceAtIndex: 1182 if (index < g_plugin_instances.size()) 1183 { 1184 instance = g_plugin_instances[index]; 1185 return true; 1186 } 1187 break; 1188 1189 default: 1190 break; 1191 } 1192 return false; 1193 } 1194 1195 bool 1196 PluginManager::RegisterPlugin 1197 ( 1198 const char *name, 1199 const char *description, 1200 SymbolVendorCreateInstance create_callback 1201 ) 1202 { 1203 if (create_callback) 1204 { 1205 SymbolVendorInstance instance; 1206 assert (name && name[0]); 1207 instance.name = name; 1208 if (description && description[0]) 1209 instance.description = description; 1210 instance.create_callback = create_callback; 1211 return AccessSymbolVendorInstances (ePluginRegisterInstance, instance, 0); 1212 } 1213 return false; 1214 } 1215 1216 bool 1217 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback) 1218 { 1219 if (create_callback) 1220 { 1221 SymbolVendorInstance instance; 1222 instance.create_callback = create_callback; 1223 return AccessSymbolVendorInstances (ePluginUnregisterInstance, instance, 0); 1224 } 1225 return false; 1226 } 1227 1228 SymbolVendorCreateInstance 1229 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx) 1230 { 1231 SymbolVendorInstance instance; 1232 if (AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx)) 1233 return instance.create_callback; 1234 return NULL; 1235 } 1236 1237 SymbolVendorCreateInstance 1238 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name) 1239 { 1240 if (name && name[0]) 1241 { 1242 SymbolVendorInstance instance; 1243 std::string ss_name(name); 1244 for (uint32_t idx = 0; AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 1245 { 1246 if (instance.name == ss_name) 1247 return instance.create_callback; 1248 } 1249 } 1250 return NULL; 1251 } 1252 1253 1254 #pragma mark UnwindAssemblyProfiler 1255 1256 struct UnwindAssemblyProfilerInstance 1257 { 1258 UnwindAssemblyProfilerInstance() : 1259 name(), 1260 description(), 1261 create_callback(NULL) 1262 { 1263 } 1264 1265 std::string name; 1266 std::string description; 1267 UnwindAssemblyProfilerCreateInstance create_callback; 1268 }; 1269 1270 typedef std::vector<UnwindAssemblyProfilerInstance> UnwindAssemblyProfilerInstances; 1271 1272 static bool 1273 AccessUnwindAssemblyProfilerInstances (PluginAction action, UnwindAssemblyProfilerInstance &instance, uint32_t index) 1274 { 1275 static UnwindAssemblyProfilerInstances g_plugin_instances; 1276 1277 switch (action) 1278 { 1279 case ePluginRegisterInstance: 1280 if (instance.create_callback) 1281 { 1282 g_plugin_instances.push_back (instance); 1283 return true; 1284 } 1285 break; 1286 1287 case ePluginUnregisterInstance: 1288 if (instance.create_callback) 1289 { 1290 UnwindAssemblyProfilerInstances::iterator pos, end = g_plugin_instances.end(); 1291 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 1292 { 1293 if (pos->create_callback == instance.create_callback) 1294 { 1295 g_plugin_instances.erase(pos); 1296 return true; 1297 } 1298 } 1299 } 1300 break; 1301 1302 case ePluginGetInstanceAtIndex: 1303 if (index < g_plugin_instances.size()) 1304 { 1305 instance = g_plugin_instances[index]; 1306 return true; 1307 } 1308 break; 1309 1310 default: 1311 break; 1312 } 1313 return false; 1314 } 1315 1316 bool 1317 PluginManager::RegisterPlugin 1318 ( 1319 const char *name, 1320 const char *description, 1321 UnwindAssemblyProfilerCreateInstance create_callback 1322 ) 1323 { 1324 if (create_callback) 1325 { 1326 UnwindAssemblyProfilerInstance instance; 1327 assert (name && name[0]); 1328 instance.name = name; 1329 if (description && description[0]) 1330 instance.description = description; 1331 instance.create_callback = create_callback; 1332 return AccessUnwindAssemblyProfilerInstances (ePluginRegisterInstance, instance, 0); 1333 } 1334 return false; 1335 } 1336 1337 bool 1338 PluginManager::UnregisterPlugin (UnwindAssemblyProfilerCreateInstance create_callback) 1339 { 1340 if (create_callback) 1341 { 1342 UnwindAssemblyProfilerInstance instance; 1343 instance.create_callback = create_callback; 1344 return AccessUnwindAssemblyProfilerInstances (ePluginUnregisterInstance, instance, 0); 1345 } 1346 return false; 1347 } 1348 1349 UnwindAssemblyProfilerCreateInstance 1350 PluginManager::GetUnwindAssemblyProfilerCreateCallbackAtIndex (uint32_t idx) 1351 { 1352 UnwindAssemblyProfilerInstance instance; 1353 if (AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx)) 1354 return instance.create_callback; 1355 return NULL; 1356 } 1357 1358 UnwindAssemblyProfilerCreateInstance 1359 PluginManager::GetUnwindAssemblyProfilerCreateCallbackForPluginName (const char *name) 1360 { 1361 if (name && name[0]) 1362 { 1363 UnwindAssemblyProfilerInstance instance; 1364 std::string ss_name(name); 1365 for (uint32_t idx = 0; AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 1366 { 1367 if (instance.name == ss_name) 1368 return instance.create_callback; 1369 } 1370 } 1371 return NULL; 1372 } 1373 1374 #pragma mark ArchDefaultUnwindPlan 1375 1376 struct ArchDefaultUnwindPlanInstance 1377 { 1378 ArchDefaultUnwindPlanInstance() : 1379 name(), 1380 description(), 1381 create_callback(NULL) 1382 { 1383 } 1384 1385 std::string name; 1386 std::string description; 1387 ArchDefaultUnwindPlanCreateInstance create_callback; 1388 }; 1389 1390 typedef std::vector<ArchDefaultUnwindPlanInstance> ArchDefaultUnwindPlanInstances; 1391 1392 static bool 1393 AccessArchDefaultUnwindPlanInstances (PluginAction action, ArchDefaultUnwindPlanInstance &instance, uint32_t index) 1394 { 1395 static ArchDefaultUnwindPlanInstances g_plugin_instances; 1396 1397 switch (action) 1398 { 1399 case ePluginRegisterInstance: 1400 if (instance.create_callback) 1401 { 1402 g_plugin_instances.push_back (instance); 1403 return true; 1404 } 1405 break; 1406 1407 case ePluginUnregisterInstance: 1408 if (instance.create_callback) 1409 { 1410 ArchDefaultUnwindPlanInstances::iterator pos, end = g_plugin_instances.end(); 1411 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 1412 { 1413 if (pos->create_callback == instance.create_callback) 1414 { 1415 g_plugin_instances.erase(pos); 1416 return true; 1417 } 1418 } 1419 } 1420 break; 1421 1422 case ePluginGetInstanceAtIndex: 1423 if (index < g_plugin_instances.size()) 1424 { 1425 instance = g_plugin_instances[index]; 1426 return true; 1427 } 1428 break; 1429 1430 default: 1431 break; 1432 } 1433 return false; 1434 } 1435 1436 bool 1437 PluginManager::RegisterPlugin 1438 ( 1439 const char *name, 1440 const char *description, 1441 ArchDefaultUnwindPlanCreateInstance create_callback 1442 ) 1443 { 1444 if (create_callback) 1445 { 1446 ArchDefaultUnwindPlanInstance instance; 1447 assert (name && name[0]); 1448 instance.name = name; 1449 if (description && description[0]) 1450 instance.description = description; 1451 instance.create_callback = create_callback; 1452 return AccessArchDefaultUnwindPlanInstances (ePluginRegisterInstance, instance, 0); 1453 } 1454 return false; 1455 } 1456 1457 bool 1458 PluginManager::UnregisterPlugin (ArchDefaultUnwindPlanCreateInstance create_callback) 1459 { 1460 if (create_callback) 1461 { 1462 ArchDefaultUnwindPlanInstance instance; 1463 instance.create_callback = create_callback; 1464 return AccessArchDefaultUnwindPlanInstances (ePluginUnregisterInstance, instance, 0); 1465 } 1466 return false; 1467 } 1468 1469 ArchDefaultUnwindPlanCreateInstance 1470 PluginManager::GetArchDefaultUnwindPlanCreateCallbackAtIndex (uint32_t idx) 1471 { 1472 ArchDefaultUnwindPlanInstance instance; 1473 if (AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx)) 1474 return instance.create_callback; 1475 return NULL; 1476 } 1477 1478 ArchDefaultUnwindPlanCreateInstance 1479 PluginManager::GetArchDefaultUnwindPlanCreateCallbackForPluginName (const char *name) 1480 { 1481 if (name && name[0]) 1482 { 1483 ArchDefaultUnwindPlanInstance instance; 1484 std::string ss_name(name); 1485 for (uint32_t idx = 0; AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 1486 { 1487 if (instance.name == ss_name) 1488 return instance.create_callback; 1489 } 1490 } 1491 return NULL; 1492 } 1493 1494 #pragma mark ArchVolatileRegs 1495 1496 struct ArchVolatileRegsInstance 1497 { 1498 ArchVolatileRegsInstance() : 1499 name(), 1500 description(), 1501 create_callback(NULL) 1502 { 1503 } 1504 1505 std::string name; 1506 std::string description; 1507 ArchVolatileRegsCreateInstance create_callback; 1508 }; 1509 1510 typedef std::vector<ArchVolatileRegsInstance> ArchVolatileRegsInstances; 1511 1512 static bool 1513 AccessArchVolatileRegsInstances (PluginAction action, ArchVolatileRegsInstance &instance, uint32_t index) 1514 { 1515 static ArchVolatileRegsInstances g_plugin_instances; 1516 1517 switch (action) 1518 { 1519 case ePluginRegisterInstance: 1520 if (instance.create_callback) 1521 { 1522 g_plugin_instances.push_back (instance); 1523 return true; 1524 } 1525 break; 1526 1527 case ePluginUnregisterInstance: 1528 if (instance.create_callback) 1529 { 1530 ArchVolatileRegsInstances::iterator pos, end = g_plugin_instances.end(); 1531 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 1532 { 1533 if (pos->create_callback == instance.create_callback) 1534 { 1535 g_plugin_instances.erase(pos); 1536 return true; 1537 } 1538 } 1539 } 1540 break; 1541 1542 case ePluginGetInstanceAtIndex: 1543 if (index < g_plugin_instances.size()) 1544 { 1545 instance = g_plugin_instances[index]; 1546 return true; 1547 } 1548 break; 1549 1550 default: 1551 break; 1552 } 1553 return false; 1554 } 1555 1556 bool 1557 PluginManager::RegisterPlugin 1558 ( 1559 const char *name, 1560 const char *description, 1561 ArchVolatileRegsCreateInstance create_callback 1562 ) 1563 { 1564 if (create_callback) 1565 { 1566 ArchVolatileRegsInstance instance; 1567 assert (name && name[0]); 1568 instance.name = name; 1569 if (description && description[0]) 1570 instance.description = description; 1571 instance.create_callback = create_callback; 1572 return AccessArchVolatileRegsInstances (ePluginRegisterInstance, instance, 0); 1573 } 1574 return false; 1575 } 1576 1577 bool 1578 PluginManager::UnregisterPlugin (ArchVolatileRegsCreateInstance create_callback) 1579 { 1580 if (create_callback) 1581 { 1582 ArchVolatileRegsInstance instance; 1583 instance.create_callback = create_callback; 1584 return AccessArchVolatileRegsInstances (ePluginUnregisterInstance, instance, 0); 1585 } 1586 return false; 1587 } 1588 1589 ArchVolatileRegsCreateInstance 1590 PluginManager::GetArchVolatileRegsCreateCallbackAtIndex (uint32_t idx) 1591 { 1592 ArchVolatileRegsInstance instance; 1593 if (AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx)) 1594 return instance.create_callback; 1595 return NULL; 1596 } 1597 1598 ArchVolatileRegsCreateInstance 1599 PluginManager::GetArchVolatileRegsCreateCallbackForPluginName (const char *name) 1600 { 1601 if (name && name[0]) 1602 { 1603 ArchVolatileRegsInstance instance; 1604 std::string ss_name(name); 1605 for (uint32_t idx = 0; AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 1606 { 1607 if (instance.name == ss_name) 1608 return instance.create_callback; 1609 } 1610 } 1611 return NULL; 1612 } 1613 1614