forked from OSchip/llvm-project
Provide ADB port forwarding support for abstract sockets.
http://reviews.llvm.org/D14262 llvm-svn: 251879
This commit is contained in:
parent
52151b3edf
commit
e7df5f5d41
|
@ -34,6 +34,17 @@ class SocketAddress;
|
|||
class ConnectionFileDescriptor : public Connection
|
||||
{
|
||||
public:
|
||||
static const char* LISTEN_SCHEME;
|
||||
static const char* ACCEPT_SCHEME;
|
||||
static const char* UNIX_ACCEPT_SCHEME;
|
||||
static const char* CONNECT_SCHEME;
|
||||
static const char* TCP_CONNECT_SCHEME;
|
||||
static const char* UDP_SCHEME;
|
||||
static const char* UNIX_CONNECT_SCHEME;
|
||||
static const char* UNIX_ABSTRACT_CONNECT_SCHEME;
|
||||
static const char* FD_SCHEME;
|
||||
static const char* FILE_SCHEME;
|
||||
|
||||
ConnectionFileDescriptor(bool child_processes_inherit = false);
|
||||
|
||||
ConnectionFileDescriptor(int fd, bool owns_fd);
|
||||
|
|
|
@ -53,6 +53,31 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
const char* ConnectionFileDescriptor::LISTEN_SCHEME = "listen";
|
||||
const char* ConnectionFileDescriptor::ACCEPT_SCHEME = "accept";
|
||||
const char* ConnectionFileDescriptor::UNIX_ACCEPT_SCHEME = "unix-accept";
|
||||
const char* ConnectionFileDescriptor::CONNECT_SCHEME = "connect";
|
||||
const char* ConnectionFileDescriptor::TCP_CONNECT_SCHEME = "tcp-connect";
|
||||
const char* ConnectionFileDescriptor::UDP_SCHEME = "udp";
|
||||
const char* ConnectionFileDescriptor::UNIX_CONNECT_SCHEME = "unix-connect";
|
||||
const char* ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME = "unix-abstract-connect";
|
||||
const char* ConnectionFileDescriptor::FD_SCHEME = "fd";
|
||||
const char* ConnectionFileDescriptor::FILE_SCHEME = "file";
|
||||
|
||||
namespace {
|
||||
|
||||
const char*
|
||||
GetURLAddress(const char *url, const char *scheme)
|
||||
{
|
||||
const auto prefix = std::string(scheme) + "://";
|
||||
if (strstr(url, prefix.c_str()) != url)
|
||||
return nullptr;
|
||||
|
||||
return url + prefix.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit)
|
||||
: Connection()
|
||||
, m_pipe()
|
||||
|
@ -154,51 +179,51 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr)
|
|||
|
||||
if (s && s[0])
|
||||
{
|
||||
if (strstr(s, "listen://") == s)
|
||||
const char *addr = nullptr;
|
||||
if ((addr = GetURLAddress(s, LISTEN_SCHEME)))
|
||||
{
|
||||
// listen://HOST:PORT
|
||||
return SocketListenAndAccept(s + strlen("listen://"), error_ptr);
|
||||
return SocketListenAndAccept(addr, error_ptr);
|
||||
}
|
||||
else if (strstr(s, "accept://") == s)
|
||||
else if ((addr = GetURLAddress(s, ACCEPT_SCHEME)))
|
||||
{
|
||||
// unix://SOCKNAME
|
||||
return NamedSocketAccept(s + strlen("accept://"), error_ptr);
|
||||
return NamedSocketAccept(addr, error_ptr);
|
||||
}
|
||||
else if (strstr(s, "unix-accept://") == s)
|
||||
else if ((addr = GetURLAddress(s, UNIX_ACCEPT_SCHEME)))
|
||||
{
|
||||
// unix://SOCKNAME
|
||||
return NamedSocketAccept(s + strlen("unix-accept://"), error_ptr);
|
||||
return NamedSocketAccept(addr, error_ptr);
|
||||
}
|
||||
else if (strstr(s, "connect://") == s)
|
||||
else if ((addr = GetURLAddress(s, CONNECT_SCHEME)))
|
||||
{
|
||||
return ConnectTCP(s + strlen("connect://"), error_ptr);
|
||||
return ConnectTCP(addr, error_ptr);
|
||||
}
|
||||
else if (strstr(s, "tcp-connect://") == s)
|
||||
else if ((addr = GetURLAddress(s, TCP_CONNECT_SCHEME)))
|
||||
{
|
||||
return ConnectTCP(s + strlen("tcp-connect://"), error_ptr);
|
||||
return ConnectTCP(addr, error_ptr);
|
||||
}
|
||||
else if (strstr(s, "udp://") == s)
|
||||
else if ((addr = GetURLAddress(s, UDP_SCHEME)))
|
||||
{
|
||||
return ConnectUDP(s + strlen("udp://"), error_ptr);
|
||||
return ConnectUDP(addr, error_ptr);
|
||||
}
|
||||
else if (strstr(s, "unix-connect://") == s)
|
||||
else if ((addr = GetURLAddress(s, UNIX_CONNECT_SCHEME)))
|
||||
{
|
||||
// unix-connect://SOCKNAME
|
||||
return NamedSocketConnect(s + strlen("unix-connect://"), error_ptr);
|
||||
return NamedSocketConnect(addr, error_ptr);
|
||||
}
|
||||
else if (strstr(s, "unix-abstract-connect://") == s)
|
||||
else if ((addr = GetURLAddress(s, UNIX_ABSTRACT_CONNECT_SCHEME)))
|
||||
{
|
||||
// unix-abstract-connect://SOCKNAME
|
||||
return UnixAbstractSocketConnect(s + strlen("unix-abstract-connect://"), error_ptr);
|
||||
return UnixAbstractSocketConnect(addr, error_ptr);
|
||||
}
|
||||
#ifndef LLDB_DISABLE_POSIX
|
||||
else if (strstr(s, "fd://") == s)
|
||||
else if ((addr = GetURLAddress(s, FD_SCHEME)))
|
||||
{
|
||||
// Just passing a native file descriptor within this current process
|
||||
// that is already opened (possibly from a service or other source).
|
||||
s += strlen("fd://");
|
||||
bool success = false;
|
||||
int fd = StringConvert::ToSInt32(s, -1, 0, &success);
|
||||
int fd = StringConvert::ToSInt32(addr, -1, 0, &success);
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
@ -244,21 +269,21 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr)
|
|||
m_read_sp.reset(new File(fd, false));
|
||||
m_write_sp.reset(new File(fd, false));
|
||||
}
|
||||
m_uri.assign(s);
|
||||
m_uri.assign(addr);
|
||||
return eConnectionStatusSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
if (error_ptr)
|
||||
error_ptr->SetErrorStringWithFormat("invalid file descriptor: \"fd://%s\"", s);
|
||||
error_ptr->SetErrorStringWithFormat("invalid file descriptor: \"%s\"", s);
|
||||
m_read_sp.reset();
|
||||
m_write_sp.reset();
|
||||
return eConnectionStatusError;
|
||||
}
|
||||
else if (strstr(s, "file://") == s)
|
||||
else if ((addr = GetURLAddress(s, FILE_SCHEME)))
|
||||
{
|
||||
// file:///PATH
|
||||
const char *path = s + strlen("file://");
|
||||
const char *path = addr;
|
||||
int fd = -1;
|
||||
do
|
||||
{
|
||||
|
|
|
@ -50,6 +50,9 @@ const size_t kMaxPushData = 2*1024;
|
|||
// 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 @@ AdbClient::SetPortForwarding (const uint16_t local_port, const uint16_t remote_p
|
|||
}
|
||||
|
||||
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 ())
|
||||
|
|
|
@ -33,6 +33,12 @@ namespace platform_android {
|
|||
class AdbClient
|
||||
{
|
||||
public:
|
||||
enum UnixSocketNamespace
|
||||
{
|
||||
UnixSocketNamespaceAbstract,
|
||||
UnixSocketNamespaceFileSystem,
|
||||
};
|
||||
|
||||
using DeviceIDList = std::list<std::string>;
|
||||
|
||||
static Error
|
||||
|
@ -51,7 +57,9 @@ public:
|
|||
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);
|
||||
|
|
|
@ -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 @@ static Error
|
|||
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 @@ ForwardPortWithAdb (const uint16_t local_port,
|
|||
|
||||
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 @@ PlatformAndroidRemoteGDBServer::ConnectRemote (Args& args)
|
|||
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 @@ PlatformAndroidRemoteGDBServer::MakeConnectURL(const lldb::pid_t pid,
|
|||
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;
|
||||
|
|
|
@ -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 @@ public:
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue