Add support for 'info proc files' on FreeBSD core dumps.
authorJohn Baldwin <jhb@FreeBSD.org>
Tue, 18 Sep 2018 21:05:47 +0000 (14:05 -0700)
committerJohn Baldwin <jhb@FreeBSD.org>
Tue, 18 Sep 2018 21:05:47 +0000 (14:05 -0700)
Walk the list of struct kinfo_file objects in the
NT_FREEBSD_PROCSTAT_FILES core dump note outputting a description of
each open file descriptor.  For sockets, the local and remote socket
addresses are displayed in place of the file name field.  For UNIX
local domain sockets, only a single address is displayed since most
UNIX sockets only have one valid address and printing both pathnames
could be quite long.  The output format was somewhat inspired by the
output of the "procstat -f" command on FreeBSD, but with a few less
details and some fields were condensed.

gdb/ChangeLog:

* fbsd-tdep.c (KF_FLAGS, KF_OFFSET, KF_VNODE_TYPE, KF_SOCK_DOMAIN)
(KF_SOCK_TYPE, KF_SOCK_PROTOCOL, KF_SA_LOCAL, KF_SA_PEER)
(KINFO_FILE_TYPE_SOCKET, KINFO_FILE_TYPE_PIPE)
(KINFO_FILE_TYPE_FIFO, KINFO_FILE_TYPE_KQUEUE)
(KINFO_FILE_TYPE_CRYPTO, KINFO_FILE_TYPE_MQUEUE)
(KINFO_FILE_TYPE_SHM, KINFO_FILE_TYPE_SEM, KINFO_FILE_TYPE_PTS)
(KINFO_FILE_TYPE_PROCDESC, KINFO_FILE_FD_TYPE_ROOT)
(KINFO_FILE_FD_TYPE_JAIL, KINFO_FILE_FD_TYPE_TRACE)
(KINFO_FILE_FD_TYPE_CTTY, KINFO_FILE_FLAG_READ)
(KINFO_FILE_FLAG_WRITE, KINFO_FILE_FLAG_APPEND)
(KINFO_FILE_FLAG_ASYNC, KINFO_FILE_FLAG_FSYNC)
(KINFO_FILE_FLAG_NONBLOCK, KINFO_FILE_FLAG_DIRECT)
(KINFO_FILE_FLAG_HASLOCK, KINFO_FILE_FLAG_EXEC)
(KINFO_FILE_VTYPE_VREG, KINFO_FILE_VTYPE_VDIR)
(KINFO_FILE_VTYPE_VCHR, KINFO_FILE_VTYPE_VLNK)
(KINFO_FILE_VTYPE_VSOCK, KINFO_FILE_VTYPE_VFIFO, FBSD_AF_UNIX)
(FBSD_AF_INET, FBSD_AF_INET6, FBSD_SOCK_STREAM, FBSD_SOCK_DGRAM)
(FBSD_SOCK_SEQPACKET, FBSD_IPPROTO_ICMP, FBSD_IPPROTO_TCP)
(FBSD_IPPROTO_UDP, FBSD_IPPROTO_SCTP): New defines.
(struct fbsd_sockaddr_in, struct fbsd_sockaddr_in6)
(struct fbsd_sockaddr_un): New types.
(fbsd_file_fd, fbsd_file_type, fbsd_file_flags, fbsd_ipproto)
(fbsd_print_sockaddr_in, fbsd_print_sockaddr_in6)
(fbsd_info_proc_files_header, fbsd_info_proc_files_entry)
(fbsd_core_info_proc_files): New functions.
(fbsd_core_info_proc): List open file descriptors for IP_FILES and
IP_ALL.
* fbsd-tdep.h (fbsd_info_proc_files_header)
(fbsd_info_proc_files_entry): New.

gdb/ChangeLog
gdb/fbsd-tdep.c
gdb/fbsd-tdep.h

index a5ce64fdb5a75e72e24b485e81b46b2d5e2c0fec..7cd17a5dab84528871d46ae227e97c925c7b3b8a 100644 (file)
@@ -1,3 +1,35 @@
+2018-09-18  John Baldwin  <jhb@FreeBSD.org>
+
+       * fbsd-tdep.c (KF_FLAGS, KF_OFFSET, KF_VNODE_TYPE, KF_SOCK_DOMAIN)
+       (KF_SOCK_TYPE, KF_SOCK_PROTOCOL, KF_SA_LOCAL, KF_SA_PEER)
+       (KINFO_FILE_TYPE_SOCKET, KINFO_FILE_TYPE_PIPE)
+       (KINFO_FILE_TYPE_FIFO, KINFO_FILE_TYPE_KQUEUE)
+       (KINFO_FILE_TYPE_CRYPTO, KINFO_FILE_TYPE_MQUEUE)
+       (KINFO_FILE_TYPE_SHM, KINFO_FILE_TYPE_SEM, KINFO_FILE_TYPE_PTS)
+       (KINFO_FILE_TYPE_PROCDESC, KINFO_FILE_FD_TYPE_ROOT)
+       (KINFO_FILE_FD_TYPE_JAIL, KINFO_FILE_FD_TYPE_TRACE)
+       (KINFO_FILE_FD_TYPE_CTTY, KINFO_FILE_FLAG_READ)
+       (KINFO_FILE_FLAG_WRITE, KINFO_FILE_FLAG_APPEND)
+       (KINFO_FILE_FLAG_ASYNC, KINFO_FILE_FLAG_FSYNC)
+       (KINFO_FILE_FLAG_NONBLOCK, KINFO_FILE_FLAG_DIRECT)
+       (KINFO_FILE_FLAG_HASLOCK, KINFO_FILE_FLAG_EXEC)
+       (KINFO_FILE_VTYPE_VREG, KINFO_FILE_VTYPE_VDIR)
+       (KINFO_FILE_VTYPE_VCHR, KINFO_FILE_VTYPE_VLNK)
+       (KINFO_FILE_VTYPE_VSOCK, KINFO_FILE_VTYPE_VFIFO, FBSD_AF_UNIX)
+       (FBSD_AF_INET, FBSD_AF_INET6, FBSD_SOCK_STREAM, FBSD_SOCK_DGRAM)
+       (FBSD_SOCK_SEQPACKET, FBSD_IPPROTO_ICMP, FBSD_IPPROTO_TCP)
+       (FBSD_IPPROTO_UDP, FBSD_IPPROTO_SCTP): New defines.
+       (struct fbsd_sockaddr_in, struct fbsd_sockaddr_in6)
+       (struct fbsd_sockaddr_un): New types.
+       (fbsd_file_fd, fbsd_file_type, fbsd_file_flags, fbsd_ipproto)
+       (fbsd_print_sockaddr_in, fbsd_print_sockaddr_in6)
+       (fbsd_info_proc_files_header, fbsd_info_proc_files_entry)
+       (fbsd_core_info_proc_files): New functions.
+       (fbsd_core_info_proc): List open file descriptors for IP_FILES and
+       IP_ALL.
+       * fbsd-tdep.h (fbsd_info_proc_files_header)
+       (fbsd_info_proc_files_entry): New.
+
 2018-09-18  John Baldwin  <jhb@FreeBSD.org>
 
        * defs.h (enum info_proc_what) [IP_FILES]: New value.
index 48544b5370f3a4bad723c2bc677aa6f88c328950..d4ffc71ae583f343b2b450a8807f87dda2a17edb 100644 (file)
@@ -25,6 +25,8 @@
 #include "regset.h"
 #include "gdbthread.h"
 #include "xml-syscall.h"
+#include <sys/socket.h>
+#include <arpa/inet.h>
 
 #include "elf-bfd.h"
 #include "fbsd-tdep.h"
 /* Offsets in data structure used in NT_FREEBSD_PROCSTAT_VMMAP core
    dump notes.  See <sys/user.h> for the definition of struct
    kinfo_vmentry.  This data structure should have the same layout on
-   all architectures.  */
+   all architectures.
+
+   Note that FreeBSD 7.0 used an older version of this structure
+   (struct kinfo_ovmentry), but the NT_FREEBSD_PROCSTAT_VMMAP core
+   dump note wasn't introduced until FreeBSD 9.2.  As a result, the
+   core dump note has always used the 7.1 and later structure
+   format.  */
 
 #define        KVE_STRUCTSIZE          0x0
 #define        KVE_START               0x8
 /* Offsets in data structure used in NT_FREEBSD_PROCSTAT_FILES core
    dump notes.  See <sys/user.h> for the definition of struct
    kinfo_file.  This data structure should have the same layout on all
-   architectures.  */
+   architectures.
+
+   Note that FreeBSD 7.0 used an older version of this structure
+   (struct kinfo_ofile), but the NT_FREEBSD_PROCSTAT_FILES core dump
+   note wasn't introduced until FreeBSD 9.2.  As a result, the core
+   dump note has always used the 7.1 and later structure format.  */
 
 #define        KF_STRUCTSIZE           0x0
 #define        KF_TYPE                 0x4
 #define        KF_FD                   0x8
+#define        KF_FLAGS                0x10
+#define        KF_OFFSET               0x18
+#define        KF_VNODE_TYPE           0x20
+#define        KF_SOCK_DOMAIN          0x24
+#define        KF_SOCK_TYPE            0x28
+#define        KF_SOCK_PROTOCOL        0x2c
+#define        KF_SA_LOCAL             0x30
+#define        KF_SA_PEER              0xb0
 #define        KF_PATH                 0x170
 
 /* Constants for the 'kf_type' field in struct kinfo_file.  These
    match the KF_TYPE_* constants in <sys/user.h>.  */
 
 #define        KINFO_FILE_TYPE_VNODE   1
+#define        KINFO_FILE_TYPE_SOCKET  2
+#define        KINFO_FILE_TYPE_PIPE    3
+#define        KINFO_FILE_TYPE_FIFO    4
+#define        KINFO_FILE_TYPE_KQUEUE  5
+#define        KINFO_FILE_TYPE_CRYPTO  6
+#define        KINFO_FILE_TYPE_MQUEUE  7
+#define        KINFO_FILE_TYPE_SHM     8
+#define        KINFO_FILE_TYPE_SEM     9
+#define        KINFO_FILE_TYPE_PTS     10
+#define        KINFO_FILE_TYPE_PROCDESC 11
 
 /* Special values for the 'kf_fd' field in struct kinfo_file.  These
    match the KF_FD_TYPE_* constants in <sys/user.h>.  */
 
 #define        KINFO_FILE_FD_TYPE_CWD  -1
+#define        KINFO_FILE_FD_TYPE_ROOT -2
+#define        KINFO_FILE_FD_TYPE_JAIL -3
+#define        KINFO_FILE_FD_TYPE_TRACE -4
 #define        KINFO_FILE_FD_TYPE_TEXT -5
+#define        KINFO_FILE_FD_TYPE_CTTY -6
+
+/* Flags in the 'kf_flags' field in struct kinfo_file.  These match
+   the KF_FLAG_* constants in <sys/user.h>.  */
+
+#define        KINFO_FILE_FLAG_READ            0x00000001
+#define        KINFO_FILE_FLAG_WRITE           0x00000002
+#define        KINFO_FILE_FLAG_APPEND          0x00000004
+#define        KINFO_FILE_FLAG_ASYNC           0x00000008
+#define        KINFO_FILE_FLAG_FSYNC           0x00000010
+#define        KINFO_FILE_FLAG_NONBLOCK        0x00000020
+#define        KINFO_FILE_FLAG_DIRECT          0x00000040
+#define        KINFO_FILE_FLAG_HASLOCK         0x00000080
+#define        KINFO_FILE_FLAG_EXEC            0x00004000
+
+/* Constants for the 'kf_vnode_type' field in struct kinfo_file.
+   These match the KF_VTYPE_* constants in <sys/user.h>.  */
+
+#define        KINFO_FILE_VTYPE_VREG   1
+#define        KINFO_FILE_VTYPE_VDIR   2
+#define        KINFO_FILE_VTYPE_VCHR   4
+#define        KINFO_FILE_VTYPE_VLNK   5
+#define        KINFO_FILE_VTYPE_VSOCK  6
+#define        KINFO_FILE_VTYPE_VFIFO  7
+
+/* Constants for socket address families.  These match AF_* constants
+   in <sys/socket.h>.  */
+
+#define        FBSD_AF_UNIX            1
+#define        FBSD_AF_INET            2
+#define        FBSD_AF_INET6           28
+
+/* Constants for socket types.  These match SOCK_* constants in
+   <sys/socket.h>.  */
+
+#define        FBSD_SOCK_STREAM        1
+#define        FBSD_SOCK_DGRAM         2
+#define        FBSD_SOCK_SEQPACKET     5
+
+/* Constants for IP protocols.  These match IPPROTO_* constants in
+   <netinet/in.h>.  */
+
+#define        FBSD_IPPROTO_ICMP       1
+#define        FBSD_IPPROTO_TCP        6
+#define        FBSD_IPPROTO_UDP        17
+#define        FBSD_IPPROTO_SCTP       132
+
+/* Socket address structures.  These have the same layout on all
+   FreeBSD architectures.  In addition, multibyte fields such as IP
+   addresses are always stored in network byte order.  */
+
+struct fbsd_sockaddr_in
+{
+  uint8_t sin_len;
+  uint8_t sin_family;
+  uint8_t sin_port[2];
+  uint8_t sin_addr[4];
+  char sin_zero[8];
+};
+
+struct fbsd_sockaddr_in6
+{
+  uint8_t sin6_len;
+  uint8_t sin6_family;
+  uint8_t sin6_port[2];
+  uint32_t sin6_flowinfo;
+  uint8_t sin6_addr[16];
+  uint32_t sin6_scope_id;
+};
+
+struct fbsd_sockaddr_un
+{
+  uint8_t sun_len;
+  uint8_t sun_family;
+  char sun_path[104];
+};
 
 /* Number of 32-bit words in a signal set.  This matches _SIG_WORDS in
    <sys/_sigset.h> and is the same value on all architectures.  */
@@ -645,6 +755,295 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
   return note_data;
 }
 
+/* Helper function to generate the file descriptor description for a
+   single open file in 'info proc files'.  */
+
+static const char *
+fbsd_file_fd (int kf_fd)
+{
+  switch (kf_fd)
+    {
+    case KINFO_FILE_FD_TYPE_CWD:
+      return "cwd";
+    case KINFO_FILE_FD_TYPE_ROOT:
+      return "root";
+    case KINFO_FILE_FD_TYPE_JAIL:
+      return "jail";
+    case KINFO_FILE_FD_TYPE_TRACE:
+      return "trace";
+    case KINFO_FILE_FD_TYPE_TEXT:
+      return "text";
+    case KINFO_FILE_FD_TYPE_CTTY:
+      return "ctty";
+    default:
+      return int_string (kf_fd, 10, 1, 0, 0);
+    }
+}
+
+/* Helper function to generate the file type for a single open file in
+   'info proc files'.  */
+
+static const char *
+fbsd_file_type (int kf_type, int kf_vnode_type)
+{
+  switch (kf_type)
+    {
+    case KINFO_FILE_TYPE_VNODE:
+      switch (kf_vnode_type)
+       {
+       case KINFO_FILE_VTYPE_VREG:
+         return "file";
+       case KINFO_FILE_VTYPE_VDIR:
+         return "dir";
+       case KINFO_FILE_VTYPE_VCHR:
+         return "chr";
+       case KINFO_FILE_VTYPE_VLNK:
+         return "link";
+       case KINFO_FILE_VTYPE_VSOCK:
+         return "socket";
+       case KINFO_FILE_VTYPE_VFIFO:
+         return "fifo";
+       default:
+         {
+           char *str = get_print_cell ();
+
+           xsnprintf (str, PRINT_CELL_SIZE, "vn:%d", kf_vnode_type);
+           return str;
+         }
+       }
+    case KINFO_FILE_TYPE_SOCKET:
+      return "socket";
+    case KINFO_FILE_TYPE_PIPE:
+      return "pipe";
+    case KINFO_FILE_TYPE_FIFO:
+      return "fifo";
+    case KINFO_FILE_TYPE_KQUEUE:
+      return "kqueue";
+    case KINFO_FILE_TYPE_CRYPTO:
+      return "crypto";
+    case KINFO_FILE_TYPE_MQUEUE:
+      return "mqueue";
+    case KINFO_FILE_TYPE_SHM:
+      return "shm";
+    case KINFO_FILE_TYPE_SEM:
+      return "sem";
+    case KINFO_FILE_TYPE_PTS:
+      return "pts";
+    case KINFO_FILE_TYPE_PROCDESC:
+      return "proc";
+    default:
+      return int_string (kf_type, 10, 1, 0, 0);
+    }
+}
+
+/* Helper function to generate the file flags for a single open file in
+   'info proc files'.  */
+
+static const char *
+fbsd_file_flags (int kf_flags)
+{
+  static char file_flags[10];
+
+  file_flags[0] = (kf_flags & KINFO_FILE_FLAG_READ) ? 'r' : '-';
+  file_flags[1] = (kf_flags & KINFO_FILE_FLAG_WRITE) ? 'w' : '-';
+  file_flags[2] = (kf_flags & KINFO_FILE_FLAG_EXEC) ? 'x' : '-';
+  file_flags[3] = (kf_flags & KINFO_FILE_FLAG_APPEND) ? 'a' : '-';
+  file_flags[4] = (kf_flags & KINFO_FILE_FLAG_ASYNC) ? 's' : '-';
+  file_flags[5] = (kf_flags & KINFO_FILE_FLAG_FSYNC) ? 'f' : '-';
+  file_flags[6] = (kf_flags & KINFO_FILE_FLAG_NONBLOCK) ? 'n' : '-';
+  file_flags[7] = (kf_flags & KINFO_FILE_FLAG_DIRECT) ? 'd' : '-';
+  file_flags[8] = (kf_flags & KINFO_FILE_FLAG_HASLOCK) ? 'l' : '-';
+  file_flags[9] = '\0';
+
+  return file_flags;
+}
+
+/* Helper function to generate the name of an IP protocol.  */
+
+static const char *
+fbsd_ipproto (int protocol)
+{
+  switch (protocol)
+    {
+    case FBSD_IPPROTO_ICMP:
+      return "icmp";
+    case FBSD_IPPROTO_TCP:
+      return "tcp";
+    case FBSD_IPPROTO_UDP:
+      return "udp";
+    case FBSD_IPPROTO_SCTP:
+      return "sctp";
+    default:
+      {
+       char *str = get_print_cell ();
+
+       xsnprintf (str, PRINT_CELL_SIZE, "ip<%d>", protocol);
+       return str;
+      }
+    }
+}
+
+/* Helper function to print out an IPv4 socket address.  */
+
+static void
+fbsd_print_sockaddr_in (const void *sockaddr)
+{
+  const struct fbsd_sockaddr_in *sin =
+    reinterpret_cast<const struct fbsd_sockaddr_in *> (sockaddr);
+  char buf[INET_ADDRSTRLEN];
+
+  if (inet_ntop(AF_INET, sin->sin_addr, buf, sizeof buf) == nullptr)
+    error (_("Failed to format IPv4 address"));
+  printf_filtered ("%s:%u", buf,
+                  (sin->sin_port[0] << 8) | sin->sin_port[1]);
+}
+
+/* Helper function to print out an IPv6 socket address.  */
+
+static void
+fbsd_print_sockaddr_in6 (const void *sockaddr)
+{
+  const struct fbsd_sockaddr_in6 *sin6 =
+    reinterpret_cast<const struct fbsd_sockaddr_in6 *> (sockaddr);
+  char buf[INET6_ADDRSTRLEN];
+
+  if (inet_ntop(AF_INET6, sin6->sin6_addr, buf, sizeof buf) == nullptr)
+    error (_("Failed to format IPv6 address"));
+  printf_filtered ("%s.%u", buf,
+                  (sin6->sin6_port[0] << 8) | sin6->sin6_port[1]);
+}
+
+/* See fbsd-tdep.h.  */
+
+void
+fbsd_info_proc_files_header ()
+{
+  printf_filtered (_("Open files:\n\n"));
+  printf_filtered ("  %6s %6s %10s %9s %s\n",
+                  "FD", "Type", "Offset", "Flags  ", "Name");
+}
+
+/* See fbsd-tdep.h.  */
+
+void
+fbsd_info_proc_files_entry (int kf_type, int kf_fd, int kf_flags,
+                           LONGEST kf_offset, int kf_vnode_type,
+                           int kf_sock_domain, int kf_sock_type,
+                           int kf_sock_protocol, const void *kf_sa_local,
+                           const void *kf_sa_peer, const void *kf_path)
+{
+  printf_filtered ("  %6s %6s %10s %8s ",
+                  fbsd_file_fd (kf_fd),
+                  fbsd_file_type (kf_type, kf_vnode_type),
+                  kf_offset > -1 ? hex_string (kf_offset) : "-",
+                  fbsd_file_flags (kf_flags));
+  if (kf_type == KINFO_FILE_TYPE_SOCKET)
+    {
+      switch (kf_sock_domain)
+       {
+       case FBSD_AF_UNIX:
+         {
+           switch (kf_sock_type)
+             {
+             case FBSD_SOCK_STREAM:
+               printf_filtered ("unix stream:");
+               break;
+             case FBSD_SOCK_DGRAM:
+               printf_filtered ("unix dgram:");
+               break;
+             case FBSD_SOCK_SEQPACKET:
+               printf_filtered ("unix seqpacket:");
+               break;
+             default:
+               printf_filtered ("unix <%d>:", kf_sock_type);
+               break;
+             }
+
+           /* For local sockets, print out the first non-nul path
+              rather than both paths.  */
+           const struct fbsd_sockaddr_un *sun
+             = reinterpret_cast<const struct fbsd_sockaddr_un *> (kf_sa_local);
+           if (sun->sun_path[0] == 0)
+             sun = reinterpret_cast<const struct fbsd_sockaddr_un *>
+               (kf_sa_peer);
+           printf_filtered ("%s", sun->sun_path);
+           break;
+         }
+       case FBSD_AF_INET:
+         printf_filtered ("%s4 ", fbsd_ipproto (kf_sock_protocol));
+         fbsd_print_sockaddr_in (kf_sa_local);
+         printf_filtered (" -> ");
+         fbsd_print_sockaddr_in (kf_sa_peer);
+         break;
+       case FBSD_AF_INET6:
+         printf_filtered ("%s6 ", fbsd_ipproto (kf_sock_protocol));
+         fbsd_print_sockaddr_in6 (kf_sa_local);
+         printf_filtered (" -> ");
+         fbsd_print_sockaddr_in6 (kf_sa_peer);
+         break;
+       }
+    }
+  else
+    printf_filtered ("%s", reinterpret_cast<const char *> (kf_path));
+  printf_filtered ("\n");
+}
+
+/* Implement "info proc files" for a corefile.  */
+
+static void
+fbsd_core_info_proc_files (struct gdbarch *gdbarch)
+{
+  asection *section
+    = bfd_get_section_by_name (core_bfd, ".note.freebsdcore.files");
+  if (section == NULL)
+    {
+      warning (_("unable to find open files in core file"));
+      return;
+    }
+
+  size_t note_size = bfd_get_section_size (section);
+  if (note_size < 4)
+    error (_("malformed core note - too short for header"));
+
+  gdb::def_vector<unsigned char> contents (note_size);
+  if (!bfd_get_section_contents (core_bfd, section, contents.data (),
+                                0, note_size))
+    error (_("could not get core note contents"));
+
+  unsigned char *descdata = contents.data ();
+  unsigned char *descend = descdata + note_size;
+
+  /* Skip over the structure size.  */
+  descdata += 4;
+
+  fbsd_info_proc_files_header ();
+
+  while (descdata + KF_PATH < descend)
+    {
+      ULONGEST structsize = bfd_get_32 (core_bfd, descdata + KF_STRUCTSIZE);
+      if (structsize < KF_PATH)
+       error (_("malformed core note - file structure too small"));
+
+      LONGEST type = bfd_get_signed_32 (core_bfd, descdata + KF_TYPE);
+      LONGEST fd = bfd_get_signed_32 (core_bfd, descdata + KF_FD);
+      LONGEST flags = bfd_get_signed_32 (core_bfd, descdata + KF_FLAGS);
+      LONGEST offset = bfd_get_signed_64 (core_bfd, descdata + KF_OFFSET);
+      LONGEST vnode_type = bfd_get_signed_32 (core_bfd,
+                                             descdata + KF_VNODE_TYPE);
+      LONGEST sock_domain = bfd_get_signed_32 (core_bfd,
+                                              descdata + KF_SOCK_DOMAIN);
+      LONGEST sock_type = bfd_get_signed_32 (core_bfd, descdata + KF_SOCK_TYPE);
+      LONGEST sock_protocol = bfd_get_signed_32 (core_bfd,
+                                                descdata + KF_SOCK_PROTOCOL);
+      fbsd_info_proc_files_entry (type, fd, flags, offset, vnode_type,
+                                 sock_domain, sock_type, sock_protocol,
+                                 descdata + KF_SA_LOCAL, descdata + KF_SA_PEER,
+                                 descdata + KF_PATH);
+
+      descdata += structsize;
+    }
+}
+
 /* Helper function to generate mappings flags for a single VM map
    entry in 'info proc mappings'.  */
 
@@ -995,6 +1394,7 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args,
   bool do_cmdline = false;
   bool do_cwd = false;
   bool do_exe = false;
+  bool do_files = false;
   bool do_mappings = false;
   bool do_status = false;
   int pid;
@@ -1022,10 +1422,14 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args,
     case IP_CWD:
       do_cwd = true;
       break;
+    case IP_FILES:
+      do_files = true;
+      break;
     case IP_ALL:
       do_cmdline = true;
       do_cwd = true;
       do_exe = true;
+      do_files = true;
       do_mappings = true;
       do_status = true;
       break;
@@ -1065,6 +1469,8 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args,
       else
        warning (_("unable to read executable path name"));
     }
+  if (do_files)
+    fbsd_core_info_proc_files (gdbarch);
   if (do_mappings)
     fbsd_core_info_proc_mappings (gdbarch);
   if (do_status)
index 0b293e5a256c9e487ddd5f42d88cd64eecd77da3..e0cad7deadb7bdbf81c8d86364942478e083e664 100644 (file)
 
 extern void fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
 
+/* Output the header for "info proc files".  */
+
+extern void fbsd_info_proc_files_header ();
+
+/* Output description of a single file descriptor for "info proc
+   files".  The KF_TYPE, KF_FD, KF_FLAGS, KF_OFFSET, KF_VNODE_TYPE,
+   KF_SOCK_DOMAIN, KF_SOCK_TYPE, and KF_SOCK_PROTOCOL parameters
+   should contain the value of the corresponding fields in a 'struct
+   kinfo_file'.  The KF_SA_LOCAL, KF_SA_PEER, and KF_PATH parameters
+   should contain pointers to the corresponding fields in a 'struct
+   kinfo_file'. */
+
+extern void fbsd_info_proc_files_entry (int kf_type, int kf_fd, int kf_flags,
+                                       LONGEST kf_offset, int kf_vnode_type,
+                                       int kf_sock_domain, int kf_sock_type,
+                                       int kf_sock_protocol,
+                                       const void *kf_sa_local,
+                                       const void *kf_sa_peer,
+                                       const void *kf_path);
+
 /* Helper function to generate mappings flags for a single VM map
    entry in 'info proc mappings'.  The KVE_FLAGS and KVE_PROTECTION
    parameters should contain the values of the corresponding fields in