[Lldb-commits] [lldb] r195273 - Expose SBPlatform through the public API.

Greg Clayton gclayton at apple.com
Wed Nov 20 13:07:02 PST 2013


Author: gclayton
Date: Wed Nov 20 15:07:01 2013
New Revision: 195273

URL: http://llvm.org/viewvc/llvm-project?rev=195273&view=rev
Log:
Expose SBPlatform through the public API.

Example code:

remote_platform = lldb.SBPlatform("remote-macosx"); 
remote_platform.SetWorkingDirectory("/private/tmp")
debugger.SetSelectedPlatform(remote_platform)

connect_options = lldb.SBPlatformConnectOptions("connect://localhost:1111"); 
err = remote_platform.ConnectRemote(connect_options)
if err.Success():
    print >> result, 'Connected to remote platform:'
    print >> result, 'hostname: %s' % (remote_platform.GetHostname())
    src = lldb.SBFileSpec("/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework", False)
    dst = lldb.SBFileSpec()
    # copy src to platform working directory since "dst" is empty
    err = remote_platform.Install(src, dst);
    if err.Success():
        print >> result, '%s installed successfully' % (src)
    else:
        print >> result, 'error: failed to install "%s": %s' % (src, err)


Implemented many calls needed in lldb-platform to be able to install a directory that contains symlinks, file and directories.

The remote lldb-platform can now launch GDB servers on the remote system so that remote debugging can be spawned through the remote platform when connected to a remote platform.

The API in SBPlatform is subject to change and will be getting many new functions.


Added:
    lldb/trunk/include/lldb/API/SBPlatform.h
    lldb/trunk/scripts/Python/interface/SBPlatform.i
    lldb/trunk/source/API/SBPlatform.cpp
Modified:
    lldb/trunk/include/lldb/API/SBDebugger.h
    lldb/trunk/include/lldb/API/SBError.h
    lldb/trunk/include/lldb/API/SBFileSpec.h
    lldb/trunk/include/lldb/API/SBModule.h
    lldb/trunk/include/lldb/API/SBTarget.h
    lldb/trunk/include/lldb/Core/Module.h
    lldb/trunk/include/lldb/Host/File.h
    lldb/trunk/include/lldb/Host/FileSpec.h
    lldb/trunk/include/lldb/Host/Host.h
    lldb/trunk/include/lldb/Target/Platform.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/scripts/Python/build-swig-Python.sh
    lldb/trunk/scripts/Python/interface/SBDebugger.i
    lldb/trunk/scripts/Python/interface/SBFileSpec.i
    lldb/trunk/scripts/Python/interface/SBModule.i
    lldb/trunk/scripts/Python/interface/SBTarget.i
    lldb/trunk/scripts/lldb.swig
    lldb/trunk/source/API/SBDebugger.cpp
    lldb/trunk/source/API/SBFileSpec.cpp
    lldb/trunk/source/API/SBModule.cpp
    lldb/trunk/source/API/SBStream.cpp
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/Commands/CommandObjectPlatform.cpp
    lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
    lldb/trunk/source/Core/Module.cpp
    lldb/trunk/source/Core/StreamFile.cpp
    lldb/trunk/source/Host/common/File.cpp
    lldb/trunk/source/Host/common/FileSpec.cpp
    lldb/trunk/source/Host/common/Host.cpp
    lldb/trunk/source/Host/macosx/Host.mm
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/source/Target/Platform.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/Target.cpp
    lldb/trunk/source/Utility/StringExtractor.cpp
    lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
    lldb/trunk/source/Utility/StringExtractorGDBRemote.h
    lldb/trunk/tools/debugserver/debugserver.xcodeproj/xcshareddata/xcschemes/debugserver.xcscheme
    lldb/trunk/tools/lldb-platform/lldb-platform.cpp

Modified: lldb/trunk/include/lldb/API/SBDebugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDebugger.h (original)
+++ lldb/trunk/include/lldb/API/SBDebugger.h Wed Nov 20 15:07:01 2013
@@ -10,9 +10,11 @@
 #ifndef LLDB_SBDebugger_h_
 #define LLDB_SBDebugger_h_
 
-#include "lldb/API/SBDefines.h"
 #include <stdio.h>
 
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBPlatform.h"
+
 namespace lldb {
 
 class SBDebugger
@@ -153,6 +155,12 @@ public:
     void
     SetSelectedTarget (SBTarget& target);
 
+    lldb::SBPlatform
+    GetSelectedPlatform();
+
+    void
+    SetSelectedPlatform(lldb::SBPlatform &platform);
+
     lldb::SBSourceManager
     GetSourceManager ();
 

Modified: lldb/trunk/include/lldb/API/SBError.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBError.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBError.h (original)
+++ lldb/trunk/include/lldb/API/SBError.h Wed Nov 20 15:07:01 2013
@@ -72,6 +72,7 @@ protected:
     friend class SBCommunication;
     friend class SBHostOS;
     friend class SBInputReader;
+    friend class SBPlatform;
     friend class SBProcess;
     friend class SBThread;
     friend class SBTarget;

Modified: lldb/trunk/include/lldb/API/SBFileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFileSpec.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBFileSpec.h (original)
+++ lldb/trunk/include/lldb/API/SBFileSpec.h Wed Nov 20 15:07:01 2013
@@ -45,6 +45,12 @@ public:
     const char *
     GetDirectory() const;
 
+    void
+    SetFilename(const char *filename);
+    
+    void
+    SetDirectory(const char *directory);
+
     uint32_t
     GetPath (char *dst_path, size_t dst_len) const;
 
@@ -65,6 +71,7 @@ private:
     friend class SBLineEntry;
     friend class SBModule;
     friend class SBModuleSpec;
+    friend class SBPlatform;
     friend class SBProcess;
     friend class SBSourceManager;
     friend class SBThread;

Modified: lldb/trunk/include/lldb/API/SBModule.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBModule.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBModule.h (original)
+++ lldb/trunk/include/lldb/API/SBModule.h Wed Nov 20 15:07:01 2013
@@ -76,6 +76,42 @@ public:
     bool
     SetPlatformFileSpec (const lldb::SBFileSpec &platform_file);
 
+    //------------------------------------------------------------------
+    /// Get accessor for the remote install path for a module.
+    ///
+    /// When debugging to a remote platform by connecting to a remote
+    /// platform, the install path of the module can be set. If the
+    /// install path is set, every time the process is about to launch
+    /// the target will install this module on the remote platform prior
+    /// to launching.
+    ///
+    /// @return
+    ///     A file specification object.
+    //------------------------------------------------------------------
+    lldb::SBFileSpec
+    GetRemoteInstallFileSpec ();
+    
+    //------------------------------------------------------------------
+    /// Set accessor for the remote install path for a module.
+    ///
+    /// When debugging to a remote platform by connecting to a remote
+    /// platform, the install path of the module can be set. If the
+    /// install path is set, every time the process is about to launch
+    /// the target will install this module on the remote platform prior
+    /// to launching.
+    ///
+    /// If \a file specifies a full path to an install location, the
+    /// module will be installed to this path. If the path is relative
+    /// (no directory specified, or the path is partial like "usr/lib"
+    /// or "./usr/lib", then the install path will be resolved using
+    /// the platform's current working directory as the base path.
+    ///
+    /// @param[in]
+    ///     A file specification object.
+    //------------------------------------------------------------------
+    bool
+    SetRemoteInstallFileSpec (lldb::SBFileSpec &file);
+    
     lldb::ByteOrder
     GetByteOrder ();
     

Added: lldb/trunk/include/lldb/API/SBPlatform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBPlatform.h?rev=195273&view=auto
==============================================================================
--- lldb/trunk/include/lldb/API/SBPlatform.h (added)
+++ lldb/trunk/include/lldb/API/SBPlatform.h Wed Nov 20 15:07:01 2013
@@ -0,0 +1,198 @@
+//===-- SBPlatform.h --------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBPlatform_h_
+#define LLDB_SBPlatform_h_
+
+#include "lldb/API/SBDefines.h"
+
+struct PlatformConnectOptions;
+struct PlatformShellCommand;
+
+namespace lldb {
+
+    class SBPlatformConnectOptions
+    {
+    public:
+        SBPlatformConnectOptions (const char *url);
+
+        SBPlatformConnectOptions (const SBPlatformConnectOptions &rhs);
+
+        ~SBPlatformConnectOptions ();
+        
+        void
+        operator=(const SBPlatformConnectOptions &rhs);
+
+        const char *
+        GetURL();
+        
+        void
+        SetURL(const char *url);
+        
+        bool
+        GetRsyncEnabled();
+        
+        void
+        EnableRsync (const char *options,
+                     const char *remote_path_prefix,
+                     bool omit_remote_hostname);
+                     
+        void
+        DisableRsync ();
+        
+        const char *
+        GetLocalCacheDirectory();
+
+        void
+        SetLocalCacheDirectory(const char *path);
+    protected:
+        PlatformConnectOptions *m_opaque_ptr;
+    };
+
+    class SBPlatformShellCommand
+    {
+    public:
+        SBPlatformShellCommand (const char *shell_command);
+        
+        SBPlatformShellCommand (const SBPlatformShellCommand &rhs);
+        
+        ~SBPlatformShellCommand();
+        
+        void
+        Clear();
+
+        const char *
+        GetCommand();
+
+        void
+        SetCommand(const char *shell_command);
+        
+        const char *
+        GetWorkingDirectory ();
+
+        void
+        SetWorkingDirectory (const char *path);
+
+        uint32_t
+        GetTimeoutSeconds ();
+        
+        void
+        SetTimeoutSeconds (uint32_t sec);
+        
+        int
+        GetSignal ();
+        
+        int
+        GetStatus ();
+        
+        const char *
+        GetOutput ();
+
+    protected:
+        friend class SBPlatform;
+
+        PlatformShellCommand *m_opaque_ptr;
+    };
+
+    class SBPlatform
+    {
+    public:
+        
+        SBPlatform ();
+        
+        SBPlatform (const char *platform_name);
+        
+        ~SBPlatform();
+        
+        bool
+        IsValid () const;
+        
+        void
+        Clear ();
+
+        const char *
+        GetWorkingDirectory();
+
+        bool
+        SetWorkingDirectory(const char *path);
+
+        const char *
+        GetName ();
+
+        SBError
+        ConnectRemote (SBPlatformConnectOptions &connect_options);
+
+        void
+        DisconnectRemote ();
+        
+        bool
+        IsConnected();
+
+        //----------------------------------------------------------------------
+        // The following functions will work if the platform is connected
+        //----------------------------------------------------------------------
+        const char *
+        GetTriple();
+
+        const char *
+        GetHostname ();
+        
+        const char *
+        GetOSBuild ();
+        
+        const char *
+        GetOSDescription ();
+
+        uint32_t
+        GetOSMajorVersion ();
+
+        uint32_t
+        GetOSMinorVersion ();
+
+        uint32_t
+        GetOSUpdateVersion ();
+
+        SBError
+        Put (SBFileSpec &src, SBFileSpec &dst);
+        
+        SBError
+        Get (SBFileSpec &src, SBFileSpec &dst);
+
+        SBError
+        Install (SBFileSpec& src, SBFileSpec& dst);
+
+        SBError
+        Run (SBPlatformShellCommand &shell_command);
+
+        SBError
+        MakeDirectory (const char *path, uint32_t file_permissions = eFilePermissionsDirectoryDefault);
+
+        uint32_t
+        GetFilePermissions (const char *path);
+        
+        SBError
+        SetFilePermissions (const char *path, uint32_t file_permissions);
+
+    protected:
+        
+        friend class SBDebugger;
+        friend class SBTarget;
+
+        lldb::PlatformSP
+        GetSP () const;
+        
+        void
+        SetSP (const lldb::PlatformSP& platform_sp);
+
+        lldb::PlatformSP m_opaque_sp;
+    };
+
+} // namespace lldb
+
+#endif // LLDB_SBPlatform_h_

Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Wed Nov 20 15:07:01 2013
@@ -268,6 +268,23 @@ public:
     GetProcess ();
 
     //------------------------------------------------------------------
+    /// Install any binaries that need to be installed.
+    ///
+    /// This function does nothing when debugging on the host system.
+    /// When connected to remote platforms, the target's main executable
+    /// and any modules that have their remote install path set will be
+    /// installed on the remote platform. If the main executable doesn't
+    /// have an install location set, it will be installed in the remote
+    /// platform's working directory.
+    ///
+    /// @return
+    ///     An error describing anything that went wrong during
+    ///     installation.
+    //------------------------------------------------------------------
+    SBError
+    Install();
+    
+    //------------------------------------------------------------------
     /// Launch a new process.
     ///
     /// Launch a new process by spawning a new process using the

Modified: lldb/trunk/include/lldb/Core/Module.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Module.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Module.h (original)
+++ lldb/trunk/include/lldb/Core/Module.h Wed Nov 20 15:07:01 2013
@@ -570,6 +570,18 @@ public:
     }
 
     const FileSpec &
+    GetRemoteInstallFileSpec () const
+    {
+        return m_remote_install_file;
+    }
+    
+    void
+    SetRemoteInstallFileSpec (const FileSpec &file)
+    {
+        m_remote_install_file = file;
+    }
+    
+    const FileSpec &
     GetSymbolFileFileSpec () const
     {
         return m_symfile_spec;
@@ -1059,6 +1071,7 @@ protected:
     lldb_private::UUID          m_uuid;         ///< Each module is assumed to have a unique identifier to help match it up to debug symbols.
     FileSpec                    m_file;         ///< The file representation on disk for this module (if there is one).
     FileSpec                    m_platform_file;///< The path to the module on the platform on which it is being debugged
+    FileSpec                    m_remote_install_file;  ///< If set when debugging on remote platforms, this module will be installed at this location
     FileSpec                    m_symfile_spec; ///< If this path is valid, then this is the file that _will_ be used as the symbol file for this module
     ConstString                 m_object_name;  ///< The name an object within this module that is selected, or empty of the module is represented by \a m_file.
     uint64_t                    m_object_offset;

Modified: lldb/trunk/include/lldb/Host/File.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/File.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/File.h (original)
+++ lldb/trunk/include/lldb/Host/File.h Wed Nov 20 15:07:01 2013
@@ -40,46 +40,13 @@ public:
         eOpenOptionTruncate             = (1u << 3),    // Truncate file when opening
         eOpenOptionNonBlocking          = (1u << 4),    // File reads
         eOpenOptionCanCreate            = (1u << 5),    // Create file if doesn't already exist
-        eOpenOptionCanCreateNewOnly     = (1u << 6)     // Can create file only if it doesn't already exist
+        eOpenOptionCanCreateNewOnly     = (1u << 6),    // Can create file only if it doesn't already exist
+        eOpenoptionDontFollowSymlinks   = (1u << 7)
     };
     
     static mode_t
     ConvertOpenOptionsForPOSIXOpen (uint32_t open_options);
     
-    enum Permissions
-    {
-        ePermissionsUserRead        = (1u << 8),
-        ePermissionsUserWrite       = (1u << 7),
-        ePermissionsUserExecute     = (1u << 6),
-        ePermissionsGroupRead       = (1u << 5),
-        ePermissionsGroupWrite      = (1u << 4),
-        ePermissionsGroupExecute    = (1u << 3),
-        ePermissionsWorldRead       = (1u << 2),
-        ePermissionsWorldWrite      = (1u << 1),
-        ePermissionsWorldExecute    = (1u << 0),
-
-        ePermissionsUserRW      = (ePermissionsUserRead    | ePermissionsUserWrite    | 0                        ),
-        ePermissionsUserRX      = (ePermissionsUserRead    | 0                        | ePermissionsUserExecute  ),
-        ePermissionsUserRWX     = (ePermissionsUserRead    | ePermissionsUserWrite    | ePermissionsUserExecute  ),
-
-        ePermissionsGroupRW     = (ePermissionsGroupRead   | ePermissionsGroupWrite   | 0                        ),
-        ePermissionsGroupRX     = (ePermissionsGroupRead   | 0                        | ePermissionsGroupExecute ),
-        ePermissionsGroupRWX    = (ePermissionsGroupRead   | ePermissionsGroupWrite   | ePermissionsGroupExecute ),
-
-        ePermissionsWorldRW     = (ePermissionsWorldRead   | ePermissionsWorldWrite   | 0                        ),
-        ePermissionsWorldRX     = (ePermissionsWorldRead   | 0                        | ePermissionsWorldExecute ),
-        ePermissionsWorldRWX    = (ePermissionsWorldRead   | ePermissionsWorldWrite   | ePermissionsWorldExecute ),
-
-        ePermissionsEveryoneR   = (ePermissionsUserRead    | ePermissionsGroupRead    | ePermissionsWorldRead    ),
-        ePermissionsEveryoneW   = (ePermissionsUserWrite   | ePermissionsGroupWrite   | ePermissionsWorldWrite   ),
-        ePermissionsEveryoneX   = (ePermissionsUserExecute | ePermissionsGroupExecute | ePermissionsWorldExecute ),
-
-        ePermissionsEveryoneRW  = (ePermissionsEveryoneR   | ePermissionsEveryoneW    | 0                        ),
-        ePermissionsEveryoneRX  = (ePermissionsEveryoneR   | 0                        | ePermissionsEveryoneX    ),
-        ePermissionsEveryoneRWX = (ePermissionsEveryoneR   | ePermissionsEveryoneW    | ePermissionsEveryoneX    ),
-        ePermissionsDefault     = (ePermissionsUserRW      | ePermissionsGroupRead)
-    };
-
     File() : 
         m_descriptor (kInvalidDescriptor),
         m_stream (kInvalidStream),
@@ -120,7 +87,7 @@ public:
     //------------------------------------------------------------------
     File (const char *path,
           uint32_t options,
-          uint32_t permissions = ePermissionsDefault);
+          uint32_t permissions = lldb::eFilePermissionsFileDefault);
 
     //------------------------------------------------------------------
     /// Constructor with FileSpec.
@@ -142,7 +109,7 @@ public:
     //------------------------------------------------------------------
     File (const FileSpec& filespec,
           uint32_t options,
-          uint32_t permissions = ePermissionsDefault);
+          uint32_t permissions = lldb::eFilePermissionsFileDefault);
     
     File (int fd, bool tranfer_ownership) : 
         m_descriptor (fd),
@@ -236,7 +203,7 @@ public:
     Error
     Open (const char *path,
           uint32_t options,
-          uint32_t permissions = ePermissionsDefault);
+          uint32_t permissions = lldb::eFilePermissionsFileDefault);
 
     Error
     Close ();

Modified: lldb/trunk/include/lldb/Host/FileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/FileSpec.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/FileSpec.h (original)
+++ lldb/trunk/include/lldb/Host/FileSpec.h Wed Nov 20 15:07:01 2013
@@ -420,6 +420,21 @@ public:
     FileType
     GetFileType () const;
 
+    //------------------------------------------------------------------
+    /// Return the current permissions of the path.
+    ///
+    /// Returns a bitmask for the current permissions of the file
+    /// ( zero or more of the permission bits defined in
+    /// File::Permissions).
+    ///
+    /// @return
+    ///     Zero if the file doesn't exist or we are unable to get
+    ///     information for the file, otherwise one or more permission
+    ///     bits from the File::Permissions enumeration.
+    //------------------------------------------------------------------
+    uint32_t
+    GetPermissions () const;
+    
     bool
     IsDirectory () const
     {
@@ -636,7 +651,7 @@ public:
     void
     RemoveLastPathComponent ();
     
-    const char*
+    ConstString
     GetLastPathComponent () const;
     
     //------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Wed Nov 20 15:07:01 2013
@@ -510,13 +510,28 @@ public:
                              const char *symbol_name, 
                              Error &error);
     
-    static uint32_t
-    MakeDirectory (const char* path, mode_t mode);
+    static Error
+    MakeDirectory (const char* path, uint32_t mode);
     
+    static Error
+    GetFilePermissions (const char* path, uint32_t &file_permissions);
+
+    static Error
+    SetFilePermissions (const char* path, uint32_t file_permissions);
+    
+    static Error
+    Symlink (const char *src, const char *dst);
+    
+    static Error
+    Readlink (const char *path, char *buf, size_t buf_len);
+
+    static Error
+    Unlink (const char *path);
+
     static lldb::user_id_t
     OpenFile (const FileSpec& file_spec,
               uint32_t flags,
-              mode_t mode,
+              uint32_t mode,
               Error &error);
     
     static bool

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Wed Nov 20 15:07:01 2013
@@ -40,7 +40,8 @@ namespace lldb_private {
     ///     @li listing and getting info for existing processes
     ///     @li attaching and possibly debugging the platform's kernel
     //----------------------------------------------------------------------
-    class Platform : public PluginInterface
+    class Platform :
+        public PluginInterface
     {
     public:
 
@@ -214,8 +215,7 @@ namespace lldb_private {
         bool
         GetOSKernelDescription (std::string &s);
 
-        // Returns the the hostname if we are connected, else the short plugin
-        // name.
+        // Returns the the name of the platform
         ConstString
         GetName ();
 
@@ -269,6 +269,19 @@ namespace lldb_private {
         {
             return ArchSpec(); // Return an invalid architecture
         }
+        
+        virtual ConstString
+        GetRemoteWorkingDirectory()
+        {
+            return m_working_dir;
+        }
+        
+        virtual bool
+        SetRemoteWorkingDirectory(const ConstString &path)
+        {
+            m_working_dir = path;
+            return true;
+        }
 
         virtual const char *
         GetUserName (uint32_t uid);
@@ -384,10 +397,13 @@ namespace lldb_private {
         }
 
         //------------------------------------------------------------------
-        /// Subclasses should NOT need to implement this function as it uses
-        /// the Platform::LaunchProcess() followed by Platform::Attach ()
+        /// Subclasses do not need to implement this function as it uses
+        /// the Platform::LaunchProcess() followed by Platform::Attach ().
+        /// Remote platforms will want to subclass this function in order
+        /// to be able to intercept STDIO and possibly launch a separate
+        /// process that will debug the debuggee.
         //------------------------------------------------------------------
-        lldb::ProcessSP
+        virtual lldb::ProcessSP
         DebugProcess (ProcessLaunchInfo &launch_info,
                       Debugger &debugger,
                       Target *target,       // Can be NULL, if NULL create a new target, else use existing one
@@ -542,6 +558,12 @@ namespace lldb_private {
         {
             m_sdk_build = sdk_build;
         }    
+
+        ConstString
+        GetWorkingDirectory ();
+        
+        bool
+        SetWorkingDirectory (const ConstString &path);
         
         // There may be modules that we don't want to find by default for operations like "setting breakpoint by name".
         // The platform will return "true" from this call if the passed in module happens to be one of these.
@@ -552,23 +574,19 @@ namespace lldb_private {
             return false;
         }
         
-        virtual uint32_t
-        MakeDirectory (const std::string &path,
-                       mode_t mode)
-        {
-            return UINT32_MAX;
-        }
-        
-        // this need not be virtual: the core behavior is in
-        // MakeDirectory(std::string,mode_t)
-        uint32_t
-        MakeDirectory (const FileSpec &spec,
-                       mode_t mode);
+        virtual Error
+        MakeDirectory (const char *path, uint32_t permissions);
         
+        virtual Error
+        GetFilePermissions (const char *path, uint32_t &file_permissions);
+
+        virtual Error
+        SetFilePermissions (const char *path, uint32_t file_permissions);
+
         virtual lldb::user_id_t
         OpenFile (const FileSpec& file_spec,
                   uint32_t flags,
-                  mode_t mode,
+                  uint32_t mode,
                   Error &error)
         {
             return UINT64_MAX;
@@ -610,28 +628,54 @@ namespace lldb_private {
         }
         
         virtual Error
+        GetFile (const FileSpec& source,
+                 const FileSpec& destination);
+        
+        virtual Error
         PutFile (const FileSpec& source,
                  const FileSpec& destination,
                  uint32_t uid = UINT32_MAX,
                  uint32_t gid = UINT32_MAX);
-                
+
+        virtual Error
+        CreateSymlink (const char *src, // The name of the link is in src
+                       const char *dst);// The symlink points to dst
+
+        //----------------------------------------------------------------------
+        /// Install a file or directory to the remote system.
+        ///
+        /// Install is similar to Platform::PutFile(), but it differs in that if
+        /// an application/framework/shared library is installed on a remote
+        /// platform and the remote platform requires something to be done to
+        /// register the application/framework/shared library, then this extra
+        /// registration can be done.
+        ///
+        /// @param[in] src
+        ///     The source file/directory to install on the remote system.
+        ///
+        /// @param[in] dst
+        ///     The destination file/directory where \a src will be installed.
+        ///     If \a dst has no filename specified, then its filename will
+        ///     be set from \a src. It \a dst has no directory specified, it
+        ///     will use the platform working directory. If \a dst has a
+        ///     directory specified, but the directory path is relative, the
+        ///     platform working directory will be prepended to the relative
+        ///     directory.
+        ///
+        /// @return
+        ///     An error object that describes anything that went wrong.
+        //----------------------------------------------------------------------
+        virtual Error
+        Install (const FileSpec& src, const FileSpec& dst);
+
         virtual size_t
         GetEnvironment (StringList &environment);
         
-        virtual Error
-        GetFile (const FileSpec& source,
-                 const FileSpec& destination);
-        
         virtual bool
         GetFileExists (const lldb_private::FileSpec& file_spec);
         
-        virtual uint32_t
-        GetFilePermissions (const lldb_private::FileSpec &file_spec,
-                            Error &error)
-        {
-            error.SetErrorStringWithFormat ("Platform::GetFilePermissions() is not supported in the %s platform", GetName().GetCString());
-            return 0;
-        }
+        virtual Error
+        Unlink (const char *path);
 
         virtual bool
         GetSupportsRSync ()
@@ -806,6 +850,7 @@ namespace lldb_private {
         bool m_system_arch_set_while_connected;
         ConstString m_sdk_sysroot; // the root location of where the SDK files are all located
         ConstString m_sdk_build;
+        ConstString m_working_dir; // The working directory which is used when installing modules that have no install path set
         std::string m_remote_url;
         std::string m_name;
         uint32_t m_major_os_version;

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Wed Nov 20 15:07:01 2013
@@ -1745,7 +1745,7 @@ public:
     ///     the error object is success.
     //------------------------------------------------------------------
     virtual Error
-    Launch (const ProcessLaunchInfo &launch_info);
+    Launch (ProcessLaunchInfo &launch_info);
 
     virtual Error
     LoadCore ();

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Wed Nov 20 15:07:01 2013
@@ -1041,6 +1041,12 @@ public:
     ClangASTImporter *
     GetClangASTImporter();
     
+    //----------------------------------------------------------------------
+    // Install any files through the platform that need be to installed
+    // prior to launching or attaching.
+    //----------------------------------------------------------------------
+    Error
+    Install(ProcessLaunchInfo *launch_info);
     
     // Since expressions results can persist beyond the lifetime of a process,
     // and the const expression results are available after a process is gone,

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Wed Nov 20 15:07:01 2013
@@ -684,6 +684,48 @@ namespace lldb {
         eAddressClassRuntime
     } AddressClass;
 
+    //----------------------------------------------------------------------
+    // File Permissions
+    //
+    // Designed to mimic the unix file permission bits so they can be
+    // used with functions that set 'mode_t' to certain values for
+    // permissions.
+    //----------------------------------------------------------------------
+    typedef enum FilePermissions
+    {
+        eFilePermissionsUserRead        = (1u << 8),
+        eFilePermissionsUserWrite       = (1u << 7),
+        eFilePermissionsUserExecute     = (1u << 6),
+        eFilePermissionsGroupRead       = (1u << 5),
+        eFilePermissionsGroupWrite      = (1u << 4),
+        eFilePermissionsGroupExecute    = (1u << 3),
+        eFilePermissionsWorldRead       = (1u << 2),
+        eFilePermissionsWorldWrite      = (1u << 1),
+        eFilePermissionsWorldExecute    = (1u << 0),
+        
+        eFilePermissionsUserRW      = (eFilePermissionsUserRead    | eFilePermissionsUserWrite      | 0                             ),
+        eFileFilePermissionsUserRX  = (eFilePermissionsUserRead    | 0                              | eFilePermissionsUserExecute   ),
+        eFilePermissionsUserRWX     = (eFilePermissionsUserRead    | eFilePermissionsUserWrite      | eFilePermissionsUserExecute   ),
+            
+        eFilePermissionsGroupRW     = (eFilePermissionsGroupRead   | eFilePermissionsGroupWrite     | 0                             ),
+        eFilePermissionsGroupRX     = (eFilePermissionsGroupRead   | 0                              | eFilePermissionsGroupExecute  ),
+        eFilePermissionsGroupRWX    = (eFilePermissionsGroupRead   | eFilePermissionsGroupWrite     | eFilePermissionsGroupExecute  ),
+        
+        eFilePermissionsWorldRW     = (eFilePermissionsWorldRead   | eFilePermissionsWorldWrite     | 0                             ),
+        eFilePermissionsWorldRX     = (eFilePermissionsWorldRead   | 0                              | eFilePermissionsWorldExecute  ),
+        eFilePermissionsWorldRWX    = (eFilePermissionsWorldRead   | eFilePermissionsWorldWrite     | eFilePermissionsWorldExecute  ),
+        
+        eFilePermissionsEveryoneR   = (eFilePermissionsUserRead    | eFilePermissionsGroupRead      | eFilePermissionsWorldRead     ),
+        eFilePermissionsEveryoneW   = (eFilePermissionsUserWrite   | eFilePermissionsGroupWrite     | eFilePermissionsWorldWrite    ),
+        eFilePermissionsEveryoneX   = (eFilePermissionsUserExecute | eFilePermissionsGroupExecute   | eFilePermissionsWorldExecute  ),
+        
+        eFilePermissionsEveryoneRW  = (eFilePermissionsEveryoneR   | eFilePermissionsEveryoneW      | 0                             ),
+        eFilePermissionsEveryoneRX  = (eFilePermissionsEveryoneR   | 0                              | eFilePermissionsEveryoneX     ),
+        eFilePermissionsEveryoneRWX = (eFilePermissionsEveryoneR   | eFilePermissionsEveryoneW      | eFilePermissionsEveryoneX     ),
+        eFilePermissionsFileDefault = eFilePermissionsUserRW,
+        eFilePermissionsDirectoryDefault = eFilePermissionsUserRWX,
+    } FilePermissions;
+
 } // namespace lldb
 
 

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Wed Nov 20 15:07:01 2013
@@ -89,6 +89,8 @@
 		262D24E613FB8710002D1960 /* RegisterContextMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 262D24E413FB8710002D1960 /* RegisterContextMemory.cpp */; };
 		262ED0051631FA2800879631 /* OptionGroupString.h in Headers */ = {isa = PBXBuildFile; fileRef = 262ED0041631FA2800879631 /* OptionGroupString.h */; };
 		262ED0081631FA3A00879631 /* OptionGroupString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 262ED0071631FA3A00879631 /* OptionGroupString.cpp */; };
+		262F12B51835468600AEB384 /* SBPlatform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 262F12B41835468600AEB384 /* SBPlatform.cpp */; };
+		262F12B71835469C00AEB384 /* SBPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = 262F12B61835469C00AEB384 /* SBPlatform.h */; };
 		2635879417822FC2004C30BA /* SymbolVendorELF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2635879017822E56004C30BA /* SymbolVendorELF.cpp */; };
 		26368A3C126B697600E8659F /* darwin-debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26368A3B126B697600E8659F /* darwin-debug.cpp */; };
 		26368AF7126B960500E8659F /* darwin-debug in Resources */ = {isa = PBXBuildFile; fileRef = 26579F68126A25920007C5CB /* darwin-debug */; };
@@ -947,6 +949,9 @@
 		262D24E513FB8710002D1960 /* RegisterContextMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMemory.h; path = Utility/RegisterContextMemory.h; sourceTree = "<group>"; };
 		262ED0041631FA2800879631 /* OptionGroupString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OptionGroupString.h; path = include/lldb/Interpreter/OptionGroupString.h; sourceTree = "<group>"; };
 		262ED0071631FA3A00879631 /* OptionGroupString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupString.cpp; path = source/Interpreter/OptionGroupString.cpp; sourceTree = "<group>"; };
+		262F12B41835468600AEB384 /* SBPlatform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBPlatform.cpp; path = source/API/SBPlatform.cpp; sourceTree = "<group>"; };
+		262F12B61835469C00AEB384 /* SBPlatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBPlatform.h; path = include/lldb/API/SBPlatform.h; sourceTree = "<group>"; };
+		262F12B8183546C900AEB384 /* SBPlatform.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBPlatform.i; sourceTree = "<group>"; };
 		2635879017822E56004C30BA /* SymbolVendorELF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolVendorELF.cpp; sourceTree = "<group>"; };
 		2635879117822E56004C30BA /* SymbolVendorELF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolVendorELF.h; sourceTree = "<group>"; };
 		263664921140A4930075843B /* Debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = Debugger.cpp; path = source/Core/Debugger.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
@@ -2169,6 +2174,7 @@
 				2611FF05142D83060017FEA3 /* SBListener.i */,
 				2611FF06142D83060017FEA3 /* SBModule.i */,
 				263C493B178B61CC0070F12D /* SBModuleSpec.i */,
+				262F12B8183546C900AEB384 /* SBPlatform.i */,
 				2611FF07142D83060017FEA3 /* SBProcess.i */,
 				2611FF08142D83060017FEA3 /* SBSection.i */,
 				2611FF09142D83060017FEA3 /* SBSourceManager.i */,
@@ -2269,6 +2275,8 @@
 				26DE204C11618E7A00A093E2 /* SBModule.cpp */,
 				263C4939178B50CF0070F12D /* SBModuleSpec.h */,
 				263C4937178B50C40070F12D /* SBModuleSpec.cpp */,
+				262F12B61835469C00AEB384 /* SBPlatform.h */,
+				262F12B41835468600AEB384 /* SBPlatform.cpp */,
 				9A9831041125FC5800A56CB0 /* SBProcess.h */,
 				9A9831031125FC5800A56CB0 /* SBProcess.cpp */,
 				26B8283C142D01E9002DBC64 /* SBSection.h */,
@@ -3600,6 +3608,7 @@
 				26C72C94124322890068DC16 /* SBStream.h in Headers */,
 				9A357671116E7B5200E8ED2F /* SBStringList.h in Headers */,
 				26DE205B11618FF600A093E2 /* SBSymbol.h in Headers */,
+				262F12B71835469C00AEB384 /* SBPlatform.h in Headers */,
 				26DE204111618AB900A093E2 /* SBSymbolContext.h in Headers */,
 				268F9D53123AA15200B91E9B /* SBSymbolContextList.h in Headers */,
 				2668022C115FD13D008E1FE4 /* SBTarget.h in Headers */,
@@ -3981,6 +3990,7 @@
 			files = (
 				9461569A14E358A6003A195C /* SBTypeFilter.cpp in Sources */,
 				9461569B14E358A6003A195C /* SBTypeFormat.cpp in Sources */,
+				262F12B51835468600AEB384 /* SBPlatform.cpp in Sources */,
 				9461569C14E358A6003A195C /* SBTypeSummary.cpp in Sources */,
 				9461569D14E358A6003A195C /* SBTypeSynthetic.cpp in Sources */,
 				26680324116005D9008E1FE4 /* SBThread.cpp in Sources */,

Modified: lldb/trunk/scripts/Python/build-swig-Python.sh
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/build-swig-Python.sh?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/build-swig-Python.sh (original)
+++ lldb/trunk/scripts/Python/build-swig-Python.sh Wed Nov 20 15:07:01 2013
@@ -152,6 +152,7 @@ INTERFACE_FILES="${SRC_ROOT}/scripts/Pyt
 " ${SRC_ROOT}/scripts/Python/interface/SBListener.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBModule.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBModuleSpec.i"\
+" ${SRC_ROOT}/scripts/Python/interface/SBPlatform.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBProcess.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBSourceManager.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBStream.i"\

Modified: lldb/trunk/scripts/Python/interface/SBDebugger.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBDebugger.i?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBDebugger.i (original)
+++ lldb/trunk/scripts/Python/interface/SBDebugger.i Wed Nov 20 15:07:01 2013
@@ -231,6 +231,12 @@ public:
     void
     SetSelectedTarget (lldb::SBTarget &target);
 
+    lldb::SBPlatform
+    GetSelectedPlatform();
+    
+    void
+    SetSelectedPlatform(lldb::SBPlatform &platform);
+
     lldb::SBSourceManager
     GetSourceManager ();
 

Modified: lldb/trunk/scripts/Python/interface/SBFileSpec.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBFileSpec.i?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBFileSpec.i (original)
+++ lldb/trunk/scripts/Python/interface/SBFileSpec.i Wed Nov 20 15:07:01 2013
@@ -58,6 +58,12 @@ public:
     const char *
     GetDirectory() const;
 
+    void
+    SetFilename(const char *filename);
+    
+    void
+    SetDirectory(const char *directory);
+
     uint32_t
     GetPath (char *dst_path, size_t dst_len) const;
 

Modified: lldb/trunk/scripts/Python/interface/SBModule.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBModule.i?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBModule.i (original)
+++ lldb/trunk/scripts/Python/interface/SBModule.i Wed Nov 20 15:07:01 2013
@@ -148,6 +148,12 @@ public:
 
     bool
     SetPlatformFileSpec (const lldb::SBFileSpec &platform_file);
+             
+    lldb::SBFileSpec
+    GetRemoteInstallFileSpec ();
+
+    bool
+    SetRemoteInstallFileSpec (lldb::SBFileSpec &file);
 
     %feature("docstring", "Returns the UUID of the module as a Python string."
     ) GetUUIDString;

Added: lldb/trunk/scripts/Python/interface/SBPlatform.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBPlatform.i?rev=195273&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBPlatform.i (added)
+++ lldb/trunk/scripts/Python/interface/SBPlatform.i Wed Nov 20 15:07:01 2013
@@ -0,0 +1,187 @@
+//===-- SWIG Interface for SBPlatform ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+    
+class SBPlatformConnectOptions
+{
+public:
+    SBPlatformConnectOptions (const char *url);
+    
+    SBPlatformConnectOptions (const SBPlatformConnectOptions &rhs);
+    
+    ~SBPlatformConnectOptions ();
+    
+    const char *
+    GetURL();
+    
+    void
+    SetURL(const char *url);
+    
+    bool
+    GetRsyncEnabled();
+    
+    void
+    EnableRsync (const char *options,
+                 const char *remote_path_prefix,
+                 bool omit_remote_hostname);
+    
+    void
+    DisableRsync ();
+    
+    const char *
+    GetLocalCacheDirectory();
+    
+    void
+    SetLocalCacheDirectory(const char *path);
+};
+
+class SBPlatformShellCommand
+{
+public:
+    SBPlatformShellCommand (const char *shell_command);
+    
+    SBPlatformShellCommand (const SBPlatformShellCommand &rhs);
+    
+    ~SBPlatformShellCommand();
+    
+    void
+    Clear();
+
+    const char *
+    GetCommand();
+
+    void
+    SetCommand(const char *shell_command);
+    
+    const char *
+    GetWorkingDirectory ();
+
+    void
+    SetWorkingDirectory (const char *path);
+
+    uint32_t
+    GetTimeoutSeconds ();
+    
+    void
+    SetTimeoutSeconds (uint32_t sec);
+    
+    int
+    GetSignal ();
+    
+    int
+    GetStatus ();
+    
+    const char *
+    GetOutput ();
+};
+
+%feature("docstring",
+"A class that represents the a platform that can represent the current host or a remote host debug platform.
+
+The SBPlatform class represents the current host, or a remote host.
+It can be connected to a remote platform in order to provide ways
+to remotely launch and attach to processes, upload/download files,
+create directories, run remote shell commands, find locally cached
+versions of files from the remote system, and much more.
+         
+SBPlatform objects can be created and then used to connect to a remote
+platform which allows the SBPlatform to be used to get a list of the
+current processes on the remote host, attach to one of those processes,
+install programs on the remote system, attach and launch processes,
+and much more.
+
+Every SBTarget has a corresponding SBPlatform. The platform can be
+specified upon target creation, or the currently selected platform
+will attempt to be used when creating the target automatically as long
+as the currently selected platform matches the target architecture
+and executable type. If the architecture or executable type do not match,
+a suitable platform will be found automatically."
+         
+) SBPlatform;
+class SBPlatform
+{
+public:
+
+    SBPlatform ();
+
+    SBPlatform (const char *);
+
+    ~SBPlatform();
+    
+    bool
+    IsValid () const;
+
+    void
+    Clear ();
+
+    const char *
+    GetWorkingDirectory();
+    
+    bool
+    SetWorkingDirectory(const char *);
+
+    const char *
+    GetName ();
+    
+    SBError
+    ConnectRemote (lldb::SBPlatformConnectOptions &connect_options);
+    
+    void
+    DisconnectRemote ();
+
+    bool
+    IsConnected();
+    
+    const char *
+    GetTriple();
+    
+    const char *
+    GetHostname ();
+    
+    const char *
+    GetOSBuild ();
+    
+    const char *
+    GetOSDescription ();
+    
+    uint32_t
+    GetOSMajorVersion ();
+    
+    uint32_t
+    GetOSMinorVersion ();
+    
+    uint32_t
+    GetOSUpdateVersion ();
+    
+    lldb::SBError
+    Get (lldb::SBFileSpec &src, lldb::SBFileSpec &dst);
+
+    lldb::SBError
+    Put (lldb::SBFileSpec &src, lldb::SBFileSpec &dst);
+    
+    lldb::SBError
+    Install (lldb::SBFileSpec &src, lldb::SBFileSpec &dst);
+    
+    lldb::SBError
+    Run (lldb::SBPlatformShellCommand &shell_command);
+
+    lldb::SBError
+    MakeDirectory (const char *path, uint32_t file_permissions = lldb::eFilePermissionsDirectoryDefault);
+    
+    uint32_t
+    GetFilePermissions (const char *path);
+    
+    lldb::SBError
+    SetFilePermissions (const char *path, uint32_t file_permissions);
+
+};
+
+} // namespace lldb

Modified: lldb/trunk/scripts/Python/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBTarget.i?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBTarget.i (original)
+++ lldb/trunk/scripts/Python/interface/SBTarget.i Wed Nov 20 15:07:01 2013
@@ -266,6 +266,25 @@ public:
 
     %feature("docstring", "
     //------------------------------------------------------------------
+    /// Install any binaries that need to be installed.
+    ///
+    /// This function does nothing when debugging on the host system.
+    /// When connected to remote platforms, the target's main executable
+    /// and any modules that have their install path set will be
+    /// installed on the remote platform. If the main executable doesn't
+    /// have an install location set, it will be installed in the remote
+    /// platform's working directory.
+    ///
+    /// @return
+    ///     An error describing anything that went wrong during
+    ///     installation.
+    //------------------------------------------------------------------
+    ") Install;
+    lldb::SBError
+    Install();
+
+    %feature("docstring", "
+    //------------------------------------------------------------------
     /// Launch a new process.
     ///
     /// Launch a new process by spawning a new process using the

Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Wed Nov 20 15:07:01 2013
@@ -79,6 +79,7 @@ import os
 #include "lldb/API/SBListener.h"
 #include "lldb/API/SBModule.h"
 #include "lldb/API/SBModuleSpec.h"
+#include "lldb/API/SBPlatform.h"
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBSection.h"
 #include "lldb/API/SBSourceManager.h"
@@ -143,6 +144,7 @@ import os
 %include "./Python/interface/SBListener.i"
 %include "./Python/interface/SBModule.i"
 %include "./Python/interface/SBModuleSpec.i"
+%include "./Python/interface/SBPlatform.i"
 %include "./Python/interface/SBProcess.i"
 %include "./Python/interface/SBSection.i"
 %include "./Python/interface/SBSourceManager.i"

Modified: lldb/trunk/source/API/SBDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/API/SBDebugger.cpp (original)
+++ lldb/trunk/source/API/SBDebugger.cpp Wed Nov 20 15:07:01 2013
@@ -804,6 +804,42 @@ SBDebugger::SetSelectedTarget (SBTarget
     }
 }
 
+SBPlatform
+SBDebugger::GetSelectedPlatform()
+{
+    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+    SBPlatform sb_platform;
+    DebuggerSP debugger_sp(m_opaque_sp);
+    if (debugger_sp)
+    {
+        sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform());
+    }
+    if (log)
+    {
+        log->Printf ("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s", m_opaque_sp.get(),
+                     sb_platform.GetSP().get(), sb_platform.GetName());
+    }
+    return sb_platform;
+}
+
+void
+SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform)
+{
+    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+    
+    DebuggerSP debugger_sp(m_opaque_sp);
+    if (debugger_sp)
+    {
+        debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP());
+    }
+    if (log)
+    {
+        log->Printf ("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)", m_opaque_sp.get(),
+                     sb_platform.GetSP().get(), sb_platform.GetName());
+    }
+}
+
 void
 SBDebugger::DispatchInput (void* baton, const void *data, size_t data_len)
 {

Modified: lldb/trunk/source/API/SBFileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFileSpec.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/API/SBFileSpec.cpp (original)
+++ lldb/trunk/source/API/SBFileSpec.cpp Wed Nov 20 15:07:01 2013
@@ -121,6 +121,24 @@ SBFileSpec::GetDirectory() const
     return s;
 }
 
+void
+SBFileSpec::SetFilename(const char *filename)
+{
+    if (filename && filename[0])
+        m_opaque_ap->GetFilename().SetCString(filename);
+    else
+        m_opaque_ap->GetFilename().Clear();
+}
+
+void
+SBFileSpec::SetDirectory(const char *directory)
+{
+    if (directory && directory[0])
+        m_opaque_ap->GetDirectory().SetCString(directory);
+    else
+        m_opaque_ap->GetDirectory().Clear();
+}
+
 uint32_t
 SBFileSpec::GetPath (char *dst_path, size_t dst_len) const
 {

Modified: lldb/trunk/source/API/SBModule.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBModule.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/API/SBModule.cpp (original)
+++ lldb/trunk/source/API/SBModule.cpp Wed Nov 20 15:07:01 2013
@@ -162,6 +162,27 @@ SBModule::SetPlatformFileSpec (const lld
     return result;
 }
 
+lldb::SBFileSpec
+SBModule::GetRemoteInstallFileSpec ()
+{
+    SBFileSpec sb_file_spec;
+    ModuleSP module_sp (GetSP ());
+    if (module_sp)
+        sb_file_spec.SetFileSpec (module_sp->GetRemoteInstallFileSpec());
+    return sb_file_spec;
+}
+
+bool
+SBModule::SetRemoteInstallFileSpec (lldb::SBFileSpec &file)
+{
+    ModuleSP module_sp (GetSP ());
+    if (module_sp)
+    {
+        module_sp->SetRemoteInstallFileSpec(file.ref());
+        return true;
+    }
+    return false;
+}
 
 
 const uint8_t *

Added: lldb/trunk/source/API/SBPlatform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBPlatform.cpp?rev=195273&view=auto
==============================================================================
--- lldb/trunk/source/API/SBPlatform.cpp (added)
+++ lldb/trunk/source/API/SBPlatform.cpp Wed Nov 20 15:07:01 2013
@@ -0,0 +1,632 @@
+//===-- SBPlatform.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/API/SBPlatform.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Host/File.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Platform.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// PlatformConnectOptions
+//----------------------------------------------------------------------
+struct PlatformConnectOptions {
+    PlatformConnectOptions(const char *url = NULL) :
+        m_url(),
+        m_rsync_options(),
+        m_rsync_remote_path_prefix(),
+        m_rsync_enabled(false),
+        m_rsync_omit_hostname_from_remote_path(false),
+        m_local_cache_directory ()
+    {
+        if (url && url[0])
+            m_url = url;
+    }
+    
+    ~PlatformConnectOptions()
+    {
+    }
+
+    std::string m_url;
+    std::string m_rsync_options;
+    std::string m_rsync_remote_path_prefix;
+    bool m_rsync_enabled;
+    bool m_rsync_omit_hostname_from_remote_path;
+    ConstString m_local_cache_directory;
+};
+
+//----------------------------------------------------------------------
+// PlatformShellCommand
+//----------------------------------------------------------------------
+struct PlatformShellCommand {
+    PlatformShellCommand(const char *shell_command = NULL) :
+        m_command(),
+        m_working_dir(),
+        m_status(0),
+        m_signo(0),
+        m_timeout_sec(UINT32_MAX)
+    {
+        if (shell_command && shell_command[0])
+            m_command = shell_command;
+    }
+    
+    ~PlatformShellCommand()
+    {
+    }
+    
+    std::string m_command;
+    std::string m_working_dir;
+    std::string m_output;
+    int m_status;
+    int m_signo;
+    uint32_t m_timeout_sec;
+};
+//----------------------------------------------------------------------
+// SBPlatformConnectOptions
+//----------------------------------------------------------------------
+SBPlatformConnectOptions::SBPlatformConnectOptions (const char *url) :
+    m_opaque_ptr(new PlatformConnectOptions(url))
+{
+    
+}
+
+SBPlatformConnectOptions::SBPlatformConnectOptions(const SBPlatformConnectOptions &rhs) :
+    m_opaque_ptr(new PlatformConnectOptions())
+{
+    *m_opaque_ptr = *rhs.m_opaque_ptr;
+}
+    
+SBPlatformConnectOptions::~SBPlatformConnectOptions ()
+{
+    delete m_opaque_ptr;
+}
+
+void
+SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs)
+{
+    *m_opaque_ptr = *rhs.m_opaque_ptr;
+}
+
+const char *
+SBPlatformConnectOptions::GetURL()
+{
+    if (m_opaque_ptr->m_url.empty())
+        return NULL;
+    return m_opaque_ptr->m_url.c_str();
+}
+    
+void
+SBPlatformConnectOptions::SetURL(const char *url)
+{
+    if (url && url[0])
+        m_opaque_ptr->m_url = url;
+    else
+        m_opaque_ptr->m_url.clear();
+}
+
+bool
+SBPlatformConnectOptions::GetRsyncEnabled()
+{
+    return m_opaque_ptr->m_rsync_enabled;
+}
+    
+void
+SBPlatformConnectOptions::EnableRsync (const char *options,
+                                       const char *remote_path_prefix,
+                                       bool omit_hostname_from_remote_path)
+{
+    m_opaque_ptr->m_rsync_enabled = true;
+    m_opaque_ptr->m_rsync_omit_hostname_from_remote_path = omit_hostname_from_remote_path;
+    if (remote_path_prefix && remote_path_prefix[0])
+        m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
+    else
+        m_opaque_ptr->m_rsync_remote_path_prefix.clear();
+
+    if (options && options[0])
+        m_opaque_ptr->m_rsync_options = options;
+    else
+        m_opaque_ptr->m_rsync_options.clear();
+
+}
+
+void
+SBPlatformConnectOptions::DisableRsync ()
+{
+    m_opaque_ptr->m_rsync_enabled = false;
+}
+    
+const char *
+SBPlatformConnectOptions::GetLocalCacheDirectory()
+{
+    return m_opaque_ptr->m_local_cache_directory.GetCString();
+}
+    
+void
+SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path)
+{
+    if (path && path[0])
+        m_opaque_ptr->m_local_cache_directory.SetCString(path);
+    else
+        m_opaque_ptr->m_local_cache_directory = ConstString();
+}
+
+//----------------------------------------------------------------------
+// SBPlatformShellCommand
+//----------------------------------------------------------------------
+SBPlatformShellCommand::SBPlatformShellCommand (const char *shell_command) :
+    m_opaque_ptr(new PlatformShellCommand(shell_command))
+{
+}
+
+SBPlatformShellCommand::SBPlatformShellCommand (const SBPlatformShellCommand &rhs) :
+    m_opaque_ptr(new PlatformShellCommand())
+{
+    *m_opaque_ptr = *rhs.m_opaque_ptr;
+}
+
+SBPlatformShellCommand::~SBPlatformShellCommand()
+{
+    delete m_opaque_ptr;
+}
+
+void
+SBPlatformShellCommand::Clear()
+{
+    m_opaque_ptr->m_output = std::move(std::string());
+    m_opaque_ptr->m_status = 0;
+    m_opaque_ptr->m_signo = 0;
+}
+
+const char *
+SBPlatformShellCommand::GetCommand()
+{
+    if (m_opaque_ptr->m_command.empty())
+        return NULL;
+    return m_opaque_ptr->m_command.c_str();
+}
+
+void
+SBPlatformShellCommand::SetCommand(const char *shell_command)
+{
+    if (shell_command && shell_command[0])
+        m_opaque_ptr->m_command = shell_command;
+    else
+        m_opaque_ptr->m_command.clear();
+}
+
+const char *
+SBPlatformShellCommand::GetWorkingDirectory ()
+{
+    if (m_opaque_ptr->m_working_dir.empty())
+        return NULL;
+    return m_opaque_ptr->m_working_dir.c_str();
+}
+
+void
+SBPlatformShellCommand::SetWorkingDirectory (const char *path)
+{
+    if (path && path[0])
+        m_opaque_ptr->m_working_dir = path;
+    else
+        m_opaque_ptr->m_working_dir.clear();
+}
+
+uint32_t
+SBPlatformShellCommand::GetTimeoutSeconds ()
+{
+    return m_opaque_ptr->m_timeout_sec;
+}
+
+void
+SBPlatformShellCommand::SetTimeoutSeconds (uint32_t sec)
+{
+    m_opaque_ptr->m_timeout_sec = sec;
+}
+
+int
+SBPlatformShellCommand::GetSignal ()
+{
+    return m_opaque_ptr->m_signo;
+}
+
+int
+SBPlatformShellCommand::GetStatus ()
+{
+    return m_opaque_ptr->m_status;
+}
+
+const char *
+SBPlatformShellCommand::GetOutput ()
+{
+    if (m_opaque_ptr->m_output.empty())
+        return NULL;
+    return m_opaque_ptr->m_output.c_str();
+}
+
+//----------------------------------------------------------------------
+// SBPlatform
+//----------------------------------------------------------------------
+SBPlatform::SBPlatform () :
+    m_opaque_sp ()
+{
+    
+}
+
+SBPlatform::SBPlatform (const char *platform_name) :
+    m_opaque_sp ()
+{
+    Error error;
+    m_opaque_sp = Platform::Create (platform_name, error);
+}
+
+SBPlatform::~SBPlatform()
+{
+}
+
+bool
+SBPlatform::IsValid () const
+{
+    return m_opaque_sp.get() != NULL;
+}
+
+void
+SBPlatform::Clear ()
+{
+    m_opaque_sp.reset();
+}
+
+const char *
+SBPlatform::GetName ()
+{
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+        return platform_sp->GetName().GetCString();
+    return NULL;
+}
+
+lldb::PlatformSP
+SBPlatform::GetSP () const
+{
+    return m_opaque_sp;
+}
+
+void
+SBPlatform::SetSP (const lldb::PlatformSP& platform_sp)
+{
+    m_opaque_sp = platform_sp;
+}
+
+const char *
+SBPlatform::GetWorkingDirectory()
+{
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+        return platform_sp->GetWorkingDirectory().GetCString();
+    return NULL;
+}
+
+bool
+SBPlatform::SetWorkingDirectory(const char *path)
+{
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        if (path)
+            platform_sp->SetWorkingDirectory(ConstString(path));
+        else
+            platform_sp->SetWorkingDirectory(ConstString());
+        return true;
+    }
+    return false;
+}
+
+SBError
+SBPlatform::ConnectRemote (SBPlatformConnectOptions &connect_options)
+{
+    SBError sb_error;
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp && connect_options.GetURL())
+    {
+        Args args;
+        args.AppendArgument(connect_options.GetURL());
+        sb_error.ref() = platform_sp->ConnectRemote(args);
+    }
+    else
+    {
+        sb_error.SetErrorString("invalid platform");
+    }
+    return sb_error;
+}
+
+void
+SBPlatform::DisconnectRemote ()
+{
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+        platform_sp->DisconnectRemote();
+}
+
+bool
+SBPlatform::IsConnected()
+{
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+        platform_sp->IsConnected();
+    return false;
+}
+
+const char *
+SBPlatform::GetTriple()
+{
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        ArchSpec arch(platform_sp->GetRemoteSystemArchitecture());
+        if (arch.IsValid())
+        {
+            // Const-ify the string so we don't need to worry about the lifetime of the string
+            return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
+        }
+    }
+    return NULL;
+}
+
+const char *
+SBPlatform::GetOSBuild()
+{
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        std::string s;
+        if (platform_sp->GetOSBuildString(s))
+        {
+            if (!s.empty())
+            {
+                // Const-ify the string so we don't need to worry about the lifetime of the string
+                return ConstString(s.c_str()).GetCString();
+            }
+        }
+    }
+    return NULL;
+}
+
+const char *
+SBPlatform::GetOSDescription()
+{
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        std::string s;
+        if (platform_sp->GetOSKernelDescription(s))
+        {
+            if (!s.empty())
+            {
+                // Const-ify the string so we don't need to worry about the lifetime of the string
+                return ConstString(s.c_str()).GetCString();
+            }
+        }
+    }
+    return NULL;
+}
+
+const char *
+SBPlatform::GetHostname ()
+{
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+        return platform_sp->GetHostname();
+    return NULL;
+}
+
+uint32_t
+SBPlatform::GetOSMajorVersion ()
+{
+    uint32_t major, minor, update;
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
+        return major;
+    return UINT32_MAX;
+    
+}
+
+uint32_t
+SBPlatform::GetOSMinorVersion ()
+{
+    uint32_t major, minor, update;
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
+        return minor;
+    return UINT32_MAX;
+}
+
+uint32_t
+SBPlatform::GetOSUpdateVersion ()
+{
+    uint32_t major, minor, update;
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
+        return update;
+    return UINT32_MAX;
+}
+
+SBError
+SBPlatform::Get (SBFileSpec &src,
+                 SBFileSpec &dst)
+{
+    SBError sb_error;
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
+    }
+    else
+    {
+        sb_error.SetErrorString("invalid platform");
+    }
+    return sb_error;
+}
+
+SBError
+SBPlatform::Put (SBFileSpec &src,
+                 SBFileSpec &dst)
+{
+    SBError sb_error;
+    
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        if (src.Exists())
+        {
+            uint32_t permissions = src.ref().GetPermissions();
+            if (permissions == 0)
+            {
+                if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory)
+                    permissions = eFilePermissionsDirectoryDefault;
+                else
+                    permissions = eFilePermissionsFileDefault;
+            }
+
+            sb_error.ref() = platform_sp->PutFile(src.ref(),
+                                                  dst.ref(),
+                                                  permissions);
+        }
+        else
+        {
+            sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
+        }
+    }
+    else
+    {
+        sb_error.SetErrorString("invalid platform");
+    }
+    return sb_error;
+}
+
+SBError
+SBPlatform::Install (SBFileSpec &src,
+                     SBFileSpec &dst)
+{
+    SBError sb_error;
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        if (src.Exists())
+        {
+            sb_error.ref() = platform_sp->Install(src.ref(), dst.ref());
+        }
+        else
+        {
+            sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
+        }
+    }
+    else
+    {
+        sb_error.SetErrorString("invalid platform");
+    }
+    return sb_error;
+}
+
+
+SBError
+SBPlatform::Run (SBPlatformShellCommand &shell_command)
+{
+    SBError sb_error;
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        if (platform_sp->IsConnected())
+        {
+            const char *command = shell_command.GetCommand();
+            if (command)
+            {
+                const char *working_dir = shell_command.GetWorkingDirectory();
+                if (working_dir == NULL)
+                {
+                    working_dir = platform_sp->GetWorkingDirectory().GetCString();
+                    if (working_dir)
+                        shell_command.SetWorkingDirectory(working_dir);
+                }
+                sb_error.ref() = platform_sp->RunShellCommand(command,
+                                                              working_dir,
+                                                              &shell_command.m_opaque_ptr->m_status,
+                                                              &shell_command.m_opaque_ptr->m_signo,
+                                                              &shell_command.m_opaque_ptr->m_output,
+                                                              shell_command.m_opaque_ptr->m_timeout_sec);
+            }
+            else
+            {
+                sb_error.SetErrorString("invalid shell command (empty)");
+            }
+        }
+        else
+        {
+            sb_error.SetErrorString("not connected");
+        }
+    }
+    else
+    {
+        sb_error.SetErrorString("invalid platform");
+    }
+    return sb_error;
+}
+
+SBError
+SBPlatform::MakeDirectory (const char *path, uint32_t file_permissions)
+{
+    SBError sb_error;
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        sb_error.ref() = platform_sp->MakeDirectory(path, file_permissions);
+    }
+    else
+    {
+        sb_error.SetErrorString("invalid platform");
+    }
+    return sb_error;
+}
+
+uint32_t
+SBPlatform::GetFilePermissions (const char *path)
+{
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        uint32_t file_permissions = 0;
+        platform_sp->GetFilePermissions(path, file_permissions);
+        return file_permissions;
+    }
+    return 0;
+    
+}
+
+SBError
+SBPlatform::SetFilePermissions (const char *path, uint32_t file_permissions)
+{
+    SBError sb_error;
+    PlatformSP platform_sp(GetSP());
+    if (platform_sp)
+    {
+        sb_error.ref() = platform_sp->SetFilePermissions(path, file_permissions);
+    }
+    else
+    {
+        sb_error.SetErrorString("invalid platform");
+    }
+    return sb_error;
+    
+}
+

Modified: lldb/trunk/source/API/SBStream.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBStream.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/API/SBStream.cpp (original)
+++ lldb/trunk/source/API/SBStream.cpp Wed Nov 20 15:07:01 2013
@@ -82,7 +82,7 @@ SBStream::RedirectToFile (const char *pa
     uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
     if (append)
         open_options |= File::eOpenOptionAppend;
-    stream_file->GetFile().Open (path, open_options, File::ePermissionsDefault);
+    stream_file->GetFile().Open (path, open_options, lldb::eFilePermissionsFileDefault);
 
     m_opaque_ap.reset (stream_file);
 

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Wed Nov 20 15:07:01 2013
@@ -605,6 +605,19 @@ SBTarget::LaunchSimple
                    error);
 }
 
+SBError
+SBTarget::Install()
+{
+    SBError sb_error;
+    TargetSP target_sp(GetSP());
+    if (target_sp)
+    {
+        Mutex::Locker api_locker (target_sp->GetAPIMutex());
+        sb_error.ref() = target_sp->Install(NULL);
+    }
+    return sb_error;
+}
+
 SBProcess
 SBTarget::Launch 
 (

Modified: lldb/trunk/source/Commands/CommandObjectPlatform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectPlatform.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectPlatform.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectPlatform.cpp Wed Nov 20 15:07:01 2013
@@ -22,6 +22,7 @@
 #include "lldb/Interpreter/Args.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionGroupFile.h"
 #include "lldb/Interpreter/OptionGroupPlatform.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Platform.h"
@@ -119,31 +120,31 @@ public:
                     m_permissions = perms;
             }
             case 'r':
-                m_permissions |= File::ePermissionsUserRead;
+                m_permissions |= lldb::eFilePermissionsUserRead;
                 break;
             case 'w':
-                m_permissions |= File::ePermissionsUserWrite;
+                m_permissions |= lldb::eFilePermissionsUserWrite;
                 break;
             case 'x':
-                m_permissions |= File::ePermissionsUserExecute;
+                m_permissions |= lldb::eFilePermissionsUserExecute;
                 break;
             case 'R':
-                m_permissions |= File::ePermissionsGroupRead;
+                m_permissions |= lldb::eFilePermissionsGroupRead;
                 break;
             case 'W':
-                m_permissions |= File::ePermissionsGroupWrite;
+                m_permissions |= lldb::eFilePermissionsGroupWrite;
                 break;
             case 'X':
-                m_permissions |= File::ePermissionsGroupExecute;
+                m_permissions |= lldb::eFilePermissionsGroupExecute;
                 break;
             case 'd':
-                m_permissions |= File::ePermissionsWorldRead;
+                m_permissions |= lldb::eFilePermissionsWorldRead;
                 break;
             case 't':
-                m_permissions |= File::ePermissionsWorldWrite;
+                m_permissions |= lldb::eFilePermissionsWorldWrite;
                 break;
             case 'e':
-                m_permissions |= File::ePermissionsWorldExecute;
+                m_permissions |= lldb::eFilePermissionsWorldExecute;
                 break;
 
             default:
@@ -524,6 +525,65 @@ protected:
 };
 
 //----------------------------------------------------------------------
+// "platform settings"
+//----------------------------------------------------------------------
+class CommandObjectPlatformSettings : public CommandObjectParsed
+{
+public:
+    CommandObjectPlatformSettings (CommandInterpreter &interpreter) :
+        CommandObjectParsed (interpreter,
+                             "platform settings",
+                             "Set settings for the current target's platform, or for a platform by name.",
+                             "platform settings",
+                             0),
+        m_options (interpreter),
+        m_option_working_dir (LLDB_OPT_SET_1, false, "working-dir", 'w', 0, eArgTypePath, "The working directory for the platform.")
+    {
+        m_options.Append (&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+    }
+    
+    virtual
+    ~CommandObjectPlatformSettings ()
+    {
+    }
+    
+protected:
+    virtual bool
+    DoExecute (Args& args, CommandReturnObject &result)
+    {
+        PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+        if (platform_sp)
+        {
+            if (m_option_working_dir.GetOptionValue().OptionWasSet())
+                platform_sp->SetWorkingDirectory (ConstString(m_option_working_dir.GetOptionValue().GetCurrentValue().GetPath().c_str()));
+        }
+        else
+        {
+            result.AppendError ("no platform is currently selected");
+            result.SetStatus (eReturnStatusFailed);
+        }
+        return result.Succeeded();
+    }
+    
+    virtual Options *
+    GetOptions ()
+    {
+        if (m_options.DidFinalize() == false)
+        {
+            m_options.Append(new OptionPermissions());
+            m_options.Finalize();
+        }
+        return &m_options;
+    }
+protected:
+    
+    OptionGroupOptions m_options;
+    OptionGroupFile m_option_working_dir;
+
+};
+
+
+//----------------------------------------------------------------------
 // "platform mkdir"
 //----------------------------------------------------------------------
 class CommandObjectPlatformMkDir : public CommandObjectParsed
@@ -552,15 +612,22 @@ public:
         {
             std::string cmd_line;
             args.GetCommandString(cmd_line);
-            mode_t perms;
+            uint32_t mode;
             const OptionPermissions* options_permissions = (OptionPermissions*)m_options.GetGroupWithOption('r');
             if (options_permissions)
-                perms = options_permissions->m_permissions;
+                mode = options_permissions->m_permissions;
             else
-                perms = 0000700 | 0000070 | 0000007;
-            uint32_t retcode = platform_sp->MakeDirectory(cmd_line,perms);
-            result.AppendMessageWithFormat("Status = %d\n",retcode);
-            result.SetStatus (eReturnStatusSuccessFinishResult);
+                mode = lldb::eFilePermissionsUserRWX | lldb::eFilePermissionsGroupRWX | lldb::eFilePermissionsWorldRX;
+            Error error = platform_sp->MakeDirectory(cmd_line.c_str(), mode);
+            if (error.Success())
+            {
+                result.SetStatus (eReturnStatusSuccessFinishResult);
+            }
+            else
+            {
+                result.AppendError(error.AsCString());
+                result.SetStatus (eReturnStatusFailed);
+            }
         }
         else
         {
@@ -619,7 +686,7 @@ public:
             if (options_permissions)
                 perms = options_permissions->m_permissions;
             else
-                perms = 0000700 | 0000070 | 0000007;
+                perms = lldb::eFilePermissionsUserRW | lldb::eFilePermissionsGroupRW | lldb::eFilePermissionsWorldRead;
             lldb::user_id_t fd = platform_sp->OpenFile(FileSpec(cmd_line.c_str(),false),
                                                        File::eOpenOptionRead | File::eOpenOptionWrite |
                                                        File::eOpenOptionAppend | File::eOpenOptionCanCreate,
@@ -2129,82 +2196,6 @@ CommandObjectPlatformShell::CommandOptio
     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
 };
 
-struct RecurseCopyBaton
-{
-    const std::string& destination;
-    const PlatformSP& platform_sp;
-    Error error;
-};
-
-
-static FileSpec::EnumerateDirectoryResult
-RecurseCopy_Callback (void *baton,
-                      FileSpec::FileType file_type,
-                      const FileSpec &spec)
-{
-    RecurseCopyBaton* rc_baton = (RecurseCopyBaton*)baton;
-    switch (file_type)
-    {
-        case FileSpec::eFileTypePipe:
-        case FileSpec::eFileTypeSocket:
-            // we have no way to copy pipes and sockets - ignore them and continue
-            return FileSpec::eEnumerateDirectoryResultNext;
-            break;
-            
-        case FileSpec::eFileTypeSymbolicLink:
-            // what to do for symlinks?
-            return FileSpec::eEnumerateDirectoryResultNext;
-            break;
-            
-        case FileSpec::eFileTypeDirectory:
-        {
-            // make the new directory and get in there
-            FileSpec new_directory(rc_baton->destination.c_str(),false);
-            new_directory.AppendPathComponent(spec.GetLastPathComponent());
-            uint32_t errcode = rc_baton->platform_sp->MakeDirectory(new_directory, 0777);
-            std::string new_directory_path (new_directory.GetPath());
-            if (errcode != 0)
-            {
-                rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end",new_directory_path.c_str());
-                return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
-            }
-            
-            // now recurse
-            std::string local_path (spec.GetPath());
-            RecurseCopyBaton rc_baton2 = { new_directory_path, rc_baton->platform_sp, Error() };
-            FileSpec::EnumerateDirectory(local_path.c_str(), true, true, true, RecurseCopy_Callback, &rc_baton2);
-            if (rc_baton2.error.Fail())
-            {
-                rc_baton->error.SetErrorString(rc_baton2.error.AsCString());
-                return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
-            }
-            return FileSpec::eEnumerateDirectoryResultNext;
-        }
-            break;
-            
-        case FileSpec::eFileTypeRegular:
-        {
-            // copy the file and keep going
-            std::string dest(rc_baton->destination);
-            dest.append(spec.GetFilename().GetCString());
-            Error err = rc_baton->platform_sp->PutFile(spec, FileSpec(dest.c_str(), false));
-            if (err.Fail())
-            {
-                rc_baton->error.SetErrorString(err.AsCString());
-                return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
-            }
-            return FileSpec::eEnumerateDirectoryResultNext;
-        }
-            break;
-            
-        case FileSpec::eFileTypeInvalid:
-        case FileSpec::eFileTypeOther:
-        case FileSpec::eFileTypeUnknown:
-            rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s/%s", spec.GetDirectory().GetCString(), spec.GetFilename().GetCString());
-            return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
-            break;
-    }
-}
 
 //----------------------------------------------------------------------
 // "platform install" - install a target to a remote end
@@ -2236,10 +2227,9 @@ public:
             return false;
         }
         // TODO: move the bulk of this code over to the platform itself
-        std::string local_thing(args.GetArgumentAtIndex(0));
-        std::string remote_sandbox(args.GetArgumentAtIndex(1));
-        FileSpec source(local_thing.c_str(), true);
-        if (source.Exists() == false)
+        FileSpec src(args.GetArgumentAtIndex(0), true);
+        FileSpec dst(args.GetArgumentAtIndex(1), false);
+        if (src.Exists() == false)
         {
             result.AppendError("source location does not exist or is not accessible");
             result.SetStatus(eReturnStatusFailed);
@@ -2252,75 +2242,21 @@ public:
             result.SetStatus (eReturnStatusFailed);
             return false;
         }
-        FileSpec::FileType source_type(source.GetFileType());
-        if (source_type == FileSpec::eFileTypeDirectory)
-        {
-            if (platform_sp->GetSupportsRSync())
-            {
-                FileSpec remote_folder(remote_sandbox.c_str(), false);
-                Error rsync_err = platform_sp->PutFile(source, remote_folder);
-                if (rsync_err.Success())
-                {
-                    result.SetStatus(eReturnStatusSuccessFinishResult);
-                    return result.Succeeded();
-                }
-            }
-            FileSpec remote_folder(remote_sandbox.c_str(), false);
-            remote_folder.AppendPathComponent(source.GetLastPathComponent());
-            // TODO: default permissions are bad
-            uint32_t errcode = platform_sp->MakeDirectory(remote_folder, 0777);
-            if (errcode != 0)
-            {
-                result.AppendError("unable to setup target directory on remote end");
-                result.SetStatus(eReturnStatusSuccessFinishNoResult);
-                return result.Succeeded();
-            }
-            // now recurse
-            std::string remote_folder_path (remote_folder.GetPath());
-            Error err = RecurseCopy(source,remote_folder_path,platform_sp);
-            if (err.Fail())
-            {
-                result.AppendError(err.AsCString());
-                result.SetStatus(eReturnStatusFailed);
-            }
-            else
-                result.SetStatus(eReturnStatusSuccessFinishResult);
-            return result.Succeeded();
-        }
-        else if (source_type == FileSpec::eFileTypeRegular)
+        
+        Error error = platform_sp->Install(src, dst);
+        if (error.Success())
         {
-            // just a plain file - push it to remote and be done
-            remote_sandbox.append(source.GetFilename().GetCString());
-            FileSpec destination(remote_sandbox.c_str(),false);
-            Error err = platform_sp->PutFile(source, destination);
-            if (err.Success())
-                result.SetStatus(eReturnStatusSuccessFinishResult);
-            else
-            {
-                result.AppendError(err.AsCString());
-                result.SetStatus(eReturnStatusFailed);
-            }
-            return result.Succeeded();
+            result.SetStatus(eReturnStatusSuccessFinishNoResult);
         }
         else
         {
-            result.AppendError("source is not a known type of file");
+            result.AppendErrorWithFormat("install failed: %s", error.AsCString());
             result.SetStatus(eReturnStatusFailed);
-            return result.Succeeded();
         }
+        return result.Succeeded();
     }
 private:
-    
-    Error
-    RecurseCopy (const FileSpec& source,
-                 const std::string& destination,
-                 const PlatformSP& platform_sp)
-    {
-        std::string source_path (source.GetPath());
-        RecurseCopyBaton baton = { destination, platform_sp, Error() };
-        FileSpec::EnumerateDirectory(source_path.c_str(), true, true, true, RecurseCopy_Callback, &baton);
-        return baton.error;
-    }
+
 };
 
 //----------------------------------------------------------------------
@@ -2332,21 +2268,22 @@ CommandObjectPlatform::CommandObjectPlat
                             "A set of commands to manage and create platforms.",
                             "platform [connect|disconnect|info|list|status|select] ...")
 {
-    LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect  (interpreter)));
-    LoadSubCommand ("list"  , CommandObjectSP (new CommandObjectPlatformList    (interpreter)));
-    LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus  (interpreter)));
-    LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect  (interpreter)));
-    LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect  (interpreter)));
+    LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
+    LoadSubCommand ("list"  , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
+    LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
+    LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
+    LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
+    LoadSubCommand ("settings", CommandObjectSP (new CommandObjectPlatformSettings (interpreter)));
 #ifdef LLDB_CONFIGURATION_DEBUG
-    LoadSubCommand ("mkdir", CommandObjectSP (new CommandObjectPlatformMkDir  (interpreter)));
-    LoadSubCommand ("file", CommandObjectSP (new CommandObjectPlatformFile  (interpreter)));
-    LoadSubCommand ("get-file", CommandObjectSP (new CommandObjectPlatformGetFile  (interpreter)));
-    LoadSubCommand ("get-size", CommandObjectSP (new CommandObjectPlatformGetSize  (interpreter)));
-    LoadSubCommand ("put-file", CommandObjectSP (new CommandObjectPlatformPutFile  (interpreter)));
+    LoadSubCommand ("mkdir", CommandObjectSP (new CommandObjectPlatformMkDir (interpreter)));
+    LoadSubCommand ("file", CommandObjectSP (new CommandObjectPlatformFile (interpreter)));
+    LoadSubCommand ("get-file", CommandObjectSP (new CommandObjectPlatformGetFile (interpreter)));
+    LoadSubCommand ("get-size", CommandObjectSP (new CommandObjectPlatformGetSize (interpreter)));
+    LoadSubCommand ("put-file", CommandObjectSP (new CommandObjectPlatformPutFile (interpreter)));
 #endif
-    LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess  (interpreter)));
-    LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell  (interpreter)));
-    LoadSubCommand ("target-install", CommandObjectSP (new CommandObjectPlatformInstall  (interpreter)));
+    LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
+    LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter)));
+    LoadSubCommand ("target-install", CommandObjectSP (new CommandObjectPlatformInstall (interpreter)));
 }
 
 

Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Wed Nov 20 15:07:01 2013
@@ -53,6 +53,8 @@
 #include "lldb/Core/Log.h"
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/Timer.h"
+#include "lldb/Host/Host.h"
+
 
 using namespace lldb;
 using namespace lldb_private;
@@ -1209,6 +1211,7 @@ ConnectionFileDescriptor::NamedSocketAcc
     saddr_un.sun_len = SUN_LEN (&saddr_un);
 #endif
 
+    Host::Unlink (socket_name);
     if (::bind (listen_socket, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0) 
     {
         if (::listen (listen_socket, 5) == 0) 

Modified: lldb/trunk/source/Core/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Module.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Core/Module.cpp (original)
+++ lldb/trunk/source/Core/Module.cpp Wed Nov 20 15:07:01 2013
@@ -135,6 +135,7 @@ Module::Module (const ModuleSpec &module
     m_uuid (),
     m_file (module_spec.GetFileSpec()),
     m_platform_file(module_spec.GetPlatformFileSpec()),
+    m_remote_install_file(),
     m_symfile_spec (module_spec.GetSymbolFileSpec()),
     m_object_name (module_spec.GetObjectName()),
     m_object_offset (module_spec.GetObjectOffset()),
@@ -179,6 +180,7 @@ Module::Module(const FileSpec& file_spec
     m_uuid (),
     m_file (file_spec),
     m_platform_file(),
+    m_remote_install_file (),
     m_symfile_spec (),
     m_object_name (),
     m_object_offset (object_offset),

Modified: lldb/trunk/source/Core/StreamFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/StreamFile.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Core/StreamFile.cpp (original)
+++ lldb/trunk/source/Core/StreamFile.cpp Wed Nov 20 15:07:01 2013
@@ -49,7 +49,7 @@ StreamFile::StreamFile (FILE *fh, bool t
 
 StreamFile::StreamFile (const char *path) :
     Stream (),
-    m_file (path, File::eOpenOptionWrite | File::eOpenOptionCanCreate, File::ePermissionsDefault)
+    m_file (path, File::eOpenOptionWrite | File::eOpenOptionCanCreate, lldb::eFilePermissionsFileDefault)
 {
 }
 

Modified: lldb/trunk/source/Host/common/File.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/File.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/File.cpp (original)
+++ lldb/trunk/source/Host/common/File.cpp Wed Nov 20 15:07:01 2013
@@ -1,4 +1,4 @@
-//===-- FileSpec.cpp --------------------------------------------*- C++ -*-===//
+//===-- File.cpp ------------------------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,7 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-
 #include "lldb/Host/File.h"
 
 #include <errno.h>
@@ -237,6 +236,9 @@ File::Open (const char *path, uint32_t o
     else if (read)
     {
         oflag |= O_RDONLY;
+
+        if (options & eOpenoptionDontFollowSymlinks)
+            oflag |= O_NOFOLLOW;
     }
     
 #ifndef _WIN32
@@ -249,15 +251,15 @@ File::Open (const char *path, uint32_t o
     mode_t mode = 0;
     if (oflag & O_CREAT)
     {
-        if (permissions & ePermissionsUserRead)     mode |= S_IRUSR;
-        if (permissions & ePermissionsUserWrite)    mode |= S_IWUSR;
-        if (permissions & ePermissionsUserExecute)  mode |= S_IXUSR;
-        if (permissions & ePermissionsGroupRead)    mode |= S_IRGRP;
-        if (permissions & ePermissionsGroupWrite)   mode |= S_IWGRP;
-        if (permissions & ePermissionsGroupExecute) mode |= S_IXGRP;
-        if (permissions & ePermissionsWorldRead)    mode |= S_IROTH;
-        if (permissions & ePermissionsWorldWrite)   mode |= S_IWOTH;
-        if (permissions & ePermissionsWorldExecute) mode |= S_IXOTH;
+        if (permissions & lldb::eFilePermissionsUserRead)     mode |= S_IRUSR;
+        if (permissions & lldb::eFilePermissionsUserWrite)    mode |= S_IWUSR;
+        if (permissions & lldb::eFilePermissionsUserExecute)  mode |= S_IXUSR;
+        if (permissions & lldb::eFilePermissionsGroupRead)    mode |= S_IRGRP;
+        if (permissions & lldb::eFilePermissionsGroupWrite)   mode |= S_IWGRP;
+        if (permissions & lldb::eFilePermissionsGroupExecute) mode |= S_IXGRP;
+        if (permissions & lldb::eFilePermissionsWorldRead)    mode |= S_IROTH;
+        if (permissions & lldb::eFilePermissionsWorldWrite)   mode |= S_IWOTH;
+        if (permissions & lldb::eFilePermissionsWorldExecute) mode |= S_IXOTH;
     }
 
     do

Modified: lldb/trunk/source/Host/common/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/FileSpec.cpp (original)
+++ lldb/trunk/source/Host/common/FileSpec.cpp Wed Nov 20 15:07:01 2013
@@ -34,6 +34,7 @@
 #include "lldb/Core/StreamString.h"
 #include "lldb/Host/File.h"
 #include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataBufferMemoryMap.h"
 #include "lldb/Core/RegularExpression.h"
@@ -646,6 +647,15 @@ FileSpec::GetFileType () const
     return eFileTypeInvalid;
 }
 
+uint32_t
+FileSpec::GetPermissions () const
+{
+    uint32_t file_permissions = 0;
+    if (*this)
+        Host::GetFilePermissions(GetPath().c_str(), file_permissions);
+    return file_permissions;
+}
+
 TimeValue
 FileSpec::GetModificationTime () const
 {
@@ -1161,26 +1171,26 @@ FileSpec::CopyByRemovingLastPathComponen
         return FileSpec(m_directory.GetCString(),resolve);
 }
 
-const char*
+ConstString
 FileSpec::GetLastPathComponent () const
 {
-    if (m_filename.IsEmpty() && m_directory.IsEmpty())
-        return NULL;
-    if (m_filename.IsEmpty())
+    if (m_filename)
+        return m_filename;
+    if (m_directory)
     {
         const char* dir_cstr = m_directory.GetCString();
         const char* last_slash_ptr = ::strrchr(dir_cstr, '/');
         if (last_slash_ptr == NULL)
-            return m_directory.GetCString();
+            return m_directory;
         if (last_slash_ptr == dir_cstr)
         {
             if (last_slash_ptr[1] == 0)
-                return last_slash_ptr;
+                return ConstString(last_slash_ptr);
             else
-                return last_slash_ptr+1;
+                return ConstString(last_slash_ptr+1);
         }
         if (last_slash_ptr[1] != 0)
-            return last_slash_ptr+1;
+            return ConstString(last_slash_ptr+1);
         const char* penultimate_slash_ptr = last_slash_ptr;
         while (*penultimate_slash_ptr)
         {
@@ -1190,10 +1200,10 @@ FileSpec::GetLastPathComponent () const
             if (*penultimate_slash_ptr == '/')
                 break;
         }
-        ConstString new_path(penultimate_slash_ptr+1,last_slash_ptr-penultimate_slash_ptr);
-        return new_path.AsCString();
+        ConstString result(penultimate_slash_ptr+1,last_slash_ptr-penultimate_slash_ptr);
+        return result;
     }
-    return m_filename.GetCString();
+    return ConstString();
 }
 
 void

Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Wed Nov 20 15:07:01 2013
@@ -1826,11 +1826,130 @@ Host::LaunchApplication (const FileSpec
     return LLDB_INVALID_PROCESS_ID;
 }
 
-uint32_t
-Host::MakeDirectory (const char* path, mode_t mode)
+#endif
+
+
+#ifdef LLDB_DISABLE_POSIX
+
+Error
+Host::MakeDirectory (const char* path, uint32_t mode)
+{
+    Error error;
+    error.SetErrorString("%s in not implemented on this host", __PRETTY_FUNCTION__);
+    return error;
+}
+
+Error
+Host::GetFilePermissions (const char* path, uint32_t &file_permissions)
+{
+    Error error;
+    error.SetErrorString("%s is not supported on this host", __PRETTY_FUNCTION__);
+    return error;
+}
+
+Error
+Host::SetFilePermissions (const char* path, uint32_t file_permissions)
+{
+    Error error;
+    error.SetErrorString("%s is not supported on this host", __PRETTY_FUNCTION__);
+    return error;
+}
+
+Error
+Host::Symlink (const char *src, const char *dst)
+{
+    Error error;
+    error.SetErrorString("%s is not supported on this host", __PRETTY_FUNCTION__);
+    return error;
+}
+
+Error
+Host::Readlink (const char *path, char *buf, size_t buf_len)
+{
+    Error error;
+    error.SetErrorString("%s is not supported on this host", __PRETTY_FUNCTION__);
+    return error;
+}
+
+Error
+Host::Unlink (const char *path)
+{
+    Error error;
+    error.SetErrorString("%s is not supported on this host", __PRETTY_FUNCTION__);
+    return error;
+}
+
+#else
+
+Error
+Host::MakeDirectory (const char* path, uint32_t file_permissions)
+{
+    Error error;
+    if (::mkdir(path, file_permissions) != 0)
+        error.SetErrorToErrno();
+    return error;
+}
+
+Error
+Host::GetFilePermissions (const char* path, uint32_t &file_permissions)
+{
+    Error error;
+    struct stat file_stats;
+    if (::stat (path, &file_stats) == 0)
+    {
+        // The bits in "st_mode" currently match the definitions
+        // for the file mode bits in unix.
+        file_permissions = file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+    }
+    else
+    {
+        error.SetErrorToErrno();
+    }
+    return error;
+}
+
+Error
+Host::SetFilePermissions (const char* path, uint32_t file_permissions)
+{
+    Error error;
+    if (::chmod(path, file_permissions) != 0)
+        error.SetErrorToErrno();
+    return error;
+}
+
+Error
+Host::Symlink (const char *src, const char *dst)
+{
+    Error error;
+    if (::symlink(dst, src) == -1)
+        error.SetErrorToErrno();
+    return error;
+}
+
+Error
+Host::Unlink (const char *path)
 {
-    return UINT32_MAX;
+    Error error;
+    if (::unlink(path) == -1)
+        error.SetErrorToErrno();
+    return error;
 }
+
+Error
+Host::Readlink (const char *path, char *buf, size_t buf_len)
+{
+    Error error;
+    ssize_t count = ::readlink(path, buf, buf_len);
+    if (count < 0)
+        error.SetErrorToErrno();
+    else if (count < (buf_len-1))
+        buf[count] = '\0'; // Success
+    else
+        error.SetErrorString("'buf' buffer is too small to contain link contents");
+    return error;
+}
+
+
 #endif
 
 typedef std::map<lldb::user_id_t, lldb::FileSP> FDToFileMap;
@@ -1843,7 +1962,7 @@ FDToFileMap& GetFDToFileMap()
 lldb::user_id_t
 Host::OpenFile (const FileSpec& file_spec,
                 uint32_t flags,
-                mode_t mode,
+                uint32_t mode,
                 Error &error)
 {
     std::string path (file_spec.GetPath());

Modified: lldb/trunk/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Host.mm (original)
+++ lldb/trunk/source/Host/macosx/Host.mm Wed Nov 20 15:07:01 2013
@@ -363,7 +363,7 @@ WaitForProcessToSIGSTOP (const lldb::pid
 //    StreamFile command_file;
 //    command_file.GetFile().Open (temp_file_path, 
 //                                 File::eOpenOptionWrite | File::eOpenOptionCanCreate,
-//                                 File::ePermissionsDefault);
+//                                 lldb::eFilePermissionsDefault);
 //    
 //    if (!command_file.GetFile().IsValid())
 //        return LLDB_INVALID_PROCESS_ID;
@@ -1984,10 +1984,3 @@ Host::GetAuxvData(lldb_private::Process
 {
     return lldb::DataBufferSP();
 }
-
-uint32_t
-Host::MakeDirectory (const char* path, mode_t mode)
-{
-    return ::mkdir(path,mode);
-}
-

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Wed Nov 20 15:07:01 2013
@@ -761,6 +761,31 @@ PlatformDarwin::LaunchProcess (ProcessLa
 }
 
 lldb::ProcessSP
+PlatformDarwin::DebugProcess (ProcessLaunchInfo &launch_info,
+                              Debugger &debugger,
+                              Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+                              Listener &listener,
+                              Error &error)
+{
+    ProcessSP process_sp;
+    
+    if (IsHost())
+    {
+        process_sp = Platform::DebugProcess (launch_info, debugger, target, listener, error);
+    }
+    else
+    {
+        if (m_remote_platform_sp)
+            process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, listener, error);
+        else
+            error.SetErrorString ("the platform is not currently connected");
+    }
+    return process_sp;
+    
+}
+
+
+lldb::ProcessSP
 PlatformDarwin::Attach (ProcessAttachInfo &attach_info,
                         Debugger &debugger,
                         Target *target,

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h Wed Nov 20 15:07:01 2013
@@ -99,6 +99,13 @@ public:
     LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
 
     virtual lldb::ProcessSP
+    DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
+                  lldb_private::Debugger &debugger,
+                  lldb_private::Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+                  lldb_private::Listener &listener,
+                  lldb_private::Error &error);
+
+    virtual lldb::ProcessSP
     Attach (lldb_private::ProcessAttachInfo &attach_info,
             lldb_private::Debugger &debugger,
             lldb_private::Target *target,       // Can be NULL, if NULL create a new target, else use existing one

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp Wed Nov 20 15:07:01 2013
@@ -76,44 +76,56 @@ PlatformPOSIX::RunShellCommand (const ch
     }
 }
 
-uint32_t
-PlatformPOSIX::MakeDirectory (const std::string &path,
-                               mode_t mode)
+Error
+PlatformPOSIX::MakeDirectory (const char *path, uint32_t file_permissions)
 {
-    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);
+    if (m_remote_platform_sp)
+        return m_remote_platform_sp->MakeDirectory(path, file_permissions);
+    else
+        return Platform::MakeDirectory(path ,file_permissions);
+}
+
+Error
+PlatformPOSIX::GetFilePermissions (const char *path, uint32_t &file_permissions)
+{
+    if (m_remote_platform_sp)
+        return m_remote_platform_sp->GetFilePermissions(path, file_permissions);
+    else
+        return Platform::GetFilePermissions(path ,file_permissions);
+}
+
+Error
+PlatformPOSIX::SetFilePermissions (const char *path, uint32_t file_permissions)
+{
+    if (m_remote_platform_sp)
+        return m_remote_platform_sp->MakeDirectory(path, file_permissions);
+    else
+        return Platform::SetFilePermissions(path ,file_permissions);
 }
 
 lldb::user_id_t
 PlatformPOSIX::OpenFile (const FileSpec& file_spec,
                          uint32_t flags,
-                         mode_t mode,
+                         uint32_t mode,
                          Error &error)
 {
     if (IsHost())
-    {
         return Host::OpenFile(file_spec, flags, mode, error);
-    }
-    if (IsRemote() && m_remote_platform_sp)
+    else if (m_remote_platform_sp)
         return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error);
-    return Platform::OpenFile(file_spec, flags, mode, error);
+    else
+        return Platform::OpenFile(file_spec, flags, mode, error);
 }
 
 bool
 PlatformPOSIX::CloseFile (lldb::user_id_t fd, Error &error)
 {
     if (IsHost())
-    {
         return Host::CloseFile(fd, error);
-    }
-    if (IsRemote() && m_remote_platform_sp)
+    else if (m_remote_platform_sp)
         return m_remote_platform_sp->CloseFile(fd, error);
-    return Platform::CloseFile(fd, error);
+    else
+        return Platform::CloseFile(fd, error);
 }
 
 uint64_t
@@ -124,12 +136,11 @@ PlatformPOSIX::ReadFile (lldb::user_id_t
                          Error &error)
 {
     if (IsHost())
-    {
         return Host::ReadFile(fd, offset, dst, dst_len, error);
-    }
-    if (IsRemote() && m_remote_platform_sp)
+    else if (m_remote_platform_sp)
         return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error);
-    return Platform::ReadFile(fd, offset, dst, dst_len, error);
+    else
+        return Platform::ReadFile(fd, offset, dst, dst_len, error);
 }
 
 uint64_t
@@ -140,13 +151,11 @@ PlatformPOSIX::WriteFile (lldb::user_id_
                           Error &error)
 {
     if (IsHost())
-    {
         return Host::WriteFile(fd, offset, src, src_len, error);
-    }
-    if (IsRemote() && m_remote_platform_sp)
+    else if (m_remote_platform_sp)
         return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error);
-
-    return Platform::WriteFile(fd, offset, src, src_len, error);
+    else
+        return Platform::WriteFile(fd, offset, src, src_len, error);
 }
 
 static uint32_t
@@ -184,6 +193,8 @@ PlatformPOSIX::PutFile (const lldb_priva
                          uint32_t uid,
                          uint32_t gid)
 {
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+
     if (IsHost())
     {
         if (FileSpec::Equal(source, destination, true))
@@ -213,7 +224,7 @@ PlatformPOSIX::PutFile (const lldb_priva
             return Error("unable to perform chown");
         return Error();
     }
-    else if (IsRemote() && m_remote_platform_sp)
+    else if (m_remote_platform_sp)
     {
         if (GetSupportsRSync())
         {
@@ -244,7 +255,6 @@ PlatformPOSIX::PutFile (const lldb_priva
                                src_path.c_str(),
                                GetHostname(),
                                dst_path.c_str());
-            Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
             if (log)
                 log->Printf("[PutFile] Running command: %s\n", command.GetData());
             int retcode;
@@ -263,20 +273,35 @@ PlatformPOSIX::PutFile (const lldb_priva
             }
             // if we are still here rsync has failed - let's try the slow way before giving up
         }
+        
+        if (log)
+            log->Printf ("PlatformPOSIX::PutFile(src='%s', dst='%s', uid=%u, gid=%u)",
+                         source.GetPath().c_str(),
+                         destination.GetPath().c_str(),
+                         uid,
+                         gid); // REMOVE THIS PRINTF PRIOR TO CHECKIN
         // open
         // read, write, read, write, ...
         // close
         // chown uid:gid dst
-        Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
-            if (log)
-                log->Printf("[PutFile] Using block by block transfer....\n");
-        File source_file(source, File::eOpenOptionRead, File::ePermissionsUserRW);
+        if (log)
+            log->Printf("[PutFile] Using block by block transfer....\n");
+        
+        uint32_t source_open_options = File::eOpenOptionRead;
+        if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink)
+            source_open_options |= File::eOpenoptionDontFollowSymlinks;
+
+        File source_file(source, source_open_options, lldb::eFilePermissionsUserRW);
+        Error error;
+        uint32_t permissions = source_file.GetPermissions(error);
+        if (permissions == 0)
+            permissions = lldb::eFilePermissionsFileDefault;
+
         if (!source_file.IsValid())
             return Error("unable to open source file");
-        Error error;
         lldb::user_id_t dest_file = OpenFile (destination,
                                               File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate,
-                                              File::ePermissionsUserRWX | File::ePermissionsGroupRX | File::ePermissionsWorldRX,
+                                              permissions,
                                               error);
         if (log)
             log->Printf ("dest_file = %" PRIu64 "\n", dest_file);
@@ -314,45 +339,52 @@ lldb::user_id_t
 PlatformPOSIX::GetFileSize (const FileSpec& file_spec)
 {
     if (IsHost())
-    {
         return Host::GetFileSize(file_spec);
-    }
-    if (IsRemote() && m_remote_platform_sp)
+    else if (m_remote_platform_sp)
         return m_remote_platform_sp->GetFileSize(file_spec);
-    return Platform::GetFileSize(file_spec);
+    else
+        return Platform::GetFileSize(file_spec);
+}
+
+Error
+PlatformPOSIX::CreateSymlink(const char *src, const char *dst)
+{
+    if (IsHost())
+        return Host::Symlink(src, dst);
+    else if (m_remote_platform_sp)
+        return m_remote_platform_sp->CreateSymlink(src, dst);
+    else
+        return Platform::CreateSymlink(src, dst);
 }
 
 bool
 PlatformPOSIX::GetFileExists (const FileSpec& file_spec)
 {
     if (IsHost())
-    {
         return file_spec.Exists();
-    }
-    if (IsRemote() && m_remote_platform_sp)
+    else if (m_remote_platform_sp)
         return m_remote_platform_sp->GetFileExists(file_spec);
-    return Platform::GetFileExists(file_spec);
+    else
+        return Platform::GetFileExists(file_spec);
 }
 
-uint32_t
-PlatformPOSIX::GetFilePermissions (const lldb_private::FileSpec &file_spec,
-                                   lldb_private::Error &error)
+Error
+PlatformPOSIX::Unlink (const char *path)
 {
     if (IsHost())
-    {
-        return File::GetPermissions(file_spec.GetPath().c_str(), error);
-    }
-    if (IsRemote() && m_remote_platform_sp)
-        return m_remote_platform_sp->GetFilePermissions(file_spec, error);
-    return Platform::GetFilePermissions(file_spec, error);
-    
+        return Host::Unlink (path);
+    else if (m_remote_platform_sp)
+        return m_remote_platform_sp->Unlink(path);
+    else
+        return Platform::Unlink(path);
 }
 
-
 lldb_private::Error
 PlatformPOSIX::GetFile (const lldb_private::FileSpec& source /* remote file path */,
-                         const lldb_private::FileSpec& destination /* local file path */)
+                        const lldb_private::FileSpec& destination /* local file path */)
 {
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+
     // Check the args, first.
     std::string src_path (source.GetPath());
     if (src_path.empty())
@@ -378,7 +410,7 @@ PlatformPOSIX::GetFile (const lldb_priva
             return Error("unable to perform copy");
         return Error();
     }
-    else if (IsRemote() && m_remote_platform_sp)
+    else if (m_remote_platform_sp)
     {
         if (GetSupportsRSync())
         {
@@ -403,7 +435,6 @@ PlatformPOSIX::GetFile (const lldb_priva
                                m_remote_platform_sp->GetHostname(),
                                src_path.c_str(),
                                dst_path.c_str());
-            Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
             if (log)
                 log->Printf("[GetFile] Running command: %s\n", command.GetData());
             int retcode;
@@ -421,22 +452,22 @@ PlatformPOSIX::GetFile (const lldb_priva
         // read/write, read/write, read/write, ...
         // close src
         // close dst
-        Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
-            if (log)
-                log->Printf("[GetFile] Using block by block transfer....\n");
+        if (log)
+            log->Printf("[GetFile] Using block by block transfer....\n");
         Error error;
         user_id_t fd_src = OpenFile (source,
                                      File::eOpenOptionRead,
-                                     File::ePermissionsDefault,
+                                     lldb::eFilePermissionsFileDefault,
                                      error);
 
         if (fd_src == UINT64_MAX)
             return Error("unable to open source file");
 
-        uint32_t permissions = GetFilePermissions(source, error);
+        uint32_t permissions = 0;
+        error = GetFilePermissions(source.GetPath().c_str(), permissions);
         
         if (permissions == 0)
-            permissions = File::ePermissionsDefault;
+            permissions = lldb::eFilePermissionsFileDefault;
 
         user_id_t fd_dst = Host::OpenFile(destination,
                                           File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate,
@@ -539,3 +570,22 @@ PlatformPOSIX::CalculateMD5 (const FileS
         return m_remote_platform_sp->CalculateMD5(file_spec, low, high);
     return false;
 }
+
+lldb_private::ConstString
+PlatformPOSIX::GetRemoteWorkingDirectory()
+{
+    if (IsRemote() && m_remote_platform_sp)
+        return m_remote_platform_sp->GetRemoteWorkingDirectory();
+    else
+        return Platform::GetRemoteWorkingDirectory();
+}
+
+bool
+PlatformPOSIX::SetRemoteWorkingDirectory(const lldb_private::ConstString &path)
+{
+    if (IsRemote() && m_remote_platform_sp)
+        return m_remote_platform_sp->SetRemoteWorkingDirectory(path);
+    else
+        return Platform::SetRemoteWorkingDirectory(path);
+}
+

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h Wed Nov 20 15:07:01 2013
@@ -43,7 +43,7 @@ public:
     virtual lldb::user_id_t
     OpenFile (const lldb_private::FileSpec& file_spec,
               uint32_t flags,
-              mode_t mode,
+              uint32_t mode,
               lldb_private::Error &error);
     
     virtual bool
@@ -68,9 +68,18 @@ public:
     GetFileSize (const lldb_private::FileSpec& file_spec);
 
     virtual lldb_private::Error
+    CreateSymlink(const char *src, const char *dst);
+
+    virtual lldb_private::Error
     GetFile (const lldb_private::FileSpec& source,
              const lldb_private::FileSpec& destination);
     
+    virtual lldb_private::ConstString
+    GetRemoteWorkingDirectory();
+    
+    virtual bool
+    SetRemoteWorkingDirectory(const lldb_private::ConstString &path);
+    
     virtual lldb_private::Error
     RunShellCommand (const char *command,           // Shouldn't be NULL
                      const char *working_dir,       // Pass NULL to use the current working directory
@@ -79,16 +88,20 @@ public:
                      std::string *command_output,   // Pass NULL if you don't want the command output
                      uint32_t timeout_sec);         // Timeout in seconds to wait for shell program to finish
     
-    virtual uint32_t
-    MakeDirectory (const std::string &path,
-                   mode_t mode);
+    virtual lldb_private::Error
+    MakeDirectory (const char *path, uint32_t mode);
     
+    virtual lldb_private::Error
+    GetFilePermissions (const char *path, uint32_t &file_permissions);
+
+    virtual lldb_private::Error
+    SetFilePermissions (const char *path, uint32_t file_permissions);
+
     virtual bool
     GetFileExists (const lldb_private::FileSpec& file_spec);
     
-    virtual uint32_t
-    GetFilePermissions (const lldb_private::FileSpec &file_spec,
-                        lldb_private::Error &error);
+    virtual lldb_private::Error
+    Unlink (const char *path);
 
     virtual std::string
     GetPlatformSpecificConnectionInformation();

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp Wed Nov 20 15:07:01 2013
@@ -194,6 +194,39 @@ PlatformRemoteGDBServer::GetRemoteSystem
     return m_gdb_client.GetSystemArchitecture();
 }
 
+lldb_private::ConstString
+PlatformRemoteGDBServer::GetRemoteWorkingDirectory()
+{
+    if (IsConnected())
+    {
+        if (!m_working_dir)
+        {
+            std::string cwd;
+            if (m_gdb_client.GetWorkingDir(cwd))
+                m_working_dir = ConstString(cwd.c_str());
+        }
+        return m_working_dir;
+    }
+    else
+    {
+        return Platform::GetRemoteWorkingDirectory();
+    }
+}
+
+bool
+PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const lldb_private::ConstString &path)
+{
+    if (IsConnected())
+    {
+        // Clear the working directory it case it doesn't get set correctly. This will
+        // for use to re-read it
+        m_working_dir.Clear();
+        return m_gdb_client.SetWorkingDir(path.GetCString()) == 0;
+    }
+    else
+        return Platform::SetRemoteWorkingDirectory(path);
+}
+
 bool
 PlatformRemoteGDBServer::IsConnected () const
 {
@@ -222,6 +255,9 @@ PlatformRemoteGDBServer::ConnectRemote (
                 {
                     m_gdb_client.QueryNoAckModeSupported();
                     m_gdb_client.GetHostInfo();
+                    // If a working directory was set prior to connecting, send it down now
+                    if (m_working_dir)
+                        m_gdb_client.SetWorkingDir(m_working_dir.GetCString());
 #if 0
                     m_gdb_client.TestPacketSpeed(10000);
 #endif
@@ -324,7 +360,6 @@ PlatformRemoteGDBServer::LaunchProcess (
     }
     
     // Send the environment and the program + arguments after we connect
-    const char **argv = launch_info.GetArguments().GetConstArgumentVector();
     const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector();
 
     if (envp)
@@ -343,7 +378,7 @@ PlatformRemoteGDBServer::LaunchProcess (
     m_gdb_client.SendLaunchArchPacket(arch_triple);
     
     const uint32_t old_packet_timeout = m_gdb_client.SetPacketTimeout (5);
-    int arg_packet_err = m_gdb_client.SendArgumentsPacket (argv);
+    int arg_packet_err = m_gdb_client.SendArgumentsPacket (launch_info);
     m_gdb_client.SetPacketTimeout (old_packet_timeout);
     if (arg_packet_err == 0)
     {
@@ -367,6 +402,80 @@ PlatformRemoteGDBServer::LaunchProcess (
 }
 
 lldb::ProcessSP
+PlatformRemoteGDBServer::DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
+                                       lldb_private::Debugger &debugger,
+                                       lldb_private::Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+                                       lldb_private::Listener &listener,
+                                       lldb_private::Error &error)
+{
+    lldb::ProcessSP process_sp;
+    if (IsRemote())
+    {
+        if (IsConnected())
+        {
+            lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
+            uint16_t port = m_gdb_client.LaunchGDBserverAndGetPort(debugserver_pid);
+            
+            if (port == 0)
+            {
+                error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ());
+            }
+            else
+            {
+                if (target == NULL)
+                {
+                    TargetSP new_target_sp;
+                    
+                    error = debugger.GetTargetList().CreateTarget (debugger,
+                                                                   NULL,
+                                                                   NULL,
+                                                                   false,
+                                                                   NULL,
+                                                                   new_target_sp);
+                    target = new_target_sp.get();
+                }
+                else
+                    error.Clear();
+                
+                if (target && error.Success())
+                {
+                    debugger.GetTargetList().SetSelectedTarget(target);
+                    
+                    // The darwin always currently uses the GDB remote debugger plug-in
+                    // so even when debugging locally we are debugging remotely!
+                    process_sp = target->CreateProcess (listener, "gdb-remote", NULL);
+                    
+                    if (process_sp)
+                    {
+                        char connect_url[256];
+                        const char *override_hostname = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
+                        const char *port_offset_c_str = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET");
+                        int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0;
+                        const int connect_url_len = ::snprintf (connect_url,
+                                                                sizeof(connect_url),
+                                                                "connect://%s:%u",
+                                                                override_hostname ? override_hostname : GetHostname (),
+                                                                port + port_offset);
+                        assert (connect_url_len < (int)sizeof(connect_url));
+                        error = process_sp->ConnectRemote (NULL, connect_url);
+                        if (error.Success())
+                            error = process_sp->Launch(launch_info);
+                        else if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
+                            m_gdb_client.KillSpawnedProcess(debugserver_pid);
+                    }
+                }
+            }
+        }
+        else
+        {
+            error.SetErrorString("not connected to remote gdb server");
+        }
+    }
+    return process_sp;
+    
+}
+
+lldb::ProcessSP
 PlatformRemoteGDBServer::Attach (lldb_private::ProcessAttachInfo &attach_info,
                                  Debugger &debugger,
                                  Target *target,       // Can be NULL, if NULL create a new target, else use existing one
@@ -441,17 +550,42 @@ PlatformRemoteGDBServer::Attach (lldb_pr
     return process_sp;
 }
 
-uint32_t
-PlatformRemoteGDBServer::MakeDirectory (const std::string &path,
-                                        mode_t mode)
+Error
+PlatformRemoteGDBServer::MakeDirectory (const char *path, uint32_t mode)
+{
+    Error error = m_gdb_client.MakeDirectory(path,mode);
+    Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+    if (log)
+        log->Printf ("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) error = %u (%s)", path, mode, error.GetError(), error.AsCString());
+    return error;
+}
+
+
+Error
+PlatformRemoteGDBServer::GetFilePermissions (const char *path, uint32_t &file_permissions)
 {
-    return m_gdb_client.MakeDirectory(path,mode);
+    Error error = m_gdb_client.GetFilePermissions(path, file_permissions);
+    Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+    if (log)
+        log->Printf ("PlatformRemoteGDBServer::GetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)", path, file_permissions, error.GetError(), error.AsCString());
+    return error;
 }
 
+Error
+PlatformRemoteGDBServer::SetFilePermissions (const char *path, uint32_t file_permissions)
+{
+    Error error = m_gdb_client.SetFilePermissions(path, file_permissions);
+    Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+    if (log)
+        log->Printf ("PlatformRemoteGDBServer::SetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)", path, file_permissions, error.GetError(), error.AsCString());
+    return error;
+}
+
+
 lldb::user_id_t
 PlatformRemoteGDBServer::OpenFile (const lldb_private::FileSpec& file_spec,
                                    uint32_t flags,
-                                   mode_t mode,
+                                   uint32_t mode,
                                    Error &error)
 {
     return m_gdb_client.OpenFile (file_spec, flags, mode, error);
@@ -469,13 +603,6 @@ PlatformRemoteGDBServer::GetFileSize (co
     return m_gdb_client.GetFileSize(file_spec);
 }
 
-uint32_t
-PlatformRemoteGDBServer::GetFilePermissions (const lldb_private::FileSpec &file_spec,
-                                             lldb_private::Error &error)
-{
-    return m_gdb_client.GetFilePermissions(file_spec, error);
-}
-
 uint64_t
 PlatformRemoteGDBServer::ReadFile (lldb::user_id_t fd,
                                    uint64_t offset,
@@ -505,6 +632,27 @@ PlatformRemoteGDBServer::PutFile (const
     return Platform::PutFile(source,destination,uid,gid);
 }
 
+Error
+PlatformRemoteGDBServer::CreateSymlink (const char *src,    // The name of the link is in src
+                                        const char *dst)    // The symlink points to dst
+{
+    Error error = m_gdb_client.CreateSymlink (src, dst);
+    Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+    if (log)
+        log->Printf ("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') error = %u (%s)", src, dst, error.GetError(), error.AsCString());
+    return error;
+}
+
+Error
+PlatformRemoteGDBServer::Unlink (const char *path)
+{
+    Error error = m_gdb_client.Unlink (path);
+    Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+    if (log)
+        log->Printf ("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)", path, error.GetError(), error.AsCString());
+    return error;
+}
+
 bool
 PlatformRemoteGDBServer::GetFileExists (const lldb_private::FileSpec& file_spec)
 {

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h Wed Nov 20 15:07:01 2013
@@ -89,6 +89,13 @@ public:
     LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
     
     virtual lldb::ProcessSP
+    DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
+                  lldb_private::Debugger &debugger,
+                  lldb_private::Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+                  lldb_private::Listener &listener,
+                  lldb_private::Error &error);
+
+    virtual lldb::ProcessSP
     Attach (lldb_private::ProcessAttachInfo &attach_info,
             lldb_private::Debugger &debugger,
             lldb_private::Target *target,       // Can be NULL, if NULL create a new target, else use existing one
@@ -115,6 +122,13 @@ public:
     virtual lldb_private::ArchSpec
     GetRemoteSystemArchitecture ();
 
+    virtual lldb_private::ConstString
+    GetRemoteWorkingDirectory();
+    
+    virtual bool
+    SetRemoteWorkingDirectory(const lldb_private::ConstString &path);
+    
+
     // Remote subclasses should override this and return a valid instance
     // name if connected.
     virtual const char *
@@ -135,14 +149,20 @@ public:
     virtual lldb_private::Error
     DisconnectRemote ();
     
-    virtual uint32_t
-    MakeDirectory (const std::string &path,
-                   mode_t mode);
+    virtual lldb_private::Error
+    MakeDirectory (const char *path, uint32_t file_permissions);
+    
+    virtual lldb_private::Error
+    GetFilePermissions (const char *path, uint32_t &file_permissions);
     
+    virtual lldb_private::Error
+    SetFilePermissions (const char *path, uint32_t file_permissions);
+    
+
     virtual lldb::user_id_t
     OpenFile (const lldb_private::FileSpec& file_spec,
               uint32_t flags,
-              mode_t mode,
+              uint32_t mode,
               lldb_private::Error &error);
     
     virtual bool
@@ -172,12 +192,14 @@ public:
              uint32_t uid = UINT32_MAX,
              uint32_t gid = UINT32_MAX);
     
+    virtual lldb_private::Error
+    CreateSymlink (const char *src, const char *dst);
+
     virtual bool
     GetFileExists (const lldb_private::FileSpec& file_spec);
-    
-    virtual uint32_t
-    GetFilePermissions (const lldb_private::FileSpec &file_spec,
-                        lldb_private::Error &error);
+
+    virtual lldb_private::Error
+    Unlink (const char *path);
 
     virtual lldb_private::Error
     RunShellCommand (const char *command,           // Shouldn't be NULL

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Wed Nov 20 15:07:01 2013
@@ -989,19 +989,43 @@ GDBRemoteCommunicationClient::GetLaunchS
 }
 
 int
-GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
+GDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &launch_info)
 {
-    if (argv && argv[0])
+    // Since we don't get the send argv0 separate from the executable path, we need to
+    // make sure to use the actual exectuable path found in the launch_info...
+    std::vector<const char *> argv;
+    FileSpec exe_file = launch_info.GetExecutableFile();
+    std::string exe_path;
+    const char *arg = NULL;
+    const Args &launch_args = launch_info.GetArguments();
+    if (exe_file)
+        exe_path = exe_file.GetPath();
+    else
+    {
+        arg = launch_args.GetArgumentAtIndex(0);
+        if (arg)
+            exe_path = arg;
+    }
+    if (!exe_path.empty())
+    {
+        argv.push_back(exe_path.c_str());
+        for (uint32_t i=1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL; ++i)
+        {
+            if (arg)
+                argv.push_back(arg);
+        }
+    }
+    if (!argv.empty())
     {
         StreamString packet;
         packet.PutChar('A');
-        const char *arg;
-        for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
+        for (size_t i = 0, n = argv.size(); i < n; ++i)
         {
+            arg = argv[i];
             const int arg_len = strlen(arg);
             if (i > 0)
                 packet.PutChar(',');
-            packet.Printf("%i,%i,", arg_len * 2, i);
+            packet.Printf("%i,%i,", arg_len * 2, (int)i);
             packet.PutBytesAsRawHex8 (arg, arg_len);
         }
 
@@ -1785,6 +1809,22 @@ GDBRemoteCommunicationClient::SetSTDERR
     return -1;
 }
 
+bool
+GDBRemoteCommunicationClient::GetWorkingDir (std::string &cwd)
+{
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false))
+    {
+        if (response.IsUnsupportedResponse())
+            return false;
+        if (response.IsErrorResponse())
+            return false;
+        response.GetHexByteString (cwd);
+        return !cwd.empty();
+    }
+    return false;
+}
+
 int
 GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
 {
@@ -2497,7 +2537,7 @@ GDBRemoteCommunicationClient::RunShellCo
                                                uint32_t timeout_sec)          // Timeout in seconds to wait for shell program to finish
 {
     lldb_private::StreamString stream;
-    stream.PutCString("qPlatform_RunCommand:");
+    stream.PutCString("qPlatform_shell:");
     stream.PutBytesAsRawHex8(command, strlen(command));
     stream.PutChar(',');
     stream.PutHex32(timeout_sec);
@@ -2536,26 +2576,46 @@ GDBRemoteCommunicationClient::RunShellCo
     return Error("unable to send packet");
 }
 
-uint32_t
-GDBRemoteCommunicationClient::MakeDirectory (const std::string &path,
-                                             mode_t mode)
+Error
+GDBRemoteCommunicationClient::MakeDirectory (const char *path,
+                                             uint32_t file_permissions)
 {
     lldb_private::StreamString stream;
-    stream.PutCString("qPlatform_IO_MkDir:");
-    stream.PutHex32(mode);
+    stream.PutCString("qPlatform_mkdir:");
+    stream.PutHex32(file_permissions);
     stream.PutChar(',');
-    stream.PutBytesAsRawHex8(path.c_str(), path.size());
+    stream.PutBytesAsRawHex8(path, strlen(path));
     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 Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
     }
-    return UINT32_MAX;
+    return Error();
 
 }
 
+Error
+GDBRemoteCommunicationClient::SetFilePermissions (const char *path,
+                                                  uint32_t file_permissions)
+{
+    lldb_private::StreamString stream;
+    stream.PutCString("qPlatform_chmod:");
+    stream.PutHex32(file_permissions);
+    stream.PutChar(',');
+    stream.PutBytesAsRawHex8(path, strlen(path));
+    const char *packet = stream.GetData();
+    int packet_len = stream.GetSize();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
+    }
+    return Error();
+    
+}
+
 static uint64_t
 ParseHostIOPacketResponse (StringExtractorGDBRemote &response,
                            uint64_t fail_result,
@@ -2643,13 +2703,13 @@ GDBRemoteCommunicationClient::GetFileSiz
     return UINT64_MAX;
 }
 
-uint32_t
-GDBRemoteCommunicationClient::GetFilePermissions(const lldb_private::FileSpec& file_spec, Error &error)
+Error
+GDBRemoteCommunicationClient::GetFilePermissions(const char *path, uint32_t &file_permissions)
 {
+    Error error;
     lldb_private::StreamString stream;
     stream.PutCString("vFile:mode:");
-    std::string path (file_spec.GetPath());
-    stream.PutCStringAsRawHex8(path.c_str());
+    stream.PutCStringAsRawHex8(path);
     const char* packet = stream.GetData();
     int packet_len = stream.GetSize();
     StringExtractorGDBRemote response;
@@ -2658,29 +2718,34 @@ GDBRemoteCommunicationClient::GetFilePer
         if (response.GetChar() != 'F')
         {
             error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet);
-            return 0;
         }
-        const uint32_t mode = response.GetS32(-1);
-        if (mode == -1)
+        else
         {
-            if (response.GetChar() == ',')
+            const uint32_t mode = response.GetS32(-1);
+            if (mode == -1)
             {
-                int response_errno = response.GetS32(-1);
-                if (response_errno > 0)
-                    error.SetError(response_errno, lldb::eErrorTypePOSIX);
+                if (response.GetChar() == ',')
+                {
+                    int response_errno = response.GetS32(-1);
+                    if (response_errno > 0)
+                        error.SetError(response_errno, lldb::eErrorTypePOSIX);
+                    else
+                        error.SetErrorToGenericError();
+                }
                 else
                     error.SetErrorToGenericError();
             }
+            else
+            {
+                file_permissions = mode & (S_IRWXU|S_IRWXG|S_IRWXO);
+            }
         }
-        else
-            error.Clear();
-        return mode & (S_IRWXU|S_IRWXG|S_IRWXO);
     }
     else
     {
         error.SetErrorStringWithFormat ("failed to send '%s' packet", packet);
     }
-    return 0;
+    return error;
 }
 
 uint64_t
@@ -2762,6 +2827,90 @@ GDBRemoteCommunicationClient::WriteFile
     return 0;
 }
 
+Error
+GDBRemoteCommunicationClient::CreateSymlink (const char *src, const char *dst)
+{
+    Error error;
+    lldb_private::StreamGDBRemote stream;
+    stream.PutCString("vFile:symlink:");
+    // the unix symlink() command reverses its parameters where the dst if first,
+    // so we follow suit here
+    stream.PutCStringAsRawHex8(dst);
+    stream.PutChar(',');
+    stream.PutCStringAsRawHex8(src);
+    const char* packet = stream.GetData();
+    int packet_len = stream.GetSize();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        if (response.GetChar() == 'F')
+        {
+            uint32_t result = response.GetU32(UINT32_MAX);
+            if (result != 0)
+            {
+                error.SetErrorToGenericError();
+                if (response.GetChar() == ',')
+                {
+                    int response_errno = response.GetS32(-1);
+                    if (response_errno > 0)
+                        error.SetError(response_errno, lldb::eErrorTypePOSIX);
+                }
+            }
+        }
+        else
+        {
+            // Should have returned with 'F<result>[,<errno>]'
+            error.SetErrorStringWithFormat("symlink failed");
+        }
+    }
+    else
+    {
+        error.SetErrorString ("failed to send vFile:symlink packet");
+    }
+    return error;
+}
+
+Error
+GDBRemoteCommunicationClient::Unlink (const char *path)
+{
+    Error error;
+    lldb_private::StreamGDBRemote stream;
+    stream.PutCString("vFile:unlink:");
+    // the unix symlink() command reverses its parameters where the dst if first,
+    // so we follow suit here
+    stream.PutCStringAsRawHex8(path);
+    const char* packet = stream.GetData();
+    int packet_len = stream.GetSize();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+    {
+        if (response.GetChar() == 'F')
+        {
+            uint32_t result = response.GetU32(UINT32_MAX);
+            if (result != 0)
+            {
+                error.SetErrorToGenericError();
+                if (response.GetChar() == ',')
+                {
+                    int response_errno = response.GetS32(-1);
+                    if (response_errno > 0)
+                        error.SetError(response_errno, lldb::eErrorTypePOSIX);
+                }
+            }
+        }
+        else
+        {
+            // Should have returned with 'F<result>[,<errno>]'
+            error.SetErrorStringWithFormat("unlink failed");
+        }
+    }
+    else
+    {
+        error.SetErrorString ("failed to send vFile:unlink packet");
+    }
+    return error;
+}
+
 // Extension of host I/O packets to get whether a file exists.
 bool
 GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Wed Nov 20 15:07:01 2013
@@ -38,7 +38,6 @@ public:
     //------------------------------------------------------------------
     GDBRemoteCommunicationClient(bool is_platform);
 
-    virtual
     ~GDBRemoteCommunicationClient();
 
     //------------------------------------------------------------------
@@ -65,7 +64,7 @@ public:
                                           size_t packet_length,
                                           StringExtractorGDBRemote &response);
 
-    virtual bool
+    bool
     GetThreadSuffixSupported ();
 
     void
@@ -109,7 +108,7 @@ public:
     ///     response was received.
     //------------------------------------------------------------------
     int
-    SendArgumentsPacket (char const *argv[]);
+    SendArgumentsPacket (const lldb_private::ProcessLaunchInfo &launch_info);
 
     //------------------------------------------------------------------
     /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
@@ -185,7 +184,10 @@ public:
 
     //------------------------------------------------------------------
     /// Sets the working directory to \a path for a process that will 
-    /// be launched with the 'A' packet.
+    /// be launched with the 'A' packet for non platform based
+    /// connections. If this packet is sent to a GDB server that
+    /// implements the platform, it will change the current working
+    /// directory for the platform process.
     ///
     /// @param[in] path
     ///     The path to a directory to use when launching our processs
@@ -196,6 +198,19 @@ public:
     int
     SetWorkingDir (char const *path);
 
+    //------------------------------------------------------------------
+    /// Gets the current working directory of a remote platform GDB
+    /// server.
+    ///
+    /// @param[out] cwd
+    ///     The current working directory on the remote platform.
+    ///
+    /// @return
+    ///     Boolean for success
+    //------------------------------------------------------------------
+    bool
+    GetWorkingDir (std::string &cwd);
+
     lldb::addr_t
     AllocateMemory (size_t size, uint32_t permissions);
 
@@ -356,45 +371,54 @@ public:
         return m_interrupt_sent;
     }
     
-    virtual lldb::user_id_t
+    lldb::user_id_t
     OpenFile (const lldb_private::FileSpec& file_spec,
               uint32_t flags,
               mode_t mode,
               lldb_private::Error &error);
     
-    virtual bool
+    bool
     CloseFile (lldb::user_id_t fd,
                lldb_private::Error &error);
     
-    virtual lldb::user_id_t
+    lldb::user_id_t
     GetFileSize (const lldb_private::FileSpec& file_spec);
     
-    virtual uint32_t
-    GetFilePermissions(const lldb_private::FileSpec& file_spec,
-                       lldb_private::Error &error);
+    lldb_private::Error
+    GetFilePermissions(const char *path, uint32_t &file_permissions);
 
-    virtual uint64_t
+    lldb_private::Error
+    SetFilePermissions(const char *path, uint32_t file_permissions);
+
+    uint64_t
     ReadFile (lldb::user_id_t fd,
               uint64_t offset,
               void *dst,
               uint64_t dst_len,
               lldb_private::Error &error);
     
-    virtual uint64_t
+    uint64_t
     WriteFile (lldb::user_id_t fd,
                uint64_t offset,
                const void* src,
                uint64_t src_len,
                lldb_private::Error &error);
     
-    virtual uint32_t
-    MakeDirectory (const std::string &path,
-                   mode_t mode);
+    lldb_private::Error
+    CreateSymlink (const char *src,
+                   const char *dst);
+    
+    lldb_private::Error
+    Unlink (const char *path);
+
+    lldb_private::Error
+    MakeDirectory (const char *path,
+                   uint32_t mode);
     
-    virtual bool
+    bool
     GetFileExists (const lldb_private::FileSpec& file_spec);
     
-    virtual lldb_private::Error
+    lldb_private::Error
     RunShellCommand (const char *command,           // Shouldn't be NULL
                      const char *working_dir,       // Pass NULL to use the current working directory
                      int *status_ptr,               // Pass NULL if you don't want the process exit status
@@ -402,7 +426,7 @@ public:
                      std::string *command_output,   // Pass NULL if you don't want the command output
                      uint32_t timeout_sec);         // Timeout in seconds to wait for shell program to finish
     
-    virtual bool
+    bool
     CalculateMD5 (const lldb_private::FileSpec& file_spec,
                   uint64_t &high,
                   uint64_t &low);

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Wed Nov 20 15:07:01 2013
@@ -166,6 +166,9 @@ GDBRemoteCommunicationServer::GetPacketA
             case StringExtractorGDBRemote::eServerPacketType_qUserName:
                 return Handle_qUserName (packet);
 
+            case StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir:
+                return Handle_qGetWorkingDir(packet);
+    
             case StringExtractorGDBRemote::eServerPacketType_QEnvironment:
                 return Handle_QEnvironment (packet);
 
@@ -190,38 +193,47 @@ GDBRemoteCommunicationServer::GetPacketA
             case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
                 return Handle_QStartNoAckMode (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_qPlatform_IO_MkDir:
-                return Handle_qPlatform_IO_MkDir (packet);
+            case StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir:
+                return Handle_qPlatform_mkdir (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_qPlatform_RunCommand:
-                return Handle_qPlatform_RunCommand (packet);
+            case StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod:
+                return Handle_qPlatform_chmod (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_vFile_Open:
+            case StringExtractorGDBRemote::eServerPacketType_qPlatform_shell:
+                return Handle_qPlatform_shell (packet);
+
+            case StringExtractorGDBRemote::eServerPacketType_vFile_open:
                 return Handle_vFile_Open (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_vFile_Close:
+            case StringExtractorGDBRemote::eServerPacketType_vFile_close:
                 return Handle_vFile_Close (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_vFile_pRead:
+            case StringExtractorGDBRemote::eServerPacketType_vFile_pread:
                 return Handle_vFile_pRead (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_vFile_pWrite:
+            case StringExtractorGDBRemote::eServerPacketType_vFile_pwrite:
                 return Handle_vFile_pWrite (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_vFile_Size:
+            case StringExtractorGDBRemote::eServerPacketType_vFile_size:
                 return Handle_vFile_Size (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_vFile_Mode:
+            case StringExtractorGDBRemote::eServerPacketType_vFile_mode:
                 return Handle_vFile_Mode (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_vFile_Exists:
+            case StringExtractorGDBRemote::eServerPacketType_vFile_exists:
                 return Handle_vFile_Exists (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_vFile_Stat:
+            case StringExtractorGDBRemote::eServerPacketType_vFile_stat:
                 return Handle_vFile_Stat (packet);
 
-            case StringExtractorGDBRemote::eServerPacketType_vFile_MD5:
+            case StringExtractorGDBRemote::eServerPacketType_vFile_md5:
                 return Handle_vFile_MD5 (packet);
+
+            case StringExtractorGDBRemote::eServerPacketType_vFile_symlink:
+                return Handle_vFile_symlink (packet);
+                
+            case StringExtractorGDBRemote::eServerPacketType_vFile_unlink:
+                return Handle_vFile_unlink (packet);
         }
         return true;
     }
@@ -810,19 +822,20 @@ GDBRemoteCommunicationServer::Handle_qLa
                 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
                 if (log)
                     log->Printf("Launching debugserver with: %s...\n", host_and_port_cstr);
+
+                debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
+                
                 error = StartDebugserverProcess (host_and_port_cstr,
                                                  unix_socket_name,
                                                  debugserver_launch_info);
 
                 lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
 
+
                 if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
                 {
-                    {
-                        Mutex::Locker locker (m_spawned_pids_mutex);
-                        m_spawned_pids.insert(debugserver_pid);
-                    }
-                    Host::StartMonitoringChildProcess (ReapDebugserverProcess, this, debugserver_pid, false);
+                    Mutex::Locker locker (m_spawned_pids_mutex);
+                    m_spawned_pids.insert(debugserver_pid);
                 }
 
                 if (error.Success())
@@ -979,11 +992,56 @@ GDBRemoteCommunicationServer::Handle_QSe
     packet.SetFilePos(::strlen ("QSetWorkingDir:"));
     std::string path;
     packet.GetHexByteString(path);
-    m_process_launch_info.SwapWorkingDirectory (path);
+    if (m_is_platform)
+    {
+        // If this packet is sent to a platform, then change the current working directory
+        if (::chdir(path.c_str()) != 0)
+            return SendErrorResponse(errno);
+    }
+    else
+    {
+        m_process_launch_info.SwapWorkingDirectory (path);
+    }
     return SendOKResponse ();
 }
 
 bool
+GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
+{
+    StreamString response;
+
+    if (m_is_platform)
+    {
+        // If this packet is sent to a platform, then change the current working directory
+        char cwd[PATH_MAX];
+        if (getcwd(cwd, sizeof(cwd)) == NULL)
+        {
+            return SendErrorResponse(errno);
+        }
+        else
+        {
+            response.PutBytesAsRawHex8(cwd, strlen(cwd));
+            SendPacketNoLock(response.GetData(), response.GetSize());
+            return true;
+        }
+    }
+    else
+    {
+        const char *working_dir = m_process_launch_info.GetWorkingDirectory();
+        if (working_dir && working_dir[0])
+        {
+            response.PutBytesAsRawHex8(working_dir, strlen(working_dir));
+            SendPacketNoLock(response.GetData(), response.GetSize());
+            return true;
+        }
+        else
+        {
+            return SendErrorResponse(1);
+        }
+    }
+}
+
+bool
 GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
 {
     packet.SetFilePos(::strlen ("QSetSTDIN:"));
@@ -1044,18 +1102,37 @@ GDBRemoteCommunicationServer::Handle_QSt
 }
 
 bool
-GDBRemoteCommunicationServer::Handle_qPlatform_IO_MkDir (StringExtractorGDBRemote &packet)
+GDBRemoteCommunicationServer::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet)
 {
-    packet.SetFilePos(::strlen("qPlatform_IO_MkDir:"));
+    packet.SetFilePos(::strlen("qPlatform_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);
-    SendPacketNoLock(response.GetData(), response.GetSize());
+    Error error = Host::MakeDirectory(path.c_str(),mode);
+    if (error.Success())
+        return SendPacketNoLock ("OK", 2);
+    else
+        return SendErrorResponse(error.GetError());
+    return true;
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen("qPlatform_chmod:"));
+    
+    mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
+    if (packet.GetChar() != ',')
+        return false;
+    std::string path;
+    packet.GetHexByteString(path);
+    Error error = Host::SetFilePermissions (path.c_str(), mode);
+    if (error.Success())
+        return SendPacketNoLock ("OK", 2);
+    else
+        return SendErrorResponse(error.GetError());
     return true;
 }
 
@@ -1247,9 +1324,37 @@ GDBRemoteCommunicationServer::Handle_vFi
 }
 
 bool
-GDBRemoteCommunicationServer::Handle_qPlatform_RunCommand (StringExtractorGDBRemote &packet)
+GDBRemoteCommunicationServer::Handle_vFile_symlink (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen("vFile:symlink:"));
+    std::string dst, src;
+    packet.GetHexByteStringTerminatedBy(dst, ',');
+    packet.GetChar(); // Skip ',' char
+    packet.GetHexByteString(src);
+    Error error = Host::Symlink(src.c_str(), dst.c_str());
+    StreamString response;
+    response.Printf("F%u,%u", error.GetError(), error.GetError());
+    SendPacketNoLock(response.GetData(), response.GetSize());
+    return true;
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_vFile_unlink (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(::strlen("vFile:unlink:"));
+    std::string path;
+    packet.GetHexByteString(path);
+    Error error = Host::Unlink(path.c_str());
+    StreamString response;
+    response.Printf("F%u,%u", error.GetError(), error.GetError());
+    SendPacketNoLock(response.GetData(), response.GetSize());
+    return true;
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_qPlatform_shell (StringExtractorGDBRemote &packet)
 {
-    packet.SetFilePos(::strlen("qPlatform_RunCommand:"));
+    packet.SetFilePos(::strlen("qPlatform_shell:"));
     std::string path;
     std::string working_dir;
     packet.GetHexByteStringTerminatedBy(path,',');
@@ -1257,7 +1362,7 @@ GDBRemoteCommunicationServer::Handle_qPl
         return false;
     if (packet.GetChar() != ',')
         return false;
-    // FIXME: add timeout to qPlatform_RunCommand packet
+    // FIXME: add timeout to qPlatform_shell packet
     // uint32_t timeout = packet.GetHexMaxU32(false, 32);
     uint32_t timeout = 10;
     if (packet.GetChar() == ',')

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h Wed Nov 20 15:07:01 2013
@@ -121,7 +121,10 @@ protected:
     Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
 
     bool
-    Handle_qPlatform_IO_MkDir (StringExtractorGDBRemote &packet);
+    Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet);
+    
+    bool
+    Handle_qPlatform_chmod (StringExtractorGDBRemote &packet);
     
     bool
     Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
@@ -155,6 +158,9 @@ protected:
 
     bool
     Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
+    
+    bool
+    Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
 
     bool
     Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
@@ -188,6 +194,12 @@ protected:
 
     bool
     Handle_vFile_Exists (StringExtractorGDBRemote &packet);
+    
+    bool
+    Handle_vFile_symlink (StringExtractorGDBRemote &packet);
+    
+    bool
+    Handle_vFile_unlink (StringExtractorGDBRemote &packet);
 
     bool
     Handle_vFile_Stat (StringExtractorGDBRemote &packet);
@@ -196,7 +208,7 @@ protected:
     Handle_vFile_MD5 (StringExtractorGDBRemote &packet);
     
     bool
-    Handle_qPlatform_RunCommand (StringExtractorGDBRemote &packet);
+    Handle_qPlatform_shell (StringExtractorGDBRemote &packet);
 
 private:
     bool

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Wed Nov 20 15:07:01 2013
@@ -820,7 +820,7 @@ ProcessGDBRemote::DoLaunch (Module *exe_
             }
 
             const uint32_t old_packet_timeout = m_gdb_comm.SetPacketTimeout (10);
-            int arg_packet_err = m_gdb_comm.SendArgumentsPacket (launch_info.GetArguments().GetConstArgumentVector());
+            int arg_packet_err = m_gdb_comm.SendArgumentsPacket (launch_info);
             if (arg_packet_err == 0)
             {
                 std::string error_str;
@@ -1158,6 +1158,13 @@ ProcessGDBRemote::DoAttachToProcessWithN
 }
 
 
+bool
+ProcessGDBRemote::SetExitStatus (int exit_status, const char *cstr)
+{
+    m_gdb_comm.Disconnect();
+    return Process::SetExitStatus (exit_status, cstr);
+}
+
 void
 ProcessGDBRemote::DidAttach ()
 {
@@ -2787,6 +2794,7 @@ ProcessGDBRemote::MonitorDebugserverProc
 void
 ProcessGDBRemote::KillDebugserverProcess ()
 {
+    m_gdb_comm.Disconnect();
     if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
     {
         Host::Kill (m_debugserver_pid, SIGINT);

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Wed Nov 20 15:07:01 2013
@@ -222,6 +222,13 @@ public:
     {
         return m_gdb_comm;
     }
+    
+    //----------------------------------------------------------------------
+    // Override SetExitStatus so we can disconnect from the remote GDB server
+    //----------------------------------------------------------------------
+    virtual bool
+    SetExitStatus (int exit_status, const char *cstr);
+
 
 protected:
     friend class ThreadGDBRemote;

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Wed Nov 20 15:07:01 2013
@@ -237,6 +237,7 @@ Platform::Platform (bool is_host) :
     m_system_arch_set_while_connected (false),
     m_sdk_sysroot (),
     m_sdk_build (),
+    m_working_dir (),
     m_remote_url (),
     m_name (),
     m_major_os_version (UINT32_MAX),
@@ -319,6 +320,10 @@ Platform::GetStatus (Stream &strm)
         strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
     }
 
+    if (GetWorkingDirectory())
+    {
+        strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString());
+    }
     if (!IsConnected())
         return;
 
@@ -405,12 +410,323 @@ Platform::GetOSKernelDescription (std::s
 }
 
 ConstString
+Platform::GetWorkingDirectory ()
+{
+    if (IsHost())
+    {
+        char cwd[PATH_MAX];
+        if (getcwd(cwd, sizeof(cwd)))
+            return ConstString(cwd);
+        else
+            return ConstString();
+    }
+    else
+    {
+        if (!m_working_dir)
+            m_working_dir = GetRemoteWorkingDirectory();
+        return m_working_dir;
+    }
+}
+
+
+struct RecurseCopyBaton
+{
+    const FileSpec& dst;
+    Platform *platform_ptr;
+    Error error;
+};
+
+
+static FileSpec::EnumerateDirectoryResult
+RecurseCopy_Callback (void *baton,
+                      FileSpec::FileType file_type,
+                      const FileSpec &src)
+{
+    RecurseCopyBaton* rc_baton = (RecurseCopyBaton*)baton;
+    switch (file_type)
+    {
+        case FileSpec::eFileTypePipe:
+        case FileSpec::eFileTypeSocket:
+            // we have no way to copy pipes and sockets - ignore them and continue
+            return FileSpec::eEnumerateDirectoryResultNext;
+            break;
+            
+        case FileSpec::eFileTypeDirectory:
+            {
+                // make the new directory and get in there
+                FileSpec dst_dir = rc_baton->dst;
+                if (!dst_dir.GetFilename())
+                    dst_dir.GetFilename() = src.GetLastPathComponent();
+                std::string dst_dir_path (dst_dir.GetPath());
+                Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir_path.c_str(), lldb::eFilePermissionsDirectoryDefault);
+                if (error.Fail())
+                {
+                    rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end", dst_dir_path.c_str());
+                    return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+                }
+                
+                // now recurse
+                std::string src_dir_path (src.GetPath());
+                
+                // Make a filespec that only fills in the directory of a FileSpec so
+                // when we enumerate we can quickly fill in the filename for dst copies
+                FileSpec recurse_dst;
+                recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str());
+                RecurseCopyBaton rc_baton2 = { recurse_dst, rc_baton->platform_ptr, Error() };
+                FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &rc_baton2);
+                if (rc_baton2.error.Fail())
+                {
+                    rc_baton->error.SetErrorString(rc_baton2.error.AsCString());
+                    return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+                }
+                return FileSpec::eEnumerateDirectoryResultNext;
+            }
+            break;
+            
+        case FileSpec::eFileTypeSymbolicLink:
+            {
+                // copy the file and keep going
+                FileSpec dst_file = rc_baton->dst;
+                if (!dst_file.GetFilename())
+                    dst_file.GetFilename() = src.GetFilename();
+                
+                char buf[PATH_MAX];
+                
+                rc_baton->error = Host::Readlink (src.GetPath().c_str(), buf, sizeof(buf));
+
+                if (rc_baton->error.Fail())
+                    return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+                
+                rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file.GetPath().c_str(), buf);
+
+                if (rc_baton->error.Fail())
+                    return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+
+                return FileSpec::eEnumerateDirectoryResultNext;
+            }
+            break;
+        case FileSpec::eFileTypeRegular:
+            {
+                // copy the file and keep going
+                FileSpec dst_file = rc_baton->dst;
+                if (!dst_file.GetFilename())
+                    dst_file.GetFilename() = src.GetFilename();
+                Error err = rc_baton->platform_ptr->PutFile(src, dst_file);
+                if (err.Fail())
+                {
+                    rc_baton->error.SetErrorString(err.AsCString());
+                    return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+                }
+                return FileSpec::eEnumerateDirectoryResultNext;
+            }
+            break;
+            
+        case FileSpec::eFileTypeInvalid:
+        case FileSpec::eFileTypeOther:
+        case FileSpec::eFileTypeUnknown:
+            rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s", src.GetPath().c_str());
+            return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
+            break;
+    }
+}
+
+Error
+Platform::Install (const FileSpec& src, const FileSpec& dst)
+{
+    Error error;
+    
+    Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+    if (log)
+        log->Printf ("Platform::Install (src='%s', dst='%s')", src.GetPath().c_str(), dst.GetPath().c_str());
+    FileSpec fixed_dst(dst);
+    
+    if (!fixed_dst.GetFilename())
+        fixed_dst.GetFilename() = src.GetFilename();
+
+    ConstString working_dir = GetWorkingDirectory();
+
+    if (dst)
+    {
+        if (dst.GetDirectory())
+        {
+            const char first_dst_dir_char = dst.GetDirectory().GetCString()[0];
+            if (first_dst_dir_char == '/' || first_dst_dir_char  == '\\')
+            {
+                fixed_dst.GetDirectory() = dst.GetDirectory();
+            }
+            // If the fixed destination file doesn't have a directory yet,
+            // then we must have a relative path. We will resolve this relative
+            // path against the platform's working directory
+            if (!fixed_dst.GetDirectory())
+            {
+                FileSpec relative_spec;
+                std::string path;
+                if (working_dir)
+                {
+                    relative_spec.SetFile(working_dir.GetCString(), false);
+                    relative_spec.AppendPathComponent(dst.GetPath().c_str());
+                    fixed_dst.GetDirectory() = relative_spec.GetDirectory();
+                }
+                else
+                {
+                    error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str());
+                    return error;
+                }
+            }
+        }
+        else
+        {
+            if (working_dir)
+            {
+                fixed_dst.GetDirectory() = working_dir;
+            }
+            else
+            {
+                error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str());
+                return error;
+            }
+        }
+    }
+    else
+    {
+        if (working_dir)
+        {
+            fixed_dst.GetDirectory() = working_dir;
+        }
+        else
+        {
+            error.SetErrorStringWithFormat("platform working directory must be valid when destination directory is empty");
+            return error;
+        }
+    }
+    
+    if (log)
+        log->Printf ("Platform::Install (src='%s', dst='%s') fixed_dst='%s'", src.GetPath().c_str(), dst.GetPath().c_str(), fixed_dst.GetPath().c_str());
+
+    if (GetSupportsRSync())
+    {
+        error = PutFile(src, dst);
+    }
+    else
+    {
+        switch (src.GetFileType())
+        {
+            case FileSpec::eFileTypeDirectory:
+                {
+                    if (GetFileExists (fixed_dst))
+                        Unlink (fixed_dst.GetPath().c_str());
+                    uint32_t permissions = src.GetPermissions();
+                    if (permissions == 0)
+                        permissions = eFilePermissionsDirectoryDefault;
+                    std::string dst_dir_path(fixed_dst.GetPath());
+                    error = MakeDirectory(dst_dir_path.c_str(), permissions);
+                    if (error.Success())
+                    {
+                        // Make a filespec that only fills in the directory of a FileSpec so
+                        // when we enumerate we can quickly fill in the filename for dst copies
+                        FileSpec recurse_dst;
+                        recurse_dst.GetDirectory().SetCString(dst_dir_path.c_str());
+                        std::string src_dir_path (src.GetPath());
+                        RecurseCopyBaton baton = { recurse_dst, this, Error() };
+                        FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &baton);
+                        return baton.error;
+                    }
+                }
+                break;
+
+            case FileSpec::eFileTypeRegular:
+                if (GetFileExists (fixed_dst))
+                    Unlink (fixed_dst.GetPath().c_str());
+                error = PutFile(src, fixed_dst);
+                break;
+
+            case FileSpec::eFileTypeSymbolicLink:
+                {
+                    if (GetFileExists (fixed_dst))
+                        Unlink (fixed_dst.GetPath().c_str());
+                    char buf[PATH_MAX];
+                    error = Host::Readlink(src.GetPath().c_str(), buf, sizeof(buf));
+                    if (error.Success())
+                        error = CreateSymlink(dst.GetPath().c_str(), buf);
+                }
+                break;
+            case FileSpec::eFileTypePipe:
+                error.SetErrorString("platform install doesn't handle pipes");
+                break;
+            case FileSpec::eFileTypeSocket:
+                error.SetErrorString("platform install doesn't handle sockets");
+                break;
+            case FileSpec::eFileTypeInvalid:
+            case FileSpec::eFileTypeUnknown:
+            case FileSpec::eFileTypeOther:
+                error.SetErrorString("platform install doesn't handle non file or directory items");
+                break;
+        }
+    }
+    return error;
+}
+
+bool
+Platform::SetWorkingDirectory (const ConstString &path)
+{
+    if (IsHost())
+    {
+        if (path)
+        {
+            if (chdir(path.GetCString()) == 0)
+                return true;
+        }
+        return false;
+    }
+    else
+    {
+        return SetRemoteWorkingDirectory(path);
+    }
+}
+
+Error
+Platform::MakeDirectory (const char *path, uint32_t permissions)
+{
+    if (IsHost())
+        return Host::MakeDirectory (path, permissions);
+    else
+    {
+        Error error;
+        error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
+        return error;
+    }
+}
+
+Error
+Platform::GetFilePermissions (const char *path, uint32_t &file_permissions)
+{
+    if (IsHost())
+        return Host::GetFilePermissions(path, file_permissions);
+    else
+    {
+        Error error;
+        error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
+        return error;
+    }
+}
+
+Error
+Platform::SetFilePermissions (const char *path, uint32_t file_permissions)
+{
+    if (IsHost())
+        return Host::SetFilePermissions(path, file_permissions);
+    else
+    {
+        Error error;
+        error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
+        return error;
+    }
+}
+
+ConstString
 Platform::GetName ()
 {
-    const char *name = GetHostname();
-    if (name == NULL || name[0] == '\0')
-        return GetPluginName();
-    return ConstString (name);
+    return GetPluginName();
 }
 
 const char *
@@ -779,14 +1095,6 @@ Platform::IsCompatibleArchitecture (cons
     return false;
 }
 
-uint32_t
-Platform::MakeDirectory (const FileSpec &spec,
-                         mode_t mode)
-{
-    std::string path(spec.GetPath());
-    return this->MakeDirectory(path,mode);
-}
-
 Error
 Platform::PutFile (const FileSpec& source,
                    const FileSpec& destination,
@@ -805,12 +1113,29 @@ Platform::GetFile (const FileSpec& sourc
     return error;
 }
 
+Error
+Platform::CreateSymlink (const char *src, // The name of the link is in src
+                         const char *dst)// The symlink points to dst
+{
+    Error error("unimplemented");
+    return error;
+}
+
 bool
 Platform::GetFileExists (const lldb_private::FileSpec& file_spec)
 {
     return false;
 }
 
+Error
+Platform::Unlink (const char *path)
+{
+    Error error("unimplemented");
+    return error;
+}
+
+
+
 lldb_private::Error
 Platform::RunShellCommand (const char *command,           // Shouldn't be NULL
                            const char *working_dir,       // Pass NULL to use the current working directory

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Wed Nov 20 15:07:01 2013
@@ -2113,12 +2113,37 @@ Process::CreateBreakpointSite (const Bre
                 }
                 else
                 {
-                    // Report error for setting breakpoint...
-                    m_target.GetDebugger().GetErrorFile().Printf ("warning: failed to set breakpoint site at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
-                                                                  load_addr,
-                                                                  owner->GetBreakpoint().GetID(),
-                                                                  owner->GetID(),
-                                                                  error.AsCString() ? error.AsCString() : "unkown error");
+                    bool show_error = true;
+                    switch (GetState())
+                    {
+                        case eStateInvalid:
+                        case eStateUnloaded:
+                        case eStateConnected:
+                        case eStateAttaching:
+                        case eStateLaunching:
+                        case eStateDetached:
+                        case eStateExited:
+                            show_error = false;
+                            break;
+                            
+                        case eStateStopped:
+                        case eStateRunning:
+                        case eStateStepping:
+                        case eStateCrashed:
+                        case eStateSuspended:
+                            show_error = IsAlive();
+                            break;
+                    }
+                    
+                    if (show_error)
+                    {
+                        // Report error for setting breakpoint...
+                        m_target.GetDebugger().GetErrorFile().Printf ("warning: failed to set breakpoint site at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
+                                                                      load_addr,
+                                                                      owner->GetBreakpoint().GetID(),
+                                                                      owner->GetID(),
+                                                                      error.AsCString() ? error.AsCString() : "unkown error");
+                    }
                 }
             }
         }
@@ -2884,7 +2909,7 @@ Process::WaitForProcessStopPrivate (cons
 }
 
 Error
-Process::Launch (const ProcessLaunchInfo &launch_info)
+Process::Launch (ProcessLaunchInfo &launch_info)
 {
     Error error;
     m_abi_sp.reset();
@@ -2902,6 +2927,13 @@ Process::Launch (const ProcessLaunchInfo
         exe_module->GetPlatformFileSpec().GetPath(platform_exec_file_path, sizeof(platform_exec_file_path));
         if (exe_module->GetFileSpec().Exists())
         {
+            // Install anything that might need to be installed prior to launching.
+            // For host systems, this will do nothing, but if we are connected to a
+            // remote platform it will install any needed binaries
+            error = GetTarget().Install(&launch_info);
+            if (error.Fail())
+                return error;
+
             if (PrivateStateThreadIsValid ())
                 PausePrivateStateThread ();
     

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Wed Nov 20 15:07:01 2013
@@ -2190,12 +2190,78 @@ Target::RunStopHooks ()
     result.GetImmediateErrorStream()->Flush();
 }
 
+const TargetPropertiesSP &
+Target::GetGlobalProperties()
+{
+    static TargetPropertiesSP g_settings_sp;
+    if (!g_settings_sp)
+    {
+        g_settings_sp.reset (new TargetProperties (NULL));
+    }
+    return g_settings_sp;
+}
+
+Error
+Target::Install (ProcessLaunchInfo *launch_info)
+{
+    Error error;
+    PlatformSP platform_sp (GetPlatform());
+    if (platform_sp)
+    {
+        if (platform_sp->IsRemote())
+        {
+            if (platform_sp->IsConnected())
+            {
+                // Install all files that have an install path, and always install the
+                // main executable when connected to a remote platform
+                const ModuleList& modules = GetImages();
+                const size_t num_images = modules.GetSize();
+                for (size_t idx = 0; idx < num_images; ++idx)
+                {
+                    const bool is_main_executable = idx == 0;
+                    ModuleSP module_sp(modules.GetModuleAtIndex(idx));
+                    if (module_sp)
+                    {
+                        FileSpec local_file (module_sp->GetFileSpec());
+                        if (local_file)
+                        {
+                            FileSpec remote_file (module_sp->GetRemoteInstallFileSpec());
+                            if (!remote_file)
+                            {
+                                if (is_main_executable) // TODO: add setting for always installing main executable???
+                                {
+                                    // Always install the main executable
+                                    remote_file.GetDirectory() = platform_sp->GetWorkingDirectory();
+                                    remote_file.GetFilename() = module_sp->GetFileSpec().GetFilename();
+                                }
+                            }
+                            if (remote_file)
+                            {
+                                error = platform_sp->Install(local_file, remote_file);
+                                if (error.Success())
+                                {
+                                    module_sp->SetPlatformFileSpec(remote_file);
+                                    if (is_main_executable)
+                                    {
+                                        if (launch_info)
+                                            launch_info->SetExecutableFile(remote_file, false);
+                                    }
+                                }
+                                else
+                                    break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return error;
+}
 
 //--------------------------------------------------------------
-// class Target::StopHook
+// Target::StopHook
 //--------------------------------------------------------------
-
-
 Target::StopHook::StopHook (lldb::TargetSP target_sp, lldb::user_id_t uid) :
         UserID (uid),
         m_target_sp (target_sp),
@@ -2527,6 +2593,9 @@ protected:
     mutable bool m_got_host_env;
 };
 
+//----------------------------------------------------------------------
+// TargetProperties
+//----------------------------------------------------------------------
 TargetProperties::TargetProperties (Target *target) :
     Properties ()
 {
@@ -2815,17 +2884,10 @@ TargetProperties::GetMemoryModuleLoadLev
 }
 
 
-const TargetPropertiesSP &
-Target::GetGlobalProperties()
-{
-    static TargetPropertiesSP g_settings_sp;
-    if (!g_settings_sp)
-    {
-        g_settings_sp.reset (new TargetProperties (NULL));
-    }
-    return g_settings_sp;
-}
 
+//----------------------------------------------------------------------
+// Target::TargetEventData
+//----------------------------------------------------------------------
 const ConstString &
 Target::TargetEventData::GetFlavorString ()
 {

Modified: lldb/trunk/source/Utility/StringExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractor.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractor.cpp (original)
+++ lldb/trunk/source/Utility/StringExtractor.cpp Wed Nov 20 15:07:01 2013
@@ -145,11 +145,10 @@ StringExtractor::GetChar (char fail_valu
 uint8_t
 StringExtractor::GetHexU8 (uint8_t fail_value, bool set_eof_on_fail)
 {
-    uint32_t i = m_index;
-    if ((i + 2) <= m_packet.size())
+    if (GetBytesLeft() >= 2)
     {
-        const uint8_t hi_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[i])];
-        const uint8_t lo_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[i+1])];
+        const uint8_t hi_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[m_index])];
+        const uint8_t lo_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[m_index+1])];
         if (hi_nibble < 16 && lo_nibble < 16)
         {
             m_index += 2;

Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp Wed Nov 20 15:07:01 2013
@@ -117,6 +117,7 @@ StringExtractorGDBRemote::GetServerPacke
 
         case 'G':
             if (PACKET_STARTS_WITH ("qGroupName:"))             return eServerPacketType_qGroupName;
+            if (PACKET_MATCHES ("qGetWorkingDir"))              return eServerPacketType_qGetWorkingDir;
             break;
 
         case 'H':
@@ -133,9 +134,10 @@ StringExtractorGDBRemote::GetServerPacke
             break;
             
         case 'P':
-            if (PACKET_STARTS_WITH ("qProcessInfoPID:"))                 return eServerPacketType_qProcessInfoPID;
-            if (PACKET_STARTS_WITH ("qPlatform_RunCommand:"))            return eServerPacketType_qPlatform_RunCommand;
-            if (PACKET_STARTS_WITH ("qPlatform_IO_MkDir:"))              return eServerPacketType_qPlatform_IO_MkDir;
+            if (PACKET_STARTS_WITH ("qProcessInfoPID:"))        return eServerPacketType_qProcessInfoPID;
+            if (PACKET_STARTS_WITH ("qPlatform_shell:"))   return eServerPacketType_qPlatform_shell;
+            if (PACKET_STARTS_WITH ("qPlatform_mkdir:"))        return eServerPacketType_qPlatform_mkdir;
+            if (PACKET_STARTS_WITH ("qPlatform_chmod:"))        return eServerPacketType_qPlatform_chmod;
             break;
                 
 
@@ -151,15 +153,17 @@ StringExtractorGDBRemote::GetServerPacke
     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;
-                else if (PACKET_STARTS_WITH("vFile:size"))           return eServerPacketType_vFile_Size;
-                else if (PACKET_STARTS_WITH("vFile:exists"))         return eServerPacketType_vFile_Exists;
-                else if (PACKET_STARTS_WITH("vFile:stat"))           return eServerPacketType_vFile_Stat;
-                else if (PACKET_STARTS_WITH("vFile:mode"))           return eServerPacketType_vFile_Mode;
-                else if (PACKET_STARTS_WITH("vFile:MD5"))            return eServerPacketType_vFile_MD5;
+                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;
+                else if (PACKET_STARTS_WITH("vFile:size"))      return eServerPacketType_vFile_size;
+                else if (PACKET_STARTS_WITH("vFile:exists"))    return eServerPacketType_vFile_exists;
+                else if (PACKET_STARTS_WITH("vFile:stat"))      return eServerPacketType_vFile_stat;
+                else if (PACKET_STARTS_WITH("vFile:mode"))      return eServerPacketType_vFile_mode;
+                else if (PACKET_STARTS_WITH("vFile:MD5"))       return eServerPacketType_vFile_md5;
+                else if (PACKET_STARTS_WITH("vFile:symlink"))   return eServerPacketType_vFile_symlink;
+                else if (PACKET_STARTS_WITH("vFile:unlink"))    return eServerPacketType_vFile_unlink;
 
             }
             break;

Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.h?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.h (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.h Wed Nov 20 15:07:01 2013
@@ -58,6 +58,7 @@ public:
         eServerPacketType_qProcessInfoPID,
         eServerPacketType_qSpeedTest,
         eServerPacketType_qUserName,
+        eServerPacketType_qGetWorkingDir,
         eServerPacketType_QEnvironment,
         eServerPacketType_QLaunchArch,
         eServerPacketType_QSetDisableASLR,
@@ -66,17 +67,20 @@ public:
         eServerPacketType_QSetSTDERR,
         eServerPacketType_QSetWorkingDir,
         eServerPacketType_QStartNoAckMode,
-        eServerPacketType_qPlatform_RunCommand,
-        eServerPacketType_qPlatform_IO_MkDir,
-        eServerPacketType_vFile_Open,
-        eServerPacketType_vFile_Close,
-        eServerPacketType_vFile_pRead,
-        eServerPacketType_vFile_pWrite,
-        eServerPacketType_vFile_Size,
-        eServerPacketType_vFile_Mode,
-        eServerPacketType_vFile_Exists,
-        eServerPacketType_vFile_MD5,
-        eServerPacketType_vFile_Stat
+        eServerPacketType_qPlatform_shell,
+        eServerPacketType_qPlatform_mkdir,
+        eServerPacketType_qPlatform_chmod,
+        eServerPacketType_vFile_open,
+        eServerPacketType_vFile_close,
+        eServerPacketType_vFile_pread,
+        eServerPacketType_vFile_pwrite,
+        eServerPacketType_vFile_size,
+        eServerPacketType_vFile_mode,
+        eServerPacketType_vFile_exists,
+        eServerPacketType_vFile_md5,
+        eServerPacketType_vFile_stat,
+        eServerPacketType_vFile_symlink,
+        eServerPacketType_vFile_unlink
     };
     
     ServerPacketType

Modified: lldb/trunk/tools/debugserver/debugserver.xcodeproj/xcshareddata/xcschemes/debugserver.xcscheme
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/debugserver.xcodeproj/xcshareddata/xcschemes/debugserver.xcscheme?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/debugserver.xcodeproj/xcshareddata/xcschemes/debugserver.xcscheme (original)
+++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/xcshareddata/xcschemes/debugserver.xcscheme Wed Nov 20 15:07:01 2013
@@ -66,6 +66,12 @@
             ReferencedContainer = "container:debugserver.xcodeproj">
          </BuildableReference>
       </BuildableProductRunnable>
+      <CommandLineArguments>
+         <CommandLineArgument
+            argument = "lldb.apple.com:0 --native-regs --setsid --unix-socket /tmp/gtJlji"
+            isEnabled = "YES">
+         </CommandLineArgument>
+      </CommandLineArguments>
       <EnvironmentVariables>
          <EnvironmentVariable
             key = "UBBY"

Modified: lldb/trunk/tools/lldb-platform/lldb-platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-platform/lldb-platform.cpp?rev=195273&r1=195272&r2=195273&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-platform/lldb-platform.cpp (original)
+++ lldb/trunk/tools/lldb-platform/lldb-platform.cpp Wed Nov 20 15:07:01 2013
@@ -21,6 +21,7 @@
 // C++ Includes
 
 // Other libraries and framework includes
+#include "lldb/lldb-private-log.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/ConnectionFileDescriptor.h"
 #include "lldb/Core/ConnectionMachPort.h"
@@ -96,44 +97,9 @@ main (int argc, char *argv[])
     int ch;
     Debugger::Initialize();
     
-//    ConnectionMachPort a;
-//    ConnectionMachPort b;
-//
-//    lldb::ConnectionStatus status;
-//    const char *bootstrap_service_name = "HelloWorld";
-//    status = a.BootstrapCheckIn(bootstrap_service_name, &error);
-//    
-//    if (status != eConnectionStatusSuccess)
-//    {
-//        fprintf(stderr, "%s", error.AsCString());
-//        return 1;
-//    }
-//    status = b.BootstrapLookup (bootstrap_service_name, &error);
-//    if (status != eConnectionStatusSuccess)
-//    {
-//        fprintf(stderr, "%s", error.AsCString());
-//        return 2;
-//    }
-//    
-//    if (a.Write ("hello", 5, status, &error) == 5)
-//    {
-//        char buf[32];
-//        memset(buf, 0, sizeof(buf));
-//        if (b.Read (buf, 5, status, &error))
-//        {
-//            printf("read returned bytes: %s", buf);
-//        }
-//        else
-//        {
-//            fprintf(stderr, "%s", error.AsCString());
-//            return 4;
-//        }
-//    }
-//    else
-//    {
-//        fprintf(stderr, "%s", error.AsCString());
-//        return 3;
-//    }
+//    StreamSP stream_sp (new StreamFile(stdout, false));
+//    const char *log_channels[] = { "host", "process", NULL };
+//    EnableLog (stream_sp, 0, log_channels, NULL);
     
     while ((ch = getopt_long_only(argc, argv, "l:f:L:", g_long_options, &long_option_index)) != -1)
     {





More information about the lldb-commits mailing list