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