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/lldb-python.h"
11 
12 #include "lldb/Core/PluginManager.h"
13 
14 #include <limits.h>
15 
16 #include <string>
17 #include <vector>
18 
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/Error.h"
21 #include "lldb/Host/FileSpec.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Host/Mutex.h"
24 #include "lldb/Interpreter/OptionValueProperties.h"
25 
26 #include "llvm/ADT/StringRef.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 enum PluginAction
32 {
33     ePluginRegisterInstance,
34     ePluginUnregisterInstance,
35     ePluginGetInstanceAtIndex
36 };
37 
38 
39 typedef bool (*PluginInitCallback) (void);
40 typedef void (*PluginTermCallback) (void);
41 
42 struct PluginInfo
43 {
44     void *plugin_handle;
45     PluginInitCallback plugin_init_callback;
46     PluginTermCallback plugin_term_callback;
47 };
48 
49 typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
50 
51 static Mutex &
GetPluginMapMutex()52 GetPluginMapMutex ()
53 {
54     static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
55     return g_plugin_map_mutex;
56 }
57 
58 static PluginTerminateMap &
GetPluginMap()59 GetPluginMap ()
60 {
61     static PluginTerminateMap g_plugin_map;
62     return g_plugin_map;
63 }
64 
65 static bool
PluginIsLoaded(const FileSpec & plugin_file_spec)66 PluginIsLoaded (const FileSpec &plugin_file_spec)
67 {
68     Mutex::Locker locker (GetPluginMapMutex ());
69     PluginTerminateMap &plugin_map = GetPluginMap ();
70     return plugin_map.find (plugin_file_spec) != plugin_map.end();
71 }
72 
73 static void
SetPluginInfo(const FileSpec & plugin_file_spec,const PluginInfo & plugin_info)74 SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
75 {
76     Mutex::Locker locker (GetPluginMapMutex ());
77     PluginTerminateMap &plugin_map = GetPluginMap ();
78     assert (plugin_map.find (plugin_file_spec) == plugin_map.end());
79     plugin_map[plugin_file_spec] = plugin_info;
80 }
81 
82 
83 static FileSpec::EnumerateDirectoryResult
LoadPluginCallback(void * baton,FileSpec::FileType file_type,const FileSpec & file_spec)84 LoadPluginCallback
85 (
86     void *baton,
87     FileSpec::FileType file_type,
88     const FileSpec &file_spec
89 )
90 {
91 //    PluginManager *plugin_manager = (PluginManager *)baton;
92     Error error;
93 
94     // If we have a regular file, a symbolic link or unknown file type, try
95     // and process the file. We must handle unknown as sometimes the directory
96     // enumeration might be enumerating a file system that doesn't have correct
97     // file type information.
98     if (file_type == FileSpec::eFileTypeRegular         ||
99         file_type == FileSpec::eFileTypeSymbolicLink    ||
100         file_type == FileSpec::eFileTypeUnknown          )
101     {
102         FileSpec plugin_file_spec (file_spec);
103         plugin_file_spec.ResolvePath();
104 
105         if (PluginIsLoaded (plugin_file_spec))
106             return FileSpec::eEnumerateDirectoryResultNext;
107         else
108         {
109             PluginInfo plugin_info = { NULL, NULL, NULL };
110             uint32_t flags = Host::eDynamicLibraryOpenOptionLazy |
111                              Host::eDynamicLibraryOpenOptionLocal |
112                              Host::eDynamicLibraryOpenOptionLimitGetSymbol;
113 
114             plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, flags, error);
115             if (plugin_info.plugin_handle)
116             {
117                 bool success = false;
118                 plugin_info.plugin_init_callback = (PluginInitCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error);
119                 if (plugin_info.plugin_init_callback)
120                 {
121                     // Call the plug-in "bool LLDBPluginInitialize(void)" function
122                     success = plugin_info.plugin_init_callback();
123                 }
124 
125                 if (success)
126                 {
127                     // It is ok for the "LLDBPluginTerminate" symbol to be NULL
128                     plugin_info.plugin_term_callback = (PluginTermCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error);
129                 }
130                 else
131                 {
132                     // The initialize function returned FALSE which means the
133                     // plug-in might not be compatible, or might be too new or
134                     // too old, or might not want to run on this machine.
135                     Host::DynamicLibraryClose (plugin_info.plugin_handle);
136                     plugin_info.plugin_handle = NULL;
137                     plugin_info.plugin_init_callback = NULL;
138                 }
139 
140                 // Regardless of success or failure, cache the plug-in load
141                 // in our plug-in info so we don't try to load it again and
142                 // again.
143                 SetPluginInfo (plugin_file_spec, plugin_info);
144 
145                 return FileSpec::eEnumerateDirectoryResultNext;
146             }
147         }
148     }
149 
150     if (file_type == FileSpec::eFileTypeUnknown     ||
151         file_type == FileSpec::eFileTypeDirectory   ||
152         file_type == FileSpec::eFileTypeSymbolicLink )
153     {
154         // Try and recurse into anything that a directory or symbolic link.
155         // We must also do this for unknown as sometimes the directory enumeration
156         // might be enurating a file system that doesn't have correct file type
157         // information.
158         return FileSpec::eEnumerateDirectoryResultEnter;
159     }
160 
161     return FileSpec::eEnumerateDirectoryResultNext;
162 }
163 
164 
165 void
Initialize()166 PluginManager::Initialize ()
167 {
168 #if 1
169     FileSpec dir_spec;
170     const bool find_directories = true;
171     const bool find_files = true;
172     const bool find_other = true;
173     char dir_path[PATH_MAX];
174     if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
175     {
176         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
177         {
178             FileSpec::EnumerateDirectory (dir_path,
179                                           find_directories,
180                                           find_files,
181                                           find_other,
182                                           LoadPluginCallback,
183                                           NULL);
184         }
185     }
186 
187     if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
188     {
189         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
190         {
191             FileSpec::EnumerateDirectory (dir_path,
192                                           find_directories,
193                                           find_files,
194                                           find_other,
195                                           LoadPluginCallback,
196                                           NULL);
197         }
198     }
199 #endif
200 }
201 
202 void
Terminate()203 PluginManager::Terminate ()
204 {
205     Mutex::Locker locker (GetPluginMapMutex ());
206     PluginTerminateMap &plugin_map = GetPluginMap ();
207 
208     PluginTerminateMap::const_iterator pos, end = plugin_map.end();
209     for (pos = plugin_map.begin(); pos != end; ++pos)
210     {
211         // Call the plug-in "void LLDBPluginTerminate (void)" function if there
212         // is one (if the symbol was not NULL).
213         if (pos->second.plugin_handle)
214         {
215             if (pos->second.plugin_term_callback)
216                 pos->second.plugin_term_callback();
217             Host::DynamicLibraryClose (pos->second.plugin_handle);
218         }
219     }
220     plugin_map.clear();
221 }
222 
223 
224 #pragma mark ABI
225 
226 
227 struct ABIInstance
228 {
ABIInstanceABIInstance229     ABIInstance() :
230         name(),
231         description(),
232         create_callback(NULL)
233     {
234     }
235 
236     ConstString name;
237     std::string description;
238     ABICreateInstance create_callback;
239 };
240 
241 typedef std::vector<ABIInstance> ABIInstances;
242 
243 static Mutex &
GetABIInstancesMutex()244 GetABIInstancesMutex ()
245 {
246     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
247     return g_instances_mutex;
248 }
249 
250 static ABIInstances &
GetABIInstances()251 GetABIInstances ()
252 {
253     static ABIInstances g_instances;
254     return g_instances;
255 }
256 
257 bool
RegisterPlugin(const ConstString & name,const char * description,ABICreateInstance create_callback)258 PluginManager::RegisterPlugin
259 (
260     const ConstString &name,
261     const char *description,
262     ABICreateInstance create_callback
263 )
264 {
265     if (create_callback)
266     {
267         ABIInstance instance;
268         assert ((bool)name);
269         instance.name = name;
270         if (description && description[0])
271             instance.description = description;
272         instance.create_callback = create_callback;
273         Mutex::Locker locker (GetABIInstancesMutex ());
274         GetABIInstances ().push_back (instance);
275         return true;
276     }
277     return false;
278 }
279 
280 bool
UnregisterPlugin(ABICreateInstance create_callback)281 PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
282 {
283     if (create_callback)
284     {
285         Mutex::Locker locker (GetABIInstancesMutex ());
286         ABIInstances &instances = GetABIInstances ();
287 
288         ABIInstances::iterator pos, end = instances.end();
289         for (pos = instances.begin(); pos != end; ++ pos)
290         {
291             if (pos->create_callback == create_callback)
292             {
293                 instances.erase(pos);
294                 return true;
295             }
296         }
297     }
298     return false;
299 }
300 
301 ABICreateInstance
GetABICreateCallbackAtIndex(uint32_t idx)302 PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
303 {
304     Mutex::Locker locker (GetABIInstancesMutex ());
305     ABIInstances &instances = GetABIInstances ();
306     if (idx < instances.size())
307         return instances[idx].create_callback;
308     return NULL;
309 }
310 
311 ABICreateInstance
GetABICreateCallbackForPluginName(const ConstString & name)312 PluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
313 {
314     if (name)
315     {
316         Mutex::Locker locker (GetABIInstancesMutex ());
317         ABIInstances &instances = GetABIInstances ();
318 
319         ABIInstances::iterator pos, end = instances.end();
320         for (pos = instances.begin(); pos != end; ++ pos)
321         {
322             if (name == pos->name)
323                 return pos->create_callback;
324         }
325     }
326     return NULL;
327 }
328 
329 
330 #pragma mark Disassembler
331 
332 
333 struct DisassemblerInstance
334 {
DisassemblerInstanceDisassemblerInstance335     DisassemblerInstance() :
336         name(),
337         description(),
338         create_callback(NULL)
339     {
340     }
341 
342     ConstString name;
343     std::string description;
344     DisassemblerCreateInstance create_callback;
345 };
346 
347 typedef std::vector<DisassemblerInstance> DisassemblerInstances;
348 
349 static Mutex &
GetDisassemblerMutex()350 GetDisassemblerMutex ()
351 {
352     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
353     return g_instances_mutex;
354 }
355 
356 static DisassemblerInstances &
GetDisassemblerInstances()357 GetDisassemblerInstances ()
358 {
359     static DisassemblerInstances g_instances;
360     return g_instances;
361 }
362 
363 bool
RegisterPlugin(const ConstString & name,const char * description,DisassemblerCreateInstance create_callback)364 PluginManager::RegisterPlugin
365 (
366     const ConstString &name,
367     const char *description,
368     DisassemblerCreateInstance create_callback
369 )
370 {
371     if (create_callback)
372     {
373         DisassemblerInstance instance;
374         assert ((bool)name);
375         instance.name = name;
376         if (description && description[0])
377             instance.description = description;
378         instance.create_callback = create_callback;
379         Mutex::Locker locker (GetDisassemblerMutex ());
380         GetDisassemblerInstances ().push_back (instance);
381         return true;
382     }
383     return false;
384 }
385 
386 bool
UnregisterPlugin(DisassemblerCreateInstance create_callback)387 PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
388 {
389     if (create_callback)
390     {
391         Mutex::Locker locker (GetDisassemblerMutex ());
392         DisassemblerInstances &instances = GetDisassemblerInstances ();
393 
394         DisassemblerInstances::iterator pos, end = instances.end();
395         for (pos = instances.begin(); pos != end; ++ pos)
396         {
397             if (pos->create_callback == create_callback)
398             {
399                 instances.erase(pos);
400                 return true;
401             }
402         }
403     }
404     return false;
405 }
406 
407 DisassemblerCreateInstance
GetDisassemblerCreateCallbackAtIndex(uint32_t idx)408 PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
409 {
410     Mutex::Locker locker (GetDisassemblerMutex ());
411     DisassemblerInstances &instances = GetDisassemblerInstances ();
412     if (idx < instances.size())
413         return instances[idx].create_callback;
414     return NULL;
415 }
416 
417 DisassemblerCreateInstance
GetDisassemblerCreateCallbackForPluginName(const ConstString & name)418 PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &name)
419 {
420     if (name)
421     {
422         Mutex::Locker locker (GetDisassemblerMutex ());
423         DisassemblerInstances &instances = GetDisassemblerInstances ();
424 
425         DisassemblerInstances::iterator pos, end = instances.end();
426         for (pos = instances.begin(); pos != end; ++ pos)
427         {
428             if (name == pos->name)
429                 return pos->create_callback;
430         }
431     }
432     return NULL;
433 }
434 
435 
436 
437 #pragma mark DynamicLoader
438 
439 
440 struct DynamicLoaderInstance
441 {
DynamicLoaderInstanceDynamicLoaderInstance442     DynamicLoaderInstance() :
443         name(),
444         description(),
445         create_callback(NULL),
446         debugger_init_callback (NULL)
447     {
448     }
449 
450     ConstString name;
451     std::string description;
452     DynamicLoaderCreateInstance create_callback;
453     DebuggerInitializeCallback debugger_init_callback;
454 };
455 
456 typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
457 
458 
459 static Mutex &
GetDynamicLoaderMutex()460 GetDynamicLoaderMutex ()
461 {
462     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
463     return g_instances_mutex;
464 }
465 
466 static DynamicLoaderInstances &
GetDynamicLoaderInstances()467 GetDynamicLoaderInstances ()
468 {
469     static DynamicLoaderInstances g_instances;
470     return g_instances;
471 }
472 
473 
474 bool
RegisterPlugin(const ConstString & name,const char * description,DynamicLoaderCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)475 PluginManager::RegisterPlugin
476 (
477     const ConstString &name,
478     const char *description,
479     DynamicLoaderCreateInstance create_callback,
480     DebuggerInitializeCallback debugger_init_callback
481 )
482 {
483     if (create_callback)
484     {
485         DynamicLoaderInstance instance;
486         assert ((bool)name);
487         instance.name = name;
488         if (description && description[0])
489             instance.description = description;
490         instance.create_callback = create_callback;
491         instance.debugger_init_callback = debugger_init_callback;
492         Mutex::Locker locker (GetDynamicLoaderMutex ());
493         GetDynamicLoaderInstances ().push_back (instance);
494     }
495     return false;
496 }
497 
498 bool
UnregisterPlugin(DynamicLoaderCreateInstance create_callback)499 PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
500 {
501     if (create_callback)
502     {
503         Mutex::Locker locker (GetDynamicLoaderMutex ());
504         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
505 
506         DynamicLoaderInstances::iterator pos, end = instances.end();
507         for (pos = instances.begin(); pos != end; ++ pos)
508         {
509             if (pos->create_callback == create_callback)
510             {
511                 instances.erase(pos);
512                 return true;
513             }
514         }
515     }
516     return false;
517 }
518 
519 DynamicLoaderCreateInstance
GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx)520 PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
521 {
522     Mutex::Locker locker (GetDynamicLoaderMutex ());
523     DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
524     if (idx < instances.size())
525         return instances[idx].create_callback;
526     return NULL;
527 }
528 
529 DynamicLoaderCreateInstance
GetDynamicLoaderCreateCallbackForPluginName(const ConstString & name)530 PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name)
531 {
532     if (name)
533     {
534         Mutex::Locker locker (GetDynamicLoaderMutex ());
535         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
536 
537         DynamicLoaderInstances::iterator pos, end = instances.end();
538         for (pos = instances.begin(); pos != end; ++ pos)
539         {
540             if (name == pos->name)
541                 return pos->create_callback;
542         }
543     }
544     return NULL;
545 }
546 
547 #pragma mark EmulateInstruction
548 
549 
550 struct EmulateInstructionInstance
551 {
EmulateInstructionInstanceEmulateInstructionInstance552     EmulateInstructionInstance() :
553     name(),
554     description(),
555     create_callback(NULL)
556     {
557     }
558 
559     ConstString name;
560     std::string description;
561     EmulateInstructionCreateInstance create_callback;
562 };
563 
564 typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
565 
566 static Mutex &
GetEmulateInstructionMutex()567 GetEmulateInstructionMutex ()
568 {
569     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
570     return g_instances_mutex;
571 }
572 
573 static EmulateInstructionInstances &
GetEmulateInstructionInstances()574 GetEmulateInstructionInstances ()
575 {
576     static EmulateInstructionInstances g_instances;
577     return g_instances;
578 }
579 
580 
581 bool
RegisterPlugin(const ConstString & name,const char * description,EmulateInstructionCreateInstance create_callback)582 PluginManager::RegisterPlugin
583 (
584     const ConstString &name,
585     const char *description,
586     EmulateInstructionCreateInstance create_callback
587 )
588 {
589     if (create_callback)
590     {
591         EmulateInstructionInstance instance;
592         assert ((bool)name);
593         instance.name = name;
594         if (description && description[0])
595             instance.description = description;
596         instance.create_callback = create_callback;
597         Mutex::Locker locker (GetEmulateInstructionMutex ());
598         GetEmulateInstructionInstances ().push_back (instance);
599     }
600     return false;
601 }
602 
603 bool
UnregisterPlugin(EmulateInstructionCreateInstance create_callback)604 PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
605 {
606     if (create_callback)
607     {
608         Mutex::Locker locker (GetEmulateInstructionMutex ());
609         EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
610 
611         EmulateInstructionInstances::iterator pos, end = instances.end();
612         for (pos = instances.begin(); pos != end; ++ pos)
613         {
614             if (pos->create_callback == create_callback)
615             {
616                 instances.erase(pos);
617                 return true;
618             }
619         }
620     }
621     return false;
622 }
623 
624 EmulateInstructionCreateInstance
GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx)625 PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
626 {
627     Mutex::Locker locker (GetEmulateInstructionMutex ());
628     EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
629     if (idx < instances.size())
630         return instances[idx].create_callback;
631     return NULL;
632 }
633 
634 EmulateInstructionCreateInstance
GetEmulateInstructionCreateCallbackForPluginName(const ConstString & name)635 PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name)
636 {
637     if (name)
638     {
639         Mutex::Locker locker (GetEmulateInstructionMutex ());
640         EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
641 
642         EmulateInstructionInstances::iterator pos, end = instances.end();
643         for (pos = instances.begin(); pos != end; ++ pos)
644         {
645             if (name == pos->name)
646                 return pos->create_callback;
647         }
648     }
649     return NULL;
650 }
651 #pragma mark OperatingSystem
652 
653 
654 struct OperatingSystemInstance
655 {
OperatingSystemInstanceOperatingSystemInstance656     OperatingSystemInstance() :
657         name(),
658         description(),
659         create_callback(NULL)
660     {
661     }
662 
663     ConstString name;
664     std::string description;
665     OperatingSystemCreateInstance create_callback;
666 };
667 
668 typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;
669 
670 static Mutex &
GetOperatingSystemMutex()671 GetOperatingSystemMutex ()
672 {
673     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
674     return g_instances_mutex;
675 }
676 
677 static OperatingSystemInstances &
GetOperatingSystemInstances()678 GetOperatingSystemInstances ()
679 {
680     static OperatingSystemInstances g_instances;
681     return g_instances;
682 }
683 
684 bool
RegisterPlugin(const ConstString & name,const char * description,OperatingSystemCreateInstance create_callback)685 PluginManager::RegisterPlugin (const ConstString &name,
686                                const char *description,
687                                OperatingSystemCreateInstance create_callback)
688 {
689     if (create_callback)
690     {
691         OperatingSystemInstance instance;
692         assert ((bool)name);
693         instance.name = name;
694         if (description && description[0])
695             instance.description = description;
696         instance.create_callback = create_callback;
697         Mutex::Locker locker (GetOperatingSystemMutex ());
698         GetOperatingSystemInstances ().push_back (instance);
699     }
700     return false;
701 }
702 
703 bool
UnregisterPlugin(OperatingSystemCreateInstance create_callback)704 PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
705 {
706     if (create_callback)
707     {
708         Mutex::Locker locker (GetOperatingSystemMutex ());
709         OperatingSystemInstances &instances = GetOperatingSystemInstances ();
710 
711         OperatingSystemInstances::iterator pos, end = instances.end();
712         for (pos = instances.begin(); pos != end; ++ pos)
713         {
714             if (pos->create_callback == create_callback)
715             {
716                 instances.erase(pos);
717                 return true;
718             }
719         }
720     }
721     return false;
722 }
723 
724 OperatingSystemCreateInstance
GetOperatingSystemCreateCallbackAtIndex(uint32_t idx)725 PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
726 {
727     Mutex::Locker locker (GetOperatingSystemMutex ());
728     OperatingSystemInstances &instances = GetOperatingSystemInstances ();
729     if (idx < instances.size())
730         return instances[idx].create_callback;
731     return NULL;
732 }
733 
734 OperatingSystemCreateInstance
GetOperatingSystemCreateCallbackForPluginName(const ConstString & name)735 PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
736 {
737     if (name)
738     {
739         Mutex::Locker locker (GetOperatingSystemMutex ());
740         OperatingSystemInstances &instances = GetOperatingSystemInstances ();
741 
742         OperatingSystemInstances::iterator pos, end = instances.end();
743         for (pos = instances.begin(); pos != end; ++ pos)
744         {
745             if (name == pos->name)
746                 return pos->create_callback;
747         }
748     }
749     return NULL;
750 }
751 
752 
753 #pragma mark LanguageRuntime
754 
755 
756 struct LanguageRuntimeInstance
757 {
LanguageRuntimeInstanceLanguageRuntimeInstance758     LanguageRuntimeInstance() :
759         name(),
760         description(),
761         create_callback(NULL)
762     {
763     }
764 
765     ConstString name;
766     std::string description;
767     LanguageRuntimeCreateInstance create_callback;
768 };
769 
770 typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
771 
772 static Mutex &
GetLanguageRuntimeMutex()773 GetLanguageRuntimeMutex ()
774 {
775     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
776     return g_instances_mutex;
777 }
778 
779 static LanguageRuntimeInstances &
GetLanguageRuntimeInstances()780 GetLanguageRuntimeInstances ()
781 {
782     static LanguageRuntimeInstances g_instances;
783     return g_instances;
784 }
785 
786 bool
RegisterPlugin(const ConstString & name,const char * description,LanguageRuntimeCreateInstance create_callback)787 PluginManager::RegisterPlugin
788 (
789     const ConstString &name,
790     const char *description,
791     LanguageRuntimeCreateInstance create_callback
792 )
793 {
794     if (create_callback)
795     {
796         LanguageRuntimeInstance instance;
797         assert ((bool)name);
798         instance.name = name;
799         if (description && description[0])
800             instance.description = description;
801         instance.create_callback = create_callback;
802         Mutex::Locker locker (GetLanguageRuntimeMutex ());
803         GetLanguageRuntimeInstances ().push_back (instance);
804     }
805     return false;
806 }
807 
808 bool
UnregisterPlugin(LanguageRuntimeCreateInstance create_callback)809 PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
810 {
811     if (create_callback)
812     {
813         Mutex::Locker locker (GetLanguageRuntimeMutex ());
814         LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
815 
816         LanguageRuntimeInstances::iterator pos, end = instances.end();
817         for (pos = instances.begin(); pos != end; ++ pos)
818         {
819             if (pos->create_callback == create_callback)
820             {
821                 instances.erase(pos);
822                 return true;
823             }
824         }
825     }
826     return false;
827 }
828 
829 LanguageRuntimeCreateInstance
GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx)830 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
831 {
832     Mutex::Locker locker (GetLanguageRuntimeMutex ());
833     LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
834     if (idx < instances.size())
835         return instances[idx].create_callback;
836     return NULL;
837 }
838 
839 LanguageRuntimeCreateInstance
GetLanguageRuntimeCreateCallbackForPluginName(const ConstString & name)840 PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
841 {
842     if (name)
843     {
844         Mutex::Locker locker (GetLanguageRuntimeMutex ());
845         LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
846 
847         LanguageRuntimeInstances::iterator pos, end = instances.end();
848         for (pos = instances.begin(); pos != end; ++ pos)
849         {
850             if (name == pos->name)
851                 return pos->create_callback;
852         }
853     }
854     return NULL;
855 }
856 
857 #pragma mark ObjectFile
858 
859 struct ObjectFileInstance
860 {
ObjectFileInstanceObjectFileInstance861     ObjectFileInstance() :
862         name(),
863         description(),
864         create_callback(NULL),
865         create_memory_callback (NULL),
866         get_module_specifications (NULL)
867     {
868     }
869 
870     ConstString name;
871     std::string description;
872     ObjectFileCreateInstance create_callback;
873     ObjectFileCreateMemoryInstance create_memory_callback;
874     ObjectFileGetModuleSpecifications get_module_specifications;
875 };
876 
877 typedef std::vector<ObjectFileInstance> ObjectFileInstances;
878 
879 static Mutex &
GetObjectFileMutex()880 GetObjectFileMutex ()
881 {
882     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
883     return g_instances_mutex;
884 }
885 
886 static ObjectFileInstances &
GetObjectFileInstances()887 GetObjectFileInstances ()
888 {
889     static ObjectFileInstances g_instances;
890     return g_instances;
891 }
892 
893 
894 bool
RegisterPlugin(const ConstString & name,const char * description,ObjectFileCreateInstance create_callback,ObjectFileCreateMemoryInstance create_memory_callback,ObjectFileGetModuleSpecifications get_module_specifications)895 PluginManager::RegisterPlugin (const ConstString &name,
896                                const char *description,
897                                ObjectFileCreateInstance create_callback,
898                                ObjectFileCreateMemoryInstance create_memory_callback,
899                                ObjectFileGetModuleSpecifications get_module_specifications)
900 {
901     if (create_callback)
902     {
903         ObjectFileInstance instance;
904         assert ((bool)name);
905         instance.name = name;
906         if (description && description[0])
907             instance.description = description;
908         instance.create_callback = create_callback;
909         instance.create_memory_callback = create_memory_callback;
910         instance.get_module_specifications = get_module_specifications;
911         Mutex::Locker locker (GetObjectFileMutex ());
912         GetObjectFileInstances ().push_back (instance);
913     }
914     return false;
915 }
916 
917 bool
UnregisterPlugin(ObjectFileCreateInstance create_callback)918 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
919 {
920     if (create_callback)
921     {
922         Mutex::Locker locker (GetObjectFileMutex ());
923         ObjectFileInstances &instances = GetObjectFileInstances ();
924 
925         ObjectFileInstances::iterator pos, end = instances.end();
926         for (pos = instances.begin(); pos != end; ++ pos)
927         {
928             if (pos->create_callback == create_callback)
929             {
930                 instances.erase(pos);
931                 return true;
932             }
933         }
934     }
935     return false;
936 }
937 
938 ObjectFileCreateInstance
GetObjectFileCreateCallbackAtIndex(uint32_t idx)939 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
940 {
941     Mutex::Locker locker (GetObjectFileMutex ());
942     ObjectFileInstances &instances = GetObjectFileInstances ();
943     if (idx < instances.size())
944         return instances[idx].create_callback;
945     return NULL;
946 }
947 
948 
949 ObjectFileCreateMemoryInstance
GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx)950 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
951 {
952     Mutex::Locker locker (GetObjectFileMutex ());
953     ObjectFileInstances &instances = GetObjectFileInstances ();
954     if (idx < instances.size())
955         return instances[idx].create_memory_callback;
956     return NULL;
957 }
958 
959 ObjectFileGetModuleSpecifications
GetObjectFileGetModuleSpecificationsCallbackAtIndex(uint32_t idx)960 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
961 {
962     Mutex::Locker locker (GetObjectFileMutex ());
963     ObjectFileInstances &instances = GetObjectFileInstances ();
964     if (idx < instances.size())
965         return instances[idx].get_module_specifications;
966     return NULL;
967 }
968 
969 ObjectFileCreateInstance
GetObjectFileCreateCallbackForPluginName(const ConstString & name)970 PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
971 {
972     if (name)
973     {
974         Mutex::Locker locker (GetObjectFileMutex ());
975         ObjectFileInstances &instances = GetObjectFileInstances ();
976 
977         ObjectFileInstances::iterator pos, end = instances.end();
978         for (pos = instances.begin(); pos != end; ++ pos)
979         {
980             if (name == pos->name)
981                 return pos->create_callback;
982         }
983     }
984     return NULL;
985 }
986 
987 
988 ObjectFileCreateMemoryInstance
GetObjectFileCreateMemoryCallbackForPluginName(const ConstString & name)989 PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
990 {
991     if (name)
992     {
993         Mutex::Locker locker (GetObjectFileMutex ());
994         ObjectFileInstances &instances = GetObjectFileInstances ();
995 
996         ObjectFileInstances::iterator pos, end = instances.end();
997         for (pos = instances.begin(); pos != end; ++ pos)
998         {
999             if (name == pos->name)
1000                 return pos->create_memory_callback;
1001         }
1002     }
1003     return NULL;
1004 }
1005 
1006 
1007 
1008 #pragma mark ObjectContainer
1009 
1010 struct ObjectContainerInstance
1011 {
ObjectContainerInstanceObjectContainerInstance1012     ObjectContainerInstance() :
1013         name(),
1014         description(),
1015         create_callback (NULL),
1016         get_module_specifications (NULL)
1017     {
1018     }
1019 
1020     ConstString name;
1021     std::string description;
1022     ObjectContainerCreateInstance create_callback;
1023     ObjectFileGetModuleSpecifications get_module_specifications;
1024 
1025 };
1026 
1027 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
1028 
1029 static Mutex &
GetObjectContainerMutex()1030 GetObjectContainerMutex ()
1031 {
1032     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1033     return g_instances_mutex;
1034 }
1035 
1036 static ObjectContainerInstances &
GetObjectContainerInstances()1037 GetObjectContainerInstances ()
1038 {
1039     static ObjectContainerInstances g_instances;
1040     return g_instances;
1041 }
1042 
1043 bool
RegisterPlugin(const ConstString & name,const char * description,ObjectContainerCreateInstance create_callback,ObjectFileGetModuleSpecifications get_module_specifications)1044 PluginManager::RegisterPlugin (const ConstString &name,
1045                                const char *description,
1046                                ObjectContainerCreateInstance create_callback,
1047                                ObjectFileGetModuleSpecifications get_module_specifications)
1048 {
1049     if (create_callback)
1050     {
1051         ObjectContainerInstance instance;
1052         assert ((bool)name);
1053         instance.name = name;
1054         if (description && description[0])
1055             instance.description = description;
1056         instance.create_callback = create_callback;
1057         instance.get_module_specifications = get_module_specifications;
1058         Mutex::Locker locker (GetObjectContainerMutex ());
1059         GetObjectContainerInstances ().push_back (instance);
1060     }
1061     return false;
1062 }
1063 
1064 bool
UnregisterPlugin(ObjectContainerCreateInstance create_callback)1065 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
1066 {
1067     if (create_callback)
1068     {
1069         Mutex::Locker locker (GetObjectContainerMutex ());
1070         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1071 
1072         ObjectContainerInstances::iterator pos, end = instances.end();
1073         for (pos = instances.begin(); pos != end; ++ pos)
1074         {
1075             if (pos->create_callback == create_callback)
1076             {
1077                 instances.erase(pos);
1078                 return true;
1079             }
1080         }
1081     }
1082     return false;
1083 }
1084 
1085 ObjectContainerCreateInstance
GetObjectContainerCreateCallbackAtIndex(uint32_t idx)1086 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
1087 {
1088     Mutex::Locker locker (GetObjectContainerMutex ());
1089     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1090     if (idx < instances.size())
1091         return instances[idx].create_callback;
1092     return NULL;
1093 }
1094 
1095 ObjectContainerCreateInstance
GetObjectContainerCreateCallbackForPluginName(const ConstString & name)1096 PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
1097 {
1098     if (name)
1099     {
1100         Mutex::Locker locker (GetObjectContainerMutex ());
1101         ObjectContainerInstances &instances = GetObjectContainerInstances ();
1102 
1103         ObjectContainerInstances::iterator pos, end = instances.end();
1104         for (pos = instances.begin(); pos != end; ++ pos)
1105         {
1106             if (name == pos->name)
1107                 return pos->create_callback;
1108         }
1109     }
1110     return NULL;
1111 }
1112 
1113 ObjectFileGetModuleSpecifications
GetObjectContainerGetModuleSpecificationsCallbackAtIndex(uint32_t idx)1114 PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
1115 {
1116     Mutex::Locker locker (GetObjectContainerMutex ());
1117     ObjectContainerInstances &instances = GetObjectContainerInstances ();
1118     if (idx < instances.size())
1119         return instances[idx].get_module_specifications;
1120     return NULL;
1121 }
1122 
1123 #pragma mark LogChannel
1124 
1125 struct LogInstance
1126 {
LogInstanceLogInstance1127     LogInstance() :
1128         name(),
1129         description(),
1130         create_callback(NULL)
1131     {
1132     }
1133 
1134     ConstString name;
1135     std::string description;
1136     LogChannelCreateInstance create_callback;
1137 };
1138 
1139 typedef std::vector<LogInstance> LogInstances;
1140 
1141 static Mutex &
GetLogMutex()1142 GetLogMutex ()
1143 {
1144     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1145     return g_instances_mutex;
1146 }
1147 
1148 static LogInstances &
GetLogInstances()1149 GetLogInstances ()
1150 {
1151     static LogInstances g_instances;
1152     return g_instances;
1153 }
1154 
1155 
1156 
1157 bool
RegisterPlugin(const ConstString & name,const char * description,LogChannelCreateInstance create_callback)1158 PluginManager::RegisterPlugin
1159 (
1160     const ConstString &name,
1161     const char *description,
1162     LogChannelCreateInstance create_callback
1163 )
1164 {
1165     if (create_callback)
1166     {
1167         LogInstance 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         Mutex::Locker locker (GetLogMutex ());
1174         GetLogInstances ().push_back (instance);
1175     }
1176     return false;
1177 }
1178 
1179 bool
UnregisterPlugin(LogChannelCreateInstance create_callback)1180 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1181 {
1182     if (create_callback)
1183     {
1184         Mutex::Locker locker (GetLogMutex ());
1185         LogInstances &instances = GetLogInstances ();
1186 
1187         LogInstances::iterator pos, end = instances.end();
1188         for (pos = instances.begin(); pos != end; ++ pos)
1189         {
1190             if (pos->create_callback == create_callback)
1191             {
1192                 instances.erase(pos);
1193                 return true;
1194             }
1195         }
1196     }
1197     return false;
1198 }
1199 
1200 const char *
GetLogChannelCreateNameAtIndex(uint32_t idx)1201 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1202 {
1203     Mutex::Locker locker (GetLogMutex ());
1204     LogInstances &instances = GetLogInstances ();
1205     if (idx < instances.size())
1206         return instances[idx].name.GetCString();
1207     return NULL;
1208 }
1209 
1210 
1211 LogChannelCreateInstance
GetLogChannelCreateCallbackAtIndex(uint32_t idx)1212 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1213 {
1214     Mutex::Locker locker (GetLogMutex ());
1215     LogInstances &instances = GetLogInstances ();
1216     if (idx < instances.size())
1217         return instances[idx].create_callback;
1218     return NULL;
1219 }
1220 
1221 LogChannelCreateInstance
GetLogChannelCreateCallbackForPluginName(const ConstString & name)1222 PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
1223 {
1224     if (name)
1225     {
1226         Mutex::Locker locker (GetLogMutex ());
1227         LogInstances &instances = GetLogInstances ();
1228 
1229         LogInstances::iterator pos, end = instances.end();
1230         for (pos = instances.begin(); pos != end; ++ pos)
1231         {
1232             if (name == pos->name)
1233                 return pos->create_callback;
1234         }
1235     }
1236     return NULL;
1237 }
1238 
1239 #pragma mark Platform
1240 
1241 struct PlatformInstance
1242 {
PlatformInstancePlatformInstance1243     PlatformInstance() :
1244         name(),
1245         description(),
1246         create_callback(NULL),
1247         debugger_init_callback (NULL)
1248     {
1249     }
1250 
1251     ConstString name;
1252     std::string description;
1253     PlatformCreateInstance create_callback;
1254     DebuggerInitializeCallback debugger_init_callback;
1255 };
1256 
1257 typedef std::vector<PlatformInstance> PlatformInstances;
1258 
1259 static Mutex &
GetPlatformInstancesMutex()1260 GetPlatformInstancesMutex ()
1261 {
1262     static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1263     return g_platform_instances_mutex;
1264 }
1265 
1266 static PlatformInstances &
GetPlatformInstances()1267 GetPlatformInstances ()
1268 {
1269     static PlatformInstances g_platform_instances;
1270     return g_platform_instances;
1271 }
1272 
1273 
1274 bool
RegisterPlugin(const ConstString & name,const char * description,PlatformCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)1275 PluginManager::RegisterPlugin (const ConstString &name,
1276                                const char *description,
1277                                PlatformCreateInstance create_callback,
1278                                DebuggerInitializeCallback debugger_init_callback)
1279 {
1280     if (create_callback)
1281     {
1282         Mutex::Locker locker (GetPlatformInstancesMutex ());
1283 
1284         PlatformInstance instance;
1285         assert ((bool)name);
1286         instance.name = name;
1287         if (description && description[0])
1288             instance.description = description;
1289         instance.create_callback = create_callback;
1290         instance.debugger_init_callback = debugger_init_callback;
1291         GetPlatformInstances ().push_back (instance);
1292         return true;
1293     }
1294     return false;
1295 }
1296 
1297 
1298 const char *
GetPlatformPluginNameAtIndex(uint32_t idx)1299 PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1300 {
1301     Mutex::Locker locker (GetPlatformInstancesMutex ());
1302     PlatformInstances &instances = GetPlatformInstances ();
1303     if (idx < instances.size())
1304         return instances[idx].name.GetCString();
1305     return NULL;
1306 }
1307 
1308 const char *
GetPlatformPluginDescriptionAtIndex(uint32_t idx)1309 PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1310 {
1311     Mutex::Locker locker (GetPlatformInstancesMutex ());
1312     PlatformInstances &instances = GetPlatformInstances ();
1313     if (idx < instances.size())
1314         return instances[idx].description.c_str();
1315     return NULL;
1316 }
1317 
1318 bool
UnregisterPlugin(PlatformCreateInstance create_callback)1319 PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1320 {
1321     if (create_callback)
1322     {
1323         Mutex::Locker locker (GetPlatformInstancesMutex ());
1324         PlatformInstances &instances = GetPlatformInstances ();
1325 
1326         PlatformInstances::iterator pos, end = instances.end();
1327         for (pos = instances.begin(); pos != end; ++ pos)
1328         {
1329             if (pos->create_callback == create_callback)
1330             {
1331                 instances.erase(pos);
1332                 return true;
1333             }
1334         }
1335     }
1336     return false;
1337 }
1338 
1339 PlatformCreateInstance
GetPlatformCreateCallbackAtIndex(uint32_t idx)1340 PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1341 {
1342     Mutex::Locker locker (GetPlatformInstancesMutex ());
1343     PlatformInstances &instances = GetPlatformInstances ();
1344     if (idx < instances.size())
1345         return instances[idx].create_callback;
1346     return NULL;
1347 }
1348 
1349 PlatformCreateInstance
GetPlatformCreateCallbackForPluginName(const ConstString & name)1350 PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
1351 {
1352     if (name)
1353     {
1354         Mutex::Locker locker (GetPlatformInstancesMutex ());
1355         PlatformInstances &instances = GetPlatformInstances ();
1356 
1357         PlatformInstances::iterator pos, end = instances.end();
1358         for (pos = instances.begin(); pos != end; ++ pos)
1359         {
1360             if (name == pos->name)
1361                 return pos->create_callback;
1362         }
1363     }
1364     return NULL;
1365 }
1366 
1367 size_t
AutoCompletePlatformName(const char * name,StringList & matches)1368 PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1369 {
1370     if (name)
1371     {
1372         Mutex::Locker locker (GetPlatformInstancesMutex ());
1373         PlatformInstances &instances = GetPlatformInstances ();
1374         llvm::StringRef name_sref(name);
1375 
1376         PlatformInstances::iterator pos, end = instances.end();
1377         for (pos = instances.begin(); pos != end; ++ pos)
1378         {
1379             llvm::StringRef plugin_name (pos->name.GetCString());
1380             if (plugin_name.startswith(name_sref))
1381                 matches.AppendString (plugin_name.data());
1382         }
1383     }
1384     return matches.GetSize();
1385 }
1386 #pragma mark Process
1387 
1388 struct ProcessInstance
1389 {
ProcessInstanceProcessInstance1390     ProcessInstance() :
1391         name(),
1392         description(),
1393         create_callback(NULL),
1394         debugger_init_callback(NULL)
1395     {
1396     }
1397 
1398     ConstString name;
1399     std::string description;
1400     ProcessCreateInstance create_callback;
1401     DebuggerInitializeCallback debugger_init_callback;
1402 };
1403 
1404 typedef std::vector<ProcessInstance> ProcessInstances;
1405 
1406 static Mutex &
GetProcessMutex()1407 GetProcessMutex ()
1408 {
1409     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1410     return g_instances_mutex;
1411 }
1412 
1413 static ProcessInstances &
GetProcessInstances()1414 GetProcessInstances ()
1415 {
1416     static ProcessInstances g_instances;
1417     return g_instances;
1418 }
1419 
1420 
1421 bool
RegisterPlugin(const ConstString & name,const char * description,ProcessCreateInstance create_callback,DebuggerInitializeCallback debugger_init_callback)1422 PluginManager::RegisterPlugin (const ConstString &name,
1423                                const char *description,
1424                                ProcessCreateInstance create_callback,
1425                                DebuggerInitializeCallback debugger_init_callback)
1426 {
1427     if (create_callback)
1428     {
1429         ProcessInstance instance;
1430         assert ((bool)name);
1431         instance.name = name;
1432         if (description && description[0])
1433             instance.description = description;
1434         instance.create_callback = create_callback;
1435         instance.debugger_init_callback = debugger_init_callback;
1436         Mutex::Locker locker (GetProcessMutex ());
1437         GetProcessInstances ().push_back (instance);
1438     }
1439     return false;
1440 }
1441 
1442 const char *
GetProcessPluginNameAtIndex(uint32_t idx)1443 PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1444 {
1445     Mutex::Locker locker (GetProcessMutex ());
1446     ProcessInstances &instances = GetProcessInstances ();
1447     if (idx < instances.size())
1448         return instances[idx].name.GetCString();
1449     return NULL;
1450 }
1451 
1452 const char *
GetProcessPluginDescriptionAtIndex(uint32_t idx)1453 PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1454 {
1455     Mutex::Locker locker (GetProcessMutex ());
1456     ProcessInstances &instances = GetProcessInstances ();
1457     if (idx < instances.size())
1458         return instances[idx].description.c_str();
1459     return NULL;
1460 }
1461 
1462 bool
UnregisterPlugin(ProcessCreateInstance create_callback)1463 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1464 {
1465     if (create_callback)
1466     {
1467         Mutex::Locker locker (GetProcessMutex ());
1468         ProcessInstances &instances = GetProcessInstances ();
1469 
1470         ProcessInstances::iterator pos, end = instances.end();
1471         for (pos = instances.begin(); pos != end; ++ pos)
1472         {
1473             if (pos->create_callback == create_callback)
1474             {
1475                 instances.erase(pos);
1476                 return true;
1477             }
1478         }
1479     }
1480     return false;
1481 }
1482 
1483 ProcessCreateInstance
GetProcessCreateCallbackAtIndex(uint32_t idx)1484 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1485 {
1486     Mutex::Locker locker (GetProcessMutex ());
1487     ProcessInstances &instances = GetProcessInstances ();
1488     if (idx < instances.size())
1489         return instances[idx].create_callback;
1490     return NULL;
1491 }
1492 
1493 
1494 ProcessCreateInstance
GetProcessCreateCallbackForPluginName(const ConstString & name)1495 PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
1496 {
1497     if (name)
1498     {
1499         Mutex::Locker locker (GetProcessMutex ());
1500         ProcessInstances &instances = GetProcessInstances ();
1501 
1502         ProcessInstances::iterator pos, end = instances.end();
1503         for (pos = instances.begin(); pos != end; ++ pos)
1504         {
1505             if (name == pos->name)
1506                 return pos->create_callback;
1507         }
1508     }
1509     return NULL;
1510 }
1511 
1512 #pragma mark SymbolFile
1513 
1514 struct SymbolFileInstance
1515 {
SymbolFileInstanceSymbolFileInstance1516     SymbolFileInstance() :
1517         name(),
1518         description(),
1519         create_callback(NULL)
1520     {
1521     }
1522 
1523     ConstString name;
1524     std::string description;
1525     SymbolFileCreateInstance create_callback;
1526 };
1527 
1528 typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1529 
1530 static Mutex &
GetSymbolFileMutex()1531 GetSymbolFileMutex ()
1532 {
1533     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1534     return g_instances_mutex;
1535 }
1536 
1537 static SymbolFileInstances &
GetSymbolFileInstances()1538 GetSymbolFileInstances ()
1539 {
1540     static SymbolFileInstances g_instances;
1541     return g_instances;
1542 }
1543 
1544 
1545 bool
RegisterPlugin(const ConstString & name,const char * description,SymbolFileCreateInstance create_callback)1546 PluginManager::RegisterPlugin
1547 (
1548     const ConstString &name,
1549     const char *description,
1550     SymbolFileCreateInstance create_callback
1551 )
1552 {
1553     if (create_callback)
1554     {
1555         SymbolFileInstance instance;
1556         assert ((bool)name);
1557         instance.name = name;
1558         if (description && description[0])
1559             instance.description = description;
1560         instance.create_callback = create_callback;
1561         Mutex::Locker locker (GetSymbolFileMutex ());
1562         GetSymbolFileInstances ().push_back (instance);
1563     }
1564     return false;
1565 }
1566 
1567 bool
UnregisterPlugin(SymbolFileCreateInstance create_callback)1568 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1569 {
1570     if (create_callback)
1571     {
1572         Mutex::Locker locker (GetSymbolFileMutex ());
1573         SymbolFileInstances &instances = GetSymbolFileInstances ();
1574 
1575         SymbolFileInstances::iterator pos, end = instances.end();
1576         for (pos = instances.begin(); pos != end; ++ pos)
1577         {
1578             if (pos->create_callback == create_callback)
1579             {
1580                 instances.erase(pos);
1581                 return true;
1582             }
1583         }
1584     }
1585     return false;
1586 }
1587 
1588 SymbolFileCreateInstance
GetSymbolFileCreateCallbackAtIndex(uint32_t idx)1589 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1590 {
1591     Mutex::Locker locker (GetSymbolFileMutex ());
1592     SymbolFileInstances &instances = GetSymbolFileInstances ();
1593     if (idx < instances.size())
1594         return instances[idx].create_callback;
1595     return NULL;
1596 }
1597 
1598 SymbolFileCreateInstance
GetSymbolFileCreateCallbackForPluginName(const ConstString & name)1599 PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
1600 {
1601     if (name)
1602     {
1603         Mutex::Locker locker (GetSymbolFileMutex ());
1604         SymbolFileInstances &instances = GetSymbolFileInstances ();
1605 
1606         SymbolFileInstances::iterator pos, end = instances.end();
1607         for (pos = instances.begin(); pos != end; ++ pos)
1608         {
1609             if (name == pos->name)
1610                 return pos->create_callback;
1611         }
1612     }
1613     return NULL;
1614 }
1615 
1616 
1617 
1618 #pragma mark SymbolVendor
1619 
1620 struct SymbolVendorInstance
1621 {
SymbolVendorInstanceSymbolVendorInstance1622     SymbolVendorInstance() :
1623         name(),
1624         description(),
1625         create_callback(NULL)
1626     {
1627     }
1628 
1629     ConstString name;
1630     std::string description;
1631     SymbolVendorCreateInstance create_callback;
1632 };
1633 
1634 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1635 
1636 static Mutex &
GetSymbolVendorMutex()1637 GetSymbolVendorMutex ()
1638 {
1639     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1640     return g_instances_mutex;
1641 }
1642 
1643 static SymbolVendorInstances &
GetSymbolVendorInstances()1644 GetSymbolVendorInstances ()
1645 {
1646     static SymbolVendorInstances g_instances;
1647     return g_instances;
1648 }
1649 
1650 bool
RegisterPlugin(const ConstString & name,const char * description,SymbolVendorCreateInstance create_callback)1651 PluginManager::RegisterPlugin
1652 (
1653     const ConstString &name,
1654     const char *description,
1655     SymbolVendorCreateInstance create_callback
1656 )
1657 {
1658     if (create_callback)
1659     {
1660         SymbolVendorInstance instance;
1661         assert ((bool)name);
1662         instance.name = name;
1663         if (description && description[0])
1664             instance.description = description;
1665         instance.create_callback = create_callback;
1666         Mutex::Locker locker (GetSymbolVendorMutex ());
1667         GetSymbolVendorInstances ().push_back (instance);
1668     }
1669     return false;
1670 }
1671 
1672 bool
UnregisterPlugin(SymbolVendorCreateInstance create_callback)1673 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1674 {
1675     if (create_callback)
1676     {
1677         Mutex::Locker locker (GetSymbolVendorMutex ());
1678         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1679 
1680         SymbolVendorInstances::iterator pos, end = instances.end();
1681         for (pos = instances.begin(); pos != end; ++ pos)
1682         {
1683             if (pos->create_callback == create_callback)
1684             {
1685                 instances.erase(pos);
1686                 return true;
1687             }
1688         }
1689     }
1690     return false;
1691 }
1692 
1693 SymbolVendorCreateInstance
GetSymbolVendorCreateCallbackAtIndex(uint32_t idx)1694 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1695 {
1696     Mutex::Locker locker (GetSymbolVendorMutex ());
1697     SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1698     if (idx < instances.size())
1699         return instances[idx].create_callback;
1700     return NULL;
1701 }
1702 
1703 
1704 SymbolVendorCreateInstance
GetSymbolVendorCreateCallbackForPluginName(const ConstString & name)1705 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
1706 {
1707     if (name)
1708     {
1709         Mutex::Locker locker (GetSymbolVendorMutex ());
1710         SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1711 
1712         SymbolVendorInstances::iterator pos, end = instances.end();
1713         for (pos = instances.begin(); pos != end; ++ pos)
1714         {
1715             if (name == pos->name)
1716                 return pos->create_callback;
1717         }
1718     }
1719     return NULL;
1720 }
1721 
1722 
1723 #pragma mark UnwindAssembly
1724 
1725 struct UnwindAssemblyInstance
1726 {
UnwindAssemblyInstanceUnwindAssemblyInstance1727     UnwindAssemblyInstance() :
1728         name(),
1729         description(),
1730         create_callback(NULL)
1731     {
1732     }
1733 
1734     ConstString name;
1735     std::string description;
1736     UnwindAssemblyCreateInstance create_callback;
1737 };
1738 
1739 typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
1740 
1741 static Mutex &
GetUnwindAssemblyMutex()1742 GetUnwindAssemblyMutex ()
1743 {
1744     static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1745     return g_instances_mutex;
1746 }
1747 
1748 static UnwindAssemblyInstances &
GetUnwindAssemblyInstances()1749 GetUnwindAssemblyInstances ()
1750 {
1751     static UnwindAssemblyInstances g_instances;
1752     return g_instances;
1753 }
1754 
1755 bool
RegisterPlugin(const ConstString & name,const char * description,UnwindAssemblyCreateInstance create_callback)1756 PluginManager::RegisterPlugin
1757 (
1758     const ConstString &name,
1759     const char *description,
1760     UnwindAssemblyCreateInstance create_callback
1761 )
1762 {
1763     if (create_callback)
1764     {
1765         UnwindAssemblyInstance instance;
1766         assert ((bool)name);
1767         instance.name = name;
1768         if (description && description[0])
1769             instance.description = description;
1770         instance.create_callback = create_callback;
1771         Mutex::Locker locker (GetUnwindAssemblyMutex ());
1772         GetUnwindAssemblyInstances ().push_back (instance);
1773     }
1774     return false;
1775 }
1776 
1777 bool
UnregisterPlugin(UnwindAssemblyCreateInstance create_callback)1778 PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
1779 {
1780     if (create_callback)
1781     {
1782         Mutex::Locker locker (GetUnwindAssemblyMutex ());
1783         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
1784 
1785         UnwindAssemblyInstances::iterator pos, end = instances.end();
1786         for (pos = instances.begin(); pos != end; ++ pos)
1787         {
1788             if (pos->create_callback == create_callback)
1789             {
1790                 instances.erase(pos);
1791                 return true;
1792             }
1793         }
1794     }
1795     return false;
1796 }
1797 
1798 UnwindAssemblyCreateInstance
GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx)1799 PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
1800 {
1801     Mutex::Locker locker (GetUnwindAssemblyMutex ());
1802     UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
1803     if (idx < instances.size())
1804         return instances[idx].create_callback;
1805     return NULL;
1806 }
1807 
1808 
1809 UnwindAssemblyCreateInstance
GetUnwindAssemblyCreateCallbackForPluginName(const ConstString & name)1810 PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
1811 {
1812     if (name)
1813     {
1814         Mutex::Locker locker (GetUnwindAssemblyMutex ());
1815         UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
1816 
1817         UnwindAssemblyInstances::iterator pos, end = instances.end();
1818         for (pos = instances.begin(); pos != end; ++ pos)
1819         {
1820             if (name == pos->name)
1821                 return pos->create_callback;
1822         }
1823     }
1824     return NULL;
1825 }
1826 
1827 void
DebuggerInitialize(Debugger & debugger)1828 PluginManager::DebuggerInitialize (Debugger &debugger)
1829 {
1830     // Initialize the DynamicLoader plugins
1831     {
1832         Mutex::Locker locker (GetDynamicLoaderMutex ());
1833         DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
1834 
1835         DynamicLoaderInstances::iterator pos, end = instances.end();
1836         for (pos = instances.begin(); pos != end; ++ pos)
1837         {
1838             if (pos->debugger_init_callback)
1839                 pos->debugger_init_callback (debugger);
1840         }
1841     }
1842 
1843     // Initialize the Platform plugins
1844     {
1845         Mutex::Locker locker (GetPlatformInstancesMutex ());
1846         PlatformInstances &instances = GetPlatformInstances ();
1847 
1848         PlatformInstances::iterator pos, end = instances.end();
1849         for (pos = instances.begin(); pos != end; ++ pos)
1850         {
1851             if (pos->debugger_init_callback)
1852                 pos->debugger_init_callback (debugger);
1853         }
1854     }
1855 
1856     // Initialize the Process plugins
1857     {
1858         Mutex::Locker locker (GetProcessMutex());
1859         ProcessInstances &instances = GetProcessInstances();
1860 
1861         ProcessInstances::iterator pos, end = instances.end();
1862         for (pos = instances.begin(); pos != end; ++ pos)
1863         {
1864             if (pos->debugger_init_callback)
1865                 pos->debugger_init_callback (debugger);
1866         }
1867     }
1868 
1869 }
1870 
1871 // This is the preferred new way to register plugin specific settings.  e.g.
1872 // This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1873 static lldb::OptionValuePropertiesSP
GetDebuggerPropertyForPlugins(Debugger & debugger,const ConstString & plugin_type_name,const ConstString & plugin_type_desc,bool can_create)1874 GetDebuggerPropertyForPlugins (Debugger &debugger,
1875                                        const ConstString &plugin_type_name,
1876                                        const ConstString &plugin_type_desc,
1877                                        bool can_create)
1878 {
1879     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
1880     if (parent_properties_sp)
1881     {
1882         static ConstString g_property_name("plugin");
1883 
1884         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
1885         if (!plugin_properties_sp && can_create)
1886         {
1887             plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
1888             parent_properties_sp->AppendProperty (g_property_name,
1889                                                   ConstString("Settings specify to plugins."),
1890                                                   true,
1891                                                   plugin_properties_sp);
1892         }
1893 
1894         if (plugin_properties_sp)
1895         {
1896             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
1897             if (!plugin_type_properties_sp && can_create)
1898             {
1899                 plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
1900                 plugin_properties_sp->AppendProperty (plugin_type_name,
1901                                                       plugin_type_desc,
1902                                                       true,
1903                                                       plugin_type_properties_sp);
1904             }
1905             return plugin_type_properties_sp;
1906         }
1907     }
1908     return lldb::OptionValuePropertiesSP();
1909 }
1910 
1911 // This is deprecated way to register plugin specific settings.  e.g.
1912 // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
1913 // and Platform generic settings would be under "platform.SETTINGNAME".
1914 static lldb::OptionValuePropertiesSP
GetDebuggerPropertyForPluginsOldStyle(Debugger & debugger,const ConstString & plugin_type_name,const ConstString & plugin_type_desc,bool can_create)1915 GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
1916                                        const ConstString &plugin_type_name,
1917                                        const ConstString &plugin_type_desc,
1918                                        bool can_create)
1919 {
1920     static ConstString g_property_name("plugin");
1921     lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
1922     if (parent_properties_sp)
1923     {
1924         OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
1925         if (!plugin_properties_sp && can_create)
1926         {
1927             plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
1928             parent_properties_sp->AppendProperty (plugin_type_name,
1929                                                   plugin_type_desc,
1930                                                   true,
1931                                                   plugin_properties_sp);
1932         }
1933 
1934         if (plugin_properties_sp)
1935         {
1936             lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
1937             if (!plugin_type_properties_sp && can_create)
1938             {
1939                 plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
1940                 plugin_properties_sp->AppendProperty (g_property_name,
1941                                                       ConstString("Settings specific to plugins"),
1942                                                       true,
1943                                                       plugin_type_properties_sp);
1944             }
1945             return plugin_type_properties_sp;
1946         }
1947     }
1948     return lldb::OptionValuePropertiesSP();
1949 }
1950 
1951 
1952 lldb::OptionValuePropertiesSP
GetSettingForDynamicLoaderPlugin(Debugger & debugger,const ConstString & setting_name)1953 PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name)
1954 {
1955     lldb::OptionValuePropertiesSP properties_sp;
1956     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
1957                                                                                             ConstString("dynamic-loader"),
1958                                                                                             ConstString(), // not creating to so we don't need the description
1959                                                                                             false));
1960     if (plugin_type_properties_sp)
1961         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
1962     return properties_sp;
1963 }
1964 
1965 bool
CreateSettingForDynamicLoaderPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property)1966 PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
1967                                                     const lldb::OptionValuePropertiesSP &properties_sp,
1968                                                     const ConstString &description,
1969                                                     bool is_global_property)
1970 {
1971     if (properties_sp)
1972     {
1973         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
1974                                                                                                 ConstString("dynamic-loader"),
1975                                                                                                 ConstString("Settings for dynamic loader plug-ins"),
1976                                                                                                 true));
1977         if (plugin_type_properties_sp)
1978         {
1979             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
1980                                                        description,
1981                                                        is_global_property,
1982                                                        properties_sp);
1983             return true;
1984         }
1985     }
1986     return false;
1987 }
1988 
1989 
1990 lldb::OptionValuePropertiesSP
GetSettingForPlatformPlugin(Debugger & debugger,const ConstString & setting_name)1991 PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
1992 {
1993     lldb::OptionValuePropertiesSP properties_sp;
1994     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
1995                                                                                                     ConstString("platform"),
1996                                                                                                     ConstString(), // not creating to so we don't need the description
1997                                                                                                     false));
1998     if (plugin_type_properties_sp)
1999         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2000     return properties_sp;
2001 }
2002 
2003 bool
CreateSettingForPlatformPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property)2004 PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
2005                                                     const lldb::OptionValuePropertiesSP &properties_sp,
2006                                                     const ConstString &description,
2007                                                     bool is_global_property)
2008 {
2009     if (properties_sp)
2010     {
2011         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
2012                                                                                                         ConstString("platform"),
2013                                                                                                         ConstString("Settings for platform plug-ins"),
2014                                                                                                         true));
2015         if (plugin_type_properties_sp)
2016         {
2017             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2018                                                        description,
2019                                                        is_global_property,
2020                                                        properties_sp);
2021             return true;
2022         }
2023     }
2024     return false;
2025 }
2026 
2027 
2028 lldb::OptionValuePropertiesSP
GetSettingForProcessPlugin(Debugger & debugger,const ConstString & setting_name)2029 PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
2030 {
2031     lldb::OptionValuePropertiesSP properties_sp;
2032     lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2033                                                                                             ConstString("process"),
2034                                                                                             ConstString(), // not creating to so we don't need the description
2035                                                                                             false));
2036     if (plugin_type_properties_sp)
2037         properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name);
2038     return properties_sp;
2039 }
2040 
2041 bool
CreateSettingForProcessPlugin(Debugger & debugger,const lldb::OptionValuePropertiesSP & properties_sp,const ConstString & description,bool is_global_property)2042 PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
2043                                               const lldb::OptionValuePropertiesSP &properties_sp,
2044                                               const ConstString &description,
2045                                               bool is_global_property)
2046 {
2047     if (properties_sp)
2048     {
2049         lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger,
2050                                                                                                 ConstString("process"),
2051                                                                                                 ConstString("Settings for process plug-ins"),
2052                                                                                                 true));
2053         if (plugin_type_properties_sp)
2054         {
2055             plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
2056                                                        description,
2057                                                        is_global_property,
2058                                                        properties_sp);
2059             return true;
2060         }
2061     }
2062     return false;
2063 }
2064 
2065