diff options
author | Greg Clayton <gclayton@apple.com> | 2013-11-20 21:07:01 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-11-20 21:07:01 +0000 |
commit | fbb7634934d40548b650574a2f2a85ab41527674 (patch) | |
tree | 3b8bb1b8c997ecff27411cf8a16978b3ee7f9c92 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp | |
parent | 884bde303126f5e923fb34e568afd0639af9504a (diff) | |
download | bcm5719-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/GDBRemoteCommunicationClient.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp | 209 |
1 files changed, 179 insertions, 30 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) |