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 
38 namespace lldb_private {
39 class CommandInterpreter;
40 }
41 
42 using namespace lldb;
43 using namespace lldb_private;
44 
45 enum PluginAction {
46   ePluginRegisterInstance,
47   ePluginUnregisterInstance,
48   ePluginGetInstanceAtIndex
49 };
50 
51 typedef bool (*PluginInitCallback)();
52 typedef void (*PluginTermCallback)();
53 
54 struct PluginInfo {
55   PluginInfo() : plugin_init_callback(nullptr), plugin_term_callback(nullptr) {}
56 
57   llvm::sys::DynamicLibrary library;
58   PluginInitCallback plugin_init_callback;
59   PluginTermCallback plugin_term_callback;
60 };
61 
62 typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
63 
64 static std::recursive_mutex &GetPluginMapMutex() {
65   static std::recursive_mutex g_plugin_map_mutex;
66   return g_plugin_map_mutex;
67 }
68 
69 static PluginTerminateMap &GetPluginMap() {
70   static PluginTerminateMap g_plugin_map;
71   return g_plugin_map;
72 }
73 
74 static bool PluginIsLoaded(const FileSpec &plugin_file_spec) {
75   std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
76   PluginTerminateMap &plugin_map = GetPluginMap();
77   return plugin_map.find(plugin_file_spec) != plugin_map.end();
78 }
79 
80 static void SetPluginInfo(const FileSpec &plugin_file_spec,
81                           const PluginInfo &plugin_info) {
82   std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
83   PluginTerminateMap &plugin_map = GetPluginMap();
84   assert(plugin_map.find(plugin_file_spec) == plugin_map.end());
85   plugin_map[plugin_file_spec] = plugin_info;
86 }
87 
88 template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
89   return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
90 }
91 
92 static FileSpec::EnumerateDirectoryResult
93 LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
94                    const FileSpec &file_spec) {
95   //    PluginManager *plugin_manager = (PluginManager *)baton;
96   Status error;
97 
98   namespace fs = llvm::sys::fs;
99   // If we have a regular file, a symbolic link or unknown file type, try
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 
161 void 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 
184 void 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 
202 struct ABIInstance {
203   ABIInstance() : name(), description(), create_callback(nullptr) {}
204 
205   ConstString name;
206   std::string description;
207   ABICreateInstance create_callback;
208 };
209 
210 typedef std::vector<ABIInstance> ABIInstances;
211 
212 static std::recursive_mutex &GetABIInstancesMutex() {
213   static std::recursive_mutex g_instances_mutex;
214   return g_instances_mutex;
215 }
216 
217 static ABIInstances &GetABIInstances() {
218   static ABIInstances g_instances;
219   return g_instances;
220 }
221 
222 bool 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 
239 bool 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 
255 ABICreateInstance 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 
263 ABICreateInstance
264 PluginManager::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 
280 struct DisassemblerInstance {
281   DisassemblerInstance() : name(), description(), create_callback(nullptr) {}
282 
283   ConstString name;
284   std::string description;
285   DisassemblerCreateInstance create_callback;
286 };
287 
288 typedef std::vector<DisassemblerInstance> DisassemblerInstances;
289 
290 static std::recursive_mutex &GetDisassemblerMutex() {
291   static std::recursive_mutex g_instances_mutex;
292   return g_instances_mutex;
293 }
294 
295 static DisassemblerInstances &GetDisassemblerInstances() {
296   static DisassemblerInstances g_instances;
297   return g_instances;
298 }
299 
300 bool 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 
317 bool 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 
334 DisassemblerCreateInstance
335 PluginManager::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 
343 DisassemblerCreateInstance
344 PluginManager::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 
361 struct 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 
372 typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
373 
374 static std::recursive_mutex &GetDynamicLoaderMutex() {
375   static std::recursive_mutex g_instances_mutex;
376   return g_instances_mutex;
377 }
378 
379 static DynamicLoaderInstances &GetDynamicLoaderInstances() {
380   static DynamicLoaderInstances g_instances;
381   return g_instances;
382 }
383 
384 bool 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 
402 bool 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 
419 DynamicLoaderCreateInstance
420 PluginManager::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 
428 DynamicLoaderCreateInstance
429 PluginManager::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 
446 struct 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 
457 typedef std::vector<JITLoaderInstance> JITLoaderInstances;
458 
459 static std::recursive_mutex &GetJITLoaderMutex() {
460   static std::recursive_mutex g_instances_mutex;
461   return g_instances_mutex;
462 }
463 
464 static JITLoaderInstances &GetJITLoaderInstances() {
465   static JITLoaderInstances g_instances;
466   return g_instances;
467 }
468 
469 bool 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 
487 bool 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 
503 JITLoaderCreateInstance
504 PluginManager::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 
512 JITLoaderCreateInstance 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 
529 struct EmulateInstructionInstance {
530   EmulateInstructionInstance()
531       : name(), description(), create_callback(nullptr) {}
532 
533   ConstString name;
534   std::string description;
535   EmulateInstructionCreateInstance create_callback;
536 };
537 
538 typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
539 
540 static std::recursive_mutex &GetEmulateInstructionMutex() {
541   static std::recursive_mutex g_instances_mutex;
542   return g_instances_mutex;
543 }
544 
545 static EmulateInstructionInstances &GetEmulateInstructionInstances() {
546   static EmulateInstructionInstances g_instances;
547   return g_instances;
548 }
549 
550 bool 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 
566 bool 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 
583 EmulateInstructionCreateInstance
584 PluginManager::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 
592 EmulateInstructionCreateInstance
593 PluginManager::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 
610 struct 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 
621 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
622 
623 static std::recursive_mutex &GetOperatingSystemMutex() {
624   static std::recursive_mutex g_instances_mutex;
625   return g_instances_mutex;
626 }
627 
628 static OperatingSystemInstances &GetOperatingSystemInstances() {
629   static OperatingSystemInstances g_instances;
630   return g_instances;
631 }
632 
633 bool 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 
651 bool 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 
668 OperatingSystemCreateInstance
669 PluginManager::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 
677 OperatingSystemCreateInstance
678 PluginManager::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 
695 struct LanguageInstance {
696   LanguageInstance() : name(), description(), create_callback(nullptr) {}
697 
698   ConstString name;
699   std::string description;
700   LanguageCreateInstance create_callback;
701 };
702 
703 typedef std::vector<LanguageInstance> LanguageInstances;
704 
705 static std::recursive_mutex &GetLanguageMutex() {
706   static std::recursive_mutex g_instances_mutex;
707   return g_instances_mutex;
708 }
709 
710 static LanguageInstances &GetLanguageInstances() {
711   static LanguageInstances g_instances;
712   return g_instances;
713 }
714 
715 bool 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 
731 bool 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 
747 LanguageCreateInstance
748 PluginManager::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 
756 LanguageCreateInstance
757 PluginManager::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 
773 struct 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 
782 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
783 
784 static std::recursive_mutex &GetLanguageRuntimeMutex() {
785   static std::recursive_mutex g_instances_mutex;
786   return g_instances_mutex;
787 }
788 
789 static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
790   static LanguageRuntimeInstances g_instances;
791   return g_instances;
792 }
793 
794 bool 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 
812 bool 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 
829 LanguageRuntimeCreateInstance
830 PluginManager::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 
838 LanguageRuntimeGetCommandObject
839 PluginManager::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 
847 LanguageRuntimeCreateInstance
848 PluginManager::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 
865 struct SystemRuntimeInstance {
866   SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {}
867 
868   ConstString name;
869   std::string description;
870   SystemRuntimeCreateInstance create_callback;
871 };
872 
873 typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
874 
875 static std::recursive_mutex &GetSystemRuntimeMutex() {
876   static std::recursive_mutex g_instances_mutex;
877   return g_instances_mutex;
878 }
879 
880 static SystemRuntimeInstances &GetSystemRuntimeInstances() {
881   static SystemRuntimeInstances g_instances;
882   return g_instances;
883 }
884 
885 bool 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 
901 bool 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 
918 SystemRuntimeCreateInstance
919 PluginManager::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 
927 SystemRuntimeCreateInstance
928 PluginManager::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 
945 struct 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 
959 typedef std::vector<ObjectFileInstance> ObjectFileInstances;
960 
961 static std::recursive_mutex &GetObjectFileMutex() {
962   static std::recursive_mutex g_instances_mutex;
963   return g_instances_mutex;
964 }
965 
966 static ObjectFileInstances &GetObjectFileInstances() {
967   static ObjectFileInstances g_instances;
968   return g_instances;
969 }
970 
971 bool 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 
993 bool 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 
1009 ObjectFileCreateInstance
1010 PluginManager::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 
1018 ObjectFileCreateMemoryInstance
1019 PluginManager::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 
1027 ObjectFileGetModuleSpecifications
1028 PluginManager::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 
1037 ObjectFileCreateInstance
1038 PluginManager::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 
1053 ObjectFileCreateMemoryInstance
1054 PluginManager::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 
1069 Status 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 
1087 struct 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 
1098 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1099 
1100 static std::recursive_mutex &GetObjectContainerMutex() {
1101   static std::recursive_mutex g_instances_mutex;
1102   return g_instances_mutex;
1103 }
1104 
1105 static ObjectContainerInstances &GetObjectContainerInstances() {
1106   static ObjectContainerInstances g_instances;
1107   return g_instances;
1108 }
1109 
1110 bool 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 
1128 bool 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 
1145 ObjectContainerCreateInstance
1146 PluginManager::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 
1154 ObjectContainerCreateInstance
1155 PluginManager::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 
1170 ObjectFileGetModuleSpecifications
1171 PluginManager::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 
1182 struct 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 
1193 typedef std::vector<PlatformInstance> PlatformInstances;
1194 
1195 static std::recursive_mutex &GetPlatformInstancesMutex() {
1196   static std::recursive_mutex g_platform_instances_mutex;
1197   return g_platform_instances_mutex;
1198 }
1199 
1200 static PlatformInstances &GetPlatformInstances() {
1201   static PlatformInstances g_platform_instances;
1202   return g_platform_instances;
1203 }
1204 
1205 bool 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 
1225 const 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 
1233 const 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 
1241 bool 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 
1257 PlatformCreateInstance
1258 PluginManager::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 
1266 PlatformCreateInstance
1267 PluginManager::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 
1281 size_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 
1301 struct 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 
1312 typedef std::vector<ProcessInstance> ProcessInstances;
1313 
1314 static std::recursive_mutex &GetProcessMutex() {
1315   static std::recursive_mutex g_instances_mutex;
1316   return g_instances_mutex;
1317 }
1318 
1319 static ProcessInstances &GetProcessInstances() {
1320   static ProcessInstances g_instances;
1321   return g_instances;
1322 }
1323 
1324 bool 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 
1342 const 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 
1350 const 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 
1358 bool 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 
1374 ProcessCreateInstance
1375 PluginManager::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 
1383 ProcessCreateInstance
1384 PluginManager::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 
1400 struct 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 
1411 typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
1412 
1413 static std::recursive_mutex &GetScriptInterpreterMutex() {
1414   static std::recursive_mutex g_instances_mutex;
1415   return g_instances_mutex;
1416 }
1417 
1418 static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
1419   static ScriptInterpreterInstances g_instances;
1420   return g_instances;
1421 }
1422 
1423 bool 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 
1441 bool 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 
1459 ScriptInterpreterCreateInstance
1460 PluginManager::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 
1468 lldb::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 
1495 struct 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 
1507 typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;
1508 
1509 static std::recursive_mutex &GetStructuredDataPluginMutex() {
1510   static std::recursive_mutex g_instances_mutex;
1511   return g_instances_mutex;
1512 }
1513 
1514 static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
1515   static StructuredDataPluginInstances g_instances;
1516   return g_instances;
1517 }
1518 
1519 bool 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 
1539 bool 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 
1557 StructuredDataPluginCreateInstance
1558 PluginManager::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 
1566 StructuredDataPluginCreateInstance
1567 PluginManager::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 
1583 StructuredDataFilterLaunchInfo
1584 PluginManager::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 
1599 struct 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 
1610 typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1611 
1612 static std::recursive_mutex &GetSymbolFileMutex() {
1613   static std::recursive_mutex g_instances_mutex;
1614   return g_instances_mutex;
1615 }
1616 
1617 static SymbolFileInstances &GetSymbolFileInstances() {
1618   static SymbolFileInstances g_instances;
1619   return g_instances;
1620 }
1621 
1622 bool 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 
1640 bool 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 
1656 SymbolFileCreateInstance
1657 PluginManager::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 
1665 SymbolFileCreateInstance
1666 PluginManager::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 
1683 struct SymbolVendorInstance {
1684   SymbolVendorInstance() : name(), description(), create_callback(nullptr) {}
1685 
1686   ConstString name;
1687   std::string description;
1688   SymbolVendorCreateInstance create_callback;
1689 };
1690 
1691 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1692 
1693 static std::recursive_mutex &GetSymbolVendorMutex() {
1694   static std::recursive_mutex g_instances_mutex;
1695   return g_instances_mutex;
1696 }
1697 
1698 static SymbolVendorInstances &GetSymbolVendorInstances() {
1699   static SymbolVendorInstances g_instances;
1700   return g_instances;
1701 }
1702 
1703 bool 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 
1719 bool 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 
1736 SymbolVendorCreateInstance
1737 PluginManager::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 
1745 SymbolVendorCreateInstance
1746 PluginManager::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 
1763 struct UnwindAssemblyInstance {
1764   UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {}
1765 
1766   ConstString name;
1767   std::string description;
1768   UnwindAssemblyCreateInstance create_callback;
1769 };
1770 
1771 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
1772 
1773 static std::recursive_mutex &GetUnwindAssemblyMutex() {
1774   static std::recursive_mutex g_instances_mutex;
1775   return g_instances_mutex;
1776 }
1777 
1778 static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1779   static UnwindAssemblyInstances g_instances;
1780   return g_instances;
1781 }
1782 
1783 bool 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 
1799 bool 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 
1816 UnwindAssemblyCreateInstance
1817 PluginManager::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 
1825 UnwindAssemblyCreateInstance
1826 PluginManager::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 
1843 struct MemoryHistoryInstance {
1844   MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {}
1845 
1846   ConstString name;
1847   std::string description;
1848   MemoryHistoryCreateInstance create_callback;
1849 };
1850 
1851 typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
1852 
1853 static std::recursive_mutex &GetMemoryHistoryMutex() {
1854   static std::recursive_mutex g_instances_mutex;
1855   return g_instances_mutex;
1856 }
1857 
1858 static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1859   static MemoryHistoryInstances g_instances;
1860   return g_instances;
1861 }
1862 
1863 bool 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 
1879 bool 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 
1896 MemoryHistoryCreateInstance
1897 PluginManager::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 
1905 MemoryHistoryCreateInstance
1906 PluginManager::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 
1923 struct 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 
1933 typedef std::vector<InstrumentationRuntimeInstance>
1934     InstrumentationRuntimeInstances;
1935 
1936 static std::recursive_mutex &GetInstrumentationRuntimeMutex() {
1937   static std::recursive_mutex g_instances_mutex;
1938   return g_instances_mutex;
1939 }
1940 
1941 static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1942   static InstrumentationRuntimeInstances g_instances;
1943   return g_instances;
1944 }
1945 
1946 bool 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 
1965 bool 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 
1984 InstrumentationRuntimeGetType
1985 PluginManager::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 
1994 InstrumentationRuntimeCreateInstance
1995 PluginManager::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 
2004 InstrumentationRuntimeCreateInstance
2005 PluginManager::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 
2024 struct 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 
2033 typedef std::vector<TypeSystemInstance> TypeSystemInstances;
2034 
2035 static std::recursive_mutex &GetTypeSystemMutex() {
2036   static std::recursive_mutex g_instances_mutex;
2037   return g_instances_mutex;
2038 }
2039 
2040 static TypeSystemInstances &GetTypeSystemInstances() {
2041   static TypeSystemInstances g_instances;
2042   return g_instances;
2043 }
2044 
2045 bool 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 
2064 bool 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 
2080 TypeSystemCreateInstance
2081 PluginManager::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 
2089 TypeSystemCreateInstance
2090 PluginManager::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 
2105 TypeSystemEnumerateSupportedLanguages
2106 PluginManager::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 
2115 TypeSystemEnumerateSupportedLanguages
2116 PluginManager::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 
2133 struct 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 
2142 typedef std::vector<REPLInstance> REPLInstances;
2143 
2144 static std::recursive_mutex &GetREPLMutex() {
2145   static std::recursive_mutex g_instances_mutex;
2146   return g_instances_mutex;
2147 }
2148 
2149 static REPLInstances &GetREPLInstances() {
2150   static REPLInstances g_instances;
2151   return g_instances;
2152 }
2153 
2154 bool 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 
2172 bool 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 
2188 REPLCreateInstance 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 
2196 REPLCreateInstance
2197 PluginManager::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 
2211 REPLEnumerateSupportedLanguages
2212 PluginManager::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 
2220 REPLEnumerateSupportedLanguages
2221 PluginManager::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 
2238 void 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".
2318 static 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".
2354 static 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 
2386 namespace {
2387 
2388 typedef lldb::OptionValuePropertiesSP
2389 GetDebuggerPropertyForPluginsPtr(Debugger &, const ConstString &,
2390                                  const ConstString &, bool can_create);
2391 
2392 lldb::OptionValuePropertiesSP
2393 GetSettingForPlugin(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 
2408 bool 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 
2429 const char *kDynamicLoaderPluginName("dynamic-loader");
2430 const char *kPlatformPluginName("platform");
2431 const char *kProcessPluginName("process");
2432 const char *kSymbolFilePluginName("symbol-file");
2433 const char *kJITLoaderPluginName("jit-loader");
2434 const char *kStructuredDataPluginName("structured-data");
2435 
2436 } // anonymous namespace
2437 
2438 lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(
2439     Debugger &debugger, const ConstString &setting_name) {
2440   return GetSettingForPlugin(debugger, setting_name,
2441                              ConstString(kDynamicLoaderPluginName));
2442 }
2443 
2444 bool 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 
2453 lldb::OptionValuePropertiesSP
2454 PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
2455                                            const ConstString &setting_name) {
2456   return GetSettingForPlugin(debugger, setting_name,
2457                              ConstString(kPlatformPluginName),
2458                              GetDebuggerPropertyForPluginsOldStyle);
2459 }
2460 
2461 bool 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 
2470 lldb::OptionValuePropertiesSP
2471 PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
2472                                           const ConstString &setting_name) {
2473   return GetSettingForPlugin(debugger, setting_name,
2474                              ConstString(kProcessPluginName));
2475 }
2476 
2477 bool 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 
2485 lldb::OptionValuePropertiesSP
2486 PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
2487                                              const ConstString &setting_name) {
2488   return GetSettingForPlugin(debugger, setting_name,
2489                              ConstString(kSymbolFilePluginName));
2490 }
2491 
2492 bool 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 
2501 lldb::OptionValuePropertiesSP
2502 PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
2503                                             const ConstString &setting_name) {
2504   return GetSettingForPlugin(debugger, setting_name,
2505                              ConstString(kJITLoaderPluginName));
2506 }
2507 
2508 bool 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 
2516 static const char *kOperatingSystemPluginName("os");
2517 
2518 lldb::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 
2532 bool 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 
2550 lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin(
2551     Debugger &debugger, const ConstString &setting_name) {
2552   return GetSettingForPlugin(debugger, setting_name,
2553                              ConstString(kStructuredDataPluginName));
2554 }
2555 
2556 bool 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