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(const char *name, 1359 StringList &matches) { 1360 if (name) { 1361 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 1362 PlatformInstances &instances = GetPlatformInstances(); 1363 llvm::StringRef name_sref(name); 1364 1365 PlatformInstances::iterator pos, end = instances.end(); 1366 for (pos = instances.begin(); pos != end; ++pos) { 1367 llvm::StringRef plugin_name(pos->name.GetCString()); 1368 if (plugin_name.startswith(name_sref)) 1369 matches.AppendString(plugin_name.data()); 1370 } 1371 } 1372 return matches.GetSize(); 1373 } 1374 1375 #pragma mark Process 1376 1377 struct ProcessInstance { 1378 ProcessInstance() 1379 : name(), description(), create_callback(nullptr), 1380 debugger_init_callback(nullptr) {} 1381 1382 ConstString name; 1383 std::string description; 1384 ProcessCreateInstance create_callback; 1385 DebuggerInitializeCallback debugger_init_callback; 1386 }; 1387 1388 typedef std::vector<ProcessInstance> ProcessInstances; 1389 1390 static std::recursive_mutex &GetProcessMutex() { 1391 static std::recursive_mutex g_instances_mutex; 1392 return g_instances_mutex; 1393 } 1394 1395 static ProcessInstances &GetProcessInstances() { 1396 static ProcessInstances g_instances; 1397 return g_instances; 1398 } 1399 1400 bool PluginManager::RegisterPlugin( 1401 const ConstString &name, const char *description, 1402 ProcessCreateInstance create_callback, 1403 DebuggerInitializeCallback debugger_init_callback) { 1404 if (create_callback) { 1405 ProcessInstance instance; 1406 assert((bool)name); 1407 instance.name = name; 1408 if (description && description[0]) 1409 instance.description = description; 1410 instance.create_callback = create_callback; 1411 instance.debugger_init_callback = debugger_init_callback; 1412 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1413 GetProcessInstances().push_back(instance); 1414 } 1415 return false; 1416 } 1417 1418 const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { 1419 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1420 ProcessInstances &instances = GetProcessInstances(); 1421 if (idx < instances.size()) 1422 return instances[idx].name.GetCString(); 1423 return nullptr; 1424 } 1425 1426 const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { 1427 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1428 ProcessInstances &instances = GetProcessInstances(); 1429 if (idx < instances.size()) 1430 return instances[idx].description.c_str(); 1431 return nullptr; 1432 } 1433 1434 bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { 1435 if (create_callback) { 1436 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1437 ProcessInstances &instances = GetProcessInstances(); 1438 1439 ProcessInstances::iterator pos, end = instances.end(); 1440 for (pos = instances.begin(); pos != end; ++pos) { 1441 if (pos->create_callback == create_callback) { 1442 instances.erase(pos); 1443 return true; 1444 } 1445 } 1446 } 1447 return false; 1448 } 1449 1450 ProcessCreateInstance 1451 PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { 1452 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1453 ProcessInstances &instances = GetProcessInstances(); 1454 if (idx < instances.size()) 1455 return instances[idx].create_callback; 1456 return nullptr; 1457 } 1458 1459 ProcessCreateInstance 1460 PluginManager::GetProcessCreateCallbackForPluginName(const ConstString &name) { 1461 if (name) { 1462 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 1463 ProcessInstances &instances = GetProcessInstances(); 1464 1465 ProcessInstances::iterator pos, end = instances.end(); 1466 for (pos = instances.begin(); pos != end; ++pos) { 1467 if (name == pos->name) 1468 return pos->create_callback; 1469 } 1470 } 1471 return nullptr; 1472 } 1473 1474 #pragma mark ScriptInterpreter 1475 1476 struct ScriptInterpreterInstance { 1477 ScriptInterpreterInstance() 1478 : name(), language(lldb::eScriptLanguageNone), description(), 1479 create_callback(nullptr) {} 1480 1481 ConstString name; 1482 lldb::ScriptLanguage language; 1483 std::string description; 1484 ScriptInterpreterCreateInstance create_callback; 1485 }; 1486 1487 typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances; 1488 1489 static std::recursive_mutex &GetScriptInterpreterMutex() { 1490 static std::recursive_mutex g_instances_mutex; 1491 return g_instances_mutex; 1492 } 1493 1494 static ScriptInterpreterInstances &GetScriptInterpreterInstances() { 1495 static ScriptInterpreterInstances g_instances; 1496 return g_instances; 1497 } 1498 1499 bool PluginManager::RegisterPlugin( 1500 const ConstString &name, const char *description, 1501 lldb::ScriptLanguage script_language, 1502 ScriptInterpreterCreateInstance create_callback) { 1503 if (!create_callback) 1504 return false; 1505 ScriptInterpreterInstance instance; 1506 assert((bool)name); 1507 instance.name = name; 1508 if (description && description[0]) 1509 instance.description = description; 1510 instance.create_callback = create_callback; 1511 instance.language = script_language; 1512 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1513 GetScriptInterpreterInstances().push_back(instance); 1514 return false; 1515 } 1516 1517 bool PluginManager::UnregisterPlugin( 1518 ScriptInterpreterCreateInstance create_callback) { 1519 if (!create_callback) 1520 return false; 1521 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1522 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1523 1524 ScriptInterpreterInstances::iterator pos, end = instances.end(); 1525 for (pos = instances.begin(); pos != end; ++pos) { 1526 if (pos->create_callback != create_callback) 1527 continue; 1528 1529 instances.erase(pos); 1530 return true; 1531 } 1532 return false; 1533 } 1534 1535 ScriptInterpreterCreateInstance 1536 PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) { 1537 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1538 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1539 if (idx < instances.size()) 1540 return instances[idx].create_callback; 1541 return nullptr; 1542 } 1543 1544 lldb::ScriptInterpreterSP PluginManager::GetScriptInterpreterForLanguage( 1545 lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter) { 1546 std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); 1547 ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); 1548 1549 ScriptInterpreterInstances::iterator pos, end = instances.end(); 1550 ScriptInterpreterCreateInstance none_instance = nullptr; 1551 for (pos = instances.begin(); pos != end; ++pos) { 1552 if (pos->language == lldb::eScriptLanguageNone) 1553 none_instance = pos->create_callback; 1554 1555 if (script_lang == pos->language) 1556 return pos->create_callback(interpreter); 1557 } 1558 1559 // If we didn't find one, return the ScriptInterpreter for the null language. 1560 assert(none_instance != nullptr); 1561 return none_instance(interpreter); 1562 } 1563 1564 #pragma mark - 1565 #pragma mark StructuredDataPlugin 1566 1567 // ----------------------------------------------------------------------------- 1568 // StructuredDataPlugin 1569 // ----------------------------------------------------------------------------- 1570 1571 struct StructuredDataPluginInstance { 1572 StructuredDataPluginInstance() 1573 : name(), description(), create_callback(nullptr), 1574 debugger_init_callback(nullptr), filter_callback(nullptr) {} 1575 1576 ConstString name; 1577 std::string description; 1578 StructuredDataPluginCreateInstance create_callback; 1579 DebuggerInitializeCallback debugger_init_callback; 1580 StructuredDataFilterLaunchInfo filter_callback; 1581 }; 1582 1583 typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances; 1584 1585 static std::recursive_mutex &GetStructuredDataPluginMutex() { 1586 static std::recursive_mutex g_instances_mutex; 1587 return g_instances_mutex; 1588 } 1589 1590 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { 1591 static StructuredDataPluginInstances g_instances; 1592 return g_instances; 1593 } 1594 1595 bool PluginManager::RegisterPlugin( 1596 const ConstString &name, const char *description, 1597 StructuredDataPluginCreateInstance create_callback, 1598 DebuggerInitializeCallback debugger_init_callback, 1599 StructuredDataFilterLaunchInfo filter_callback) { 1600 if (create_callback) { 1601 StructuredDataPluginInstance instance; 1602 assert((bool)name); 1603 instance.name = name; 1604 if (description && description[0]) 1605 instance.description = description; 1606 instance.create_callback = create_callback; 1607 instance.debugger_init_callback = debugger_init_callback; 1608 instance.filter_callback = filter_callback; 1609 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1610 GetStructuredDataPluginInstances().push_back(instance); 1611 } 1612 return false; 1613 } 1614 1615 bool PluginManager::UnregisterPlugin( 1616 StructuredDataPluginCreateInstance create_callback) { 1617 if (create_callback) { 1618 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1619 StructuredDataPluginInstances &instances = 1620 GetStructuredDataPluginInstances(); 1621 1622 StructuredDataPluginInstances::iterator pos, end = instances.end(); 1623 for (pos = instances.begin(); pos != end; ++pos) { 1624 if (pos->create_callback == create_callback) { 1625 instances.erase(pos); 1626 return true; 1627 } 1628 } 1629 } 1630 return false; 1631 } 1632 1633 StructuredDataPluginCreateInstance 1634 PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) { 1635 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1636 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); 1637 if (idx < instances.size()) 1638 return instances[idx].create_callback; 1639 return nullptr; 1640 } 1641 1642 StructuredDataPluginCreateInstance 1643 PluginManager::GetStructuredDataPluginCreateCallbackForPluginName( 1644 const ConstString &name) { 1645 if (name) { 1646 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1647 StructuredDataPluginInstances &instances = 1648 GetStructuredDataPluginInstances(); 1649 1650 StructuredDataPluginInstances::iterator pos, end = instances.end(); 1651 for (pos = instances.begin(); pos != end; ++pos) { 1652 if (name == pos->name) 1653 return pos->create_callback; 1654 } 1655 } 1656 return nullptr; 1657 } 1658 1659 StructuredDataFilterLaunchInfo 1660 PluginManager::GetStructuredDataFilterCallbackAtIndex( 1661 uint32_t idx, bool &iteration_complete) { 1662 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 1663 StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); 1664 if (idx < instances.size()) { 1665 iteration_complete = false; 1666 return instances[idx].filter_callback; 1667 } else { 1668 iteration_complete = true; 1669 } 1670 return nullptr; 1671 } 1672 1673 #pragma mark SymbolFile 1674 1675 struct SymbolFileInstance { 1676 SymbolFileInstance() 1677 : name(), description(), create_callback(nullptr), 1678 debugger_init_callback(nullptr) {} 1679 1680 ConstString name; 1681 std::string description; 1682 SymbolFileCreateInstance create_callback; 1683 DebuggerInitializeCallback debugger_init_callback; 1684 }; 1685 1686 typedef std::vector<SymbolFileInstance> SymbolFileInstances; 1687 1688 static std::recursive_mutex &GetSymbolFileMutex() { 1689 static std::recursive_mutex g_instances_mutex; 1690 return g_instances_mutex; 1691 } 1692 1693 static SymbolFileInstances &GetSymbolFileInstances() { 1694 static SymbolFileInstances g_instances; 1695 return g_instances; 1696 } 1697 1698 bool PluginManager::RegisterPlugin( 1699 const ConstString &name, const char *description, 1700 SymbolFileCreateInstance create_callback, 1701 DebuggerInitializeCallback debugger_init_callback) { 1702 if (create_callback) { 1703 SymbolFileInstance instance; 1704 assert((bool)name); 1705 instance.name = name; 1706 if (description && description[0]) 1707 instance.description = description; 1708 instance.create_callback = create_callback; 1709 instance.debugger_init_callback = debugger_init_callback; 1710 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1711 GetSymbolFileInstances().push_back(instance); 1712 } 1713 return false; 1714 } 1715 1716 bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) { 1717 if (create_callback) { 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 (pos->create_callback == create_callback) { 1724 instances.erase(pos); 1725 return true; 1726 } 1727 } 1728 } 1729 return false; 1730 } 1731 1732 SymbolFileCreateInstance 1733 PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) { 1734 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1735 SymbolFileInstances &instances = GetSymbolFileInstances(); 1736 if (idx < instances.size()) 1737 return instances[idx].create_callback; 1738 return nullptr; 1739 } 1740 1741 SymbolFileCreateInstance 1742 PluginManager::GetSymbolFileCreateCallbackForPluginName( 1743 const ConstString &name) { 1744 if (name) { 1745 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 1746 SymbolFileInstances &instances = GetSymbolFileInstances(); 1747 1748 SymbolFileInstances::iterator pos, end = instances.end(); 1749 for (pos = instances.begin(); pos != end; ++pos) { 1750 if (name == pos->name) 1751 return pos->create_callback; 1752 } 1753 } 1754 return nullptr; 1755 } 1756 1757 #pragma mark SymbolVendor 1758 1759 struct SymbolVendorInstance { 1760 SymbolVendorInstance() : name(), description(), create_callback(nullptr) {} 1761 1762 ConstString name; 1763 std::string description; 1764 SymbolVendorCreateInstance create_callback; 1765 }; 1766 1767 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 1768 1769 static std::recursive_mutex &GetSymbolVendorMutex() { 1770 static std::recursive_mutex g_instances_mutex; 1771 return g_instances_mutex; 1772 } 1773 1774 static SymbolVendorInstances &GetSymbolVendorInstances() { 1775 static SymbolVendorInstances g_instances; 1776 return g_instances; 1777 } 1778 1779 bool PluginManager::RegisterPlugin(const ConstString &name, 1780 const char *description, 1781 SymbolVendorCreateInstance create_callback) { 1782 if (create_callback) { 1783 SymbolVendorInstance instance; 1784 assert((bool)name); 1785 instance.name = name; 1786 if (description && description[0]) 1787 instance.description = description; 1788 instance.create_callback = create_callback; 1789 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1790 GetSymbolVendorInstances().push_back(instance); 1791 } 1792 return false; 1793 } 1794 1795 bool PluginManager::UnregisterPlugin( 1796 SymbolVendorCreateInstance create_callback) { 1797 if (create_callback) { 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 (pos->create_callback == create_callback) { 1804 instances.erase(pos); 1805 return true; 1806 } 1807 } 1808 } 1809 return false; 1810 } 1811 1812 SymbolVendorCreateInstance 1813 PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { 1814 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1815 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1816 if (idx < instances.size()) 1817 return instances[idx].create_callback; 1818 return nullptr; 1819 } 1820 1821 SymbolVendorCreateInstance 1822 PluginManager::GetSymbolVendorCreateCallbackForPluginName( 1823 const ConstString &name) { 1824 if (name) { 1825 std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); 1826 SymbolVendorInstances &instances = GetSymbolVendorInstances(); 1827 1828 SymbolVendorInstances::iterator pos, end = instances.end(); 1829 for (pos = instances.begin(); pos != end; ++pos) { 1830 if (name == pos->name) 1831 return pos->create_callback; 1832 } 1833 } 1834 return nullptr; 1835 } 1836 1837 #pragma mark UnwindAssembly 1838 1839 struct UnwindAssemblyInstance { 1840 UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {} 1841 1842 ConstString name; 1843 std::string description; 1844 UnwindAssemblyCreateInstance create_callback; 1845 }; 1846 1847 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances; 1848 1849 static std::recursive_mutex &GetUnwindAssemblyMutex() { 1850 static std::recursive_mutex g_instances_mutex; 1851 return g_instances_mutex; 1852 } 1853 1854 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { 1855 static UnwindAssemblyInstances g_instances; 1856 return g_instances; 1857 } 1858 1859 bool PluginManager::RegisterPlugin( 1860 const ConstString &name, const char *description, 1861 UnwindAssemblyCreateInstance create_callback) { 1862 if (create_callback) { 1863 UnwindAssemblyInstance instance; 1864 assert((bool)name); 1865 instance.name = name; 1866 if (description && description[0]) 1867 instance.description = description; 1868 instance.create_callback = create_callback; 1869 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1870 GetUnwindAssemblyInstances().push_back(instance); 1871 } 1872 return false; 1873 } 1874 1875 bool PluginManager::UnregisterPlugin( 1876 UnwindAssemblyCreateInstance create_callback) { 1877 if (create_callback) { 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 (pos->create_callback == create_callback) { 1884 instances.erase(pos); 1885 return true; 1886 } 1887 } 1888 } 1889 return false; 1890 } 1891 1892 UnwindAssemblyCreateInstance 1893 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) { 1894 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1895 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1896 if (idx < instances.size()) 1897 return instances[idx].create_callback; 1898 return nullptr; 1899 } 1900 1901 UnwindAssemblyCreateInstance 1902 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName( 1903 const ConstString &name) { 1904 if (name) { 1905 std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); 1906 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); 1907 1908 UnwindAssemblyInstances::iterator pos, end = instances.end(); 1909 for (pos = instances.begin(); pos != end; ++pos) { 1910 if (name == pos->name) 1911 return pos->create_callback; 1912 } 1913 } 1914 return nullptr; 1915 } 1916 1917 #pragma mark MemoryHistory 1918 1919 struct MemoryHistoryInstance { 1920 MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {} 1921 1922 ConstString name; 1923 std::string description; 1924 MemoryHistoryCreateInstance create_callback; 1925 }; 1926 1927 typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances; 1928 1929 static std::recursive_mutex &GetMemoryHistoryMutex() { 1930 static std::recursive_mutex g_instances_mutex; 1931 return g_instances_mutex; 1932 } 1933 1934 static MemoryHistoryInstances &GetMemoryHistoryInstances() { 1935 static MemoryHistoryInstances g_instances; 1936 return g_instances; 1937 } 1938 1939 bool PluginManager::RegisterPlugin( 1940 const ConstString &name, const char *description, 1941 MemoryHistoryCreateInstance create_callback) { 1942 if (create_callback) { 1943 MemoryHistoryInstance instance; 1944 assert((bool)name); 1945 instance.name = name; 1946 if (description && description[0]) 1947 instance.description = description; 1948 instance.create_callback = create_callback; 1949 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1950 GetMemoryHistoryInstances().push_back(instance); 1951 } 1952 return false; 1953 } 1954 1955 bool PluginManager::UnregisterPlugin( 1956 MemoryHistoryCreateInstance create_callback) { 1957 if (create_callback) { 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 (pos->create_callback == create_callback) { 1964 instances.erase(pos); 1965 return true; 1966 } 1967 } 1968 } 1969 return false; 1970 } 1971 1972 MemoryHistoryCreateInstance 1973 PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { 1974 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1975 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1976 if (idx < instances.size()) 1977 return instances[idx].create_callback; 1978 return nullptr; 1979 } 1980 1981 MemoryHistoryCreateInstance 1982 PluginManager::GetMemoryHistoryCreateCallbackForPluginName( 1983 const ConstString &name) { 1984 if (name) { 1985 std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); 1986 MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); 1987 1988 MemoryHistoryInstances::iterator pos, end = instances.end(); 1989 for (pos = instances.begin(); pos != end; ++pos) { 1990 if (name == pos->name) 1991 return pos->create_callback; 1992 } 1993 } 1994 return nullptr; 1995 } 1996 1997 #pragma mark InstrumentationRuntime 1998 1999 struct InstrumentationRuntimeInstance { 2000 InstrumentationRuntimeInstance() 2001 : name(), description(), create_callback(nullptr) {} 2002 2003 ConstString name; 2004 std::string description; 2005 InstrumentationRuntimeCreateInstance create_callback; 2006 InstrumentationRuntimeGetType get_type_callback; 2007 }; 2008 2009 typedef std::vector<InstrumentationRuntimeInstance> 2010 InstrumentationRuntimeInstances; 2011 2012 static std::recursive_mutex &GetInstrumentationRuntimeMutex() { 2013 static std::recursive_mutex g_instances_mutex; 2014 return g_instances_mutex; 2015 } 2016 2017 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { 2018 static InstrumentationRuntimeInstances g_instances; 2019 return g_instances; 2020 } 2021 2022 bool PluginManager::RegisterPlugin( 2023 const ConstString &name, const char *description, 2024 InstrumentationRuntimeCreateInstance create_callback, 2025 InstrumentationRuntimeGetType get_type_callback) { 2026 if (create_callback) { 2027 InstrumentationRuntimeInstance instance; 2028 assert((bool)name); 2029 instance.name = name; 2030 if (description && description[0]) 2031 instance.description = description; 2032 instance.create_callback = create_callback; 2033 instance.get_type_callback = get_type_callback; 2034 std::lock_guard<std::recursive_mutex> guard( 2035 GetInstrumentationRuntimeMutex()); 2036 GetInstrumentationRuntimeInstances().push_back(instance); 2037 } 2038 return false; 2039 } 2040 2041 bool PluginManager::UnregisterPlugin( 2042 InstrumentationRuntimeCreateInstance create_callback) { 2043 if (create_callback) { 2044 std::lock_guard<std::recursive_mutex> guard( 2045 GetInstrumentationRuntimeMutex()); 2046 InstrumentationRuntimeInstances &instances = 2047 GetInstrumentationRuntimeInstances(); 2048 2049 InstrumentationRuntimeInstances::iterator pos, end = instances.end(); 2050 for (pos = instances.begin(); pos != end; ++pos) { 2051 if (pos->create_callback == create_callback) { 2052 instances.erase(pos); 2053 return true; 2054 } 2055 } 2056 } 2057 return false; 2058 } 2059 2060 InstrumentationRuntimeGetType 2061 PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { 2062 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex()); 2063 InstrumentationRuntimeInstances &instances = 2064 GetInstrumentationRuntimeInstances(); 2065 if (idx < instances.size()) 2066 return instances[idx].get_type_callback; 2067 return nullptr; 2068 } 2069 2070 InstrumentationRuntimeCreateInstance 2071 PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { 2072 std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex()); 2073 InstrumentationRuntimeInstances &instances = 2074 GetInstrumentationRuntimeInstances(); 2075 if (idx < instances.size()) 2076 return instances[idx].create_callback; 2077 return nullptr; 2078 } 2079 2080 InstrumentationRuntimeCreateInstance 2081 PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName( 2082 const ConstString &name) { 2083 if (name) { 2084 std::lock_guard<std::recursive_mutex> guard( 2085 GetInstrumentationRuntimeMutex()); 2086 InstrumentationRuntimeInstances &instances = 2087 GetInstrumentationRuntimeInstances(); 2088 2089 InstrumentationRuntimeInstances::iterator pos, end = instances.end(); 2090 for (pos = instances.begin(); pos != end; ++pos) { 2091 if (name == pos->name) 2092 return pos->create_callback; 2093 } 2094 } 2095 return nullptr; 2096 } 2097 2098 #pragma mark TypeSystem 2099 2100 struct TypeSystemInstance { 2101 TypeSystemInstance() : name(), description(), create_callback(nullptr) {} 2102 2103 ConstString name; 2104 std::string description; 2105 TypeSystemCreateInstance create_callback; 2106 TypeSystemEnumerateSupportedLanguages enumerate_callback; 2107 }; 2108 2109 typedef std::vector<TypeSystemInstance> TypeSystemInstances; 2110 2111 static std::recursive_mutex &GetTypeSystemMutex() { 2112 static std::recursive_mutex g_instances_mutex; 2113 return g_instances_mutex; 2114 } 2115 2116 static TypeSystemInstances &GetTypeSystemInstances() { 2117 static TypeSystemInstances g_instances; 2118 return g_instances; 2119 } 2120 2121 bool PluginManager::RegisterPlugin(const ConstString &name, 2122 const char *description, 2123 TypeSystemCreateInstance create_callback, 2124 TypeSystemEnumerateSupportedLanguages 2125 enumerate_supported_languages_callback) { 2126 if (create_callback) { 2127 TypeSystemInstance instance; 2128 assert((bool)name); 2129 instance.name = name; 2130 if (description && description[0]) 2131 instance.description = description; 2132 instance.create_callback = create_callback; 2133 instance.enumerate_callback = enumerate_supported_languages_callback; 2134 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2135 GetTypeSystemInstances().push_back(instance); 2136 } 2137 return false; 2138 } 2139 2140 bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) { 2141 if (create_callback) { 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 (pos->create_callback == create_callback) { 2148 instances.erase(pos); 2149 return true; 2150 } 2151 } 2152 } 2153 return false; 2154 } 2155 2156 TypeSystemCreateInstance 2157 PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) { 2158 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2159 TypeSystemInstances &instances = GetTypeSystemInstances(); 2160 if (idx < instances.size()) 2161 return instances[idx].create_callback; 2162 return nullptr; 2163 } 2164 2165 TypeSystemCreateInstance 2166 PluginManager::GetTypeSystemCreateCallbackForPluginName( 2167 const ConstString &name) { 2168 if (name) { 2169 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2170 TypeSystemInstances &instances = GetTypeSystemInstances(); 2171 2172 TypeSystemInstances::iterator pos, end = instances.end(); 2173 for (pos = instances.begin(); pos != end; ++pos) { 2174 if (name == pos->name) 2175 return pos->create_callback; 2176 } 2177 } 2178 return nullptr; 2179 } 2180 2181 TypeSystemEnumerateSupportedLanguages 2182 PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex( 2183 uint32_t idx) { 2184 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2185 TypeSystemInstances &instances = GetTypeSystemInstances(); 2186 if (idx < instances.size()) 2187 return instances[idx].enumerate_callback; 2188 return nullptr; 2189 } 2190 2191 TypeSystemEnumerateSupportedLanguages 2192 PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName( 2193 const ConstString &name) { 2194 if (name) { 2195 std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); 2196 TypeSystemInstances &instances = GetTypeSystemInstances(); 2197 2198 TypeSystemInstances::iterator pos, end = instances.end(); 2199 for (pos = instances.begin(); pos != end; ++pos) { 2200 if (name == pos->name) 2201 return pos->enumerate_callback; 2202 } 2203 } 2204 return nullptr; 2205 } 2206 2207 #pragma mark REPL 2208 2209 struct REPLInstance { 2210 REPLInstance() : name(), description(), create_callback(nullptr) {} 2211 2212 ConstString name; 2213 std::string description; 2214 REPLCreateInstance create_callback; 2215 REPLEnumerateSupportedLanguages enumerate_languages_callback; 2216 }; 2217 2218 typedef std::vector<REPLInstance> REPLInstances; 2219 2220 static std::recursive_mutex &GetREPLMutex() { 2221 static std::recursive_mutex g_instances_mutex; 2222 return g_instances_mutex; 2223 } 2224 2225 static REPLInstances &GetREPLInstances() { 2226 static REPLInstances g_instances; 2227 return g_instances; 2228 } 2229 2230 bool PluginManager::RegisterPlugin( 2231 const ConstString &name, const char *description, 2232 REPLCreateInstance create_callback, 2233 REPLEnumerateSupportedLanguages enumerate_languages_callback) { 2234 if (create_callback) { 2235 REPLInstance instance; 2236 assert((bool)name); 2237 instance.name = name; 2238 if (description && description[0]) 2239 instance.description = description; 2240 instance.create_callback = create_callback; 2241 instance.enumerate_languages_callback = enumerate_languages_callback; 2242 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2243 GetREPLInstances().push_back(instance); 2244 } 2245 return false; 2246 } 2247 2248 bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) { 2249 if (create_callback) { 2250 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2251 REPLInstances &instances = GetREPLInstances(); 2252 2253 REPLInstances::iterator pos, end = instances.end(); 2254 for (pos = instances.begin(); pos != end; ++pos) { 2255 if (pos->create_callback == create_callback) { 2256 instances.erase(pos); 2257 return true; 2258 } 2259 } 2260 } 2261 return false; 2262 } 2263 2264 REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) { 2265 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2266 REPLInstances &instances = GetREPLInstances(); 2267 if (idx < instances.size()) 2268 return instances[idx].create_callback; 2269 return nullptr; 2270 } 2271 2272 REPLCreateInstance 2273 PluginManager::GetREPLCreateCallbackForPluginName(const ConstString &name) { 2274 if (name) { 2275 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2276 REPLInstances &instances = GetREPLInstances(); 2277 2278 REPLInstances::iterator pos, end = instances.end(); 2279 for (pos = instances.begin(); pos != end; ++pos) { 2280 if (name == pos->name) 2281 return pos->create_callback; 2282 } 2283 } 2284 return nullptr; 2285 } 2286 2287 REPLEnumerateSupportedLanguages 2288 PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) { 2289 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2290 REPLInstances &instances = GetREPLInstances(); 2291 if (idx < instances.size()) 2292 return instances[idx].enumerate_languages_callback; 2293 return nullptr; 2294 } 2295 2296 REPLEnumerateSupportedLanguages 2297 PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName( 2298 const ConstString &name) { 2299 if (name) { 2300 std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); 2301 REPLInstances &instances = GetREPLInstances(); 2302 2303 REPLInstances::iterator pos, end = instances.end(); 2304 for (pos = instances.begin(); pos != end; ++pos) { 2305 if (name == pos->name) 2306 return pos->enumerate_languages_callback; 2307 } 2308 } 2309 return nullptr; 2310 } 2311 2312 #pragma mark PluginManager 2313 2314 void PluginManager::DebuggerInitialize(Debugger &debugger) { 2315 // Initialize the DynamicLoader plugins 2316 { 2317 std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); 2318 DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); 2319 2320 DynamicLoaderInstances::iterator pos, end = instances.end(); 2321 for (pos = instances.begin(); pos != end; ++pos) { 2322 if (pos->debugger_init_callback) 2323 pos->debugger_init_callback(debugger); 2324 } 2325 } 2326 2327 // Initialize the JITLoader plugins 2328 { 2329 std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); 2330 JITLoaderInstances &instances = GetJITLoaderInstances(); 2331 2332 JITLoaderInstances::iterator pos, end = instances.end(); 2333 for (pos = instances.begin(); pos != end; ++pos) { 2334 if (pos->debugger_init_callback) 2335 pos->debugger_init_callback(debugger); 2336 } 2337 } 2338 2339 // Initialize the Platform plugins 2340 { 2341 std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); 2342 PlatformInstances &instances = GetPlatformInstances(); 2343 2344 PlatformInstances::iterator pos, end = instances.end(); 2345 for (pos = instances.begin(); pos != end; ++pos) { 2346 if (pos->debugger_init_callback) 2347 pos->debugger_init_callback(debugger); 2348 } 2349 } 2350 2351 // Initialize the Process plugins 2352 { 2353 std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); 2354 ProcessInstances &instances = GetProcessInstances(); 2355 2356 ProcessInstances::iterator pos, end = instances.end(); 2357 for (pos = instances.begin(); pos != end; ++pos) { 2358 if (pos->debugger_init_callback) 2359 pos->debugger_init_callback(debugger); 2360 } 2361 } 2362 2363 // Initialize the SymbolFile plugins 2364 { 2365 std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); 2366 for (auto &sym_file : GetSymbolFileInstances()) { 2367 if (sym_file.debugger_init_callback) 2368 sym_file.debugger_init_callback(debugger); 2369 } 2370 } 2371 2372 // Initialize the OperatingSystem plugins 2373 { 2374 std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); 2375 for (auto &os : GetOperatingSystemInstances()) { 2376 if (os.debugger_init_callback) 2377 os.debugger_init_callback(debugger); 2378 } 2379 } 2380 2381 // Initialize the StructuredDataPlugin plugins 2382 { 2383 std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); 2384 for (auto &plugin : GetStructuredDataPluginInstances()) { 2385 if (plugin.debugger_init_callback) 2386 plugin.debugger_init_callback(debugger); 2387 } 2388 } 2389 } 2390 2391 // This is the preferred new way to register plugin specific settings. e.g. 2392 // This will put a plugin's settings under e.g. 2393 // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". 2394 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins( 2395 Debugger &debugger, const ConstString &plugin_type_name, 2396 const ConstString &plugin_type_desc, bool can_create) { 2397 lldb::OptionValuePropertiesSP parent_properties_sp( 2398 debugger.GetValueProperties()); 2399 if (parent_properties_sp) { 2400 static ConstString g_property_name("plugin"); 2401 2402 OptionValuePropertiesSP plugin_properties_sp = 2403 parent_properties_sp->GetSubProperty(nullptr, g_property_name); 2404 if (!plugin_properties_sp && can_create) { 2405 plugin_properties_sp.reset(new OptionValueProperties(g_property_name)); 2406 parent_properties_sp->AppendProperty( 2407 g_property_name, ConstString("Settings specify to plugins."), true, 2408 plugin_properties_sp); 2409 } 2410 2411 if (plugin_properties_sp) { 2412 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 2413 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name); 2414 if (!plugin_type_properties_sp && can_create) { 2415 plugin_type_properties_sp.reset( 2416 new OptionValueProperties(plugin_type_name)); 2417 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 2418 true, plugin_type_properties_sp); 2419 } 2420 return plugin_type_properties_sp; 2421 } 2422 } 2423 return lldb::OptionValuePropertiesSP(); 2424 } 2425 2426 // This is deprecated way to register plugin specific settings. e.g. 2427 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" 2428 // and Platform generic settings would be under "platform.SETTINGNAME". 2429 static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( 2430 Debugger &debugger, const ConstString &plugin_type_name, 2431 const ConstString &plugin_type_desc, bool can_create) { 2432 static ConstString g_property_name("plugin"); 2433 lldb::OptionValuePropertiesSP parent_properties_sp( 2434 debugger.GetValueProperties()); 2435 if (parent_properties_sp) { 2436 OptionValuePropertiesSP plugin_properties_sp = 2437 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name); 2438 if (!plugin_properties_sp && can_create) { 2439 plugin_properties_sp.reset(new OptionValueProperties(plugin_type_name)); 2440 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, 2441 true, plugin_properties_sp); 2442 } 2443 2444 if (plugin_properties_sp) { 2445 lldb::OptionValuePropertiesSP plugin_type_properties_sp = 2446 plugin_properties_sp->GetSubProperty(nullptr, g_property_name); 2447 if (!plugin_type_properties_sp && can_create) { 2448 plugin_type_properties_sp.reset( 2449 new OptionValueProperties(g_property_name)); 2450 plugin_properties_sp->AppendProperty( 2451 g_property_name, ConstString("Settings specific to plugins"), true, 2452 plugin_type_properties_sp); 2453 } 2454 return plugin_type_properties_sp; 2455 } 2456 } 2457 return lldb::OptionValuePropertiesSP(); 2458 } 2459 2460 namespace { 2461 2462 typedef lldb::OptionValuePropertiesSP 2463 GetDebuggerPropertyForPluginsPtr(Debugger &, const ConstString &, 2464 const ConstString &, bool can_create); 2465 2466 lldb::OptionValuePropertiesSP 2467 GetSettingForPlugin(Debugger &debugger, const ConstString &setting_name, 2468 const ConstString &plugin_type_name, 2469 GetDebuggerPropertyForPluginsPtr get_debugger_property = 2470 GetDebuggerPropertyForPlugins) { 2471 lldb::OptionValuePropertiesSP properties_sp; 2472 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property( 2473 debugger, plugin_type_name, 2474 ConstString(), // not creating to so we don't need the description 2475 false)); 2476 if (plugin_type_properties_sp) 2477 properties_sp = 2478 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 2479 return properties_sp; 2480 } 2481 2482 bool CreateSettingForPlugin( 2483 Debugger &debugger, const ConstString &plugin_type_name, 2484 const ConstString &plugin_type_desc, 2485 const lldb::OptionValuePropertiesSP &properties_sp, 2486 const ConstString &description, bool is_global_property, 2487 GetDebuggerPropertyForPluginsPtr get_debugger_property = 2488 GetDebuggerPropertyForPlugins) { 2489 if (properties_sp) { 2490 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2491 get_debugger_property(debugger, plugin_type_name, plugin_type_desc, 2492 true)); 2493 if (plugin_type_properties_sp) { 2494 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 2495 description, is_global_property, 2496 properties_sp); 2497 return true; 2498 } 2499 } 2500 return false; 2501 } 2502 2503 const char *kDynamicLoaderPluginName("dynamic-loader"); 2504 const char *kPlatformPluginName("platform"); 2505 const char *kProcessPluginName("process"); 2506 const char *kSymbolFilePluginName("symbol-file"); 2507 const char *kJITLoaderPluginName("jit-loader"); 2508 const char *kStructuredDataPluginName("structured-data"); 2509 2510 } // anonymous namespace 2511 2512 lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin( 2513 Debugger &debugger, const ConstString &setting_name) { 2514 return GetSettingForPlugin(debugger, setting_name, 2515 ConstString(kDynamicLoaderPluginName)); 2516 } 2517 2518 bool PluginManager::CreateSettingForDynamicLoaderPlugin( 2519 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2520 const ConstString &description, bool is_global_property) { 2521 return CreateSettingForPlugin( 2522 debugger, ConstString(kDynamicLoaderPluginName), 2523 ConstString("Settings for dynamic loader plug-ins"), properties_sp, 2524 description, is_global_property); 2525 } 2526 2527 lldb::OptionValuePropertiesSP 2528 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger, 2529 const ConstString &setting_name) { 2530 return GetSettingForPlugin(debugger, setting_name, 2531 ConstString(kPlatformPluginName), 2532 GetDebuggerPropertyForPluginsOldStyle); 2533 } 2534 2535 bool PluginManager::CreateSettingForPlatformPlugin( 2536 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2537 const ConstString &description, bool is_global_property) { 2538 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName), 2539 ConstString("Settings for platform plug-ins"), 2540 properties_sp, description, is_global_property, 2541 GetDebuggerPropertyForPluginsOldStyle); 2542 } 2543 2544 lldb::OptionValuePropertiesSP 2545 PluginManager::GetSettingForProcessPlugin(Debugger &debugger, 2546 const ConstString &setting_name) { 2547 return GetSettingForPlugin(debugger, setting_name, 2548 ConstString(kProcessPluginName)); 2549 } 2550 2551 bool PluginManager::CreateSettingForProcessPlugin( 2552 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2553 const ConstString &description, bool is_global_property) { 2554 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName), 2555 ConstString("Settings for process plug-ins"), 2556 properties_sp, description, is_global_property); 2557 } 2558 2559 lldb::OptionValuePropertiesSP 2560 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger, 2561 const ConstString &setting_name) { 2562 return GetSettingForPlugin(debugger, setting_name, 2563 ConstString(kSymbolFilePluginName)); 2564 } 2565 2566 bool PluginManager::CreateSettingForSymbolFilePlugin( 2567 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2568 const ConstString &description, bool is_global_property) { 2569 return CreateSettingForPlugin( 2570 debugger, ConstString(kSymbolFilePluginName), 2571 ConstString("Settings for symbol file plug-ins"), properties_sp, 2572 description, is_global_property); 2573 } 2574 2575 lldb::OptionValuePropertiesSP 2576 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger, 2577 const ConstString &setting_name) { 2578 return GetSettingForPlugin(debugger, setting_name, 2579 ConstString(kJITLoaderPluginName)); 2580 } 2581 2582 bool PluginManager::CreateSettingForJITLoaderPlugin( 2583 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2584 const ConstString &description, bool is_global_property) { 2585 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName), 2586 ConstString("Settings for JIT loader plug-ins"), 2587 properties_sp, description, is_global_property); 2588 } 2589 2590 static const char *kOperatingSystemPluginName("os"); 2591 2592 lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin( 2593 Debugger &debugger, const ConstString &setting_name) { 2594 lldb::OptionValuePropertiesSP properties_sp; 2595 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2596 GetDebuggerPropertyForPlugins( 2597 debugger, ConstString(kOperatingSystemPluginName), 2598 ConstString(), // not creating to so we don't need the description 2599 false)); 2600 if (plugin_type_properties_sp) 2601 properties_sp = 2602 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); 2603 return properties_sp; 2604 } 2605 2606 bool PluginManager::CreateSettingForOperatingSystemPlugin( 2607 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2608 const ConstString &description, bool is_global_property) { 2609 if (properties_sp) { 2610 lldb::OptionValuePropertiesSP plugin_type_properties_sp( 2611 GetDebuggerPropertyForPlugins( 2612 debugger, ConstString(kOperatingSystemPluginName), 2613 ConstString("Settings for operating system plug-ins"), true)); 2614 if (plugin_type_properties_sp) { 2615 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), 2616 description, is_global_property, 2617 properties_sp); 2618 return true; 2619 } 2620 } 2621 return false; 2622 } 2623 2624 lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin( 2625 Debugger &debugger, const ConstString &setting_name) { 2626 return GetSettingForPlugin(debugger, setting_name, 2627 ConstString(kStructuredDataPluginName)); 2628 } 2629 2630 bool PluginManager::CreateSettingForStructuredDataPlugin( 2631 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, 2632 const ConstString &description, bool is_global_property) { 2633 return CreateSettingForPlugin( 2634 debugger, ConstString(kStructuredDataPluginName), 2635 ConstString("Settings for structured data plug-ins"), properties_sp, 2636 description, is_global_property); 2637 } 2638