Modified local spawning in debugserver processes to use a new --reverse-connect option so that debugserver actually connects back to LLDB instead of LLDB connecting to debugserver.

This gets rid of our hacky "get_random_port()" which would grab a random port and tell debugserver to open that port. Now LLDB creates, binds, listens and accepts a connection by binding to port zero and sending the correctly bound port down as the host:port to connect back to.

Fixed the "ConnectionFileDescriptor" to be able to correctly listen for connections from a specified host, localhost, or any host. Prior to this fix "listen://" only accepted the following format:

listen://<port>

But now it can accept:

listen://<port>         // Listen for connection from localhost on port <port>
listen://<host>:<port>  // Listen for connection from <host> and <port>    
listen://*:<port>       // Listen for connection from any host on port <port>

llvm-svn: 196547
diff --git a/lldb/tools/debugserver/source/debugserver.cpp b/lldb/tools/debugserver/source/debugserver.cpp
index b0b694c..42469ce 100644
--- a/lldb/tools/debugserver/source/debugserver.cpp
+++ b/lldb/tools/debugserver/source/debugserver.cpp
@@ -644,21 +644,34 @@
 }
 
 static int
-StartListening (RNBRemote *remote, const char *listen_host, int listen_port, const char *named_pipe_path)
+ConnectRemote (RNBRemote *remote, const char *host, int port, bool reverse_connect, const char *named_pipe_path)
 {
     if (!remote->Comm().IsConnected())
     {
-        if (listen_port != 0)
-            RNBLogSTDOUT ("Listening to port %i for a connection from %s...\n", listen_port, listen_host ? listen_host : "localhost");
-        if (remote->Comm().Listen(listen_host, listen_port, PortWasBoundCallbackNamedPipe, named_pipe_path) != rnb_success)
+        if (reverse_connect)
         {
-            RNBLogSTDERR ("Failed to get connection from a remote gdb process.\n");
-            return 0;
+            if (port == 0)
+            {
+                DNBLogThreaded("error: invalid port supplied for reverse connection: %i.\n", port);
+                return 0;
+            }
+            if (remote->Comm().Connect(host, port) != rnb_success)
+            {
+                DNBLogThreaded("Failed to reverse connect to %s:%i.\n", host, port);
+                return 0;
+            }
         }
         else
         {
-            remote->StartReadRemoteDataThread();
+            if (port != 0)
+                RNBLogSTDOUT ("Listening to port %i for a connection from %s...\n", port, host ? host : "localhost");
+            if (remote->Comm().Listen(host, port, PortWasBoundCallbackNamedPipe, named_pipe_path) != rnb_success)
+            {
+                RNBLogSTDERR ("Failed to get connection from a remote gdb process.\n");
+                return 0;
+            }
         }
+        remote->StartReadRemoteDataThread();
     }
     return 1;
 }
@@ -746,6 +759,7 @@
     { "working-dir",        required_argument,  NULL,               'W' },  // The working directory that the inferior process should have (only if debugserver launches the process)
     { "platform",           required_argument,  NULL,               'p' },  // Put this executable into a remote platform mode
     { "named-pipe",         required_argument,  NULL,               'P' },
+    { "reverse-connect",    no_argument,        NULL,               'R' },
     { NULL,                 0,                  NULL,               0   }
 };
 
@@ -801,6 +815,7 @@
     useconds_t waitfor_interval = 1000;     // Time in usecs between process lists polls when waiting for a process by name, default 1 msec.
     useconds_t waitfor_duration = 0;        // Time in seconds to wait for a process by name, 0 means wait forever.
     bool no_stdio = false;
+    bool reverse_connect = false;           // Set to true by an option to indicate we should reverse connect to the host:port supplied as the first debugserver argument
 
 #if !defined (DNBLOG_ENABLED)
     compile_options += "(no-logging) ";
@@ -997,6 +1012,9 @@
                 // Do nothing, native regs is the default these days
                 break;
 
+            case 'R':
+                reverse_connect = true;
+                break;
             case 'v':
                 DNBLogSetVerbose(1);
                 break;
@@ -1117,8 +1135,8 @@
                   compile_options.c_str(),
                   RNB_ARCH);
 
-    std::string listen_host;
-    int listen_port = INT32_MAX;
+    std::string host;
+    int port = INT32_MAX;
     char str[PATH_MAX];
     str[0] = '\0';
 
@@ -1131,24 +1149,24 @@
         }
         // accept 'localhost:' prefix on port number
 
-        int items_scanned = ::sscanf (argv[0], "%[^:]:%i", str, &listen_port);
+        int items_scanned = ::sscanf (argv[0], "%[^:]:%i", str, &port);
         if (items_scanned == 2)
         {
-            listen_host = str;
-            DNBLogDebug("host = '%s'  port = %i", listen_host.c_str(), listen_port);
+            host = str;
+            DNBLogDebug("host = '%s'  port = %i", host.c_str(), port);
         }
         else
         {
             // No hostname means "localhost"
-            int items_scanned = ::sscanf (argv[0], "%i", &listen_port);
+            int items_scanned = ::sscanf (argv[0], "%i", &port);
             if (items_scanned == 1)
             {
-                listen_host = "localhost";
-                DNBLogDebug("host = '%s'  port = %i", listen_host.c_str(), listen_port);
+                host = "localhost";
+                DNBLogDebug("host = '%s'  port = %i", host.c_str(), port);
             }
             else if (argv[0][0] == '/')
             {
-                listen_port = INT32_MAX;
+                port = INT32_MAX;
                 strncpy(str, argv[0], sizeof(str));
             }
             else
@@ -1263,9 +1281,9 @@
                 }
                 else
 #endif
-                if (listen_port != INT32_MAX)
+                if (port != INT32_MAX)
                 {
-                    if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
+                    if (!ConnectRemote (remote, host.c_str(), port, reverse_connect, named_pipe_path.c_str()))
                         mode = eRNBRunLoopModeExit;
                 }
                 else if (str[0] == '/')
@@ -1376,9 +1394,9 @@
 
                 if (mode != eRNBRunLoopModeExit)
                 {
-                    if (listen_port != INT32_MAX)
+                    if (port != INT32_MAX)
                     {
-                        if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
+                        if (!ConnectRemote (remote, host.c_str(), port, reverse_connect, named_pipe_path.c_str()))
                             mode = eRNBRunLoopModeExit;
                     }
                     else if (str[0] == '/')
@@ -1401,9 +1419,9 @@
 
                     if (mode == eRNBRunLoopModeInferiorExecuting)
                     {
-                        if (listen_port != INT32_MAX)
+                        if (port != INT32_MAX)
                         {
-                            if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
+                            if (!ConnectRemote (remote, host.c_str(), port, reverse_connect, named_pipe_path.c_str()))
                                 mode = eRNBRunLoopModeExit;
                         }
                         else if (str[0] == '/')
@@ -1428,9 +1446,9 @@
                 break;
 
             case eRNBRunLoopModePlatformMode:
-                if (listen_port != INT32_MAX)
+                if (port != INT32_MAX)
                 {
-                    if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
+                    if (!ConnectRemote (remote, host.c_str(), port, reverse_connect, named_pipe_path.c_str()))
                         mode = eRNBRunLoopModeExit;
                 }
                 else if (str[0] == '/')