aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2024-05-21 15:58:02 +0100
committerAndrew Burgess <aburgess@redhat.com>2024-07-18 13:24:20 +0100
commit3055e3d2f13bb84db90b9c19d427c362053775d2 (patch)
tree7c79e60f89f0ca5c7f5ee6adcfb5b7dd2f1a75d7 /gdb
parent08a115cc1c45cd74f0e8993d1487528547c84509 (diff)
downloadgdb-3055e3d2f13bb84db90b9c19d427c362053775d2.zip
gdb-3055e3d2f13bb84db90b9c19d427c362053775d2.tar.gz
gdb-3055e3d2f13bb84db90b9c19d427c362053775d2.tar.bz2
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 <eliz@gnu.org>
Diffstat (limited to 'gdb')
-rw-r--r--gdb/NEWS5
-rw-r--r--gdb/doc/gdb.texinfo11
-rw-r--r--gdb/inf-child.c15
-rw-r--r--gdb/inf-child.h2
-rw-r--r--gdb/remote.c83
5 files changed, 105 insertions, 11 deletions
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);