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