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