blob: d1903dff36507fb572e6b79884755dc7d3f86ece [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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
Stephen Wilsonec2d9782011-04-08 13:36:44 +000012#include <limits.h>
13
Chris Lattner24943d22010-06-08 16:52:24 +000014#include <string>
15#include <vector>
16
Greg Clayton52fd9842011-02-02 02:24:04 +000017#include "lldb/Core/Error.h"
Greg Clayton5f54ac32011-02-08 05:05:52 +000018#include "lldb/Host/FileSpec.h"
Greg Clayton52fd9842011-02-02 02:24:04 +000019#include "lldb/Host/Host.h"
20#include "lldb/Host/Mutex.h"
21
Greg Clayton5e342f52011-04-13 22:47:15 +000022#include "llvm/ADT/StringRef.h"
23
Greg Clayton52fd9842011-02-02 02:24:04 +000024using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000025using namespace lldb_private;
26
Jason Molenda53d96862010-06-11 23:44:18 +000027enum PluginAction
Chris Lattner24943d22010-06-08 16:52:24 +000028{
29 ePluginRegisterInstance,
30 ePluginUnregisterInstance,
31 ePluginGetInstanceAtIndex
32};
33
Greg Clayton52fd9842011-02-02 02:24:04 +000034struct PluginInfo
35{
36 void *plugin_handle;
37 void *plugin_init_callback;
38 void *plugin_term_callback;
39};
40
41typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
42
43static Mutex &
44GetPluginMapMutex ()
45{
46 static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
47 return g_plugin_map_mutex;
48}
49
50static PluginTerminateMap &
51GetPluginMap ()
52{
53 static PluginTerminateMap g_plugin_map;
54 return g_plugin_map;
55}
56
57static bool
58PluginIsLoaded (const FileSpec &plugin_file_spec)
59{
60 Mutex::Locker locker (GetPluginMapMutex ());
61 PluginTerminateMap &plugin_map = GetPluginMap ();
62 return plugin_map.find (plugin_file_spec) != plugin_map.end();
63}
64
65static void
66SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
67{
68 Mutex::Locker locker (GetPluginMapMutex ());
69 PluginTerminateMap &plugin_map = GetPluginMap ();
70 assert (plugin_map.find (plugin_file_spec) != plugin_map.end());
71 plugin_map[plugin_file_spec] = plugin_info;
72}
73
74
75static FileSpec::EnumerateDirectoryResult
76LoadPluginCallback
77(
78 void *baton,
79 FileSpec::FileType file_type,
80 const FileSpec &file_spec
81)
82{
83// PluginManager *plugin_manager = (PluginManager *)baton;
84 Error error;
85
86 // If we have a regular file, a symbolic link or unknown file type, try
87 // and process the file. We must handle unknown as sometimes the directory
88 // enumeration might be enumerating a file system that doesn't have correct
89 // file type information.
90 if (file_type == FileSpec::eFileTypeRegular ||
91 file_type == FileSpec::eFileTypeSymbolicLink ||
92 file_type == FileSpec::eFileTypeUnknown )
93 {
94 FileSpec plugin_file_spec (file_spec);
95 plugin_file_spec.ResolvePath();
96
97 if (PluginIsLoaded (plugin_file_spec))
98 return FileSpec::eEnumerateDirectoryResultNext;
99 else
100 {
101 PluginInfo plugin_info = { NULL, NULL, NULL };
Greg Clayton14ef59f2011-02-08 00:35:34 +0000102 uint32_t flags = Host::eDynamicLibraryOpenOptionLazy |
103 Host::eDynamicLibraryOpenOptionLocal |
104 Host::eDynamicLibraryOpenOptionLimitGetSymbol;
105
106 plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, flags, error);
Greg Clayton52fd9842011-02-02 02:24:04 +0000107 if (plugin_info.plugin_handle)
108 {
109 bool success = false;
110 plugin_info.plugin_init_callback = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error);
111 if (plugin_info.plugin_init_callback)
112 {
113 // Call the plug-in "bool LLDBPluginInitialize(void)" function
114 success = ((bool (*)(void))plugin_info.plugin_init_callback)();
115 }
116
117 if (success)
118 {
119 // It is ok for the "LLDBPluginTerminate" symbol to be NULL
120 plugin_info.plugin_term_callback = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error);
121 }
122 else
123 {
124 // The initialize function returned FALSE which means the
125 // plug-in might not be compatible, or might be too new or
126 // too old, or might not want to run on this machine.
127 Host::DynamicLibraryClose (plugin_info.plugin_handle);
128 plugin_info.plugin_handle = NULL;
129 plugin_info.plugin_init_callback = NULL;
130 }
131
132 // Regardless of success or failure, cache the plug-in load
133 // in our plug-in info so we don't try to load it again and
134 // again.
135 SetPluginInfo (plugin_file_spec, plugin_info);
136
137 return FileSpec::eEnumerateDirectoryResultNext;
138 }
139 }
140 }
141
142 if (file_type == FileSpec::eFileTypeUnknown ||
143 file_type == FileSpec::eFileTypeDirectory ||
144 file_type == FileSpec::eFileTypeSymbolicLink )
145 {
146 // Try and recurse into anything that a directory or symbolic link.
147 // We must also do this for unknown as sometimes the directory enumeration
148 // might be enurating a file system that doesn't have correct file type
149 // information.
150 return FileSpec::eEnumerateDirectoryResultEnter;
151 }
152
153 return FileSpec::eEnumerateDirectoryResultNext;
154}
155
156
157void
158PluginManager::Initialize ()
159{
Greg Clayton58e26e02011-03-24 04:28:38 +0000160#if 1
Greg Clayton52fd9842011-02-02 02:24:04 +0000161 FileSpec dir_spec;
162 const bool find_directories = true;
163 const bool find_files = true;
164 const bool find_other = true;
165 char dir_path[PATH_MAX];
166 if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
167 {
168 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
169 {
170 FileSpec::EnumerateDirectory (dir_path,
171 find_directories,
172 find_files,
173 find_other,
174 LoadPluginCallback,
175 NULL);
176 }
177 }
178
179 if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
180 {
181 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
182 {
183 FileSpec::EnumerateDirectory (dir_path,
184 find_directories,
185 find_files,
186 find_other,
187 LoadPluginCallback,
188 NULL);
189 }
190 }
Greg Clayton58e26e02011-03-24 04:28:38 +0000191#endif
Greg Clayton52fd9842011-02-02 02:24:04 +0000192}
193
194void
195PluginManager::Terminate ()
196{
197 Mutex::Locker locker (GetPluginMapMutex ());
198 PluginTerminateMap &plugin_map = GetPluginMap ();
199
200 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
201 for (pos = plugin_map.begin(); pos != end; ++pos)
202 {
203 // Call the plug-in "void LLDBPluginTerminate (void)" function if there
204 // is one (if the symbol was not NULL).
205 if (pos->second.plugin_handle)
206 {
207 if (pos->second.plugin_term_callback)
208 ((void (*)(void))pos->second.plugin_term_callback)();
209 Host::DynamicLibraryClose (pos->second.plugin_handle);
210 }
211 }
212 plugin_map.clear();
213}
214
Chris Lattner24943d22010-06-08 16:52:24 +0000215
216#pragma mark ABI
217
218
Jason Molenda53d96862010-06-11 23:44:18 +0000219struct ABIInstance
Chris Lattner24943d22010-06-08 16:52:24 +0000220{
221 ABIInstance() :
222 name(),
223 description(),
224 create_callback(NULL)
225 {
226 }
227
228 std::string name;
229 std::string description;
230 ABICreateInstance create_callback;
231};
232
233typedef std::vector<ABIInstance> ABIInstances;
234
Greg Claytonb1888f22011-03-19 01:12:21 +0000235static Mutex &
236GetABIInstancesMutex ()
Chris Lattner24943d22010-06-08 16:52:24 +0000237{
Greg Claytonb1888f22011-03-19 01:12:21 +0000238 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
239 return g_instances_mutex;
Chris Lattner24943d22010-06-08 16:52:24 +0000240}
241
Greg Claytonb1888f22011-03-19 01:12:21 +0000242static ABIInstances &
243GetABIInstances ()
244{
245 static ABIInstances g_instances;
246 return g_instances;
247}
Chris Lattner24943d22010-06-08 16:52:24 +0000248
249bool
250PluginManager::RegisterPlugin
Greg Clayton52fd9842011-02-02 02:24:04 +0000251(
252 const char *name,
253 const char *description,
254 ABICreateInstance create_callback
255)
Chris Lattner24943d22010-06-08 16:52:24 +0000256{
257 if (create_callback)
258 {
259 ABIInstance instance;
260 assert (name && name[0]);
Greg Clayton5e342f52011-04-13 22:47:15 +0000261 instance.name.assign (name);
Chris Lattner24943d22010-06-08 16:52:24 +0000262 if (description && description[0])
263 instance.description = description;
264 instance.create_callback = create_callback;
Greg Claytonb1888f22011-03-19 01:12:21 +0000265 Mutex::Locker locker (GetABIInstancesMutex ());
266 GetABIInstances ().push_back (instance);
267 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000268 }
269 return false;
270}
271
272bool
273PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
274{
275 if (create_callback)
276 {
Greg Claytonb1888f22011-03-19 01:12:21 +0000277 Mutex::Locker locker (GetABIInstancesMutex ());
278 ABIInstances &instances = GetABIInstances ();
279
280 ABIInstances::iterator pos, end = instances.end();
281 for (pos = instances.begin(); pos != end; ++ pos)
282 {
283 if (pos->create_callback == create_callback)
284 {
285 instances.erase(pos);
286 return true;
287 }
288 }
Chris Lattner24943d22010-06-08 16:52:24 +0000289 }
290 return false;
291}
292
293ABICreateInstance
294PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
295{
Greg Claytonb1888f22011-03-19 01:12:21 +0000296 Mutex::Locker locker (GetABIInstancesMutex ());
297 ABIInstances &instances = GetABIInstances ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000298 if (idx < instances.size())
299 return instances[idx].create_callback;
Jason Molenda53d96862010-06-11 23:44:18 +0000300 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000301}
302
303ABICreateInstance
304PluginManager::GetABICreateCallbackForPluginName (const char *name)
305{
306 if (name && name[0])
307 {
Greg Claytonb1888f22011-03-19 01:12:21 +0000308 Mutex::Locker locker (GetABIInstancesMutex ());
Greg Clayton5e342f52011-04-13 22:47:15 +0000309 llvm::StringRef name_sref(name);
Greg Claytonb1888f22011-03-19 01:12:21 +0000310 ABIInstances &instances = GetABIInstances ();
311
312 ABIInstances::iterator pos, end = instances.end();
313 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner24943d22010-06-08 16:52:24 +0000314 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000315 if (name_sref.equals (pos->name))
Greg Claytonb1888f22011-03-19 01:12:21 +0000316 return pos->create_callback;
Chris Lattner24943d22010-06-08 16:52:24 +0000317 }
318 }
319 return NULL;
320}
321
322
323#pragma mark Disassembler
324
325
Jason Molenda53d96862010-06-11 23:44:18 +0000326struct DisassemblerInstance
Chris Lattner24943d22010-06-08 16:52:24 +0000327{
328 DisassemblerInstance() :
329 name(),
330 description(),
331 create_callback(NULL)
332 {
333 }
334
335 std::string name;
336 std::string description;
337 DisassemblerCreateInstance create_callback;
338};
339
340typedef std::vector<DisassemblerInstance> DisassemblerInstances;
341
Greg Clayton5e342f52011-04-13 22:47:15 +0000342static Mutex &
343GetDisassemblerMutex ()
Chris Lattner24943d22010-06-08 16:52:24 +0000344{
Greg Clayton5e342f52011-04-13 22:47:15 +0000345 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
346 return g_instances_mutex;
Chris Lattner24943d22010-06-08 16:52:24 +0000347}
348
Greg Clayton5e342f52011-04-13 22:47:15 +0000349static DisassemblerInstances &
350GetDisassemblerInstances ()
351{
352 static DisassemblerInstances g_instances;
353 return g_instances;
354}
Chris Lattner24943d22010-06-08 16:52:24 +0000355
356bool
357PluginManager::RegisterPlugin
358(
359 const char *name,
360 const char *description,
361 DisassemblerCreateInstance create_callback
362)
363{
364 if (create_callback)
365 {
366 DisassemblerInstance instance;
367 assert (name && name[0]);
368 instance.name = name;
369 if (description && description[0])
370 instance.description = description;
371 instance.create_callback = create_callback;
Greg Clayton5e342f52011-04-13 22:47:15 +0000372 Mutex::Locker locker (GetDisassemblerMutex ());
373 GetDisassemblerInstances ().push_back (instance);
374 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000375 }
376 return false;
377}
378
379bool
380PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
381{
382 if (create_callback)
383 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000384 Mutex::Locker locker (GetDisassemblerMutex ());
385 DisassemblerInstances &instances = GetDisassemblerInstances ();
386
387 DisassemblerInstances::iterator pos, end = instances.end();
388 for (pos = instances.begin(); pos != end; ++ pos)
389 {
390 if (pos->create_callback == create_callback)
391 {
392 instances.erase(pos);
393 return true;
394 }
395 }
Chris Lattner24943d22010-06-08 16:52:24 +0000396 }
397 return false;
398}
399
400DisassemblerCreateInstance
401PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
402{
Greg Clayton5e342f52011-04-13 22:47:15 +0000403 Mutex::Locker locker (GetDisassemblerMutex ());
404 DisassemblerInstances &instances = GetDisassemblerInstances ();
405 if (idx < instances.size())
406 return instances[idx].create_callback;
Jason Molenda53d96862010-06-11 23:44:18 +0000407 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000408}
409
410DisassemblerCreateInstance
411PluginManager::GetDisassemblerCreateCallbackForPluginName (const char *name)
412{
413 if (name && name[0])
414 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000415 llvm::StringRef name_sref(name);
416 Mutex::Locker locker (GetDisassemblerMutex ());
417 DisassemblerInstances &instances = GetDisassemblerInstances ();
418
419 DisassemblerInstances::iterator pos, end = instances.end();
420 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner24943d22010-06-08 16:52:24 +0000421 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000422 if (name_sref.equals (pos->name))
423 return pos->create_callback;
Chris Lattner24943d22010-06-08 16:52:24 +0000424 }
425 }
426 return NULL;
427}
428
429
430
431#pragma mark DynamicLoader
432
433
Jason Molenda53d96862010-06-11 23:44:18 +0000434struct DynamicLoaderInstance
Chris Lattner24943d22010-06-08 16:52:24 +0000435{
436 DynamicLoaderInstance() :
437 name(),
438 description(),
439 create_callback(NULL)
440 {
441 }
442
443 std::string name;
444 std::string description;
445 DynamicLoaderCreateInstance create_callback;
446};
447
448typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
449
Greg Clayton5e342f52011-04-13 22:47:15 +0000450
451static Mutex &
452GetDynamicLoaderMutex ()
Chris Lattner24943d22010-06-08 16:52:24 +0000453{
Greg Clayton5e342f52011-04-13 22:47:15 +0000454 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
455 return g_instances_mutex;
456}
Chris Lattner24943d22010-06-08 16:52:24 +0000457
Greg Clayton5e342f52011-04-13 22:47:15 +0000458static DynamicLoaderInstances &
459GetDynamicLoaderInstances ()
460{
461 static DynamicLoaderInstances g_instances;
462 return g_instances;
Chris Lattner24943d22010-06-08 16:52:24 +0000463}
464
465
466bool
467PluginManager::RegisterPlugin
468(
469 const char *name,
470 const char *description,
471 DynamicLoaderCreateInstance create_callback
472)
473{
474 if (create_callback)
475 {
476 DynamicLoaderInstance instance;
477 assert (name && name[0]);
478 instance.name = name;
479 if (description && description[0])
480 instance.description = description;
481 instance.create_callback = create_callback;
Greg Clayton5e342f52011-04-13 22:47:15 +0000482 Mutex::Locker locker (GetDynamicLoaderMutex ());
483 GetDynamicLoaderInstances ().push_back (instance);
Chris Lattner24943d22010-06-08 16:52:24 +0000484 }
485 return false;
486}
487
488bool
489PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
490{
491 if (create_callback)
492 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000493 Mutex::Locker locker (GetDynamicLoaderMutex ());
494 DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
495
496 DynamicLoaderInstances::iterator pos, end = instances.end();
497 for (pos = instances.begin(); pos != end; ++ pos)
498 {
499 if (pos->create_callback == create_callback)
500 {
501 instances.erase(pos);
502 return true;
503 }
504 }
Chris Lattner24943d22010-06-08 16:52:24 +0000505 }
506 return false;
507}
508
509DynamicLoaderCreateInstance
510PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
511{
Greg Clayton5e342f52011-04-13 22:47:15 +0000512 Mutex::Locker locker (GetDynamicLoaderMutex ());
513 DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
514 if (idx < instances.size())
515 return instances[idx].create_callback;
Jason Molenda53d96862010-06-11 23:44:18 +0000516 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000517}
518
519DynamicLoaderCreateInstance
520PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const char *name)
521{
522 if (name && name[0])
523 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000524 llvm::StringRef name_sref(name);
525 Mutex::Locker locker (GetDynamicLoaderMutex ());
526 DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
527
528 DynamicLoaderInstances::iterator pos, end = instances.end();
529 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner24943d22010-06-08 16:52:24 +0000530 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000531 if (name_sref.equals (pos->name))
532 return pos->create_callback;
Chris Lattner24943d22010-06-08 16:52:24 +0000533 }
534 }
535 return NULL;
536}
537
Greg Claytonb0770582011-02-01 01:37:45 +0000538#pragma mark EmulateInstruction
539
540
541struct EmulateInstructionInstance
542{
543 EmulateInstructionInstance() :
544 name(),
545 description(),
546 create_callback(NULL)
547 {
548 }
549
550 std::string name;
551 std::string description;
552 EmulateInstructionCreateInstance create_callback;
553};
554
555typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
556
Greg Clayton5e342f52011-04-13 22:47:15 +0000557static Mutex &
558GetEmulateInstructionMutex ()
Greg Claytonb0770582011-02-01 01:37:45 +0000559{
Greg Clayton5e342f52011-04-13 22:47:15 +0000560 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
561 return g_instances_mutex;
562}
563
564static EmulateInstructionInstances &
565GetEmulateInstructionInstances ()
566{
567 static EmulateInstructionInstances g_instances;
568 return g_instances;
Greg Claytonb0770582011-02-01 01:37:45 +0000569}
570
571
572bool
573PluginManager::RegisterPlugin
574(
Greg Clayton52fd9842011-02-02 02:24:04 +0000575 const char *name,
576 const char *description,
577 EmulateInstructionCreateInstance create_callback
578)
Greg Claytonb0770582011-02-01 01:37:45 +0000579{
580 if (create_callback)
581 {
582 EmulateInstructionInstance instance;
583 assert (name && name[0]);
584 instance.name = name;
585 if (description && description[0])
586 instance.description = description;
587 instance.create_callback = create_callback;
Greg Clayton5e342f52011-04-13 22:47:15 +0000588 Mutex::Locker locker (GetEmulateInstructionMutex ());
589 GetEmulateInstructionInstances ().push_back (instance);
Greg Claytonb0770582011-02-01 01:37:45 +0000590 }
591 return false;
592}
593
594bool
595PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
596{
597 if (create_callback)
598 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000599 Mutex::Locker locker (GetEmulateInstructionMutex ());
600 EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
601
602 EmulateInstructionInstances::iterator pos, end = instances.end();
603 for (pos = instances.begin(); pos != end; ++ pos)
604 {
605 if (pos->create_callback == create_callback)
606 {
607 instances.erase(pos);
608 return true;
609 }
610 }
Greg Claytonb0770582011-02-01 01:37:45 +0000611 }
612 return false;
613}
614
615EmulateInstructionCreateInstance
616PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
617{
Greg Clayton5e342f52011-04-13 22:47:15 +0000618 Mutex::Locker locker (GetEmulateInstructionMutex ());
619 EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
620 if (idx < instances.size())
621 return instances[idx].create_callback;
Greg Claytonb0770582011-02-01 01:37:45 +0000622 return NULL;
623}
624
625EmulateInstructionCreateInstance
626PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const char *name)
627{
628 if (name && name[0])
629 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000630 llvm::StringRef name_sref(name);
631 Mutex::Locker locker (GetEmulateInstructionMutex ());
632 EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
633
634 EmulateInstructionInstances::iterator pos, end = instances.end();
635 for (pos = instances.begin(); pos != end; ++ pos)
Greg Claytonb0770582011-02-01 01:37:45 +0000636 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000637 if (name_sref.equals (pos->name))
638 return pos->create_callback;
Greg Claytonb0770582011-02-01 01:37:45 +0000639 }
640 }
641 return NULL;
642}
643
Chris Lattner24943d22010-06-08 16:52:24 +0000644
Jim Ingham642036f2010-09-23 02:01:19 +0000645#pragma mark LanguageRuntime
Chris Lattner24943d22010-06-08 16:52:24 +0000646
647
Jim Ingham642036f2010-09-23 02:01:19 +0000648struct LanguageRuntimeInstance
649{
650 LanguageRuntimeInstance() :
651 name(),
652 description(),
653 create_callback(NULL)
654 {
655 }
656
657 std::string name;
658 std::string description;
659 LanguageRuntimeCreateInstance create_callback;
660};
661
662typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
663
Greg Clayton5e342f52011-04-13 22:47:15 +0000664static Mutex &
665GetLanguageRuntimeMutex ()
Jim Ingham642036f2010-09-23 02:01:19 +0000666{
Greg Clayton5e342f52011-04-13 22:47:15 +0000667 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
668 return g_instances_mutex;
Jim Ingham642036f2010-09-23 02:01:19 +0000669}
670
Greg Clayton5e342f52011-04-13 22:47:15 +0000671static LanguageRuntimeInstances &
672GetLanguageRuntimeInstances ()
673{
674 static LanguageRuntimeInstances g_instances;
675 return g_instances;
676}
Jim Ingham642036f2010-09-23 02:01:19 +0000677
678bool
679PluginManager::RegisterPlugin
Greg Clayton52fd9842011-02-02 02:24:04 +0000680(
681 const char *name,
682 const char *description,
683 LanguageRuntimeCreateInstance create_callback
684)
Jim Ingham642036f2010-09-23 02:01:19 +0000685{
686 if (create_callback)
687 {
688 LanguageRuntimeInstance instance;
689 assert (name && name[0]);
690 instance.name = name;
691 if (description && description[0])
692 instance.description = description;
693 instance.create_callback = create_callback;
Greg Clayton5e342f52011-04-13 22:47:15 +0000694 Mutex::Locker locker (GetLanguageRuntimeMutex ());
695 GetLanguageRuntimeInstances ().push_back (instance);
Jim Ingham642036f2010-09-23 02:01:19 +0000696 }
697 return false;
698}
699
700bool
701PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
702{
703 if (create_callback)
704 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000705 Mutex::Locker locker (GetLanguageRuntimeMutex ());
706 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
707
708 LanguageRuntimeInstances::iterator pos, end = instances.end();
709 for (pos = instances.begin(); pos != end; ++ pos)
710 {
711 if (pos->create_callback == create_callback)
712 {
713 instances.erase(pos);
714 return true;
715 }
716 }
Jim Ingham642036f2010-09-23 02:01:19 +0000717 }
718 return false;
719}
720
721LanguageRuntimeCreateInstance
722PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
723{
Greg Clayton5e342f52011-04-13 22:47:15 +0000724 Mutex::Locker locker (GetLanguageRuntimeMutex ());
725 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
726 if (idx < instances.size())
727 return instances[idx].create_callback;
Jim Ingham642036f2010-09-23 02:01:19 +0000728 return NULL;
729}
730
731LanguageRuntimeCreateInstance
732PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const char *name)
733{
734 if (name && name[0])
735 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000736 llvm::StringRef name_sref(name);
737 Mutex::Locker locker (GetLanguageRuntimeMutex ());
738 LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
739
740 LanguageRuntimeInstances::iterator pos, end = instances.end();
741 for (pos = instances.begin(); pos != end; ++ pos)
Jim Ingham642036f2010-09-23 02:01:19 +0000742 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000743 if (name_sref.equals (pos->name))
744 return pos->create_callback;
Jim Ingham642036f2010-09-23 02:01:19 +0000745 }
746 }
747 return NULL;
748}
749
Chris Lattner24943d22010-06-08 16:52:24 +0000750#pragma mark ObjectFile
751
Jason Molenda53d96862010-06-11 23:44:18 +0000752struct ObjectFileInstance
Chris Lattner24943d22010-06-08 16:52:24 +0000753{
754 ObjectFileInstance() :
755 name(),
756 description(),
757 create_callback(NULL)
758 {
759 }
760
761 std::string name;
762 std::string description;
763 ObjectFileCreateInstance create_callback;
764};
765
766typedef std::vector<ObjectFileInstance> ObjectFileInstances;
767
Greg Clayton5e342f52011-04-13 22:47:15 +0000768static Mutex &
769GetObjectFileMutex ()
Chris Lattner24943d22010-06-08 16:52:24 +0000770{
Greg Clayton5e342f52011-04-13 22:47:15 +0000771 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
772 return g_instances_mutex;
773}
Chris Lattner24943d22010-06-08 16:52:24 +0000774
Greg Clayton5e342f52011-04-13 22:47:15 +0000775static ObjectFileInstances &
776GetObjectFileInstances ()
777{
778 static ObjectFileInstances g_instances;
779 return g_instances;
Chris Lattner24943d22010-06-08 16:52:24 +0000780}
781
782
783bool
784PluginManager::RegisterPlugin
785(
786 const char *name,
787 const char *description,
788 ObjectFileCreateInstance create_callback
789)
790{
791 if (create_callback)
792 {
793 ObjectFileInstance instance;
794 assert (name && name[0]);
795 instance.name = name;
796 if (description && description[0])
797 instance.description = description;
798 instance.create_callback = create_callback;
Greg Clayton5e342f52011-04-13 22:47:15 +0000799 Mutex::Locker locker (GetObjectFileMutex ());
800 GetObjectFileInstances ().push_back (instance);
Chris Lattner24943d22010-06-08 16:52:24 +0000801 }
802 return false;
803}
804
805bool
806PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
807{
808 if (create_callback)
809 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000810 Mutex::Locker locker (GetObjectFileMutex ());
811 ObjectFileInstances &instances = GetObjectFileInstances ();
812
813 ObjectFileInstances::iterator pos, end = instances.end();
814 for (pos = instances.begin(); pos != end; ++ pos)
815 {
816 if (pos->create_callback == create_callback)
817 {
818 instances.erase(pos);
819 return true;
820 }
821 }
Chris Lattner24943d22010-06-08 16:52:24 +0000822 }
823 return false;
824}
825
826ObjectFileCreateInstance
827PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
828{
Greg Clayton5e342f52011-04-13 22:47:15 +0000829 Mutex::Locker locker (GetObjectFileMutex ());
830 ObjectFileInstances &instances = GetObjectFileInstances ();
831 if (idx < instances.size())
832 return instances[idx].create_callback;
Jason Molenda53d96862010-06-11 23:44:18 +0000833 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000834}
Greg Clayton5e342f52011-04-13 22:47:15 +0000835
Chris Lattner24943d22010-06-08 16:52:24 +0000836ObjectFileCreateInstance
837PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name)
838{
839 if (name && name[0])
840 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000841 llvm::StringRef name_sref(name);
842 Mutex::Locker locker (GetObjectFileMutex ());
843 ObjectFileInstances &instances = GetObjectFileInstances ();
844
845 ObjectFileInstances::iterator pos, end = instances.end();
846 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner24943d22010-06-08 16:52:24 +0000847 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000848 if (name_sref.equals (pos->name))
849 return pos->create_callback;
Chris Lattner24943d22010-06-08 16:52:24 +0000850 }
851 }
852 return NULL;
853}
854
855
856
857#pragma mark ObjectContainer
858
Jason Molenda53d96862010-06-11 23:44:18 +0000859struct ObjectContainerInstance
Chris Lattner24943d22010-06-08 16:52:24 +0000860{
861 ObjectContainerInstance() :
862 name(),
863 description(),
864 create_callback(NULL)
865 {
866 }
867
868 std::string name;
869 std::string description;
870 ObjectContainerCreateInstance create_callback;
871};
872
873typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
874
Greg Clayton5e342f52011-04-13 22:47:15 +0000875static Mutex &
876GetObjectContainerMutex ()
Chris Lattner24943d22010-06-08 16:52:24 +0000877{
Greg Clayton5e342f52011-04-13 22:47:15 +0000878 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
879 return g_instances_mutex;
Chris Lattner24943d22010-06-08 16:52:24 +0000880}
881
Greg Clayton5e342f52011-04-13 22:47:15 +0000882static ObjectContainerInstances &
883GetObjectContainerInstances ()
884{
885 static ObjectContainerInstances g_instances;
886 return g_instances;
887}
Chris Lattner24943d22010-06-08 16:52:24 +0000888
889bool
890PluginManager::RegisterPlugin
891(
892 const char *name,
893 const char *description,
894 ObjectContainerCreateInstance create_callback
895)
896{
897 if (create_callback)
898 {
899 ObjectContainerInstance instance;
900 assert (name && name[0]);
901 instance.name = name;
902 if (description && description[0])
903 instance.description = description;
904 instance.create_callback = create_callback;
Greg Clayton5e342f52011-04-13 22:47:15 +0000905 Mutex::Locker locker (GetObjectContainerMutex ());
906 GetObjectContainerInstances ().push_back (instance);
Chris Lattner24943d22010-06-08 16:52:24 +0000907 }
908 return false;
909}
910
911bool
912PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
913{
914 if (create_callback)
915 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000916 Mutex::Locker locker (GetObjectContainerMutex ());
917 ObjectContainerInstances &instances = GetObjectContainerInstances ();
918
919 ObjectContainerInstances::iterator pos, end = instances.end();
920 for (pos = instances.begin(); pos != end; ++ pos)
921 {
922 if (pos->create_callback == create_callback)
923 {
924 instances.erase(pos);
925 return true;
926 }
927 }
Chris Lattner24943d22010-06-08 16:52:24 +0000928 }
929 return false;
930}
931
932ObjectContainerCreateInstance
933PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
934{
Greg Clayton5e342f52011-04-13 22:47:15 +0000935 Mutex::Locker locker (GetObjectContainerMutex ());
936 ObjectContainerInstances &instances = GetObjectContainerInstances ();
937 if (idx < instances.size())
938 return instances[idx].create_callback;
Jason Molenda53d96862010-06-11 23:44:18 +0000939 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000940}
Greg Clayton5e342f52011-04-13 22:47:15 +0000941
Chris Lattner24943d22010-06-08 16:52:24 +0000942ObjectContainerCreateInstance
943PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name)
944{
945 if (name && name[0])
946 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000947 llvm::StringRef name_sref(name);
948 Mutex::Locker locker (GetObjectContainerMutex ());
949 ObjectContainerInstances &instances = GetObjectContainerInstances ();
950
951 ObjectContainerInstances::iterator pos, end = instances.end();
952 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner24943d22010-06-08 16:52:24 +0000953 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000954 if (name_sref.equals (pos->name))
955 return pos->create_callback;
Chris Lattner24943d22010-06-08 16:52:24 +0000956 }
957 }
958 return NULL;
959}
960
961#pragma mark LogChannel
962
Greg Clayton5e342f52011-04-13 22:47:15 +0000963struct LogInstance
Chris Lattner24943d22010-06-08 16:52:24 +0000964{
Greg Clayton5e342f52011-04-13 22:47:15 +0000965 LogInstance() :
Chris Lattner24943d22010-06-08 16:52:24 +0000966 name(),
967 description(),
968 create_callback(NULL)
969 {
970 }
971
972 std::string name;
973 std::string description;
974 LogChannelCreateInstance create_callback;
975};
976
Greg Clayton5e342f52011-04-13 22:47:15 +0000977typedef std::vector<LogInstance> LogInstances;
Chris Lattner24943d22010-06-08 16:52:24 +0000978
Greg Clayton5e342f52011-04-13 22:47:15 +0000979static Mutex &
980GetLogMutex ()
Chris Lattner24943d22010-06-08 16:52:24 +0000981{
Greg Clayton5e342f52011-04-13 22:47:15 +0000982 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
983 return g_instances_mutex;
Chris Lattner24943d22010-06-08 16:52:24 +0000984}
985
Greg Clayton5e342f52011-04-13 22:47:15 +0000986static LogInstances &
987GetLogInstances ()
988{
989 static LogInstances g_instances;
990 return g_instances;
991}
992
993
Chris Lattner24943d22010-06-08 16:52:24 +0000994
995bool
996PluginManager::RegisterPlugin
997(
998 const char *name,
999 const char *description,
1000 LogChannelCreateInstance create_callback
1001)
1002{
1003 if (create_callback)
1004 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001005 LogInstance instance;
Chris Lattner24943d22010-06-08 16:52:24 +00001006 assert (name && name[0]);
1007 instance.name = name;
1008 if (description && description[0])
1009 instance.description = description;
1010 instance.create_callback = create_callback;
Greg Clayton5e342f52011-04-13 22:47:15 +00001011 Mutex::Locker locker (GetLogMutex ());
1012 GetLogInstances ().push_back (instance);
Chris Lattner24943d22010-06-08 16:52:24 +00001013 }
1014 return false;
1015}
1016
1017bool
1018PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
1019{
1020 if (create_callback)
1021 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001022 Mutex::Locker locker (GetLogMutex ());
1023 LogInstances &instances = GetLogInstances ();
1024
1025 LogInstances::iterator pos, end = instances.end();
1026 for (pos = instances.begin(); pos != end; ++ pos)
1027 {
1028 if (pos->create_callback == create_callback)
1029 {
1030 instances.erase(pos);
1031 return true;
1032 }
1033 }
Chris Lattner24943d22010-06-08 16:52:24 +00001034 }
1035 return false;
1036}
1037
1038const char *
1039PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
1040{
Greg Clayton5e342f52011-04-13 22:47:15 +00001041 Mutex::Locker locker (GetLogMutex ());
1042 LogInstances &instances = GetLogInstances ();
1043 if (idx < instances.size())
1044 return instances[idx].name.c_str();
Chris Lattner24943d22010-06-08 16:52:24 +00001045 return NULL;
1046}
1047
1048
1049LogChannelCreateInstance
1050PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
1051{
Greg Clayton5e342f52011-04-13 22:47:15 +00001052 Mutex::Locker locker (GetLogMutex ());
1053 LogInstances &instances = GetLogInstances ();
1054 if (idx < instances.size())
1055 return instances[idx].create_callback;
Jason Molenda53d96862010-06-11 23:44:18 +00001056 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001057}
1058
1059LogChannelCreateInstance
1060PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name)
1061{
1062 if (name && name[0])
1063 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001064 llvm::StringRef name_sref(name);
1065 Mutex::Locker locker (GetLogMutex ());
1066 LogInstances &instances = GetLogInstances ();
1067
1068 LogInstances::iterator pos, end = instances.end();
1069 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner24943d22010-06-08 16:52:24 +00001070 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001071 if (name_sref.equals (pos->name))
1072 return pos->create_callback;
Chris Lattner24943d22010-06-08 16:52:24 +00001073 }
1074 }
1075 return NULL;
1076}
1077
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001078#pragma mark Platform
Chris Lattner24943d22010-06-08 16:52:24 +00001079
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001080struct PlatformInstance
Chris Lattner24943d22010-06-08 16:52:24 +00001081{
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001082 PlatformInstance() :
Chris Lattner24943d22010-06-08 16:52:24 +00001083 name(),
1084 description(),
1085 create_callback(NULL)
1086 {
1087 }
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001088
1089 std::string name;
1090 std::string description;
1091 PlatformCreateInstance create_callback;
1092};
Chris Lattner24943d22010-06-08 16:52:24 +00001093
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001094typedef std::vector<PlatformInstance> PlatformInstances;
1095
Greg Claytonb1888f22011-03-19 01:12:21 +00001096static Mutex &
1097GetPlatformInstancesMutex ()
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001098{
Greg Claytonb1888f22011-03-19 01:12:21 +00001099 static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
1100 return g_platform_instances_mutex;
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001101}
1102
Greg Claytonb1888f22011-03-19 01:12:21 +00001103static PlatformInstances &
1104GetPlatformInstances ()
1105{
1106 static PlatformInstances g_platform_instances;
1107 return g_platform_instances;
1108}
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001109
Greg Clayton5e342f52011-04-13 22:47:15 +00001110
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001111bool
1112PluginManager::RegisterPlugin (const char *name,
1113 const char *description,
1114 PlatformCreateInstance create_callback)
1115{
1116 if (create_callback)
1117 {
Greg Claytonb1888f22011-03-19 01:12:21 +00001118 Mutex::Locker locker (GetPlatformInstancesMutex ());
1119
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001120 PlatformInstance instance;
1121 assert (name && name[0]);
1122 instance.name = name;
1123 if (description && description[0])
1124 instance.description = description;
1125 instance.create_callback = create_callback;
Greg Claytonb1888f22011-03-19 01:12:21 +00001126 GetPlatformInstances ().push_back (instance);
1127 return true;
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001128 }
1129 return false;
1130}
1131
1132const char *
1133PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
1134{
Greg Claytonb1888f22011-03-19 01:12:21 +00001135 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Clayton5e342f52011-04-13 22:47:15 +00001136 PlatformInstances &instances = GetPlatformInstances ();
1137 if (idx < instances.size())
1138 return instances[idx].name.c_str();
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001139 return NULL;
1140}
1141
1142const char *
1143PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
1144{
Greg Claytonb1888f22011-03-19 01:12:21 +00001145 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Clayton5e342f52011-04-13 22:47:15 +00001146 PlatformInstances &instances = GetPlatformInstances ();
1147 if (idx < instances.size())
1148 return instances[idx].description.c_str();
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001149 return NULL;
1150}
1151
1152bool
1153PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
1154{
1155 if (create_callback)
1156 {
Greg Claytonb1888f22011-03-19 01:12:21 +00001157 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Clayton5e342f52011-04-13 22:47:15 +00001158 PlatformInstances &instances = GetPlatformInstances ();
Greg Claytonb1888f22011-03-19 01:12:21 +00001159
Greg Clayton5e342f52011-04-13 22:47:15 +00001160 PlatformInstances::iterator pos, end = instances.end();
1161 for (pos = instances.begin(); pos != end; ++ pos)
Greg Claytonb1888f22011-03-19 01:12:21 +00001162 {
1163 if (pos->create_callback == create_callback)
1164 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001165 instances.erase(pos);
Greg Claytonb1888f22011-03-19 01:12:21 +00001166 return true;
1167 }
1168 }
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001169 }
1170 return false;
1171}
1172
1173PlatformCreateInstance
1174PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
1175{
Greg Claytonb1888f22011-03-19 01:12:21 +00001176 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Clayton5e342f52011-04-13 22:47:15 +00001177 PlatformInstances &instances = GetPlatformInstances ();
1178 if (idx < instances.size())
1179 return instances[idx].create_callback;
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001180 return NULL;
1181}
1182
1183PlatformCreateInstance
1184PluginManager::GetPlatformCreateCallbackForPluginName (const char *name)
1185{
1186 if (name && name[0])
1187 {
Greg Claytonb1888f22011-03-19 01:12:21 +00001188 Mutex::Locker locker (GetPlatformInstancesMutex ());
Greg Clayton5e342f52011-04-13 22:47:15 +00001189 PlatformInstances &instances = GetPlatformInstances ();
1190 llvm::StringRef name_sref(name);
Greg Claytonb1888f22011-03-19 01:12:21 +00001191
Greg Clayton5e342f52011-04-13 22:47:15 +00001192 PlatformInstances::iterator pos, end = instances.end();
1193 for (pos = instances.begin(); pos != end; ++ pos)
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001194 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001195 if (name_sref.equals (pos->name))
Greg Claytonb1888f22011-03-19 01:12:21 +00001196 return pos->create_callback;
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001197 }
1198 }
1199 return NULL;
1200}
1201
Greg Clayton5e342f52011-04-13 22:47:15 +00001202uint32_t
1203PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
1204{
1205 if (name && name[0])
1206 {
1207 Mutex::Locker locker (GetPlatformInstancesMutex ());
1208 PlatformInstances &instances = GetPlatformInstances ();
1209 llvm::StringRef name_sref(name);
1210
1211 PlatformInstances::iterator pos, end = instances.end();
1212 for (pos = instances.begin(); pos != end; ++ pos)
1213 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001214 llvm::StringRef plugin_name (pos->name);
1215 if (plugin_name.startswith(name_sref))
1216 matches.AppendString (plugin_name.data());
Greg Clayton5e342f52011-04-13 22:47:15 +00001217 }
1218 }
1219 return matches.GetSize();
1220}
1221
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001222#pragma mark Process
1223
1224struct ProcessInstance
1225{
1226 ProcessInstance() :
1227 name(),
1228 description(),
1229 create_callback(NULL)
1230 {
1231 }
1232
Chris Lattner24943d22010-06-08 16:52:24 +00001233 std::string name;
1234 std::string description;
1235 ProcessCreateInstance create_callback;
1236};
1237
1238typedef std::vector<ProcessInstance> ProcessInstances;
1239
Greg Clayton5e342f52011-04-13 22:47:15 +00001240static Mutex &
1241GetProcessMutex ()
Chris Lattner24943d22010-06-08 16:52:24 +00001242{
Greg Clayton5e342f52011-04-13 22:47:15 +00001243 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1244 return g_instances_mutex;
1245}
1246
1247static ProcessInstances &
1248GetProcessInstances ()
1249{
1250 static ProcessInstances g_instances;
1251 return g_instances;
Chris Lattner24943d22010-06-08 16:52:24 +00001252}
1253
1254
1255bool
1256PluginManager::RegisterPlugin
1257(
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001258 const char *name,
1259 const char *description,
1260 ProcessCreateInstance create_callback
1261 )
Chris Lattner24943d22010-06-08 16:52:24 +00001262{
1263 if (create_callback)
1264 {
1265 ProcessInstance instance;
1266 assert (name && name[0]);
1267 instance.name = name;
1268 if (description && description[0])
1269 instance.description = description;
1270 instance.create_callback = create_callback;
Greg Clayton5e342f52011-04-13 22:47:15 +00001271 Mutex::Locker locker (GetProcessMutex ());
1272 GetProcessInstances ().push_back (instance);
Chris Lattner24943d22010-06-08 16:52:24 +00001273 }
1274 return false;
1275}
1276
Greg Claytond284b662011-02-18 01:44:25 +00001277const char *
1278PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
1279{
Greg Clayton5e342f52011-04-13 22:47:15 +00001280 Mutex::Locker locker (GetProcessMutex ());
1281 ProcessInstances &instances = GetProcessInstances ();
1282 if (idx < instances.size())
1283 return instances[idx].name.c_str();
Greg Claytond284b662011-02-18 01:44:25 +00001284 return NULL;
1285}
1286
1287const char *
1288PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
1289{
Greg Clayton5e342f52011-04-13 22:47:15 +00001290 Mutex::Locker locker (GetProcessMutex ());
1291 ProcessInstances &instances = GetProcessInstances ();
1292 if (idx < instances.size())
1293 return instances[idx].description.c_str();
Greg Claytond284b662011-02-18 01:44:25 +00001294 return NULL;
1295}
1296
Chris Lattner24943d22010-06-08 16:52:24 +00001297bool
1298PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1299{
1300 if (create_callback)
1301 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001302 Mutex::Locker locker (GetProcessMutex ());
1303 ProcessInstances &instances = GetProcessInstances ();
1304
1305 ProcessInstances::iterator pos, end = instances.end();
1306 for (pos = instances.begin(); pos != end; ++ pos)
1307 {
1308 if (pos->create_callback == create_callback)
1309 {
1310 instances.erase(pos);
1311 return true;
1312 }
1313 }
Chris Lattner24943d22010-06-08 16:52:24 +00001314 }
1315 return false;
1316}
1317
1318ProcessCreateInstance
1319PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1320{
Greg Clayton5e342f52011-04-13 22:47:15 +00001321 Mutex::Locker locker (GetProcessMutex ());
1322 ProcessInstances &instances = GetProcessInstances ();
1323 if (idx < instances.size())
1324 return instances[idx].create_callback;
Jason Molenda53d96862010-06-11 23:44:18 +00001325 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001326}
1327
Greg Clayton5e342f52011-04-13 22:47:15 +00001328
Chris Lattner24943d22010-06-08 16:52:24 +00001329ProcessCreateInstance
1330PluginManager::GetProcessCreateCallbackForPluginName (const char *name)
1331{
1332 if (name && name[0])
1333 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001334 llvm::StringRef name_sref(name);
1335 Mutex::Locker locker (GetProcessMutex ());
1336 ProcessInstances &instances = GetProcessInstances ();
1337
1338 ProcessInstances::iterator pos, end = instances.end();
1339 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner24943d22010-06-08 16:52:24 +00001340 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001341 if (name_sref.equals (pos->name))
1342 return pos->create_callback;
Chris Lattner24943d22010-06-08 16:52:24 +00001343 }
1344 }
1345 return NULL;
1346}
1347
1348#pragma mark SymbolFile
1349
Jason Molenda53d96862010-06-11 23:44:18 +00001350struct SymbolFileInstance
Chris Lattner24943d22010-06-08 16:52:24 +00001351{
1352 SymbolFileInstance() :
1353 name(),
1354 description(),
1355 create_callback(NULL)
1356 {
1357 }
1358
1359 std::string name;
1360 std::string description;
1361 SymbolFileCreateInstance create_callback;
1362};
1363
1364typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1365
Greg Clayton5e342f52011-04-13 22:47:15 +00001366static Mutex &
1367GetSymbolFileMutex ()
Chris Lattner24943d22010-06-08 16:52:24 +00001368{
Greg Clayton5e342f52011-04-13 22:47:15 +00001369 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1370 return g_instances_mutex;
1371}
Chris Lattner24943d22010-06-08 16:52:24 +00001372
Greg Clayton5e342f52011-04-13 22:47:15 +00001373static SymbolFileInstances &
1374GetSymbolFileInstances ()
1375{
1376 static SymbolFileInstances g_instances;
1377 return g_instances;
Chris Lattner24943d22010-06-08 16:52:24 +00001378}
1379
1380
1381bool
1382PluginManager::RegisterPlugin
1383(
1384 const char *name,
1385 const char *description,
1386 SymbolFileCreateInstance create_callback
1387)
1388{
1389 if (create_callback)
1390 {
1391 SymbolFileInstance instance;
1392 assert (name && name[0]);
1393 instance.name = name;
1394 if (description && description[0])
1395 instance.description = description;
1396 instance.create_callback = create_callback;
Greg Clayton5e342f52011-04-13 22:47:15 +00001397 Mutex::Locker locker (GetSymbolFileMutex ());
1398 GetSymbolFileInstances ().push_back (instance);
Chris Lattner24943d22010-06-08 16:52:24 +00001399 }
1400 return false;
1401}
1402
1403bool
1404PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1405{
1406 if (create_callback)
1407 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001408 Mutex::Locker locker (GetSymbolFileMutex ());
1409 SymbolFileInstances &instances = GetSymbolFileInstances ();
1410
1411 SymbolFileInstances::iterator pos, end = instances.end();
1412 for (pos = instances.begin(); pos != end; ++ pos)
1413 {
1414 if (pos->create_callback == create_callback)
1415 {
1416 instances.erase(pos);
1417 return true;
1418 }
1419 }
Chris Lattner24943d22010-06-08 16:52:24 +00001420 }
1421 return false;
1422}
1423
1424SymbolFileCreateInstance
1425PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1426{
Greg Clayton5e342f52011-04-13 22:47:15 +00001427 Mutex::Locker locker (GetSymbolFileMutex ());
1428 SymbolFileInstances &instances = GetSymbolFileInstances ();
1429 if (idx < instances.size())
1430 return instances[idx].create_callback;
Jason Molenda53d96862010-06-11 23:44:18 +00001431 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001432}
Greg Clayton5e342f52011-04-13 22:47:15 +00001433
Chris Lattner24943d22010-06-08 16:52:24 +00001434SymbolFileCreateInstance
1435PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name)
1436{
1437 if (name && name[0])
1438 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001439 llvm::StringRef name_sref(name);
1440 Mutex::Locker locker (GetSymbolFileMutex ());
1441 SymbolFileInstances &instances = GetSymbolFileInstances ();
1442
1443 SymbolFileInstances::iterator pos, end = instances.end();
1444 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner24943d22010-06-08 16:52:24 +00001445 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001446 if (name_sref.equals (pos->name))
1447 return pos->create_callback;
Chris Lattner24943d22010-06-08 16:52:24 +00001448 }
1449 }
1450 return NULL;
1451}
1452
1453
1454
1455#pragma mark SymbolVendor
1456
Jason Molenda53d96862010-06-11 23:44:18 +00001457struct SymbolVendorInstance
Chris Lattner24943d22010-06-08 16:52:24 +00001458{
1459 SymbolVendorInstance() :
1460 name(),
1461 description(),
1462 create_callback(NULL)
1463 {
1464 }
1465
1466 std::string name;
1467 std::string description;
1468 SymbolVendorCreateInstance create_callback;
1469};
1470
1471typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1472
Greg Clayton5e342f52011-04-13 22:47:15 +00001473static Mutex &
1474GetSymbolVendorMutex ()
Chris Lattner24943d22010-06-08 16:52:24 +00001475{
Greg Clayton5e342f52011-04-13 22:47:15 +00001476 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1477 return g_instances_mutex;
1478}
Chris Lattner24943d22010-06-08 16:52:24 +00001479
Greg Clayton5e342f52011-04-13 22:47:15 +00001480static SymbolVendorInstances &
1481GetSymbolVendorInstances ()
1482{
1483 static SymbolVendorInstances g_instances;
1484 return g_instances;
Chris Lattner24943d22010-06-08 16:52:24 +00001485}
1486
1487bool
1488PluginManager::RegisterPlugin
1489(
1490 const char *name,
1491 const char *description,
1492 SymbolVendorCreateInstance create_callback
1493)
1494{
1495 if (create_callback)
1496 {
1497 SymbolVendorInstance instance;
1498 assert (name && name[0]);
1499 instance.name = name;
1500 if (description && description[0])
1501 instance.description = description;
1502 instance.create_callback = create_callback;
Greg Clayton5e342f52011-04-13 22:47:15 +00001503 Mutex::Locker locker (GetSymbolVendorMutex ());
1504 GetSymbolVendorInstances ().push_back (instance);
Chris Lattner24943d22010-06-08 16:52:24 +00001505 }
1506 return false;
1507}
1508
1509bool
1510PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1511{
1512 if (create_callback)
1513 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001514 Mutex::Locker locker (GetSymbolVendorMutex ());
1515 SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1516
1517 SymbolVendorInstances::iterator pos, end = instances.end();
1518 for (pos = instances.begin(); pos != end; ++ pos)
1519 {
1520 if (pos->create_callback == create_callback)
1521 {
1522 instances.erase(pos);
1523 return true;
1524 }
1525 }
Chris Lattner24943d22010-06-08 16:52:24 +00001526 }
1527 return false;
1528}
1529
1530SymbolVendorCreateInstance
1531PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1532{
Greg Clayton5e342f52011-04-13 22:47:15 +00001533 Mutex::Locker locker (GetSymbolVendorMutex ());
1534 SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1535 if (idx < instances.size())
1536 return instances[idx].create_callback;
Jason Molenda53d96862010-06-11 23:44:18 +00001537 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001538}
1539
Greg Clayton5e342f52011-04-13 22:47:15 +00001540
Chris Lattner24943d22010-06-08 16:52:24 +00001541SymbolVendorCreateInstance
1542PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name)
1543{
1544 if (name && name[0])
1545 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001546 llvm::StringRef name_sref(name);
1547 Mutex::Locker locker (GetSymbolVendorMutex ());
1548 SymbolVendorInstances &instances = GetSymbolVendorInstances ();
1549
1550 SymbolVendorInstances::iterator pos, end = instances.end();
1551 for (pos = instances.begin(); pos != end; ++ pos)
Chris Lattner24943d22010-06-08 16:52:24 +00001552 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001553 if (name_sref.equals (pos->name))
1554 return pos->create_callback;
Chris Lattner24943d22010-06-08 16:52:24 +00001555 }
1556 }
1557 return NULL;
1558}
1559
1560
Greg Clayton8badcb22011-04-25 21:14:26 +00001561#pragma mark UnwindAssembly
Jason Molenda3a4ea242010-09-10 07:49:16 +00001562
Greg Clayton8badcb22011-04-25 21:14:26 +00001563struct UnwindAssemblyInstance
Jason Molenda3a4ea242010-09-10 07:49:16 +00001564{
Greg Clayton8badcb22011-04-25 21:14:26 +00001565 UnwindAssemblyInstance() :
Jason Molenda3a4ea242010-09-10 07:49:16 +00001566 name(),
1567 description(),
1568 create_callback(NULL)
1569 {
1570 }
1571
1572 std::string name;
1573 std::string description;
Greg Clayton8badcb22011-04-25 21:14:26 +00001574 UnwindAssemblyCreateInstance create_callback;
Jason Molenda3a4ea242010-09-10 07:49:16 +00001575};
1576
Greg Clayton8badcb22011-04-25 21:14:26 +00001577typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
Jason Molenda3a4ea242010-09-10 07:49:16 +00001578
Greg Clayton5e342f52011-04-13 22:47:15 +00001579static Mutex &
Greg Clayton8badcb22011-04-25 21:14:26 +00001580GetUnwindAssemblyMutex ()
Jason Molenda3a4ea242010-09-10 07:49:16 +00001581{
Greg Clayton5e342f52011-04-13 22:47:15 +00001582 static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
1583 return g_instances_mutex;
1584}
Jason Molenda3a4ea242010-09-10 07:49:16 +00001585
Greg Clayton8badcb22011-04-25 21:14:26 +00001586static UnwindAssemblyInstances &
1587GetUnwindAssemblyInstances ()
Greg Clayton5e342f52011-04-13 22:47:15 +00001588{
Greg Clayton8badcb22011-04-25 21:14:26 +00001589 static UnwindAssemblyInstances g_instances;
Greg Clayton5e342f52011-04-13 22:47:15 +00001590 return g_instances;
Jason Molenda3a4ea242010-09-10 07:49:16 +00001591}
1592
1593bool
1594PluginManager::RegisterPlugin
1595(
1596 const char *name,
1597 const char *description,
Greg Clayton8badcb22011-04-25 21:14:26 +00001598 UnwindAssemblyCreateInstance create_callback
Jason Molenda3a4ea242010-09-10 07:49:16 +00001599)
1600{
1601 if (create_callback)
1602 {
Greg Clayton8badcb22011-04-25 21:14:26 +00001603 UnwindAssemblyInstance instance;
Jason Molenda3a4ea242010-09-10 07:49:16 +00001604 assert (name && name[0]);
1605 instance.name = name;
1606 if (description && description[0])
1607 instance.description = description;
1608 instance.create_callback = create_callback;
Greg Clayton8badcb22011-04-25 21:14:26 +00001609 Mutex::Locker locker (GetUnwindAssemblyMutex ());
1610 GetUnwindAssemblyInstances ().push_back (instance);
Jason Molenda3a4ea242010-09-10 07:49:16 +00001611 }
1612 return false;
1613}
1614
1615bool
Greg Clayton8badcb22011-04-25 21:14:26 +00001616PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
Jason Molenda3a4ea242010-09-10 07:49:16 +00001617{
1618 if (create_callback)
1619 {
Greg Clayton8badcb22011-04-25 21:14:26 +00001620 Mutex::Locker locker (GetUnwindAssemblyMutex ());
1621 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
Greg Clayton5e342f52011-04-13 22:47:15 +00001622
Greg Clayton8badcb22011-04-25 21:14:26 +00001623 UnwindAssemblyInstances::iterator pos, end = instances.end();
Greg Clayton5e342f52011-04-13 22:47:15 +00001624 for (pos = instances.begin(); pos != end; ++ pos)
1625 {
1626 if (pos->create_callback == create_callback)
1627 {
1628 instances.erase(pos);
1629 return true;
1630 }
1631 }
Jason Molenda3a4ea242010-09-10 07:49:16 +00001632 }
1633 return false;
1634}
1635
Greg Clayton8badcb22011-04-25 21:14:26 +00001636UnwindAssemblyCreateInstance
1637PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
Jason Molenda3a4ea242010-09-10 07:49:16 +00001638{
Greg Clayton8badcb22011-04-25 21:14:26 +00001639 Mutex::Locker locker (GetUnwindAssemblyMutex ());
1640 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
Greg Clayton5e342f52011-04-13 22:47:15 +00001641 if (idx < instances.size())
1642 return instances[idx].create_callback;
Jason Molenda3a4ea242010-09-10 07:49:16 +00001643 return NULL;
1644}
1645
Greg Clayton5e342f52011-04-13 22:47:15 +00001646
Greg Clayton8badcb22011-04-25 21:14:26 +00001647UnwindAssemblyCreateInstance
1648PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const char *name)
Jason Molenda3a4ea242010-09-10 07:49:16 +00001649{
1650 if (name && name[0])
1651 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001652 llvm::StringRef name_sref(name);
Greg Clayton8badcb22011-04-25 21:14:26 +00001653 Mutex::Locker locker (GetUnwindAssemblyMutex ());
1654 UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
Greg Clayton5e342f52011-04-13 22:47:15 +00001655
Greg Clayton8badcb22011-04-25 21:14:26 +00001656 UnwindAssemblyInstances::iterator pos, end = instances.end();
Greg Clayton5e342f52011-04-13 22:47:15 +00001657 for (pos = instances.begin(); pos != end; ++ pos)
Jason Molenda3a4ea242010-09-10 07:49:16 +00001658 {
Greg Clayton5e342f52011-04-13 22:47:15 +00001659 if (name_sref.equals (pos->name))
1660 return pos->create_callback;
Jason Molenda3a4ea242010-09-10 07:49:16 +00001661 }
1662 }
1663 return NULL;
1664}
1665