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