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