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