diff options
author | Andrew Burgess <aburgess@redhat.com> | 2024-05-21 15:58:02 +0100 |
---|---|---|
committer | Andrew Burgess <aburgess@redhat.com> | 2024-07-18 13:24:20 +0100 |
commit | 3055e3d2f13bb84db90b9c19d427c362053775d2 (patch) | |
tree | 7c79e60f89f0ca5c7f5ee6adcfb5b7dd2f1a75d7 /gdb/remote.c | |
parent | 08a115cc1c45cd74f0e8993d1487528547c84509 (diff) | |
download | gdb-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/remote.c')
-rw-r--r-- | gdb/remote.c | 83 |
1 files changed, 72 insertions, 11 deletions
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); |