summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2013-11-20 21:07:01 +0000
committerGreg Clayton <gclayton@apple.com>2013-11-20 21:07:01 +0000
commitfbb7634934d40548b650574a2f2a85ab41527674 (patch)
tree3b8bb1b8c997ecff27411cf8a16978b3ee7f9c92 /lldb/source/Plugins/Process/gdb-remote
parent884bde303126f5e923fb34e568afd0639af9504a (diff)
downloadbcm5719-llvm-fbb7634934d40548b650574a2f2a85ab41527674.tar.gz
bcm5719-llvm-fbb7634934d40548b650574a2f2a85ab41527674.zip
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. llvm-svn: 195273
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp209
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h60
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp161
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h16
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp10
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h7
6 files changed, 384 insertions, 79 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index da2299a408c..7cd77e58f52 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -989,19 +989,43 @@ GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
}
int
-GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
-{
- if (argv && argv[0])
+GDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &launch_info)
+{
+ // 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 (char const *path)
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::RunShellCommand (const char *command, //
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::RunShellCommand (const char *command, //
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::GetFileSize (const lldb_private::FileSpec& file_sp
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::GetFilePermissions(const lldb_private::FileSpec& f
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 (lldb::user_id_t fd,
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)
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 530655bab6e..7d4d9a29729 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -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);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index df036cdcc8e..77cc6408a92 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -166,6 +166,9 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
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::GetPacketAndSendResponse (uint32_t timeout_usec,
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_qLaunchGDBServer (StringExtractorGDBRemote
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_QSetWorkingDir (StringExtractorGDBRemote &p
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_QStartNoAckMode (StringExtractorGDBRemote &
}
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_vFile_Exists (StringExtractorGDBRemote &pac
}
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_qPlatform_RunCommand (StringExtractorGDBRem
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() == ',')
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 64f6f8de1a2..57c34d5c153 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -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
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index aff9c7bc977..6618b071f54 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -820,7 +820,7 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, const ProcessLaunchInfo &launch_
}
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::DoAttachToProcessWithName (const char *process_name, bool wait
}
+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::MonitorDebugserverProcess
void
ProcessGDBRemote::KillDebugserverProcess ()
{
+ m_gdb_comm.Disconnect();
if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
{
Host::Kill (m_debugserver_pid, SIGINT);
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index b18ac5b1723..35244074bab 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -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;
OpenPOWER on IntegriCloud