<rdar://problem/12491387>

I added the ability for a process plug-in to implement custom commands. All the lldb_private::Process plug-in has to do is override:

virtual CommandObject *
GetPluginCommandObject();

This object returned should be a multi-word command that vends LLDB commands. There is a sample implementation in ProcessGDBRemote that is hollowed out. It is intended to be used for sending a custom packet, though the body of the command execute function has yet to be implemented! 



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@165861 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 215e885..a0658ab 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -196,7 +196,8 @@
     m_waiting_for_attach (false),
     m_destroy_tried_resuming (false),
     m_dyld_plugin_name(),
-    m_kernel_load_addr (LLDB_INVALID_ADDRESS)
+    m_kernel_load_addr (LLDB_INVALID_ADDRESS),
+    m_command_sp ()
 {
     m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit,   "async thread should exit");
     m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue,           "async thread continue");
@@ -3013,3 +3014,58 @@
     return m_dyld_ap.get();
 }
 
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+
+class CommandObjectProcessGDBRemotePacket : public CommandObjectParsed
+{
+private:
+    
+public:
+    CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter) :
+    CommandObjectParsed (interpreter,
+                         "process plugin packet",
+                         "Send a custom packet through the GDB remote protocol and print the answer.",
+                         NULL)
+    {
+    }
+    
+    ~CommandObjectProcessGDBRemotePacket ()
+    {
+    }
+    
+    bool
+    DoExecute (Args& command, CommandReturnObject &result)
+    {
+        printf ("CommandObjectProcessGDBRemotePacket::DoExecute() called!!!\n");
+        return true;
+    }
+};
+
+
+class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword
+{
+public:
+    CommandObjectMultiwordProcessGDBRemote (CommandInterpreter &interpreter) :
+        CommandObjectMultiword (interpreter,
+                                "process plugin",
+                                "A set of commands for operating on a ProcessGDBRemote process.",
+                                "process plugin <subcommand> [<subcommand-options>]")
+    {
+        LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessGDBRemotePacket    (interpreter)));
+    }
+
+    ~CommandObjectMultiwordProcessGDBRemote ()
+    {
+    }
+};
+
+
+
+CommandObject *
+ProcessGDBRemote::GetPluginCommandObject()
+{
+    if (!m_command_sp)
+        m_command_sp.reset (new CommandObjectMultiwordProcessGDBRemote (GetTarget().GetDebugger().GetCommandInterpreter()));
+    return m_command_sp.get();
+}