diff options
author | Michał Górny <mgorny@moritz.systems> | 2021-08-10 18:36:11 +0200 |
---|---|---|
committer | Michał Górny <mgorny@moritz.systems> | 2021-09-10 11:09:35 +0200 |
commit | 9e886fbb18b525c080c04f4a12bd481c9aa849c0 (patch) | |
tree | 02b46f75c3959a188e7f099d485118d70d6fb31c /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp | |
parent | 21e2d7ce43c42df5d60a2805c801b8f1eda7919c (diff) | |
download | llvm-9e886fbb18b525c080c04f4a12bd481c9aa849c0.zip llvm-9e886fbb18b525c080c04f4a12bd481c9aa849c0.tar.gz llvm-9e886fbb18b525c080c04f4a12bd481c9aa849c0.tar.bz2 |
[lldb] [gdb-server] Implement the vFile:fstat packet
Differential Revision: https://reviews.llvm.org/D107840
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index 9627fb1..21700f5 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -157,6 +157,9 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon( StringExtractorGDBRemote::eServerPacketType_vFile_size, &GDBRemoteCommunicationServerCommon::Handle_vFile_Size); RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_vFile_fstat, + &GDBRemoteCommunicationServerCommon::Handle_vFile_FStat); + RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_vFile_stat, &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat); RegisterMemberFunctionHandler( @@ -754,6 +757,46 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell( return SendErrorResponse(24); } +template <typename T, typename U> +static void fill_clamp(T &dest, U src, typename T::value_type fallback) { + dest = src <= std::numeric_limits<typename T::value_type>::max() ? src + : fallback; +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerCommon::Handle_vFile_FStat( + StringExtractorGDBRemote &packet) { + StreamGDBRemote response; + packet.SetFilePos(::strlen("vFile:fstat:")); + int fd = packet.GetS32(-1, 16); + + struct stat file_stats; + if (::fstat(fd, &file_stats) == -1) { + const int save_errno = errno; + response.Printf("F-1,%x", save_errno); + return SendPacketNoLock(response.GetString()); + } + + GDBRemoteFStatData data; + fill_clamp(data.gdb_st_dev, file_stats.st_dev, 0); + fill_clamp(data.gdb_st_ino, file_stats.st_ino, 0); + data.gdb_st_mode = file_stats.st_mode; + fill_clamp(data.gdb_st_nlink, file_stats.st_nlink, UINT32_MAX); + fill_clamp(data.gdb_st_uid, file_stats.st_uid, 0); + fill_clamp(data.gdb_st_gid, file_stats.st_gid, 0); + fill_clamp(data.gdb_st_rdev, file_stats.st_rdev, 0); + data.gdb_st_size = file_stats.st_size; + data.gdb_st_blksize = file_stats.st_blksize; + data.gdb_st_blocks = file_stats.st_blocks; + fill_clamp(data.gdb_st_atime, file_stats.st_atime, 0); + fill_clamp(data.gdb_st_mtime, file_stats.st_mtime, 0); + fill_clamp(data.gdb_st_ctime, file_stats.st_ctime, 0); + + response.Printf("F%zx;", sizeof(data)); + response.PutEscapedBytes(&data, sizeof(data)); + return SendPacketNoLock(response.GetString()); +} + GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_vFile_Stat( StringExtractorGDBRemote &packet) { |