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