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