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