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