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