Implement remote_bfd_iovec_stat
authorGary Benson <gbenson@redhat.com>
Wed, 11 Mar 2015 17:53:57 +0000 (17:53 +0000)
committerGary Benson <gbenson@redhat.com>
Wed, 11 Mar 2015 17:53:57 +0000 (17:53 +0000)
This commit adds a new packet "vFile:fstat:" to the remote protocol
that can be used by to retrieve information about files that have
been previously opened using vFile:open.  vFile:fstat: support is
added to GDB, and remote_bfd_iovec_stat is implemented using it.  If
vFile:fstat: is not supported by the remote GDB creates a dummy result
by zeroing the supplied stat structure and setting its st_size field
to INT_MAX.  This mimics GDB's previous behaviour, with the exception
that GDB did not previously zero the structure so all other fields
would have been returned unchanged, which is to say very likely
populated with random values from the stack.

gdb/ChangeLog:

* remote-fileio.h (remote_fileio_to_host_stat): New declaration.
* remote-fileio.c (remote_fileio_to_host_uint): New function.
(remote_fileio_to_host_ulong): Likewise.
(remote_fileio_to_host_mode): Likewise.
(remote_fileio_to_host_time): Likewise.
(remote_fileio_to_host_stat): Likewise.
* remote.c (PACKET_vFile_fstat): New enum value.
(remote_protocol_features): Register the "vFile:fstat" feature.
(remote_hostio_fstat): New function.
(remote_bfd_iovec_stat): Use the above.
(_initialize_remote): Register new "set/show remote
hostio-fstat-packet" command.
* symfile.c (separate_debug_file_exists): Update comment.
* NEWS: Announce new vFile:fstat packet.

gdb/doc/ChangeLog:

* gdb.texinfo (Remote Configuration): Document the
"set/show remote hostio-fstat-packet" command.
(General Query Packets): Document the vFile:fstat
qSupported features.
(Host I/O Packets): Document the vFile:fstat packet.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/remote-fileio.c
gdb/remote-fileio.h
gdb/remote.c
gdb/symfile.c

index ec92c7dce07dbfe3afc03c90f713687d0ee28cce..8aa3862cc9fdd9698ad6fc9a502762cccb7cae02 100644 (file)
@@ -1,3 +1,20 @@
+2015-03-11  Gary Benson <gbenson@redhat.com>
+
+       * remote-fileio.h (remote_fileio_to_host_stat): New declaration.
+       * remote-fileio.c (remote_fileio_to_host_uint): New function.
+       (remote_fileio_to_host_ulong): Likewise.
+       (remote_fileio_to_host_mode): Likewise.
+       (remote_fileio_to_host_time): Likewise.
+       (remote_fileio_to_host_stat): Likewise.
+       * remote.c (PACKET_vFile_fstat): New enum value.
+       (remote_protocol_features): Register the "vFile:fstat" feature.
+       (remote_hostio_fstat): New function.
+       (remote_bfd_iovec_stat): Use the above.
+       (_initialize_remote): Register new "set/show remote
+       hostio-fstat-packet" command.
+       * symfile.c (separate_debug_file_exists): Update comment.
+       * NEWS: Announce new vFile:fstat packet.
+
 2015-03-11  Gary Benson <gbenson@redhat.com>
 
        * common/common-remote-fileio.h: New file.
index 49dc0e622df35a3e93e0212d60bd0747ee91c0f5..f08f9729620050b15d81fb5032b1b214f82294f7 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -73,6 +73,9 @@ hwbreak stop reason
   Indicates the target stopped for a hardware breakpoint.  This is
   required for correct non-stop mode operation.
 
+vFile:fstat:
+  Return information about files on the remote system.
+
 * The info record command now shows the recording format and the
   branch tracing configuration for the current thread when using
   the btrace record target.
index 0a1db36086493ccf78184b900fef249319b5bfc7..5efb060545cd4607528c37a9880d487d883fc04d 100644 (file)
@@ -1,3 +1,11 @@
+2015-03-11  Gary Benson <gbenson@redhat.com>
+
+       * gdb.texinfo (Remote Configuration): Document the
+       "set/show remote hostio-fstat-packet" command.
+       (General Query Packets): Document the vFile:fstat
+       qSupported features.
+       (Host I/O Packets): Document the vFile:fstat packet.
+
 2015-03-11  Andy Wingo  <wingo@igalia.com>
 
        * guile.texi (Objfiles In Guile): Document objfile-progspace.
index 4b76ce92b4d1906d214126d167e40853482dfda8..9e7164282eb396bdc23b891198c9ba0fe99c06d0 100644 (file)
@@ -19748,6 +19748,10 @@ are:
 @tab @code{vFile:readlink}
 @tab Host I/O
 
+@item @code{hostio-fstat-packet}
+@tab @code{vFile:fstat}
+@tab Host I/O
+
 @item @code{noack-packet}
 @tab @code{QStartNoAckMode}
 @tab Packet acknowledgment
@@ -36058,6 +36062,11 @@ These are the currently defined stub features and their properties:
 @tab @samp{-}
 @tab No
 
+@item @samp{vFile:fstat}
+@tab No
+@tab @samp{-}
+@tab No
+
 @end multitable
 
 These are the currently defined stub features, in more detail:
@@ -36246,6 +36255,9 @@ breakpoints.
 The remote stub reports the @samp{hwbreak} stop reason for hardware
 breakpoints.
 
+@item vFile:fstat
+The remote stub understands the @samp{vFile:fstat} packet.
+
 @end table
 
 @item qSymbol::
@@ -37407,6 +37419,17 @@ packet is used.  @samp{vFile:write} returns the number of bytes written,
 which may be shorter than the length of @var{data}, or -1 if an
 error occurred.
 
+@item vFile:fstat: @var{fd}
+Get information about the open file corresponding to @var{fd}.
+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}.
+
+This packet is not probed by default; the remote stub must request
+it, by supplying an appropriate @samp{qSupported} response
+(@pxref{qSupported}).
+
 @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.
index 0ce071416b05b8ea192b21fad895f97757b37962..3882321cdbb74c249e4ede1ba59d73ee3f5b2f6a 100644 (file)
@@ -1321,6 +1321,70 @@ remote_fileio_request (char *buf, int ctrlc_pending_p)
 
   remote_fileio_sig_exit ();
 }
+\f
+
+/* Unpack an fio_uint_t.  */
+
+static unsigned int
+remote_fileio_to_host_uint (fio_uint_t fnum)
+{
+  return extract_unsigned_integer ((gdb_byte *) fnum, 4,
+                                  BFD_ENDIAN_BIG);
+}
+
+/* Unpack an fio_ulong_t.  */
+
+static ULONGEST
+remote_fileio_to_host_ulong (fio_ulong_t fnum)
+{
+  return extract_unsigned_integer ((gdb_byte *) fnum, 8,
+                                  BFD_ENDIAN_BIG);
+}
+
+/* Unpack an fio_mode_t.  */
+
+static mode_t
+remote_fileio_to_host_mode (fio_mode_t fnum)
+{
+  return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum),
+                                    0);
+}
+
+/* Unpack an fio_time_t.  */
+
+static time_t
+remote_fileio_to_host_time (fio_time_t fnum)
+{
+  return remote_fileio_to_host_uint (fnum);
+}
+
+
+/* See remote-fileio.h.  */
+
+void
+remote_fileio_to_host_stat (struct fio_stat *fst, struct stat *st)
+{
+  memset (st, 0, sizeof (struct stat));
+
+  st->st_dev = remote_fileio_to_host_uint (fst->fst_dev);
+  st->st_ino = remote_fileio_to_host_uint (fst->fst_ino);
+  st->st_mode = remote_fileio_to_host_mode (fst->fst_mode);
+  st->st_nlink = remote_fileio_to_host_uint (fst->fst_nlink);
+  st->st_uid = remote_fileio_to_host_uint (fst->fst_uid);
+  st->st_gid = remote_fileio_to_host_uint (fst->fst_gid);
+  st->st_rdev = remote_fileio_to_host_uint (fst->fst_rdev);
+  st->st_size = remote_fileio_to_host_ulong (fst->fst_size);
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+  st->st_blksize = remote_fileio_to_host_ulong (fst->fst_blksize);
+#endif
+#if HAVE_STRUCT_STAT_ST_BLOCKS
+  st->st_blocks = remote_fileio_to_host_ulong (fst->fst_blocks);
+#endif
+  st->st_atime = remote_fileio_to_host_time (fst->fst_atime);
+  st->st_mtime = remote_fileio_to_host_time (fst->fst_mtime);
+  st->st_ctime = remote_fileio_to_host_time (fst->fst_ctime);
+}
+\f
 
 static void
 set_system_call_allowed (char *args, int from_tty)
index 8b328686d74b410b5ad40b348f0483a074966d49..d30ae6a35bc8fdf63b6548eeeca53a25d5ae9d4e 100644 (file)
@@ -38,4 +38,8 @@ extern void initialize_remote_fileio (
   struct cmd_list_element *remote_set_cmdlist,
   struct cmd_list_element *remote_show_cmdlist);
 
+/* Unpack a struct fio_stat.  */
+extern void remote_fileio_to_host_stat (struct fio_stat *fst,
+                                       struct stat *st);
+
 #endif
index 19f56a17baf8fc75d7039ad379bdfd447ed7e06b..9aaee137bed42e28b22f5e89f112315f768aa81c 100644 (file)
@@ -1258,6 +1258,7 @@ enum {
   PACKET_vFile_close,
   PACKET_vFile_unlink,
   PACKET_vFile_readlink,
+  PACKET_vFile_fstat,
   PACKET_qXfer_auxv,
   PACKET_qXfer_features,
   PACKET_qXfer_libraries,
@@ -4047,7 +4048,9 @@ static const struct protocol_feature remote_protocol_features[] = {
   { "Qbtrace-conf:bts:size", PACKET_DISABLE, remote_supported_packet,
     PACKET_Qbtrace_conf_bts_size },
   { "swbreak", PACKET_DISABLE, remote_supported_packet, PACKET_swbreak_feature },
-  { "hwbreak", PACKET_DISABLE, remote_supported_packet, PACKET_hwbreak_feature }
+  { "hwbreak", PACKET_DISABLE, remote_supported_packet, PACKET_hwbreak_feature },
+  { "vFile:fstat", PACKET_DISABLE, remote_supported_packet,
+    PACKET_vFile_fstat },
 };
 
 static char *remote_support_xml;
@@ -10064,6 +10067,68 @@ remote_hostio_readlink (struct target_ops *self,
   return ret;
 }
 
+/* Read information about the open file FD on the remote target
+   into ST.  Return 0 on success, or -1 if an error occurs (and
+   set *REMOTE_ERRNO).  */
+
+static int
+remote_hostio_fstat (struct target_ops *self,
+                    int fd, struct stat *st,
+                    int *remote_errno)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  int left = get_remote_packet_size ();
+  int attachment_len, ret;
+  char *attachment;
+  struct fio_stat fst;
+  int read_len;
+
+  if (packet_support (PACKET_vFile_fstat) != PACKET_ENABLE)
+    {
+      /* Strictly we should return -1, ENOSYS here, but when
+        "set sysroot remote:" was implemented in August 2008
+        BFD's need for a stat function was sidestepped with
+        this hack.  This was not remedied until March 2015
+        so we retain the previous behavior to avoid breaking
+        compatibility.
+
+        Note that the memset is a March 2015 addition; older
+        GDBs set st_size *and nothing else* so the structure
+        would have garbage in all other fields.  This might
+        break something but retaining the previous behavior
+        here would be just too wrong.  */
+
+      memset (st, 0, sizeof (struct stat));
+      st->st_size = INT_MAX;
+      return 0;
+    }
+
+  remote_buffer_add_string (&p, &left, "vFile:fstat:");
+
+  remote_buffer_add_int (&p, &left, fd);
+
+  ret = remote_hostio_send_command (p - rs->buf, PACKET_vFile_fstat,
+                                   remote_errno, &attachment,
+                                   &attachment_len);
+  if (ret < 0)
+    return ret;
+
+  read_len = remote_unescape_input ((gdb_byte *) attachment, attachment_len,
+                                   (gdb_byte *) &fst, sizeof (fst));
+
+  if (read_len != ret)
+    error (_("vFile:fstat returned %d, but %d bytes."), ret, 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;
+}
+
 static int
 remote_fileio_errno_to_host (int errnum)
 {
@@ -10208,9 +10273,20 @@ remote_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
 static int
 remote_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
 {
-  /* FIXME: We should probably implement remote_hostio_stat.  */
-  sb->st_size = INT_MAX;
-  return 0;
+  int fd = *(int *) stream;
+  int remote_errno;
+  int result;
+
+  result = remote_hostio_fstat (find_target_at (process_stratum),
+                               fd, sb, &remote_errno);
+
+  if (result == -1)
+    {
+      errno = remote_fileio_errno_to_host (remote_errno);
+      bfd_set_error (bfd_error_system_call);
+    }
+
+  return result;
 }
 
 int
@@ -12351,6 +12427,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_readlink],
                         "vFile:readlink", "hostio-readlink", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_fstat],
+                        "vFile:fstat", "hostio-fstat", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vAttach],
                         "vAttach", "attach", 0);
 
index c2a71eca59882a8b47016521615c7abca46a53cb..ba099d3a29bab5d2aa601aa6c003da363dd9dc95 100644 (file)
@@ -1377,11 +1377,12 @@ separate_debug_file_exists (const char *name, unsigned long crc,
 
      Some operating systems, e.g. Windows, do not provide a meaningful
      st_ino; they always set it to zero.  (Windows does provide a
-     meaningful st_dev.)  Do not indicate a duplicate library in that
-     case.  While there is no guarantee that a system that provides
-     meaningful inode numbers will never set st_ino to zero, this is
-     merely an optimization, so we do not need to worry about false
-     negatives.  */
+     meaningful st_dev.)  Files accessed from gdbservers that do not
+     support the vFile:fstat packet will also have st_ino set to zero.
+     Do not indicate a duplicate library in either case.  While there
+     is no guarantee that a system that provides meaningful inode
+     numbers will never set st_ino to zero, this is merely an
+     optimization, so we do not need to worry about false negatives.  */
 
   if (bfd_stat (abfd, &abfd_stat) == 0
       && abfd_stat.st_ino != 0
@@ -1409,9 +1410,9 @@ separate_debug_file_exists (const char *name, unsigned long crc,
     {
       unsigned long parent_crc;
 
-      /* If one (or both) the files are accessed for example the via "remote:"
-        gdbserver way it does not support the bfd_stat operation.  Verify
-        whether those two files are not the same manually.  */
+      /* If the files could not be verified as different with
+        bfd_stat then we need to calculate the parent's CRC
+        to verify whether the files are different or not.  */
 
       if (!verified_as_different)
        {