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