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