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