Provide ADB port forwarding support for abstract sockets.

http://reviews.llvm.org/D14262

llvm-svn: 251879
diff --git a/lldb/source/Plugins/Platform/Android/AdbClient.cpp b/lldb/source/Plugins/Platform/Android/AdbClient.cpp
index f57e8c3..736447fd 100644
--- a/lldb/source/Plugins/Platform/Android/AdbClient.cpp
+++ b/lldb/source/Plugins/Platform/Android/AdbClient.cpp
@@ -50,6 +50,9 @@
 // Default mode for pushed files.
 const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG
 
+const char * kSocketNamespaceAbstract = "localabstract";
+const char * kSocketNamespaceFileSystem = "localfilesystem";
+
 }  // namespace
 
 Error
@@ -145,10 +148,17 @@
 }
 
 Error
-AdbClient::SetPortForwarding (const uint16_t local_port, const char* remote_socket_name)
+AdbClient::SetPortForwarding (const uint16_t local_port,
+                              const char* remote_socket_name,
+                              const UnixSocketNamespace socket_namespace)
 {
     char message[PATH_MAX];
-    snprintf (message, sizeof (message), "forward:tcp:%d;localfilesystem:%s", local_port, remote_socket_name);
+    const char * sock_namespace_str = (socket_namespace == UnixSocketNamespaceAbstract) ?
+        kSocketNamespaceAbstract : kSocketNamespaceFileSystem;
+    snprintf (message, sizeof (message), "forward:tcp:%d;%s:%s",
+              local_port,
+              sock_namespace_str,
+              remote_socket_name);
 
     const auto error = SendDeviceMessage (message);
     if (error.Fail ())
diff --git a/lldb/source/Plugins/Platform/Android/AdbClient.h b/lldb/source/Plugins/Platform/Android/AdbClient.h
index 43aa1db..4ec411d 100644
--- a/lldb/source/Plugins/Platform/Android/AdbClient.h
+++ b/lldb/source/Plugins/Platform/Android/AdbClient.h
@@ -33,6 +33,12 @@
 class AdbClient
 {
 public:
+    enum UnixSocketNamespace
+    {
+        UnixSocketNamespaceAbstract,
+        UnixSocketNamespaceFileSystem,
+    };
+
     using DeviceIDList = std::list<std::string>;
 
     static Error
@@ -51,7 +57,9 @@
     SetPortForwarding (const uint16_t local_port, const uint16_t remote_port);
 
     Error
-    SetPortForwarding (const uint16_t local_port, const char* remote_socket_name);
+    SetPortForwarding (const uint16_t local_port,
+                       const char* remote_socket_name,
+                       const UnixSocketNamespace socket_namespace);
 
     Error
     DeletePortForwarding (const uint16_t local_port);
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
index 42934dd..9a55be6 100644
--- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -11,7 +11,6 @@
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Host/common/TCPSocket.h"
-#include "AdbClient.h"
 #include "PlatformAndroidRemoteGDBServer.h"
 #include "Utility/UriParser.h"
 
@@ -27,6 +26,7 @@
 ForwardPortWithAdb (const uint16_t local_port,
                     const uint16_t remote_port,
                     const char* remote_socket_name,
+                    const llvm::Optional<AdbClient::UnixSocketNamespace>& socket_namespace,
                     std::string& device_id)
 {
     Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
@@ -49,7 +49,11 @@
 
     if (log)
         log->Printf("Forwarding remote socket \"%s\" to local TCP port %d", remote_socket_name, local_port);
-    return adb.SetPortForwarding(local_port, remote_socket_name);
+
+    if (!socket_namespace)
+        return Error("Invalid socket namespace");
+
+    return adb.SetPortForwarding(local_port, remote_socket_name, *socket_namespace);
 }
 
 static Error
@@ -129,6 +133,12 @@
     if (host != "localhost")
         m_device_id = host;
 
+    m_socket_namespace.reset();
+    if (scheme == ConnectionFileDescriptor::UNIX_CONNECT_SCHEME)
+        m_socket_namespace = AdbClient::UnixSocketNamespaceFileSystem;
+    else if (scheme == ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME)
+        m_socket_namespace = AdbClient::UnixSocketNamespaceAbstract;
+
     std::string connect_url;
     auto error = MakeConnectURL (g_remote_platform_pid,
                                  (remote_port < 0) ? 0 : remote_port,
@@ -196,7 +206,11 @@
         if (error.Fail())
             return error;
 
-        error = ForwardPortWithAdb(local_port, remote_port, remote_socket_name, m_device_id);
+        error = ForwardPortWithAdb(local_port,
+                                   remote_port,
+                                   remote_socket_name,
+                                   m_socket_namespace,
+                                   m_device_id);
         if (error.Success())
         {
             m_port_forwards[pid] = local_port;
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
index 3ac405b..84530ad 100644
--- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
+++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
@@ -19,6 +19,10 @@
 // Project includes
 #include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
 
+#include "llvm/ADT/Optional.h"
+
+#include "AdbClient.h"
+
 namespace lldb_private {
 namespace platform_android {
 
@@ -38,6 +42,7 @@
 protected:
     std::string m_device_id;
     std::map<lldb::pid_t, uint16_t> m_port_forwards;
+    llvm::Optional<AdbClient::UnixSocketNamespace> m_socket_namespace;
 
     bool
     LaunchGDBServer (lldb::pid_t &pid, std::string &connect_url) override;