Added support for attaching to a remote debug server with the new command:
(lldb) process connect <remote-url>

Currently when you specify a file with the file command it helps us to find
a process plug-in that is suitable for debugging. If you specify a file you
can rely upon this to find the correct debugger plug-in:

% lldb a.out
Current executable set to 'a.out' (x86_64).
(lldb) process connect connect://localhost:2345
...

If you don't specify a file, you will need to specify the plug-in name that
you wish to use:

% lldb
(lldb) process connect --plugin process.gdb-remote connect://localhost:2345

Other connection URL examples:

(lldb) process connect connect://localhost:2345
(lldb) process connect tcp://127.0.0.1
(lldb) process connect file:///dev/ttyS1

We are currently treating the "connect://host:port" as a way to do raw socket
connections. If there is a URL for this already, please let me know and we
will adopt it.

So now you can connect to a remote debug server with the ProcessGDBRemote
plug-in. After connection, it will ask for the pid info using the "qC" packet
and if it responds with a valid process ID, it will be equivalent to attaching.
If it response with an error or invalid process ID, the LLDB process will be
in a new state: eStateConnected. This allows us to then download a program or
specify the program to run (using the 'A' packet), or specify a process to
attach to (using the "vAttach" packets), or query info about the processes
that might be available.




git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@124846 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 2fd7722..2da0de9 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -354,6 +354,56 @@
 }
 
 Error
+ProcessGDBRemote::DoConnectRemote (const char *remote_url)
+{
+    Error error (WillLaunchOrAttach ());
+    
+    if (error.Fail())
+        return error;
+
+    if (strncmp (remote_url, "connect://", strlen ("connect://")) == 0)
+    {
+        error = ConnectToDebugserver (remote_url);
+    }
+    else
+    {
+        error.SetErrorStringWithFormat ("unsupported remote url: %s", remote_url);
+    }
+
+    if (error.Fail())
+        return error;
+    StartAsyncThread ();
+
+    lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID (m_packet_timeout);
+    if (pid == LLDB_INVALID_PROCESS_ID)
+    {
+        // We don't have a valid process ID, so note that we are connected
+        // and could now request to launch or attach, or get remote process 
+        // listings...
+        SetPrivateState (eStateConnected);
+    }
+    else
+    {
+        // We have a valid process
+        SetID (pid);
+        StringExtractorGDBRemote response;
+        if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, m_packet_timeout, false))
+        {
+            const StateType state = SetThreadStopInfo (response);
+            if (state == eStateStopped)
+            {
+                SetPrivateState (state);
+            }
+            else
+                error.SetErrorStringWithFormat ("Process %i was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
+        }
+        else
+            error.SetErrorStringWithFormat ("Process %i was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
+    }
+    return error;
+}
+
+Error
 ProcessGDBRemote::WillLaunchOrAttach ()
 {
     Error error;
@@ -394,6 +444,8 @@
         ArchSpec inferior_arch(module->GetArchitecture());
         char host_port[128];
         snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
+        char connect_url[128];
+        snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
 
         const bool launch_process = true;
         bool start_debugserver_with_inferior_args = false;
@@ -417,7 +469,7 @@
             if (error.Fail())
                 return error;
 
-            error = ConnectToDebugserver (host_port);
+            error = ConnectToDebugserver (connect_url);
             if (error.Success())
             {
                 SetID (m_gdb_comm.GetCurrentProcessID (m_packet_timeout));
@@ -441,7 +493,7 @@
             if (error.Fail())
                 return error;
 
-            error = ConnectToDebugserver (host_port);
+            error = ConnectToDebugserver (connect_url);
             if (error.Success())
             {
                 // Send the environment and the program + arguments after we connect
@@ -515,20 +567,18 @@
 
 
 Error
-ProcessGDBRemote::ConnectToDebugserver (const char *host_port)
+ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
 {
     Error error;
     // Sleep and wait a bit for debugserver to start to listen...
     std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
     if (conn_ap.get())
     {
-        std::string connect_url("connect://");
-        connect_url.append (host_port);
         const uint32_t max_retry_count = 50;
         uint32_t retry_count = 0;
         while (!m_gdb_comm.IsConnected())
         {
-            if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)
+            if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
             {
                 m_gdb_comm.SetConnection (conn_ap.release());
                 break;
@@ -596,21 +646,31 @@
 
         StreamString strm;
 
-        ArchSpec inferior_arch;
+        ArchSpec inferior_arch (m_gdb_comm.GetHostArchitecture());
+
         // See if the GDB server supports the qHostInfo information
         const char *vendor = m_gdb_comm.GetVendorString().AsCString();
         const char *os_type = m_gdb_comm.GetOSString().AsCString();
-        ArchSpec arch_spec (GetTarget().GetArchitecture());
-        
-        if (arch_spec.IsValid() && arch_spec == ArchSpec ("arm"))
+        const ArchSpec target_arch (GetTarget().GetArchitecture());
+        const ArchSpec arm_any("arm");
+        bool set_target_arch = true;
+        if (target_arch.IsValid())
         {
-            // For ARM we can't trust the arch of the process as it could
-            // have an armv6 object file, but be running on armv7 kernel.
-            inferior_arch = m_gdb_comm.GetHostArchitecture();
+            if (inferior_arch == arm_any)
+            {
+                // For ARM we can't trust the arch of the process as it could
+                // have an armv6 object file, but be running on armv7 kernel.
+                // So we only set the ARM architecture if the target isn't set
+                // to ARM already...
+                if (target_arch == arm_any)
+                {
+                    inferior_arch = target_arch;
+                    set_target_arch = false;
+                }
+            }
         }
-        
-        if (!inferior_arch.IsValid())
-            inferior_arch = arch_spec;
+        if (set_target_arch)
+            GetTarget().SetArchitecture (inferior_arch);
 
         if (vendor == NULL)
             vendor = Host::GetVendorString().AsCString("apple");
@@ -652,6 +712,9 @@
     {
         char host_port[128];
         snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
+        char connect_url[128];
+        snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
+
         error = StartDebugserverProcess (host_port,                 // debugserver_url
                                          NULL,                      // inferior_argv
                                          NULL,                      // inferior_envp
@@ -676,7 +739,7 @@
         }
         else
         {
-            error = ConnectToDebugserver (host_port);
+            error = ConnectToDebugserver (connect_url);
             if (error.Success())
             {
                 char packet[64];
@@ -722,9 +785,13 @@
     //LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
     if (process_name && process_name[0])
     {
-        char host_port[128];
         ArchSpec arch_spec = GetTarget().GetArchitecture();
+
+        char host_port[128];
         snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
+        char connect_url[128];
+        snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
+
         error = StartDebugserverProcess (host_port,                 // debugserver_url
                                          NULL,                      // inferior_argv
                                          NULL,                      // inferior_envp
@@ -748,7 +815,7 @@
         }
         else
         {
-            error = ConnectToDebugserver (host_port);
+            error = ConnectToDebugserver (connect_url);
             if (error.Success())
             {
                 StreamString packet;
@@ -772,9 +839,9 @@
 void
 ProcessGDBRemote::DidAttach ()
 {
+    DidLaunchOrAttach ();
     if (m_dynamic_loader_ap.get())
         m_dynamic_loader_ap->DidAttach();
-    DidLaunchOrAttach ();
 }
 
 Error