summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/examples/plugins/commands/fooplugin.cpp47
-rw-r--r--lldb/include/lldb/API/SBCommandInterpreter.h61
-rw-r--r--lldb/include/lldb/API/SBCommandReturnObject.h3
-rw-r--r--lldb/include/lldb/API/SBDebugger.h3
-rw-r--r--lldb/include/lldb/API/SBDefines.h2
-rw-r--r--lldb/include/lldb/API/SBError.h1
-rw-r--r--lldb/include/lldb/Core/Debugger.h15
-rw-r--r--lldb/include/lldb/Host/DynamicLibrary.h48
-rw-r--r--lldb/include/lldb/Interpreter/CommandObject.h11
-rw-r--r--lldb/include/lldb/Interpreter/CommandObjectMultiword.h13
-rw-r--r--lldb/include/lldb/lldb-forward.h2
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj14
-rwxr-xr-xlldb/scripts/Python/build-swig-Python.sh2
-rw-r--r--lldb/scripts/Python/interface/SBCommandInterpreter.i3
-rw-r--r--lldb/scripts/Python/interface/SBCommandReturnObject.i3
-rw-r--r--lldb/source/API/SBCommandInterpreter.cpp126
-rw-r--r--lldb/source/API/SBCommandReturnObject.cpp7
-rw-r--r--lldb/source/Commands/CommandObjectPlugin.cpp117
-rw-r--r--lldb/source/Commands/CommandObjectPlugin.h36
-rw-r--r--lldb/source/Core/Debugger.cpp107
-rw-r--r--lldb/source/Host/common/DynamicLibrary.cpp27
-rw-r--r--lldb/source/Interpreter/CommandInterpreter.cpp22
22 files changed, 657 insertions, 13 deletions
diff --git a/lldb/examples/plugins/commands/fooplugin.cpp b/lldb/examples/plugins/commands/fooplugin.cpp
new file mode 100644
index 00000000000..86033bb0de8
--- /dev/null
+++ b/lldb/examples/plugins/commands/fooplugin.cpp
@@ -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;
+}
+
diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h
index e30857b8784..ebcb6bf4715 100644
--- a/lldb/include/lldb/API/SBCommandInterpreter.h
+++ b/lldb/include/lldb/API/SBCommandInterpreter.h
@@ -11,6 +11,7 @@
#define LLDB_SBCommandInterpreter_h_
#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBDebugger.h"
namespace lldb {
@@ -65,6 +66,15 @@ public:
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 @@ public:
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 @@ protected:
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
diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h b/lldb/include/lldb/API/SBCommandReturnObject.h
index 1f4bfce8814..1dc632c84cc 100644
--- a/lldb/include/lldb/API/SBCommandReturnObject.h
+++ b/lldb/include/lldb/API/SBCommandReturnObject.h
@@ -74,6 +74,9 @@ public:
void
AppendMessage (const char *message);
+ void
+ AppendWarning (const char *message);
+
bool
GetDescription (lldb::SBStream &description);
diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h
index 60ff518e390..41bcfa5068c 100644
--- a/lldb/include/lldb/API/SBDebugger.h
+++ b/lldb/include/lldb/API/SBDebugger.h
@@ -295,11 +295,12 @@ public:
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);
diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h
index 82805d09568..7c958be4a18 100644
--- a/lldb/include/lldb/API/SBDefines.h
+++ b/lldb/include/lldb/API/SBDefines.h
@@ -29,7 +29,9 @@ class SBBlock;
class SBBreakpoint;
class SBBreakpointLocation;
class SBBroadcaster;
+class SBCommand;
class SBCommandInterpreter;
+class SBCommandPluginInterface;
class SBCommandReturnObject;
class SBCommunication;
class SBCompileUnit;
diff --git a/lldb/include/lldb/API/SBError.h b/lldb/include/lldb/API/SBError.h
index a4aa56e82ea..89617c4ccab 100644
--- a/lldb/include/lldb/API/SBError.h
+++ b/lldb/include/lldb/API/SBError.h
@@ -66,7 +66,6 @@ public:
protected:
- friend class SBArguments;
friend class SBData;
friend class SBDebugger;
friend class SBCommunication;
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index 11392c438dc..67fa370caaa 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -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 @@ public:
{
return m_instance_name;
}
+
+ typedef bool (*LLDBCommandPluginInit) (lldb::SBDebugger& debugger);
+
+ bool
+ LoadPlugin (const FileSpec& spec);
protected:
@@ -357,7 +365,12 @@ protected:
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
diff --git a/lldb/include/lldb/Host/DynamicLibrary.h b/lldb/include/lldb/Host/DynamicLibrary.h
new file mode 100644
index 00000000000..3a360b04f51
--- /dev/null
+++ b/lldb/include/lldb/Host/DynamicLibrary.h
@@ -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_
diff --git a/lldb/include/lldb/Interpreter/CommandObject.h b/lldb/include/lldb/Interpreter/CommandObject.h
index 54eaa8f9aa9..c9ffd520146 100644
--- a/lldb/include/lldb/Interpreter/CommandObject.h
+++ b/lldb/include/lldb/Interpreter/CommandObject.h
@@ -144,6 +144,17 @@ public:
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;
diff --git a/lldb/include/lldb/Interpreter/CommandObjectMultiword.h b/lldb/include/lldb/Interpreter/CommandObjectMultiword.h
index 09004e9e4fa..eb41326a5bb 100644
--- a/lldb/include/lldb/Interpreter/CommandObjectMultiword.h
+++ b/lldb/include/lldb/Interpreter/CommandObjectMultiword.h
@@ -42,7 +42,7 @@ public:
virtual bool
IsMultiwordObject () { return true; }
- bool
+ virtual bool
LoadSubCommand (const char *cmd_name,
const lldb::CommandObjectSP& command_obj);
@@ -72,9 +72,20 @@ public:
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
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 7f11f181521..84cecd184c5 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -94,6 +94,7 @@ class DataExtractor;
class Debugger;
class Declaration;
class Disassembler;
+class DynamicLibrary;
class DynamicLoader;
class EmulateInstruction;
class Error;
@@ -289,6 +290,7 @@ namespace lldb {
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;
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index ea6816b0995..6cac3cb181f 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -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;
};
diff --git a/lldb/scripts/Python/build-swig-Python.sh b/lldb/scripts/Python/build-swig-Python.sh
index 20547647282..386dde6d342 100755
--- a/lldb/scripts/Python/build-swig-Python.sh
+++ b/lldb/scripts/Python/build-swig-Python.sh
@@ -104,7 +104,7 @@ HEADER_FILES="${SRC_ROOT}/include/lldb/lldb.h"\
" ${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"\
diff --git a/lldb/scripts/Python/interface/SBCommandInterpreter.i b/lldb/scripts/Python/interface/SBCommandInterpreter.i
index 62aaf8c48aa..4cf3d22f5d0 100644
--- a/lldb/scripts/Python/interface/SBCommandInterpreter.i
+++ b/lldb/scripts/Python/interface/SBCommandInterpreter.i
@@ -101,6 +101,9 @@ public:
lldb::SBProcess
GetProcess ();
+
+ lldb::SBDebugger
+ GetDebugger ();
void
SourceInitFileInHomeDirectory (lldb::SBCommandReturnObject &result);
diff --git a/lldb/scripts/Python/interface/SBCommandReturnObject.i b/lldb/scripts/Python/interface/SBCommandReturnObject.i
index aed02eac64b..82c07ee434d 100644
--- a/lldb/scripts/Python/interface/SBCommandReturnObject.i
+++ b/lldb/scripts/Python/interface/SBCommandReturnObject.i
@@ -65,6 +65,9 @@ public:
void
AppendMessage (const char *message);
+ void
+ AppendWarning (const char *message);
+
bool
GetDescription (lldb::SBStream &description);
diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp
index 08e845f7e15..f125f55e7a0 100644
--- a/lldb/source/API/SBCommandInterpreter.cpp
+++ b/lldb/source/API/SBCommandInterpreter.cpp
@@ -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 @@ SBCommandInterpreter::GetProcess ()
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 @@ SBCommandInterpreter::InitializeSWIG ()
}
}
+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();
+}
+
diff --git a/lldb/source/API/SBCommandReturnObject.cpp b/lldb/source/API/SBCommandReturnObject.cpp
index 4e633e4b9ac..4632009679b 100644
--- a/lldb/source/API/SBCommandReturnObject.cpp
+++ b/lldb/source/API/SBCommandReturnObject.cpp
@@ -190,6 +190,13 @@ SBCommandReturnObject::AppendMessage (const char *message)
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
{
diff --git a/lldb/source/Commands/CommandObjectPlugin.cpp b/lldb/source/Commands/CommandObjectPlugin.cpp
new file mode 100644
index 00000000000..6570c1d8978
--- /dev/null
+++ b/lldb/source/Commands/CommandObjectPlugin.cpp
@@ -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 ()
+{
+}
diff --git a/lldb/source/Commands/CommandObjectPlugin.h b/lldb/source/Commands/CommandObjectPlugin.h
new file mode 100644
index 00000000000..9d0f0fcc1ed
--- /dev/null
+++ b/lldb/source/Commands/CommandObjectPlugin.h
@@ -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_
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index b6e4f811062..86b0cf53e3c 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -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 @@ Debugger::SettingsTerminate ()
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 @@ Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
Mutex::Locker locker (GetDebuggerListMutex ());
GetDebuggerList().push_back(debugger_sp);
}
+ debugger_sp->InstanceInitialize ();
return debugger_sp;
}
diff --git a/lldb/source/Host/common/DynamicLibrary.cpp b/lldb/source/Host/common/DynamicLibrary.cpp
new file mode 100644
index 00000000000..e1ac3666829
--- /dev/null
+++ b/lldb/source/Host/common/DynamicLibrary.cpp
@@ -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);
+}
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index 52ba414c5f8..eed403866ae 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -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 @@ CommandInterpreter::LoadCommandDictionary ()
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 @@ CommandInterpreter::AddCommand (const char *name, const lldb::CommandObjectSP &c
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 @@ CommandInterpreter::AddUserCommand (std::string name,
// 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;
}
OpenPOWER on IntegriCloud