From 3055e3d2f13bb84db90b9c19d427c362053775d2 Mon Sep 17 00:00:00 2001 From: Andrew Burgess Date: Tue, 21 May 2024 15:58:02 +0100 Subject: gdb: add GDB side target_ops::fileio_stat implementation This commit adds the GDB side of target_ops::fileio_stat. There's an implementation for inf_child_target, which just calls 'lstat', and there's an implementation for remote_target, which sends a new vFile:stat packet. The new packet is documented. There's still no users of target_fileio_stat as I have not yet added support for vFile::stat to gdbserver. If these packets are currently sent to gdbserver then they will be reported as not supported and the ENOSYS error code will be returned. Reviewed-By: Eli Zaretskii --- gdb/NEWS | 5 ++++ gdb/doc/gdb.texinfo | 11 +++++++ gdb/inf-child.c | 15 ++++++++++ gdb/inf-child.h | 2 ++ gdb/remote.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 105 insertions(+), 11 deletions(-) (limited to 'gdb') diff --git a/gdb/NEWS b/gdb/NEWS index 47677cb..b56ba9b 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -224,6 +224,11 @@ qIsAddressTagged file is about, this new packet provides a more generic way to perform such a check. +vFile:stat + Return information about files on the remote system. Like + vFile:fstat but takes a filename rather than an open file + descriptor. + *** Changes in GDB 14 * GDB now supports the AArch64 Scalable Matrix Extension 2 (SME2), which diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 86cd420..c55913c 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -24534,6 +24534,10 @@ future connections is shown. The available settings are: @tab @code{vFile:fstat} @tab Host I/O +@item @code{hostio-stat-packet} +@tab @code{vFile:stat} +@tab Host I/O + @item @code{hostio-setfs-packet} @tab @code{vFile:setfs} @tab Host I/O @@ -46326,6 +46330,13 @@ and the return value is the size of this attachment in bytes. If an error occurs the return value is -1. The format of the returned binary attachment is as described in @ref{struct stat}. +@item vFile:stat: @var{filename} +Get information about the file @var{filename} on the target. +On success the information is returned as a binary attachment +and the return value is the size of this attachment in bytes. +If an error occurs the return value is -1. The format of the +returned binary attachment is as described in @ref{struct stat}. + @item vFile:unlink: @var{filename} Delete the file at @var{filename} on the target. Return 0, or -1 if an error occurs. The @var{filename} is a string. diff --git a/gdb/inf-child.c b/gdb/inf-child.c index 1318d6b..df993b6 100644 --- a/gdb/inf-child.c +++ b/gdb/inf-child.c @@ -320,6 +320,21 @@ inf_child_target::fileio_fstat (int fd, struct stat *sb, fileio_error *target_er return ret; } +/* Implementation of to_fileio_stat. */ + +int +inf_child_target::fileio_stat (struct inferior *inf, const char *filename, + struct stat *sb, fileio_error *target_errno) +{ + int ret; + + ret = lstat (filename, sb); + if (ret == -1) + *target_errno = host_to_fileio_error (errno); + + return ret; +} + /* Implementation of to_fileio_close. */ int diff --git a/gdb/inf-child.h b/gdb/inf-child.h index 91955a6..65d42e1 100644 --- a/gdb/inf-child.h +++ b/gdb/inf-child.h @@ -81,6 +81,8 @@ public: int fileio_pread (int fd, gdb_byte *read_buf, int len, ULONGEST offset, fileio_error *target_errno) override; int fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) override; + int fileio_stat (struct inferior *inf, const char *filename, + struct stat *sb, fileio_error *target_errno) override; int fileio_close (int fd, fileio_error *target_errno) override; int fileio_unlink (struct inferior *inf, const char *filename, diff --git a/gdb/remote.c b/gdb/remote.c index a3617e8..efef594 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -248,6 +248,7 @@ enum { PACKET_vFile_unlink, PACKET_vFile_readlink, PACKET_vFile_fstat, + PACKET_vFile_stat, PACKET_qXfer_auxv, PACKET_qXfer_features, PACKET_qXfer_exec_file, @@ -1010,6 +1011,9 @@ public: int fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) override; + int fileio_stat (struct inferior *inf, const char *filename, + struct stat *sb, fileio_error *target_errno) override; + int fileio_close (int fd, fileio_error *target_errno) override; int fileio_unlink (struct inferior *inf, @@ -13048,6 +13052,41 @@ remote_target::fileio_readlink (struct inferior *inf, const char *filename, return ret; } +/* Helper function to handle ::fileio_fstat and ::fileio_stat result + processing. When this function is called the remote syscall has been + performed and we know we didn't get an error back. + + ATTACHMENT and ATTACHMENT_LEN are the attachment data extracted from the + remote syscall reply. EXPECTED_LEN is the length returned from the + fstat or stat call, this the length of the returned data (in ATTACHMENT) + once it has been decoded. The fstat/stat result (from the ATTACHMENT + data) is to be placed in ST. */ + +static int +fileio_process_fstat_and_stat_reply (const char *attachment, + int attachment_len, + int expected_len, + struct stat *st) +{ + struct fio_stat fst; + + int read_len + = remote_unescape_input ((gdb_byte *) attachment, attachment_len, + (gdb_byte *) &fst, sizeof (fst)); + + if (read_len != expected_len) + error (_("vFile:fstat returned %d, but %d bytes."), + expected_len, read_len); + + if (read_len != sizeof (fst)) + error (_("vFile:fstat returned %d bytes, but expecting %d."), + read_len, (int) sizeof (fst)); + + remote_fileio_to_host_stat (&fst, st); + + return 0; +} + /* Implementation of to_fileio_fstat. */ int @@ -13058,8 +13097,6 @@ remote_target::fileio_fstat (int fd, struct stat *st, fileio_error *remote_errno int left = get_remote_packet_size (); int attachment_len, ret; const char *attachment; - struct fio_stat fst; - int read_len; remote_buffer_add_string (&p, &left, "vFile:fstat:"); @@ -13091,19 +13128,41 @@ remote_target::fileio_fstat (int fd, struct stat *st, fileio_error *remote_errno return 0; } - read_len = remote_unescape_input ((gdb_byte *) attachment, attachment_len, - (gdb_byte *) &fst, sizeof (fst)); + return fileio_process_fstat_and_stat_reply (attachment, attachment_len, + ret, st); +} - if (read_len != ret) - error (_("vFile:fstat returned %d, but %d bytes."), ret, read_len); +/* Implementation of to_fileio_stat. */ - if (read_len != sizeof (fst)) - error (_("vFile:fstat returned %d bytes, but expecting %d."), - read_len, (int) sizeof (fst)); +int +remote_target::fileio_stat (struct inferior *inf, const char *filename, + struct stat *st, fileio_error *remote_errno) +{ + struct remote_state *rs = get_remote_state (); + char *p = rs->buf.data (); + int left = get_remote_packet_size () - 1; - remote_fileio_to_host_stat (&fst, st); + if (remote_hostio_set_filesystem (inf, remote_errno) != 0) + return {}; - return 0; + remote_buffer_add_string (&p, &left, "vFile:stat:"); + + remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename, + strlen (filename)); + + int attachment_len; + const char *attachment; + int ret = remote_hostio_send_command (p - rs->buf.data (), PACKET_vFile_stat, + remote_errno, &attachment, + &attachment_len); + + /* Unlike ::fileio_fstat, the stat fileio call was added later on, and + has none of the legacy bfd issues, so we can just return the error. */ + if (ret < 0) + return ret; + + return fileio_process_fstat_and_stat_reply (attachment, attachment_len, + ret, st); } /* Implementation of to_filesystem_is_local. */ @@ -16178,6 +16237,8 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, add_packet_config_cmd (PACKET_vFile_fstat, "vFile:fstat", "hostio-fstat", 0); + add_packet_config_cmd (PACKET_vFile_stat, "vFile:stat", "hostio-stat", 0); + add_packet_config_cmd (PACKET_vAttach, "vAttach", "attach", 0); add_packet_config_cmd (PACKET_vRun, "vRun", "run", 0); -- cgit v1.1