[Lldb-commits] [lldb] r154233 - in /lldb/branches/lldb-platform-work: include/lldb/Core/ include/lldb/Host/ include/lldb/Target/ lldb.xcodeproj/ source/Commands/ source/Core/ source/Host/common/ source/Host/macosx/ source/Plugins/Platform/MacOSX/ source/Plugins/Platform/gdb-server/ source/Plugins/Process/gdb-remote/ source/Target/ source/Utility/ tools/lldb-platform/

Enrico Granata egranata at apple.com
Fri Apr 6 17:03:47 PDT 2012


Author: enrico
Date: Fri Apr  6 19:03:47 2012
New Revision: 154233

URL: http://llvm.org/viewvc/llvm-project?rev=154233&view=rev
Log:
Initial checkin of new platform functionality
The local and remote mac platforms now have capabilities to:
 - spawn a process, wait for it to exit, and return its exit code
 - create a new directory given its path
 - open, read, write and close a file given its path
This allow some basic remote process running and I/O through lldb-platform
This is an initial checkin, the design and implementation of the features are not final and expected to evolve over time
Where possible and reasonable, I have used the standard commands from the GDB remote protocol. In some cases, there are new commands defined that extend the protocol.
If any of these really do exist in GDB remote itself, feel free to point me at them.

Added:
    lldb/branches/lldb-platform-work/include/lldb/Core/StreamGDBRemote.h
    lldb/branches/lldb-platform-work/source/Core/StreamGDBRemote.cpp
Modified:
    lldb/branches/lldb-platform-work/include/lldb/Core/Stream.h
    lldb/branches/lldb-platform-work/include/lldb/Host/Host.h
    lldb/branches/lldb-platform-work/include/lldb/Target/Platform.h
    lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj
    lldb/branches/lldb-platform-work/source/Commands/CommandObjectPlatform.cpp
    lldb/branches/lldb-platform-work/source/Host/common/Host.cpp
    lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm
    lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
    lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
    lldb/branches/lldb-platform-work/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
    lldb/branches/lldb-platform-work/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
    lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
    lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
    lldb/branches/lldb-platform-work/source/Target/Platform.cpp
    lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.cpp
    lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.h
    lldb/branches/lldb-platform-work/tools/lldb-platform/lldb-platform.cpp

Modified: lldb/branches/lldb-platform-work/include/lldb/Core/Stream.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Core/Stream.h?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Core/Stream.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Core/Stream.h Fri Apr  6 19:03:47 2012
@@ -590,7 +590,7 @@
     static void
     UnitTest(Stream *s);
 
-private:
+protected:
     //------------------------------------------------------------------
     // Member variables
     //------------------------------------------------------------------

Added: lldb/branches/lldb-platform-work/include/lldb/Core/StreamGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Core/StreamGDBRemote.h?rev=154233&view=auto
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Core/StreamGDBRemote.h (added)
+++ lldb/branches/lldb-platform-work/include/lldb/Core/StreamGDBRemote.h Fri Apr  6 19:03:47 2012
@@ -0,0 +1,54 @@
+//===-- StreamGDBRemote.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_StreamGDBRemote_h_
+#define liblldb_StreamGDBRemote_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/Core/StreamString.h"
+
+namespace lldb_private {
+    
+    class StreamGDBRemote : public StreamString
+    {
+        public:
+        StreamGDBRemote ();
+        
+        StreamGDBRemote (uint32_t flags,
+                         uint32_t addr_size,
+                         lldb::ByteOrder byte_order);
+        
+        virtual
+        ~StreamGDBRemote ();
+        
+        //------------------------------------------------------------------
+        /// Output a block of data to the stream performing GDB-remote escaping.
+        ///
+        /// @param[in] s
+        ///     A block of data.
+        ///
+        /// @param[in] src_len
+        ///     The amount of data to write.
+        ///
+        /// @return
+        ///     Number of bytes written.
+        //------------------------------------------------------------------
+        int
+        PutEscapedBytes (const void* s,
+                         size_t src_len);
+    };
+
+} // namespace lldb_private
+
+#endif  // liblldb_StreamGDBRemote_h_

Modified: lldb/branches/lldb-platform-work/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Host/Host.h?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Host/Host.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Host/Host.h Fri Apr  6 19:03:47 2012
@@ -438,6 +438,26 @@
     DynamicLibraryGetSymbol (void *dynamic_library_handle, 
                              const char *symbol_name, 
                              Error &error);
+    
+    static uint32_t
+    RunProgramAndGetExitCode (const FileSpec& file_spec);
+    
+    static uint32_t
+    MakeDirectory (const char* path, mode_t mode);
+    
+    static uint32_t
+    OpenFile (const FileSpec& file_spec,
+              uint32_t flags,
+              mode_t mode);
+    
+    static bool
+    CloseFile (uint32_t fd);
+    
+    static uint32_t
+    WriteFile (uint32_t fd, uint64_t offset, void* data, size_t data_len);
+    
+    static uint32_t
+    ReadFile (uint32_t fd, uint64_t offset, void* data_ptr, size_t len_wanted);
 };
 
 } // namespace lldb_private

Modified: lldb/branches/lldb-platform-work/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/Platform.h?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/Platform.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/Platform.h Fri Apr  6 19:03:47 2012
@@ -449,6 +449,53 @@
         {
             return false;
         }
+        
+        virtual uint32_t
+        RunShellCommand (const std::string &command_line)
+        {
+            return UINT32_MAX;
+        }
+        
+        virtual uint32_t
+        MakeDirectory (const std::string &path,
+                       mode_t mode)
+        {
+            return UINT32_MAX;
+        }
+        
+        virtual uint32_t
+        OpenFile (const FileSpec& file_spec,
+                  uint32_t flags,
+                  mode_t mode)
+        {
+            return UINT32_MAX;
+        }
+        
+        virtual bool
+        CloseFile (uint32_t fd)
+        {
+            return false;
+        }
+        
+        virtual uint32_t
+        ReadFile (uint32_t fd, uint64_t offset,
+                  void *data_ptr, size_t len)
+        {
+            return UINT32_MAX;
+        }
+        
+        virtual uint32_t
+        WriteFile (uint32_t fd, uint64_t offset,
+                   void* data, size_t len)
+        {
+            return UINT32_MAX;
+        }
+        
+        virtual Error
+        PutFile (const FileSpec& source,
+                 const FileSpec& destination,
+                 uint32_t uid = UINT32_MAX,
+                 uint32_t gid = UINT32_MAX);
                 
     protected:
         bool m_is_host;

Modified: lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj Fri Apr  6 19:03:47 2012
@@ -469,6 +469,8 @@
 		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, ); }; };
+		945E8D7E152F6AA80019BCCD /* StreamGDBRemote.h in Headers */ = {isa = PBXBuildFile; fileRef = 945E8D7D152F6AA80019BCCD /* StreamGDBRemote.h */; };
+		945E8D80152F6AB40019BCCD /* StreamGDBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945E8D7F152F6AB40019BCCD /* StreamGDBRemote.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 */; };
@@ -483,6 +485,7 @@
 		9475C18F14E5F858001BFC6D /* SBTypeNameSpecifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 9475C18C14E5F826001BFC6D /* SBTypeNameSpecifier.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */; };
 		94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */; };
+		94E829CA152D33C1006F96A3 /* lldb-platform in Resources */ = {isa = PBXBuildFile; fileRef = 26DC6A101337FE6900FF7998 /* lldb-platform */; };
 		94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */; };
 		9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		9A19A6B01163BBB300E0D453 /* SBValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A19A6AD1163BB9800E0D453 /* SBValue.cpp */; };
@@ -630,6 +633,13 @@
 			remoteGlobalIDString = 26DC6A0F1337FE6900FF7998;
 			remoteInfo = "lldb-platform";
 		};
+		94E829C8152D33B4006F96A3 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 26DC6A0F1337FE6900FF7998;
+			remoteInfo = "lldb-platform";
+		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
@@ -1409,6 +1419,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>"; };
+		945E8D7D152F6AA80019BCCD /* StreamGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StreamGDBRemote.h; path = include/lldb/Core/StreamGDBRemote.h; sourceTree = "<group>"; };
+		945E8D7F152F6AB40019BCCD /* StreamGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StreamGDBRemote.cpp; path = source/Core/StreamGDBRemote.cpp; 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>"; };
@@ -2419,6 +2431,8 @@
 				4C6649A214EEE81000B0316F /* StreamCallback.cpp */,
 				26BC7D7A10F1B77400F91463 /* StreamFile.h */,
 				26BC7E9210F1B85900F91463 /* StreamFile.cpp */,
+				945E8D7D152F6AA80019BCCD /* StreamGDBRemote.h */,
+				945E8D7F152F6AB40019BCCD /* StreamGDBRemote.cpp */,
 				26BC7D7B10F1B77400F91463 /* StreamString.h */,
 				26BC7E9310F1B85900F91463 /* StreamString.cpp */,
 				4C626533130F1B0A00C889F6 /* StreamTee.h */,
@@ -3257,7 +3271,7 @@
 			buildRules = (
 			);
 			dependencies = (
-				B2FA4F83152FBAF2005535AB /* PBXTargetDependency */,
+				94E829C9152D33B4006F96A3 /* PBXTargetDependency */,
 				2689011513353E9B00698AC0 /* PBXTargetDependency */,
 				262CFC7211A450CB00946C6C /* PBXTargetDependency */,
 				26368AF6126B95FA00E8659F /* PBXTargetDependency */,
@@ -3409,7 +3423,7 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				B2FA4F84152FBB0F005535AB /* lldb-platform in Resources */,
+				94E829CA152D33C1006F96A3 /* lldb-platform in Resources */,
 				262CFC7711A4510000946C6C /* debugserver in Resources */,
 				26368AF7126B960500E8659F /* darwin-debug in Resources */,
 			);
@@ -3917,6 +3931,7 @@
 				26FFC19D14FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp in Sources */,
 				2694E99D14FC0BB30076DE67 /* PlatformFreeBSD.cpp in Sources */,
 				2694E9A414FC0BBD0076DE67 /* PlatformLinux.cpp in Sources */,
+				945E8D80152F6AB40019BCCD /* StreamGDBRemote.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -4029,6 +4044,11 @@
 			target = 26DC6A0F1337FE6900FF7998 /* lldb-platform */;
 			targetProxy = B2FA4F82152FBAF2005535AB /* PBXContainerItemProxy */;
 		};
+		94E829C9152D33B4006F96A3 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 26DC6A0F1337FE6900FF7998 /* lldb-platform */;
+			targetProxy = 94E829C8152D33B4006F96A3 /* PBXContainerItemProxy */;
+		};
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */

Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectPlatform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectPlatform.cpp?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectPlatform.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectPlatform.cpp Fri Apr  6 19:03:47 2012
@@ -218,6 +218,416 @@
 };
 
 //----------------------------------------------------------------------
+// "platform shell"
+//----------------------------------------------------------------------
+class CommandObjectPlatformShell : public CommandObject
+{
+public:
+    CommandObjectPlatformShell (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "platform shell",
+                   "Run a shell command on the currently selected platform.",
+                   NULL,
+                   0)
+    {
+    }
+    
+    virtual
+    ~CommandObjectPlatformShell ()
+    {
+    }
+    
+    virtual bool
+    Execute (Args& args, CommandReturnObject &result)
+    {
+        PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+        if (platform_sp)
+        {
+            std::string cmd_line;
+            args.GetCommandString(cmd_line);
+            uint32_t retcode = platform_sp->RunShellCommand(cmd_line);
+            result.AppendMessageWithFormat("Status = %d\n",retcode);
+            result.SetStatus (eReturnStatusSuccessFinishResult);
+        }
+        else
+        {
+            result.AppendError ("no platform currently selected\n");
+            result.SetStatus (eReturnStatusFailed);            
+        }
+        return result.Succeeded();
+    }
+};
+
+//----------------------------------------------------------------------
+// "platform mkdir"
+//----------------------------------------------------------------------
+class CommandObjectPlatformMkDir : public CommandObject
+{
+public:
+    CommandObjectPlatformMkDir (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "platform shell",
+                   "Make a new directory on the remote end.",
+                   NULL,
+                   0)
+    {
+    }
+    
+    virtual
+    ~CommandObjectPlatformMkDir ()
+    {
+    }
+    
+    virtual bool
+    Execute (Args& args, CommandReturnObject &result)
+    {
+        PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+        if (platform_sp)
+        {
+            std::string cmd_line;
+            args.GetCommandString(cmd_line);
+            uint32_t retcode = platform_sp->MakeDirectory(cmd_line,0000700 | 0000070 | 0000007);
+            result.AppendMessageWithFormat("Status = %d\n",retcode);
+            result.SetStatus (eReturnStatusSuccessFinishResult);
+        }
+        else
+        {
+            result.AppendError ("no platform currently selected\n");
+            result.SetStatus (eReturnStatusFailed);
+        }
+        return result.Succeeded();
+    }
+};
+
+//----------------------------------------------------------------------
+// "platform fopen"
+//----------------------------------------------------------------------
+class CommandObjectPlatformFOpen : public CommandObject
+{
+public:
+    CommandObjectPlatformFOpen (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "platform fopen",
+                   "Open a file on the remote end.",
+                   NULL,
+                   0)
+    {
+    }
+    
+    virtual
+    ~CommandObjectPlatformFOpen ()
+    {
+    }
+    
+    virtual bool
+    Execute (Args& args, CommandReturnObject &result)
+    {
+        PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+        if (platform_sp)
+        {
+            std::string cmd_line;
+            args.GetCommandString(cmd_line);
+            uint32_t retcode = platform_sp->OpenFile(FileSpec(cmd_line.c_str(),false),0x0200 | 0x0002, 0000700 | 0000070 | 0000007);
+            result.AppendMessageWithFormat("Status = %d\n",retcode);
+            result.SetStatus (eReturnStatusSuccessFinishResult);
+        }
+        else
+        {
+            result.AppendError ("no platform currently selected\n");
+            result.SetStatus (eReturnStatusFailed);
+        }
+        return result.Succeeded();
+    }
+};
+
+//----------------------------------------------------------------------
+// "platform fclose"
+//----------------------------------------------------------------------
+class CommandObjectPlatformFClose : public CommandObject
+{
+public:
+    CommandObjectPlatformFClose (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "platform fclose",
+                   "Close a file on the remote end.",
+                   NULL,
+                   0)
+    {
+    }
+    
+    virtual
+    ~CommandObjectPlatformFClose ()
+    {
+    }
+    
+    virtual bool
+    Execute (Args& args, CommandReturnObject &result)
+    {
+        PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+        if (platform_sp)
+        {
+            std::string cmd_line;
+            args.GetCommandString(cmd_line);
+            uint32_t fd = ::atoi(cmd_line.c_str());
+            uint32_t retcode = platform_sp->CloseFile(fd);
+            result.AppendMessageWithFormat("Status = %d\n",retcode);
+            result.SetStatus (eReturnStatusSuccessFinishResult);
+        }
+        else
+        {
+            result.AppendError ("no platform currently selected\n");
+            result.SetStatus (eReturnStatusFailed);
+        }
+        return result.Succeeded();
+    }
+};
+
+//----------------------------------------------------------------------
+// "platform fread"
+//----------------------------------------------------------------------
+class CommandObjectPlatformFRead : public CommandObject
+{
+public:
+    CommandObjectPlatformFRead (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "platform fread",
+                   "Read data from a file on the remote end.",
+                   NULL,
+                   0),
+    m_options (interpreter)
+    {
+    }
+    
+    virtual
+    ~CommandObjectPlatformFRead ()
+    {
+    }
+    
+    virtual bool
+    Execute (Args& args, CommandReturnObject &result)
+    {
+        PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+        if (platform_sp)
+        {
+            std::string cmd_line;
+            args.GetCommandString(cmd_line);
+            uint32_t fd = ::atoi(cmd_line.c_str());
+            std::string buffer(m_options.m_count,' ');
+            uint32_t retcode = platform_sp->ReadFile(fd, m_options.m_offset, &buffer[0], m_options.m_count);
+            result.AppendMessageWithFormat("Return = %d\n",retcode);
+            result.AppendMessageWithFormat("Data = %s\n",buffer.c_str());
+            result.SetStatus (eReturnStatusSuccessFinishResult);
+        }
+        else
+        {
+            result.AppendError ("no platform currently selected\n");
+            result.SetStatus (eReturnStatusFailed);
+        }
+        return result.Succeeded();
+    }
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+protected:
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions ()
+        {
+        }
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            bool success = false;
+            
+            switch (short_option)
+            {
+                case 'o':
+                    m_offset = Args::StringToUInt32(option_arg, 0, 0, &success);
+                    if (!success)
+                        error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
+                    break;
+                case 'c':
+                    m_count = Args::StringToUInt32(option_arg, 0, 0, &success);
+                    if (!success)
+                        error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
+                    break;
+
+                default:
+                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_offset = 0;
+            m_count = 1;
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+        
+        // Options table: Required for subclasses of Options.
+        
+        static OptionDefinition g_option_table[];
+        
+        // Instance variables to hold the values for command options.
+        
+        uint32_t m_offset;
+        uint32_t m_count;
+    };
+    CommandOptions m_options;
+};
+OptionDefinition
+CommandObjectPlatformFRead::CommandOptions::g_option_table[] =
+{
+    {   LLDB_OPT_SET_1, false, "offset"           , 'o', required_argument, NULL, 0, eArgTypeIndex        , "Offset into the file at which to start reading." },
+    {   LLDB_OPT_SET_1, false, "count"            , 'c', required_argument, NULL, 0, eArgTypeCount        , "Number of bytes to read from the file." },
+    {  0              , false, NULL               ,  0 , 0                , NULL, 0, eArgTypeNone         , NULL }
+};
+
+
+//----------------------------------------------------------------------
+// "platform fread"
+//----------------------------------------------------------------------
+class CommandObjectPlatformFWrite : public CommandObject
+{
+public:
+    CommandObjectPlatformFWrite (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "platform fwrite",
+                   "Write data to a file on the remote end.",
+                   NULL,
+                   0),
+    m_options (interpreter)
+    {
+    }
+    
+    virtual
+    ~CommandObjectPlatformFWrite ()
+    {
+    }
+    
+    virtual bool
+    Execute (Args& args, CommandReturnObject &result)
+    {
+        PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+        if (platform_sp)
+        {
+            std::string cmd_line;
+            args.GetCommandString(cmd_line);
+            uint32_t fd = ::atoi(cmd_line.c_str());
+            uint32_t retcode = platform_sp->WriteFile(fd, m_options.m_offset, &m_options.m_data[0], m_options.m_data.size());
+            result.AppendMessageWithFormat("Return = %d\n",retcode);
+            result.SetStatus (eReturnStatusSuccessFinishResult);
+        }
+        else
+        {
+            result.AppendError ("no platform currently selected\n");
+            result.SetStatus (eReturnStatusFailed);
+        }
+        return result.Succeeded();
+    }
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+protected:
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions ()
+        {
+        }
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            bool success = false;
+            
+            switch (short_option)
+            {
+                case 'o':
+                    m_offset = Args::StringToUInt32(option_arg, 0, 0, &success);
+                    if (!success)
+                        error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
+                    break;
+                case 's':
+                    m_data.assign(option_arg);
+                    break;
+                    
+                default:
+                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_offset = 0;
+            m_data.clear();
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+        
+        // Options table: Required for subclasses of Options.
+        
+        static OptionDefinition g_option_table[];
+        
+        // Instance variables to hold the values for command options.
+        
+        uint32_t m_offset;
+        std::string m_data;
+    };
+    CommandOptions m_options;
+};
+OptionDefinition
+CommandObjectPlatformFWrite::CommandOptions::g_option_table[] =
+{
+    {   LLDB_OPT_SET_1, false, "offset"           , 'o', required_argument, NULL, 0, eArgTypeIndex        , "Offset into the file at which to start reading." },
+    {   LLDB_OPT_SET_1, false, "data"            , 'd', required_argument, NULL, 0, eArgTypeValue        , "Text to write to the file." },
+    {  0              , false, NULL               ,  0 , 0                , NULL, 0, eArgTypeNone         , NULL }
+};
+
+//----------------------------------------------------------------------
 // "platform connect <connect-url>"
 //----------------------------------------------------------------------
 class CommandObjectPlatformConnect : public CommandObject
@@ -885,6 +1295,14 @@
     LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect  (interpreter)));
     LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect  (interpreter)));
     LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess  (interpreter)));
+#ifdef LLDB_CONFIGURATION_DEBUG
+    LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell  (interpreter)));
+    LoadSubCommand ("mkdir", CommandObjectSP (new CommandObjectPlatformMkDir  (interpreter)));
+    LoadSubCommand ("fopen", CommandObjectSP (new CommandObjectPlatformFOpen  (interpreter)));
+    LoadSubCommand ("fclose", CommandObjectSP (new CommandObjectPlatformFClose  (interpreter)));
+    LoadSubCommand ("fread", CommandObjectSP (new CommandObjectPlatformFRead  (interpreter)));
+    LoadSubCommand ("fwrite", CommandObjectSP (new CommandObjectPlatformFWrite  (interpreter)));
+#endif
 }
 
 

Added: lldb/branches/lldb-platform-work/source/Core/StreamGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Core/StreamGDBRemote.cpp?rev=154233&view=auto
==============================================================================
--- lldb/branches/lldb-platform-work/source/Core/StreamGDBRemote.cpp (added)
+++ lldb/branches/lldb-platform-work/source/Core/StreamGDBRemote.cpp Fri Apr  6 19:03:47 2012
@@ -0,0 +1,54 @@
+//===-- StreamGDBRemote.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/StreamGDBRemote.h"
+#include <stdio.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+StreamGDBRemote::StreamGDBRemote () :
+StreamString ()
+{
+}
+
+StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) :
+StreamString (flags, addr_size, byte_order)
+{
+}
+
+StreamGDBRemote::~StreamGDBRemote()
+{
+}
+
+
+int
+StreamGDBRemote::PutEscapedBytes (const void* s,
+                                  size_t src_len)
+{
+    int bytes_written = 0;
+    const uint8_t *src = (const uint8_t *)s;
+    bool binary_is_set = m_flags.Test(eBinary);
+    m_flags.Clear(eBinary);
+    while (src_len)
+    {
+        uint8_t byte = *src;
+        src++; src_len--;
+        if (byte == 0x23 || byte == 0x24 || byte == 0x7d || byte == 0x2a)
+        {
+            bytes_written += PutChar(0x7d);
+            byte ^= 0x20;
+        }
+        bytes_written += PutChar(byte);
+    };
+    if (binary_is_set)
+        m_flags.Set(eBinary);
+    return bytes_written;
+}
+

Modified: lldb/branches/lldb-platform-work/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/Host.cpp?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/Host.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/Host.cpp Fri Apr  6 19:03:47 2012
@@ -1256,4 +1256,42 @@
     return LLDB_INVALID_PROCESS_ID;
 }
 
+uint32_t
+Host::RunProgramAndGetExitCode (const FileSpec& file_spec)
+{
+    return UINT32_MAX;
+}
+
+uint32_t
+Host::MakeDirectory (const char* path, mode_t mode)
+{
+    return UINT32_MAX;
+}
+
+uint32_t
+Host::OpenFile (const FileSpec& file_spec,
+                uint32_t flags,
+                mode_t mode)
+{
+    return UINT32_MAX;
+}
+
+bool
+Host::CloseFile (uint32_t fd)
+{
+    return false;
+}
+
+uint32_t
+Host::WriteFile (uint32_t fd, uint64_t offset, void* data, size_t data_len)
+{
+    return UINT32_MAX;
+}
+
+uint32_t
+Host::ReadFile (uint32_t fd, uint64_t offset, uint8_t* data_ptr, size_t len_wanted)
+{
+    return UINT32_MAX;
+}
+
 #endif

Modified: lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm Fri Apr  6 19:03:47 2012
@@ -1843,3 +1843,55 @@
 {
     return lldb::DataBufferSP();
 }
+
+uint32_t
+Host::RunProgramAndGetExitCode (const FileSpec& file_spec)
+{
+    std::string path(512, ' ');
+    uint32_t len = file_spec.GetPath(&path[0], 512);
+    if (len >= 512)
+    {
+        path = std::string(len+1,' ');
+        len = file_spec.GetPath(&path[0], len);
+    }
+    return ::system(path.c_str());
+}
+
+uint32_t
+Host::MakeDirectory (const char* path, mode_t mode)
+{
+    return ::mkdir(path,mode);
+}
+
+uint32_t
+Host::OpenFile (const FileSpec& file_spec,
+                uint32_t flags,
+                mode_t mode)
+{
+    std::string path(512, ' ');
+    uint32_t len = file_spec.GetPath(&path[0], 512);
+    if (len >= 512)
+    {
+        path = std::string(len+1,' ');
+        len = file_spec.GetPath(&path[0], len);
+    }
+    return ::open(path.c_str(),flags,mode);
+}
+
+bool
+Host::CloseFile (uint32_t fd)
+{
+    return (::close(fd) == 0);
+}
+
+uint32_t
+Host::WriteFile (uint32_t fd, uint64_t offset, void* data, size_t data_len)
+{
+    return ::pwrite(fd, data, data_len, offset);
+}
+
+uint32_t
+Host::ReadFile (uint32_t fd, uint64_t offset, void* data_ptr, size_t len_wanted)
+{
+    return ::pread(fd, data_ptr, len_wanted, offset);
+}

Modified: lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp Fri Apr  6 19:03:47 2012
@@ -10,6 +10,7 @@
 #include "PlatformMacOSX.h"
 
 // C Includes
+#include <sys/stat.h>
 #include <sys/sysctl.h>
 
 // C++ Includes
@@ -150,3 +151,88 @@
 #endif
 }
 
+uint32_t
+PlatformMacOSX::RunShellCommand (const std::string &command_line)
+{
+    if (IsHost())
+    {
+        return Host::RunProgramAndGetExitCode(FileSpec(command_line.c_str(),false));
+    }
+    if (IsRemote() && m_remote_platform_sp)
+        return m_remote_platform_sp->RunShellCommand(command_line);
+    return Platform::RunShellCommand(command_line);
+}
+
+uint32_t
+PlatformMacOSX::MakeDirectory (const std::string &path,
+                               mode_t mode)
+{
+    if (IsHost())
+    {
+        return Host::MakeDirectory (path.c_str(), mode);
+    }
+    if (IsRemote() && m_remote_platform_sp)
+        return m_remote_platform_sp->MakeDirectory(path, mode);
+    return Platform::MakeDirectory(path,mode);
+}
+
+uint32_t
+PlatformMacOSX::OpenFile (const FileSpec& file_spec,
+          uint32_t flags,
+          mode_t mode)
+{
+    if (IsHost())
+    {
+        return Host::OpenFile(file_spec, flags, mode);
+    }
+    if (IsRemote() && m_remote_platform_sp)
+        return m_remote_platform_sp->OpenFile(file_spec, flags, mode);
+    return Platform::OpenFile(file_spec, flags, mode);
+}
+
+bool
+PlatformMacOSX::CloseFile (uint32_t fd)
+{
+    if (IsHost())
+    {
+        return Host::CloseFile(fd);
+    }
+    if (IsRemote() && m_remote_platform_sp)
+        return m_remote_platform_sp->CloseFile(fd);
+    return Platform::CloseFile(fd);
+}
+
+uint32_t
+PlatformMacOSX::ReadFile (uint32_t fd, uint64_t offset,
+                          void *data_ptr, size_t len)
+{
+    if (IsHost())
+    {
+        return Host::ReadFile(fd, offset, data_ptr, len);
+    }
+    if (IsRemote() && m_remote_platform_sp)
+        return m_remote_platform_sp->ReadFile(fd, offset, data_ptr, len);
+    return Platform::ReadFile(fd, offset, data_ptr, len);
+}
+
+uint32_t
+PlatformMacOSX::WriteFile (uint32_t fd, uint64_t offset,
+                           void* data, size_t len)
+{
+    if (IsHost())
+    {
+        return Host::WriteFile(fd, offset, data, len);
+    }
+    if (IsRemote() && m_remote_platform_sp)
+        return m_remote_platform_sp->WriteFile(fd, offset, data, len);
+    return Platform::WriteFile(fd, offset, data, len);
+}
+
+lldb_private::Error
+PlatformMacOSX::PutFile (const lldb_private::FileSpec& source,
+                         const lldb_private::FileSpec& destination,
+                         uint32_t uid,
+                         uint32_t gid)
+{
+    return Platform::PutFile(source,destination,uid,gid);
+}

Modified: lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.h?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.h Fri Apr  6 19:03:47 2012
@@ -80,6 +80,35 @@
     GetFile (const lldb_private::FileSpec &platform_file, 
              const lldb_private::UUID *uuid_ptr,
              lldb_private::FileSpec &local_file);
+    
+    virtual uint32_t
+    RunShellCommand (const std::string &command_line);
+    
+    virtual uint32_t
+    MakeDirectory (const std::string &path,
+                   mode_t mode);
+    
+    virtual lldb_private::Error
+    PutFile (const lldb_private::FileSpec& source,
+             const lldb_private::FileSpec& destination,
+             uint32_t uid = UINT32_MAX,
+             uint32_t gid = UINT32_MAX);
+    
+    virtual uint32_t
+    OpenFile (const lldb_private::FileSpec& file_spec,
+              uint32_t flags,
+              mode_t mode);
+    
+    virtual bool
+    CloseFile (uint32_t fd);
+    
+    virtual uint32_t
+    ReadFile (uint32_t fd, uint64_t offset,
+              void *data_ptr, size_t len);
+    
+    virtual uint32_t
+    WriteFile (uint32_t fd, uint64_t offset,
+               void* data, size_t len);
 
     virtual bool
     GetSupportedArchitectureAtIndex (uint32_t idx, 

Modified: lldb/branches/lldb-platform-work/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp Fri Apr  6 19:03:47 2012
@@ -405,4 +405,52 @@
     return process_sp;
 }
 
+uint32_t
+PlatformRemoteGDBServer::RunShellCommand (const std::string &command_line)
+{
+    return m_gdb_client.RunShellCommand(command_line);
+}
+
+uint32_t
+PlatformRemoteGDBServer::MakeDirectory (const std::string &path,
+                                        mode_t mode)
+{
+    return m_gdb_client.MakeDirectory(path,mode);
+}
+
+uint32_t
+PlatformRemoteGDBServer::OpenFile (const lldb_private::FileSpec& file_spec,
+                                   uint32_t flags,
+                                   mode_t mode)
+{
+    return m_gdb_client.OpenFile (file_spec, flags, mode);
+}
+
+bool
+PlatformRemoteGDBServer::CloseFile (uint32_t fd)
+{
+    return m_gdb_client.CloseFile (fd);
+}
+
+uint32_t
+PlatformRemoteGDBServer::ReadFile (uint32_t fd, uint64_t offset,
+                                   void *data_ptr, size_t len)
+{
+    return m_gdb_client.ReadFile (fd, offset, data_ptr, len);
+}
 
+uint32_t
+PlatformRemoteGDBServer::WriteFile (uint32_t fd, uint64_t offset,
+                                    void* data, size_t len)
+{
+    return m_gdb_client.WriteFile (fd, offset, data, len);
+}
+
+lldb_private::Error
+PlatformRemoteGDBServer::PutFile (const lldb_private::FileSpec& source,
+         const lldb_private::FileSpec& destination,
+         uint32_t uid,
+         uint32_t gid)
+{
+    return Platform::PutFile(source,destination,uid,gid);
+}

Modified: lldb/branches/lldb-platform-work/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h Fri Apr  6 19:03:47 2012
@@ -140,6 +140,35 @@
 
     virtual lldb_private::Error
     DisconnectRemote ();
+    
+    virtual uint32_t
+    RunShellCommand (const std::string &command_line);
+    
+    virtual uint32_t
+    MakeDirectory (const std::string &path,
+                   mode_t mode);
+    
+    virtual uint32_t
+    OpenFile (const lldb_private::FileSpec& file_spec,
+              uint32_t flags,
+              mode_t mode);
+    
+    virtual bool
+    CloseFile (uint32_t fd);
+    
+    virtual uint32_t
+    ReadFile (uint32_t fd, uint64_t offset,
+              void *data_ptr, size_t len);
+    
+    virtual uint32_t
+    WriteFile (uint32_t fd, uint64_t offset,
+               void* data, size_t len);
+    
+    virtual lldb_private::Error
+    PutFile (const lldb_private::FileSpec& source,
+             const lldb_private::FileSpec& destination,
+             uint32_t uid = UINT32_MAX,
+             uint32_t gid = UINT32_MAX);
 
 protected:
     GDBRemoteCommunicationClient m_gdb_client;

Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Fri Apr  6 19:03:47 2012
@@ -18,6 +18,7 @@
 #include "lldb/Core/ConnectionFileDescriptor.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/State.h"
+#include "lldb/Core/StreamGDBRemote.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Host/Host.h"
@@ -1875,3 +1876,152 @@
     }
     return thread_ids.size();
 }
+
+uint32_t
+GDBRemoteCommunicationClient::RunShellCommand (const std::string &command_line)
+{
+    lldb_private::StreamString stream;
+    stream.PutCString("qPlatform_Syscall_System:");
+    stream.PutBytesAsRawHex8(command_line.c_str(), command_line.size());
+    const char *packet = stream.GetData();
+    int packet_len = stream.GetSize();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        return response.GetHexMaxU32(false, UINT32_MAX);
+    }
+    return UINT32_MAX;
+}
+
+uint32_t
+GDBRemoteCommunicationClient::MakeDirectory (const std::string &path,
+                                             mode_t mode)
+{
+    lldb_private::StreamString stream;
+    stream.PutCString("qPlatform_IO_MkDir:");
+    stream.PutHex32(mode);
+    stream.PutChar(',');
+    stream.PutBytesAsRawHex8(path.c_str(), path.size());
+    const char *packet = stream.GetData();
+    int packet_len = stream.GetSize();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        return response.GetHexMaxU32(false, UINT32_MAX);
+    }
+    return UINT32_MAX;
+
+}
+
+uint32_t
+GDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
+                                        uint32_t flags,
+                                        mode_t mode)
+{
+    lldb_private::StreamString stream;
+    stream.PutCString("vFile:open:");
+    std::string path(512, ' ');
+    uint32_t len = file_spec.GetPath(&path[0], 512);
+    if (len >= 512)
+    {
+        path = std::string(len+1,' ');
+        len = file_spec.GetPath(&path[0], len);
+    }
+    stream.PutCStringAsRawHex8(path.c_str());
+    stream.PutChar(',');
+    stream.PutHex32(flags);
+    stream.PutChar(',');
+    stream.PutHex32(mode);
+    const char* packet = stream.GetData();
+    int packet_len = stream.GetSize();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        if (response.GetChar() != 'F')
+            return UINT32_MAX;
+        uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
+        return retcode;
+    }
+    return UINT32_MAX;
+}
+
+bool
+GDBRemoteCommunicationClient::CloseFile (uint32_t fd)
+{
+    lldb_private::StreamString stream;
+    stream.PutCString("vFile:close:");
+    stream.PutHex32(fd);
+    const char* packet = stream.GetData();
+    int packet_len = stream.GetSize();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        if (response.GetChar() != 'F')
+            return UINT32_MAX;
+        uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
+        return retcode;
+    }
+    return UINT32_MAX;
+}
+
+uint32_t
+GDBRemoteCommunicationClient::ReadFile (uint32_t fd, uint64_t offset,
+                                        void *data_ptr, size_t len)
+{
+    lldb_private::StreamString stream;
+    stream.PutCString("vFile:read:");
+    stream.PutHex32(fd);
+    stream.PutChar(',');
+    stream.PutHex32(len);
+    stream.PutChar(',');
+    stream.PutHex32(offset);
+    const char* packet = stream.GetData();
+    int packet_len = stream.GetSize();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        if (response.GetChar() != 'F')
+            return UINT32_MAX;
+        uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
+        if (retcode == UINT32_MAX)
+            return retcode;
+        if (response.GetChar() == ',')
+            return UINT32_MAX;
+        if (response.GetChar() == ';')
+        {
+            std::string buffer;
+            response.GetEscapedBinaryData(buffer);
+            size_t data_to_write = len;
+            if (buffer.size() < len)
+                data_to_write = buffer.size();
+            memcpy(data_ptr, &buffer[0], data_to_write);
+        }
+        return retcode;
+    }
+    return UINT32_MAX;
+}
+
+uint32_t
+GDBRemoteCommunicationClient::WriteFile (uint32_t fd, uint64_t offset,
+                                         void* data, size_t len)
+{
+    lldb_private::StreamGDBRemote stream;
+    stream.PutCString("vFile:write:");
+    stream.PutHex32(fd);
+    stream.PutChar(',');
+    stream.PutHex32(offset);
+    stream.PutChar(',');
+    stream.PutEscapedBytes(data, len);
+    const char* packet = stream.GetData();
+    int packet_len = stream.GetSize();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        if (response.GetChar() != 'F')
+            return UINT32_MAX;
+        uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
+        return retcode;
+    }
+    return UINT32_MAX;
+}
+

Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Fri Apr  6 19:03:47 2012
@@ -326,6 +326,30 @@
     {
         return m_interrupt_sent;
     }
+    
+    virtual uint32_t
+    RunShellCommand (const std::string &command_line);
+    
+    virtual uint32_t
+    OpenFile (const lldb_private::FileSpec& file_spec,
+              uint32_t flags,
+              mode_t mode);
+    
+    virtual bool
+    CloseFile (uint32_t fd);
+    
+    virtual uint32_t
+    ReadFile (uint32_t fd, uint64_t offset,
+              void *data_ptr, size_t len);
+    
+    virtual uint32_t
+    WriteFile (uint32_t fd, uint64_t offset,
+               void* data, size_t len);
+    
+    virtual uint32_t
+    MakeDirectory (const std::string &path,
+                   mode_t mode);
+
 protected:
 
     //------------------------------------------------------------------

Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Fri Apr  6 19:03:47 2012
@@ -9,6 +9,7 @@
 
 
 #include "GDBRemoteCommunicationServer.h"
+#import "StreamGDBRemote.h"
 
 // C Includes
 // C++ Includes
@@ -160,6 +161,24 @@
 
             case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
                 return Handle_QStartNoAckMode (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_qPlatform_Syscall_System:
+                return Handle_qPlatform_Syscall_System (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_qPlatform_IO_MkDir:
+                return Handle_qPlatform_IO_MkDir (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_vFile_Open:
+                return Handle_vFile_Open (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_vFile_Close:
+                return Handle_vFile_Close (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_vFile_pRead:
+                return Handle_vFile_pRead (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_vFile_pWrite:
+                return Handle_vFile_pWrite (packet);
         }
         return true;
     }
@@ -832,3 +851,137 @@
     m_send_acks = false;
     return true;
 }
+
+bool
+GDBRemoteCommunicationServer::Handle_qPlatform_Syscall_System (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen("qPlatform_Syscall_System:"));
+    std::string path;
+    packet.GetHexByteString(path);
+    uint32_t retcode = Host::RunProgramAndGetExitCode(FileSpec(path.c_str(),false));
+    StreamString response;
+    response.PutHex32(retcode);
+    SendPacket(response);
+    return true;
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_qPlatform_IO_MkDir (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen("qPlatform_IO_MkDir:"));
+    mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
+    if (packet.GetChar() != ',')
+        return false;
+    std::string path;
+    packet.GetHexByteString(path);
+    uint32_t retcode = Host::MakeDirectory(path.c_str(),mode);
+    StreamString response;
+    response.PutHex32(retcode);
+    SendPacket(response);
+    return true;
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen("vFile:open:"));
+    std::string path;
+    packet.GetHexByteString(path);
+    if (packet.GetChar() != ',')
+        return false;
+    uint32_t flags = packet.GetHexMaxU32(false, UINT32_MAX);
+    if (packet.GetChar() != ',')
+        return false;
+    mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
+    uint32_t retcode = Host::OpenFile(FileSpec(path.c_str(), false), flags, mode);
+    StreamString response;
+    response.PutChar('F');
+    response.PutHex32(retcode);
+    if (retcode == UINT32_MAX)
+    {
+        response.PutChar(',');
+        response.PutHex32(retcode); // TODO: replace with Host::GetSyswideErrorCode()
+    }
+    SendPacket(response);
+    return true;
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen("vFile:close:"));
+    uint32_t fd = packet.GetHexMaxU32(false, UINT32_MAX);
+    uint32_t retcode = Host::CloseFile(fd);
+    StreamString response;
+    response.PutChar('F');
+    response.PutHex32(retcode);
+    if (retcode == UINT32_MAX)
+    {
+        response.PutChar(',');
+        response.PutHex32(retcode); // TODO: replace with Host::GetSyswideErrorCode()
+    }
+    SendPacket(response);
+    return true;
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet)
+{
+    StreamGDBRemote response;
+    packet.SetFilePos(::strlen("vFile:pread:"));
+    uint32_t fd = packet.GetHexMaxU32(false, UINT32_MAX);
+    if (packet.GetChar() != ',')
+        return false;
+    uint32_t count = packet.GetHexMaxU32(false, UINT32_MAX);
+    if (packet.GetChar() != ',')
+        return false;
+    uint32_t offset = packet.GetHexMaxU32(false, UINT32_MAX);
+    if (count == UINT32_MAX) // protect yourself against allocating a 4GB buffer
+    {
+        response.PutChar('F');
+        response.PutHex32(UINT32_MAX);
+        response.PutChar(',');
+        response.PutHex32(UINT32_MAX); // TODO: replace with Host::GetSyswideErrorCode()
+        SendPacket(response);
+        return true;
+    }
+    std::string buffer(' ',count);
+    uint32_t retcode = Host::ReadFile(fd, offset, &buffer[0], count);
+    response.PutChar('F');
+    response.PutHex32(retcode);
+    if (retcode == UINT32_MAX)
+    {
+        response.PutChar(',');
+        response.PutHex32(retcode); // TODO: replace with Host::GetSyswideErrorCode()
+    }
+    else
+    {
+        response.PutChar(';');
+        response.PutEscapedBytes(&buffer[0], retcode);
+    }
+    SendPacket(response);
+    return true;
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen("vFile:pwrite:"));
+    uint32_t fd = packet.GetHexMaxU32(false, UINT32_MAX);
+    if (packet.GetChar() != ',')
+        return false;
+    uint32_t offset = packet.GetHexMaxU32(false, UINT32_MAX);
+    std::string buffer;
+    packet.GetEscapedBinaryData(buffer);
+    uint32_t retcode = Host::WriteFile(fd, offset, &buffer[0], buffer.size());
+    StreamString response;
+    response.PutChar('F');
+    response.PutHex32(retcode);
+    if (retcode == UINT32_MAX)
+    {
+        response.PutChar(',');
+        response.PutHex32(retcode); // TODO: replace with Host::GetSyswideErrorCode()
+    }
+    SendPacket(response);
+    return true;
+}

Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h Fri Apr  6 19:03:47 2012
@@ -85,7 +85,7 @@
 
     bool
     Handle_A (StringExtractorGDBRemote &packet);
-
+    
     bool
     Handle_qLaunchSuccess (StringExtractorGDBRemote &packet);
 
@@ -96,6 +96,12 @@
     Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
 
     bool
+    Handle_qPlatform_IO_MkDir (StringExtractorGDBRemote &packet);
+    
+    bool
+    Handle_qPlatform_Syscall_System (StringExtractorGDBRemote &packet);
+    
+    bool
     Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
     
     bool
@@ -137,6 +143,17 @@
     bool
     Handle_QSetSTDERR (StringExtractorGDBRemote &packet);
     
+    bool
+    Handle_vFile_Open (StringExtractorGDBRemote &packet);
+
+    bool
+    Handle_vFile_Close (StringExtractorGDBRemote &packet);
+
+    bool
+    Handle_vFile_pRead (StringExtractorGDBRemote &packet);
+
+    bool
+    Handle_vFile_pWrite (StringExtractorGDBRemote &packet);
 private:
     //------------------------------------------------------------------
     // For GDBRemoteCommunicationServer only

Modified: lldb/branches/lldb-platform-work/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Platform.cpp?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Platform.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Platform.cpp Fri Apr  6 19:03:47 2012
@@ -658,4 +658,14 @@
     
 }
 
+Error
+Platform::PutFile (const FileSpec& source,
+                   const FileSpec& destination,
+                   uint32_t uid,
+                   uint32_t gid)
+{
+    Error error("unimplemented");
+    return error;
+}
+
 

Modified: lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.cpp?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.cpp Fri Apr  6 19:03:47 2012
@@ -126,8 +126,11 @@
             break;
             
         case 'P':
-            if (PACKET_STARTS_WITH ("qProcessInfoPID:"))        return eServerPacketType_qProcessInfoPID;
+            if (PACKET_STARTS_WITH ("qProcessInfoPID:"))                 return eServerPacketType_qProcessInfoPID;
+            if (PACKET_STARTS_WITH ("qPlatform_Syscall_System:"))        return eServerPacketType_qPlatform_Syscall_System;
+            if (PACKET_STARTS_WITH ("qPlatform_IO_MkDir:"))              return eServerPacketType_qPlatform_IO_MkDir;
             break;
+                
 
         case 'S':
             if (PACKET_STARTS_WITH ("qSpeedTest:"))             return eServerPacketType_qSpeedTest;
@@ -138,6 +141,15 @@
             break;
         }
         break;
+    case 'v':
+            if (PACKET_STARTS_WITH("vFile:"))
+            {
+                if (PACKET_STARTS_WITH("vFile:open:"))               return eServerPacketType_vFile_Open;
+                else if (PACKET_STARTS_WITH("vFile:close:"))         return eServerPacketType_vFile_Close;
+                else if (PACKET_STARTS_WITH("vFile:pread"))          return eServerPacketType_vFile_pRead;
+                else if (PACKET_STARTS_WITH("vFile:pwrite"))         return eServerPacketType_vFile_pWrite;
+            }
+            break;
     }
     return eServerPacketType_unimplemented;
 }
@@ -180,3 +192,19 @@
     }
     return 0;
 }
+
+size_t
+StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str)
+{
+    str.clear();
+    char ch;
+    while (GetBytesLeft())
+    {
+        ch = GetChar();
+        if (ch == 0x7d)
+            ch = (GetChar() ^ 0x20);
+        str.append(1,ch);
+    }
+    return str.size();
+}
+

Modified: lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.h?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.h (original)
+++ lldb/branches/lldb-platform-work/source/Utility/StringExtractorGDBRemote.h Fri Apr  6 19:03:47 2012
@@ -63,7 +63,13 @@
         eServerPacketType_QSetSTDOUT,
         eServerPacketType_QSetSTDERR,
         eServerPacketType_QSetWorkingDir,
-        eServerPacketType_QStartNoAckMode
+        eServerPacketType_QStartNoAckMode,
+        eServerPacketType_qPlatform_Syscall_System,
+        eServerPacketType_qPlatform_IO_MkDir,
+        eServerPacketType_vFile_Open,
+        eServerPacketType_vFile_Close,
+        eServerPacketType_vFile_pRead,
+        eServerPacketType_vFile_pWrite
     };
     
     ServerPacketType
@@ -98,6 +104,10 @@
     // digits. Otherwise the error encoded in XX is returned.
     uint8_t
     GetError();
+    
+    size_t
+    GetEscapedBinaryData (std::string &str);
+
 };
 
 #endif  // utility_StringExtractorGDBRemote_h_

Modified: lldb/branches/lldb-platform-work/tools/lldb-platform/lldb-platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/lldb-platform/lldb-platform.cpp?rev=154233&r1=154232&r2=154233&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/lldb-platform/lldb-platform.cpp (original)
+++ lldb/branches/lldb-platform-work/tools/lldb-platform/lldb-platform.cpp Fri Apr  6 19:03:47 2012
@@ -183,6 +183,12 @@
     GDBRemoteCommunicationServer gdb_server (true);
     if (!listen_host_port.empty())
     {
+        for (int j = 0; j < listen_host_port.size(); j++)
+        {
+            char c = listen_host_port[j];
+            if (c > '9' || c < '0')
+                printf("WARNING: passing anything but a number as argument to --listen will most probably make connecting impossible.\n");
+        }
         std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
         if (conn_ap.get())
         {





More information about the lldb-commits mailing list