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