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