[Lldb-commits] [lldb] r164865 - in /lldb/trunk: examples/plugins/ examples/plugins/commands/ include/lldb/ include/lldb/API/ include/lldb/Core/ include/lldb/Host/ include/lldb/Interpreter/ lldb.xcodeproj/ scripts/Python/ scripts/Python/interface/ source/API/ source/Commands/ source/Core/ source/Host/common/ source/Interpreter/

Enrico Granata egranata at apple.com
Fri Sep 28 16:57:52 PDT 2012


Author: enrico
Date: Fri Sep 28 18:57:51 2012
New Revision: 164865

URL: http://llvm.org/viewvc/llvm-project?rev=164865&view=rev
Log:
Implementing plugins that provide commands.
This checkin adds the capability for LLDB to load plugins from external dylibs that can provide new commands
It exports an SBCommand class from the public API layer, and a new SBCommandPluginInterface

There is a minimal load-only plugin manager built into the debugger, which can be accessed via Debugger::LoadPlugin.

Plugins are loaded from two locations at debugger startup (LLDB.framework/Resources/PlugIns and ~/Library/Application Support/LLDB/PlugIns) and more can be (re)loaded via the "plugin load" command

For an example of how to make a plugin, refer to the fooplugin.cpp file in examples/plugins/commands

Caveats:
	Currently, the new API objects and features are not exposed via Python.
	The new commands can only be "parsed" (i.e. not raw) and get their command line via a char** parameter (we do not expose our internal Args object)
	There is no unloading feature, which can potentially lead to leaks if you overwrite the commands by reloading the same or different plugins
	There is no API exposed for option parsing, which means you may need to use getopt or roll-your-own

Added:
    lldb/trunk/examples/plugins/
    lldb/trunk/examples/plugins/commands/
    lldb/trunk/examples/plugins/commands/fooplugin.cpp
    lldb/trunk/include/lldb/Host/DynamicLibrary.h
    lldb/trunk/source/Commands/CommandObjectPlugin.cpp
    lldb/trunk/source/Commands/CommandObjectPlugin.h
    lldb/trunk/source/Host/common/DynamicLibrary.cpp
Modified:
    lldb/trunk/include/lldb/API/SBCommandInterpreter.h
    lldb/trunk/include/lldb/API/SBCommandReturnObject.h
    lldb/trunk/include/lldb/API/SBDebugger.h
    lldb/trunk/include/lldb/API/SBDefines.h
    lldb/trunk/include/lldb/API/SBError.h
    lldb/trunk/include/lldb/Core/Debugger.h
    lldb/trunk/include/lldb/Interpreter/CommandObject.h
    lldb/trunk/include/lldb/Interpreter/CommandObjectMultiword.h
    lldb/trunk/include/lldb/lldb-forward.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/scripts/Python/build-swig-Python.sh
    lldb/trunk/scripts/Python/interface/SBCommandInterpreter.i
    lldb/trunk/scripts/Python/interface/SBCommandReturnObject.i
    lldb/trunk/source/API/SBCommandInterpreter.cpp
    lldb/trunk/source/API/SBCommandReturnObject.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp

Added: lldb/trunk/examples/plugins/commands/fooplugin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/plugins/commands/fooplugin.cpp?rev=164865&view=auto
==============================================================================
--- lldb/trunk/examples/plugins/commands/fooplugin.cpp (added)
+++ lldb/trunk/examples/plugins/commands/fooplugin.cpp Fri Sep 28 18:57:51 2012
@@ -0,0 +1,47 @@
+/*
+An example plugin for LLDB that provides a new foo command with a child subcommand
+Compile this into a dylib foo.dylib and load by placing in appropriate locations on disk or
+by typing plugin load foo.dylib at the LLDB command line
+*/
+
+#include <LLDB/SBCommandInterpreter.h>
+#include <LLDB/SBCommandReturnObject.h>
+#include <LLDB/SBDebugger.h>
+
+namespace lldb {
+    bool
+    PluginInitialize (lldb::SBDebugger debugger);
+}
+
+class ChildCommand : public lldb::SBCommandPluginInterface
+{
+public:
+    virtual bool
+    DoExecute (lldb::SBDebugger debugger,
+               char** command,
+               lldb::SBCommandReturnObject &result)
+    {
+        if (command)
+        {
+            const char* arg = *command;
+            while (arg)
+            {
+                printf("%s\n",arg);
+                arg = *(++command);
+            }
+            return true;
+        }
+        return false;
+    }
+    
+};
+
+bool
+lldb::PluginInitialize (lldb::SBDebugger debugger)
+{
+    lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter();
+    lldb::SBCommand foo = interpreter.AddMultiwordCommand("foo",NULL);
+    foo.AddCommand("child",new ChildCommand(),"a child of foo");
+    return true;
+}
+

Modified: lldb/trunk/include/lldb/API/SBCommandInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBCommandInterpreter.h?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBCommandInterpreter.h (original)
+++ lldb/trunk/include/lldb/API/SBCommandInterpreter.h Fri Sep 28 18:57:51 2012
@@ -11,6 +11,7 @@
 #define LLDB_SBCommandInterpreter_h_
 
 #include "lldb/API/SBDefines.h"
+#include "lldb/API/SBDebugger.h"
 
 namespace lldb {
 
@@ -65,6 +66,15 @@
 
     lldb::SBProcess
     GetProcess ();
+    
+    lldb::SBDebugger
+    GetDebugger ();
+    
+    lldb::SBCommand
+    AddMultiwordCommand (const char* name, const char* help);
+    
+    lldb::SBCommand
+    AddCommand (const char* name, lldb::SBCommandPluginInterface *impl, const char* help);
 
     void
     SourceInitFileInHomeDirectory (lldb::SBCommandReturnObject &result);
@@ -99,6 +109,9 @@
     SetCommandOverrideCallback (const char *command_name,
                                 lldb::CommandOverrideCallback callback,
                                 void *baton);
+    
+    SBCommandInterpreter (lldb_private::CommandInterpreter *interpreter_ptr = NULL);   // Access using SBDebugger::GetCommandInterpreter();
+    
 protected:
 
     lldb_private::CommandInterpreter &
@@ -112,14 +125,58 @@
 private:
     friend class SBDebugger;
 
-    SBCommandInterpreter (lldb_private::CommandInterpreter *interpreter_ptr = NULL);   // Access using SBDebugger::GetCommandInterpreter();
-
     static void
     InitializeSWIG ();
 
     lldb_private::CommandInterpreter *m_opaque_ptr;
 };
 
+class SBCommandPluginInterface
+{
+public:
+    virtual bool
+    DoExecute (lldb::SBDebugger debugger,
+               char** command,
+               lldb::SBCommandReturnObject &result)
+    {
+        return false;
+    }
+    
+    virtual
+    ~SBCommandPluginInterface ()
+    {}
+};
+    
+class SBCommand
+{
+public:
+    
+    SBCommand ();
+    
+    bool
+    IsValid ();
+    
+    const char*
+    GetName ();
+    
+    const char*
+    GetHelp ();
+    
+    lldb::SBCommand
+    AddMultiwordCommand (const char* name, const char* help = NULL);
+    
+    lldb::SBCommand
+    AddCommand (const char* name, lldb::SBCommandPluginInterface* impl, const char* help = NULL);
+    
+private:
+    
+    friend class SBDebugger;
+    friend class SBCommandInterpreter;
+    
+    SBCommand (lldb::CommandObjectSP cmd_sp);
+    
+    lldb::CommandObjectSP m_opaque_sp;
+};
 
 } // namespace lldb
 

Modified: lldb/trunk/include/lldb/API/SBCommandReturnObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBCommandReturnObject.h?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBCommandReturnObject.h (original)
+++ lldb/trunk/include/lldb/API/SBCommandReturnObject.h Fri Sep 28 18:57:51 2012
@@ -74,6 +74,9 @@
     void
     AppendMessage (const char *message);
 
+    void
+    AppendWarning (const char *message);
+    
     bool
     GetDescription (lldb::SBStream &description);
     

Modified: lldb/trunk/include/lldb/API/SBDebugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDebugger.h (original)
+++ lldb/trunk/include/lldb/API/SBDebugger.h Fri Sep 28 18:57:51 2012
@@ -295,11 +295,12 @@
 
 private:
 
+    friend class SBCommandInterpreter;
     friend class SBInputReader;
+    friend class SBListener;
     friend class SBProcess;
     friend class SBSourceManager;
     friend class SBTarget;
-    friend class SBListener;
     
     lldb::SBTarget
     FindTargetWithLLDBProcess (const lldb::ProcessSP &processSP);

Modified: lldb/trunk/include/lldb/API/SBDefines.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDefines.h?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDefines.h (original)
+++ lldb/trunk/include/lldb/API/SBDefines.h Fri Sep 28 18:57:51 2012
@@ -29,7 +29,9 @@
 class SBBreakpoint;
 class SBBreakpointLocation;
 class SBBroadcaster;
+class SBCommand;
 class SBCommandInterpreter;
+class SBCommandPluginInterface;
 class SBCommandReturnObject;
 class SBCommunication;
 class SBCompileUnit;

Modified: lldb/trunk/include/lldb/API/SBError.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBError.h?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBError.h (original)
+++ lldb/trunk/include/lldb/API/SBError.h Fri Sep 28 18:57:51 2012
@@ -66,7 +66,6 @@
 
 protected:
 
-    friend class SBArguments;
     friend class SBData;
     friend class SBDebugger;
     friend class SBCommunication;

Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Fri Sep 28 18:57:51 2012
@@ -18,6 +18,9 @@
 #include <stack>
 
 #include "lldb/lldb-public.h"
+
+#include "lldb/API/SBDefines.h"
+
 #include "lldb/Core/Broadcaster.h"
 #include "lldb/Core/Communication.h"
 #include "lldb/Core/FormatManager.h"
@@ -319,6 +322,11 @@
     {
         return m_instance_name;
     }
+    
+    typedef bool (*LLDBCommandPluginInit) (lldb::SBDebugger& debugger);
+    
+    bool
+    LoadPlugin (const FileSpec& spec);
 
 protected:
 
@@ -357,7 +365,12 @@
     LogStreamMap m_log_streams;
     lldb::StreamSP m_log_callback_stream_sp;
     ConstString m_instance_name;
-
+    typedef std::vector<lldb::DynamicLibrarySP> LoadedPluginsList;
+    LoadedPluginsList m_loaded_plugins;
+    
+    void
+    InstanceInitialize ();
+    
 private:
 
     // Use Debugger::CreateInstance() to get a shared pointer to a new

Added: lldb/trunk/include/lldb/Host/DynamicLibrary.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/DynamicLibrary.h?rev=164865&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Host/DynamicLibrary.h (added)
+++ lldb/trunk/include/lldb/Host/DynamicLibrary.h Fri Sep 28 18:57:51 2012
@@ -0,0 +1,48 @@
+//===-- DynamicLibrary.h -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DynamicLibrary_h_
+#define liblldb_DynamicLibrary_h_
+
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
+
+namespace lldb_private {
+
+class DynamicLibrary
+{
+public:
+    DynamicLibrary (const FileSpec& spec, uint32_t options = Host::eDynamicLibraryOpenOptionLazy |
+                                                             Host::eDynamicLibraryOpenOptionLocal |
+                                                             Host::eDynamicLibraryOpenOptionLimitGetSymbol);
+    
+    ~DynamicLibrary ();
+    
+    template <typename T = void*>
+    T GetSymbol (const char* name)
+    {
+        Error err;
+        if (!m_handle)
+            return (T)NULL;
+        void* symbol = Host::DynamicLibraryGetSymbol (m_handle, name, err);
+        if (!symbol)
+            return (T)NULL;
+        return (T)symbol;
+    }
+    
+private:
+    lldb_private::FileSpec m_filespec;
+    void* m_handle;
+    
+    DISALLOW_COPY_AND_ASSIGN (DynamicLibrary);
+};
+    
+} // namespace lldb_private
+
+#endif  // liblldb_DynamicLibrary_h_

Modified: lldb/trunk/include/lldb/Interpreter/CommandObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandObject.h?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandObject.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandObject.h Fri Sep 28 18:57:51 2012
@@ -144,6 +144,17 @@
     virtual bool
     IsMultiwordObject () { return false; }
 
+    // this is needed in order to allow the SBCommand class to
+    // transparently try and load subcommands - it will fail on
+    // anything but a multiword command, but it avoids us doing
+    // type checkings and casts
+    virtual bool
+    LoadSubCommand (const char *cmd_name,
+                    const lldb::CommandObjectSP& command_obj)
+    {
+        return false;
+    }
+    
     virtual bool
     WantsRawCommandString() = 0;
 

Modified: lldb/trunk/include/lldb/Interpreter/CommandObjectMultiword.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandObjectMultiword.h?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandObjectMultiword.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandObjectMultiword.h Fri Sep 28 18:57:51 2012
@@ -42,7 +42,7 @@
     virtual bool
     IsMultiwordObject () { return true; }
 
-    bool
+    virtual bool
     LoadSubCommand (const char *cmd_name, 
                     const lldb::CommandObjectSP& command_obj);
 
@@ -72,9 +72,20 @@
     virtual bool
     Execute (const char *args_string,
              CommandReturnObject &result);
+    
+    virtual bool
+    IsRemovable() { return m_can_be_removed; }
+    
+    void
+    SetRemovable (bool removable)
+    {
+        m_can_be_removed = removable;
+    }
+    
 protected:
 
     CommandObject::CommandMap m_subcommand_dict;
+    bool m_can_be_removed;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Fri Sep 28 18:57:51 2012
@@ -94,6 +94,7 @@
 class   Debugger;
 class   Declaration;
 class   Disassembler;
+class   DynamicLibrary;
 class   DynamicLoader;
 class   EmulateInstruction;
 class   Error;
@@ -289,6 +290,7 @@
     typedef STD_SHARED_PTR(lldb_private::Debugger) DebuggerSP;
     typedef STD_WEAK_PTR(  lldb_private::Debugger) DebuggerWP;
     typedef STD_SHARED_PTR(lldb_private::Disassembler) DisassemblerSP;
+    typedef STD_SHARED_PTR(lldb_private::DynamicLibrary) DynamicLibrarySP;
     typedef STD_SHARED_PTR(lldb_private::DynamicLoader) DynamicLoaderSP;
     typedef STD_SHARED_PTR(lldb_private::Event) EventSP;
     typedef STD_SHARED_PTR(lldb_private::ExecutionContextRef) ExecutionContextRefSP;

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Sep 28 18:57:51 2012
@@ -515,6 +515,7 @@
 		941BCC8214E48C4000BB969C /* SBTypeSynthetic.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568914E355F2003A195C /* SBTypeSynthetic.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		9443B122140C18C40013457C /* SBData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9443B121140C18C10013457C /* SBData.cpp */; };
 		9443B123140C26AB0013457C /* SBData.h in Headers */ = {isa = PBXBuildFile; fileRef = 9443B120140C18A90013457C /* SBData.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		9456F2241616671900656F91 /* DynamicLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9456F2211616644B00656F91 /* DynamicLibrary.cpp */; };
 		94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94611EB113CCA4A4003A22AF /* RefCounter.cpp */; };
 		9461569A14E358A6003A195C /* SBTypeFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9461568A14E35621003A195C /* SBTypeFilter.cpp */; };
 		9461569B14E358A6003A195C /* SBTypeFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9461568B14E35621003A195C /* SBTypeFormat.cpp */; };
@@ -527,6 +528,8 @@
 		9475C18914E5EA08001BFC6D /* SBTypeCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 9475C18514E5E9C5001BFC6D /* SBTypeCategory.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		9475C18E14E5F834001BFC6D /* SBTypeNameSpecifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9475C18D14E5F834001BFC6D /* SBTypeNameSpecifier.cpp */; };
 		9475C18F14E5F858001BFC6D /* SBTypeNameSpecifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 9475C18C14E5F826001BFC6D /* SBTypeNameSpecifier.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		947A1D641616476B0017C8D1 /* CommandObjectPlugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 947A1D621616476A0017C8D1 /* CommandObjectPlugin.cpp */; };
+		947A1D651616476B0017C8D1 /* CommandObjectPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 947A1D631616476A0017C8D1 /* CommandObjectPlugin.h */; };
 		949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */; };
 		94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */; };
 		94CDEB9D15F0258500DD2A7A /* CXXFormatterFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CDEB9C15F0258400DD2A7A /* CXXFormatterFunctions.cpp */; };
@@ -1504,6 +1507,8 @@
 		9415F61713B2C0EF00A52B36 /* FormatManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = FormatManager.cpp; path = source/Core/FormatManager.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
 		9443B120140C18A90013457C /* SBData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBData.h; path = include/lldb/API/SBData.h; sourceTree = "<group>"; };
 		9443B121140C18C10013457C /* SBData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBData.cpp; path = source/API/SBData.cpp; sourceTree = "<group>"; };
+		9456F2211616644B00656F91 /* DynamicLibrary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicLibrary.cpp; sourceTree = "<group>"; };
+		9456F2231616645A00656F91 /* DynamicLibrary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DynamicLibrary.h; path = include/lldb/Host/DynamicLibrary.h; sourceTree = "<group>"; };
 		94611EAF13CCA363003A22AF /* RefCounter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RefCounter.h; path = include/lldb/Utility/RefCounter.h; sourceTree = "<group>"; };
 		94611EB113CCA4A4003A22AF /* RefCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RefCounter.cpp; path = source/Utility/RefCounter.cpp; sourceTree = "<group>"; };
 		9461568614E355F2003A195C /* SBTypeFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeFilter.h; path = include/lldb/API/SBTypeFilter.h; sourceTree = "<group>"; };
@@ -1530,6 +1535,8 @@
 		9475C18B14E5F818001BFC6D /* SBTypeNameSpecifier.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBTypeNameSpecifier.i; sourceTree = "<group>"; };
 		9475C18C14E5F826001BFC6D /* SBTypeNameSpecifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeNameSpecifier.h; path = include/lldb/API/SBTypeNameSpecifier.h; sourceTree = "<group>"; };
 		9475C18D14E5F834001BFC6D /* SBTypeNameSpecifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBTypeNameSpecifier.cpp; path = source/API/SBTypeNameSpecifier.cpp; sourceTree = "<group>"; };
+		947A1D621616476A0017C8D1 /* CommandObjectPlugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectPlugin.cpp; path = source/Commands/CommandObjectPlugin.cpp; sourceTree = "<group>"; };
+		947A1D631616476A0017C8D1 /* CommandObjectPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectPlugin.h; path = source/Commands/CommandObjectPlugin.h; sourceTree = "<group>"; };
 		949ADF001406F62E004833E1 /* ValueObjectConstResultImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResultImpl.h; path = include/lldb/Core/ValueObjectConstResultImpl.h; sourceTree = "<group>"; };
 		949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResultImpl.cpp; path = source/Core/ValueObjectConstResultImpl.cpp; sourceTree = "<group>"; };
 		94A8287514031D05006C37A8 /* FormatNavigator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatNavigator.h; path = include/lldb/Core/FormatNavigator.h; sourceTree = "<group>"; };
@@ -2741,6 +2748,8 @@
 				26BC7E3610F1B84700F91463 /* CommandObjectMemory.cpp */,
 				26879CE51333F5750012C1F8 /* CommandObjectPlatform.h */,
 				26879CE71333F58B0012C1F8 /* CommandObjectPlatform.cpp */,
+				947A1D631616476A0017C8D1 /* CommandObjectPlugin.h */,
+				947A1D621616476A0017C8D1 /* CommandObjectPlugin.cpp */,
 				26BC7D1F10F1B76300F91463 /* CommandObjectProcess.h */,
 				26BC7E3810F1B84700F91463 /* CommandObjectProcess.cpp */,
 				26BC7D2010F1B76300F91463 /* CommandObjectQuit.h */,
@@ -2822,6 +2831,7 @@
 				26BC7EE510F1B88100F91463 /* MacOSX */,
 				26BC7DD210F1B7D500F91463 /* Condition.h */,
 				266F5CBB12FC846200DFCE33 /* Config.h */,
+				9456F2231616645A00656F91 /* DynamicLibrary.h */,
 				26BC7DD310F1B7D500F91463 /* Endian.h */,
 				260C6EA013011578005E16B0 /* File.h */,
 				26FA4315130103F400E71120 /* FileSpec.h */,
@@ -3274,6 +3284,7 @@
 		69A01E1A1236C5D400C660B5 /* common */ = {
 			isa = PBXGroup;
 			children = (
+				9456F2211616644B00656F91 /* DynamicLibrary.cpp */,
 				260C6EA213011581005E16B0 /* File.cpp */,
 				26FA43171301048600E71120 /* FileSpec.cpp */,
 				69A01E1B1236C5D400C660B5 /* Condition.cpp */,
@@ -3399,6 +3410,7 @@
 				2697A39515E404BA003E682C /* OptionValueArch.h in Headers */,
 				2698699D15E6CBD0002415FF /* OperatingSystemPython.h in Headers */,
 				260D9B2715EC369500960137 /* ModuleSpec.h in Headers */,
+				947A1D651616476B0017C8D1 /* CommandObjectPlugin.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -3758,6 +3770,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				9456F2241616671900656F91 /* DynamicLibrary.cpp in Sources */,
 				49C8507C1384A786007DB519 /* ProcessDataAllocator.cpp in Sources */,
 				2689FFDA13353D9D00698AC0 /* lldb.cpp in Sources */,
 				2689FFDB13353DA300698AC0 /* lldb-log.cpp in Sources */,
@@ -4119,6 +4132,7 @@
 				94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */,
 				2698699B15E6CBD0002415FF /* OperatingSystemPython.cpp in Sources */,
 				94CDEB9D15F0258500DD2A7A /* CXXFormatterFunctions.cpp in Sources */,
+				947A1D641616476B0017C8D1 /* CommandObjectPlugin.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: lldb/trunk/scripts/Python/build-swig-Python.sh
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/build-swig-Python.sh?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/build-swig-Python.sh (original)
+++ lldb/trunk/scripts/Python/build-swig-Python.sh Fri Sep 28 18:57:51 2012
@@ -104,7 +104,7 @@
 " ${SRC_ROOT}/include/lldb/API/SBTypeSynthetic.h"\
 " ${SRC_ROOT}/include/lldb/API/SBValue.h"\
 " ${SRC_ROOT}/include/lldb/API/SBValueList.h"\
-" ${SRC_ROOT}/include/lldb/API/SBWatchpoint.h"\
+" ${SRC_ROOT}/include/lldb/API/SBWatchpoint.h"
 
 INTERFACE_FILES="${SRC_ROOT}/scripts/Python/interface/SBAddress.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBBlock.i"\

Modified: lldb/trunk/scripts/Python/interface/SBCommandInterpreter.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBCommandInterpreter.i?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBCommandInterpreter.i (original)
+++ lldb/trunk/scripts/Python/interface/SBCommandInterpreter.i Fri Sep 28 18:57:51 2012
@@ -101,6 +101,9 @@
 
     lldb::SBProcess
     GetProcess ();
+    
+    lldb::SBDebugger
+    GetDebugger ();
 
     void
     SourceInitFileInHomeDirectory (lldb::SBCommandReturnObject &result);

Modified: lldb/trunk/scripts/Python/interface/SBCommandReturnObject.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBCommandReturnObject.i?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBCommandReturnObject.i (original)
+++ lldb/trunk/scripts/Python/interface/SBCommandReturnObject.i Fri Sep 28 18:57:51 2012
@@ -65,6 +65,9 @@
     void
     AppendMessage (const char *message);
 
+    void
+    AppendWarning (const char *message);
+
     bool
     GetDescription (lldb::SBStream &description);
     

Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/source/API/SBCommandInterpreter.cpp (original)
+++ lldb/trunk/source/API/SBCommandInterpreter.cpp Fri Sep 28 18:57:51 2012
@@ -8,15 +8,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/lldb-types.h"
-#include "lldb/Interpreter/Args.h"
 #include "lldb/Core/SourceManager.h"
 #include "lldb/Core/Listener.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Target/Target.h"
 
 #include "lldb/API/SBBroadcaster.h"
-#include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBCommandReturnObject.h"
 #include "lldb/API/SBCommandInterpreter.h"
 #include "lldb/API/SBProcess.h"
@@ -28,6 +27,34 @@
 using namespace lldb;
 using namespace lldb_private;
 
+class CommandPluginInterfaceImplementation : public CommandObjectParsed
+{
+public:
+    CommandPluginInterfaceImplementation (CommandInterpreter &interpreter,
+                                          const char *name,
+                                          lldb::SBCommandPluginInterface* backend,
+                                          const char *help = NULL,
+                                          const char *syntax = NULL,
+                                          uint32_t flags = 0) :
+    CommandObjectParsed (interpreter, name, help, syntax, flags),
+    m_backend(backend) {}
+    
+    virtual bool
+    IsRemovable() { return true; }
+    
+protected:
+    virtual bool
+    DoExecute (Args& command, CommandReturnObject &result)
+    {
+        SBCommandReturnObject sb_return(&result);
+        SBCommandInterpreter sb_interpreter(&m_interpreter);
+        SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this());
+        bool ret = m_backend->DoExecute (debugger_sb,(char**)command.GetArgumentVector(), sb_return);
+        sb_return.Release();
+        return ret;
+    }
+    lldb::SBCommandPluginInterface* m_backend;
+};
 
 SBCommandInterpreter::SBCommandInterpreter (CommandInterpreter *interpreter) :
     m_opaque_ptr (interpreter)
@@ -218,6 +245,22 @@
     return sb_process;
 }
 
+SBDebugger
+SBCommandInterpreter::GetDebugger ()
+{
+    SBDebugger sb_debugger;
+    if (m_opaque_ptr)
+        sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this());
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+    
+    if (log)
+        log->Printf ("SBCommandInterpreter(%p)::GetDebugger () => SBDebugger(%p)",
+                     m_opaque_ptr, sb_debugger.get());
+    
+    
+    return sb_debugger;
+}
+
 CommandInterpreter *
 SBCommandInterpreter::get ()
 {
@@ -368,3 +411,82 @@
     }
 }
 
+lldb::SBCommand
+SBCommandInterpreter::AddMultiwordCommand (const char* name, const char* help)
+{
+    CommandObjectMultiword *new_command = new CommandObjectMultiword(*m_opaque_ptr,name,help);
+    new_command->SetRemovable (true);
+    lldb::CommandObjectSP new_command_sp(new_command);
+    if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
+        return lldb::SBCommand(new_command_sp);
+    return lldb::SBCommand();
+}
+
+lldb::SBCommand
+SBCommandInterpreter::AddCommand (const char* name, lldb::SBCommandPluginInterface* impl, const char* help)
+{
+    lldb::CommandObjectSP new_command_sp;
+    new_command_sp.reset(new CommandPluginInterfaceImplementation(*m_opaque_ptr,name,impl,help));
+
+    if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
+        return lldb::SBCommand(new_command_sp);
+    return lldb::SBCommand();
+}
+
+SBCommand::SBCommand ()
+{}
+
+SBCommand::SBCommand (lldb::CommandObjectSP cmd_sp) : m_opaque_sp (cmd_sp)
+{}
+
+bool
+SBCommand::IsValid ()
+{
+    return (bool)m_opaque_sp;
+}
+
+const char*
+SBCommand::GetName ()
+{
+    if (IsValid ())
+        return m_opaque_sp->GetCommandName ();
+    return NULL;
+}
+
+const char*
+SBCommand::GetHelp ()
+{
+    if (IsValid ())
+        return m_opaque_sp->GetHelp ();
+    return NULL;
+}
+
+lldb::SBCommand
+SBCommand::AddMultiwordCommand (const char* name, const char* help)
+{
+    if (!IsValid ())
+        return lldb::SBCommand();
+    if (m_opaque_sp->IsMultiwordObject() == false)
+        return lldb::SBCommand();
+    CommandObjectMultiword *new_command = new CommandObjectMultiword(m_opaque_sp->GetCommandInterpreter(),name,help);
+    new_command->SetRemovable (true);
+    lldb::CommandObjectSP new_command_sp(new_command);
+    if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp))
+        return lldb::SBCommand(new_command_sp);
+    return lldb::SBCommand();
+}
+
+lldb::SBCommand
+SBCommand::AddCommand (const char* name, lldb::SBCommandPluginInterface *impl, const char* help)
+{
+    if (!IsValid ())
+        return lldb::SBCommand();
+    if (m_opaque_sp->IsMultiwordObject() == false)
+        return lldb::SBCommand();
+    lldb::CommandObjectSP new_command_sp;
+    new_command_sp.reset(new CommandPluginInterfaceImplementation(m_opaque_sp->GetCommandInterpreter(),name,impl,help));
+    if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp))
+        return lldb::SBCommand(new_command_sp);
+    return lldb::SBCommand();
+}
+

Modified: lldb/trunk/source/API/SBCommandReturnObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandReturnObject.cpp?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/source/API/SBCommandReturnObject.cpp (original)
+++ lldb/trunk/source/API/SBCommandReturnObject.cpp Fri Sep 28 18:57:51 2012
@@ -190,6 +190,13 @@
         m_opaque_ap->AppendMessage (message);
 }
 
+void
+SBCommandReturnObject::AppendWarning (const char *message)
+{
+    if (m_opaque_ap.get())
+        m_opaque_ap->AppendWarning (message);
+}
+
 CommandReturnObject *
 SBCommandReturnObject::operator ->() const
 {

Added: lldb/trunk/source/Commands/CommandObjectPlugin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectPlugin.cpp?rev=164865&view=auto
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectPlugin.cpp (added)
+++ lldb/trunk/source/Commands/CommandObjectPlugin.cpp Fri Sep 28 18:57:51 2012
@@ -0,0 +1,117 @@
+//===-- CommandObjectPlugin.cpp ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectPlugin.h"
+
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBCommandReturnObject.h"
+
+#include "lldb/Host/Host.h"
+
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+class CommandObjectPluginLoad : public CommandObjectParsed
+{
+private:
+public:
+    CommandObjectPluginLoad (CommandInterpreter &interpreter) :
+    CommandObjectParsed (interpreter,
+                         "plugin load",
+                         "Import a dylib that implements an LLDB plugin.",
+                         NULL)
+    {
+        CommandArgumentEntry arg1;
+        CommandArgumentData cmd_arg;
+        
+        // Define the first (and only) variant of this arg.
+        cmd_arg.arg_type = eArgTypeFilename;
+        cmd_arg.arg_repetition = eArgRepeatPlain;
+        
+        // There is only one variant this argument could be; put it into the argument entry.
+        arg1.push_back (cmd_arg);
+        
+        // Push the data for the first argument into the m_arguments vector.
+        m_arguments.push_back (arg1);
+    }
+    
+    ~CommandObjectPluginLoad ()
+    {
+    }
+    
+    int
+    HandleArgumentCompletion (Args &input,
+                              int &cursor_index,
+                              int &cursor_char_position,
+                              OptionElementVector &opt_element_vector,
+                              int match_start_point,
+                              int max_return_elements,
+                              bool &word_complete,
+                              StringList &matches)
+    {
+        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
+        completion_str.erase (cursor_char_position);
+        
+        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
+                                                             CommandCompletions::eDiskFileCompletion,
+                                                             completion_str.c_str(),
+                                                             match_start_point,
+                                                             max_return_elements,
+                                                             NULL,
+                                                             word_complete,
+                                                             matches);
+        return matches.GetSize();
+    }
+
+protected:
+    bool
+    DoExecute (Args& command, CommandReturnObject &result)
+    {
+        typedef void (*LLDBCommandPluginInit) (lldb::SBDebugger debugger);
+        
+        size_t argc = command.GetArgumentCount();
+        
+        if (argc != 1)
+        {
+            result.AppendError ("'plugin load' requires one argument");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+        
+        const char* path = command.GetArgumentAtIndex(0);
+        
+        Error error;
+        
+        FileSpec dylib_fspec(path,true);
+        
+        if (m_interpreter.GetDebugger().LoadPlugin(dylib_fspec))
+            result.SetStatus(eReturnStatusSuccessFinishResult);
+        else
+            result.SetStatus(eReturnStatusFailed);
+        
+        return result.Succeeded();
+    }
+};
+
+CommandObjectPlugin::CommandObjectPlugin (CommandInterpreter &interpreter) :
+CommandObjectMultiword (interpreter,
+                        "plugin",
+                        "A set of commands for managing or customizing plugin commands.",
+                        "plugin <subcommand> [<subcommand-options>]")
+{
+    LoadSubCommand ("load",  CommandObjectSP (new CommandObjectPluginLoad (interpreter)));
+}
+    
+CommandObjectPlugin::~CommandObjectPlugin ()
+{
+}

Added: lldb/trunk/source/Commands/CommandObjectPlugin.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectPlugin.h?rev=164865&view=auto
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectPlugin.h (added)
+++ lldb/trunk/source/Commands/CommandObjectPlugin.h Fri Sep 28 18:57:51 2012
@@ -0,0 +1,36 @@
+//===-- CommandObjectPlugin.h -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CommandObjectPlugin_h_
+#define liblldb_CommandObjectPlugin_h_
+
+// C Includes
+// C++ Includes
+
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-types.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+
+namespace lldb_private {
+    
+    class CommandObjectPlugin : public CommandObjectMultiword
+    {
+    public:
+        CommandObjectPlugin (CommandInterpreter &interpreter);
+        
+        virtual
+        ~CommandObjectPlugin ();
+    };
+    
+} // namespace lldb_private
+
+#endif  // liblldb_CommandObjectPlugin_h_

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Fri Sep 28 18:57:51 2012
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/API/SBDebugger.h"
+
 #include "lldb/Core/Debugger.h"
 
 #include <map>
@@ -28,6 +30,7 @@
 #include "lldb/Core/Timer.h"
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/Host/DynamicLibrary.h"
 #include "lldb/Host/Terminal.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/OptionValueSInt64.h"
@@ -334,6 +337,109 @@
     Target::SettingsTerminate ();
 }
 
+bool
+Debugger::LoadPlugin (const FileSpec& spec)
+{
+    lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec));
+    lldb::DebuggerSP debugger_sp(shared_from_this());
+    lldb::SBDebugger debugger_sb(debugger_sp);
+    // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays
+    LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
+    if (!init_func)
+        return false;
+    if (init_func(debugger_sb))
+    {
+        m_loaded_plugins.push_back(dynlib_sp);
+        return true;
+    }
+    return false;
+}
+
+static FileSpec::EnumerateDirectoryResult
+LoadPluginCallback
+(
+ void *baton,
+ FileSpec::FileType file_type,
+ const FileSpec &file_spec
+ )
+{
+    Error error;
+    
+    static ConstString g_dylibext("dylib");
+    
+    if (!baton)
+        return FileSpec::eEnumerateDirectoryResultQuit;
+    
+    Debugger *debugger = (Debugger*)baton;
+    
+    // If we have a regular file, a symbolic link or unknown file type, try
+    // and process the file. We must handle unknown as sometimes the directory
+    // enumeration might be enumerating a file system that doesn't have correct
+    // file type information.
+    if (file_type == FileSpec::eFileTypeRegular         ||
+        file_type == FileSpec::eFileTypeSymbolicLink    ||
+        file_type == FileSpec::eFileTypeUnknown          )
+    {
+        FileSpec plugin_file_spec (file_spec);
+        plugin_file_spec.ResolvePath ();
+        
+        if (plugin_file_spec.GetFileNameExtension() != g_dylibext)
+            return FileSpec::eEnumerateDirectoryResultNext;
+
+        debugger->LoadPlugin (plugin_file_spec);
+        
+        return FileSpec::eEnumerateDirectoryResultNext;
+    }
+    
+    else if (file_type == FileSpec::eFileTypeUnknown     ||
+        file_type == FileSpec::eFileTypeDirectory   ||
+        file_type == FileSpec::eFileTypeSymbolicLink )
+    {
+        // Try and recurse into anything that a directory or symbolic link.
+        // We must also do this for unknown as sometimes the directory enumeration
+        // might be enurating a file system that doesn't have correct file type
+        // information.
+        return FileSpec::eEnumerateDirectoryResultEnter;
+    }
+    
+    return FileSpec::eEnumerateDirectoryResultNext;
+}
+
+void
+Debugger::InstanceInitialize ()
+{
+    FileSpec dir_spec;
+    const bool find_directories = true;
+    const bool find_files = true;
+    const bool find_other = true;
+    char dir_path[PATH_MAX];
+    if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
+    {
+        if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
+        {
+            FileSpec::EnumerateDirectory (dir_path,
+                                          find_directories,
+                                          find_files,
+                                          find_other,
+                                          LoadPluginCallback,
+                                          this);
+        }
+    }
+    
+    if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
+    {
+        if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
+        {
+            FileSpec::EnumerateDirectory (dir_path,
+                                          find_directories,
+                                          find_files,
+                                          find_other,
+                                          LoadPluginCallback,
+                                          this);
+        }
+    }
+}
+
 DebuggerSP
 Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
 {
@@ -343,6 +449,7 @@
         Mutex::Locker locker (GetDebuggerListMutex ());
         GetDebuggerList().push_back(debugger_sp);
     }
+    debugger_sp->InstanceInitialize ();
     return debugger_sp;
 }
 

Added: lldb/trunk/source/Host/common/DynamicLibrary.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/DynamicLibrary.cpp?rev=164865&view=auto
==============================================================================
--- lldb/trunk/source/Host/common/DynamicLibrary.cpp (added)
+++ lldb/trunk/source/Host/common/DynamicLibrary.cpp Fri Sep 28 18:57:51 2012
@@ -0,0 +1,27 @@
+//===-- DynamicLibrary.cpp ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/Error.h"
+#include "lldb/Host/DynamicLibrary.h"
+
+using namespace lldb_private;
+
+DynamicLibrary::DynamicLibrary (const FileSpec& spec, uint32_t options) : m_filespec(spec)
+{
+    Error err;
+    m_handle = Host::DynamicLibraryOpen (spec,options,err);
+    if (err.Fail())
+        m_handle = NULL;
+}
+
+DynamicLibrary::~DynamicLibrary ()
+{
+    if (m_handle)
+        Host::DynamicLibraryClose (m_handle);
+}

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=164865&r1=164864&r2=164865&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Fri Sep 28 18:57:51 2012
@@ -26,6 +26,7 @@
 #include "../Commands/CommandObjectLog.h"
 #include "../Commands/CommandObjectMemory.h"
 #include "../Commands/CommandObjectPlatform.h"
+#include "../Commands/CommandObjectPlugin.h"
 #include "../Commands/CommandObjectProcess.h"
 #include "../Commands/CommandObjectQuit.h"
 #include "../Commands/CommandObjectRegister.h"
@@ -356,6 +357,7 @@
     m_command_dict["log"]       = CommandObjectSP (new CommandObjectLog (*this));
     m_command_dict["memory"]    = CommandObjectSP (new CommandObjectMemory (*this));
     m_command_dict["platform"]  = CommandObjectSP (new CommandObjectPlatform (*this));
+    m_command_dict["plugin"]    = CommandObjectSP (new CommandObjectPlugin (*this));
     m_command_dict["process"]   = CommandObjectSP (new CommandObjectMultiwordProcess (*this));
     m_command_dict["quit"]      = CommandObjectSP (new CommandObjectQuit (*this));
     m_command_dict["register"]  = CommandObjectSP (new CommandObjectRegister (*this));
@@ -627,6 +629,8 @@
             if (m_command_dict.find (name_sstr) != m_command_dict.end())
                 return false;
         }
+        if (m_command_dict[name_sstr]->IsRemovable() == false)
+            return false;
         m_command_dict[name_sstr] = cmd_sp;
         return true;
     }
@@ -645,11 +649,21 @@
         
         // do not allow replacement of internal commands
         if (CommandExists(name_cstr))
-            return false;
+        {
+            if (can_replace == false)
+                return false;
+            if (m_command_dict[name]->IsRemovable() == false)
+                return false;
+        }
+        
+        if (UserCommandExists(name_cstr))
+        {
+            if (can_replace == false)
+                return false;
+            if (m_user_dict[name]->IsRemovable() == false)
+                return false;
+        }
         
-        if (can_replace == false && UserCommandExists(name_cstr))
-            return false;
-
         m_user_dict[name] = cmd_sp;
         return true;
     }





More information about the lldb-commits mailing list