Fix crash when creating index from index
[binutils-gdb.git] / gdb / fbsd-tdep.c
index 170e8f5e84e2d5e99a2e3a3f205d44214e0de78b..b241e855bd6f716b36c16703ff764b1aff470599 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for FreeBSD, architecture-independent.
 
-   Copyright (C) 2002-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -75,6 +75,63 @@ enum
     FREEBSD_SIGRTMAX = 126,
   };
 
+/* Constants for values of si_code as defined in FreeBSD's
+   <sys/signal.h>.  */
+
+#define        FBSD_SI_USER            0x10001
+#define        FBSD_SI_QUEUE           0x10002
+#define        FBSD_SI_TIMER           0x10003
+#define        FBSD_SI_ASYNCIO         0x10004
+#define        FBSD_SI_MESGQ           0x10005
+#define        FBSD_SI_KERNEL          0x10006
+#define        FBSD_SI_LWP             0x10007
+
+#define        FBSD_ILL_ILLOPC         1
+#define        FBSD_ILL_ILLOPN         2
+#define        FBSD_ILL_ILLADR         3
+#define        FBSD_ILL_ILLTRP         4
+#define        FBSD_ILL_PRVOPC         5
+#define        FBSD_ILL_PRVREG         6
+#define        FBSD_ILL_COPROC         7
+#define        FBSD_ILL_BADSTK         8
+
+#define        FBSD_BUS_ADRALN         1
+#define        FBSD_BUS_ADRERR         2
+#define        FBSD_BUS_OBJERR         3
+#define        FBSD_BUS_OOMERR         100
+
+#define        FBSD_SEGV_MAPERR        1
+#define        FBSD_SEGV_ACCERR        2
+#define        FBSD_SEGV_PKUERR        100
+
+#define        FBSD_FPE_INTOVF         1
+#define        FBSD_FPE_INTDIV         2
+#define        FBSD_FPE_FLTDIV         3
+#define        FBSD_FPE_FLTOVF         4
+#define        FBSD_FPE_FLTUND         5
+#define        FBSD_FPE_FLTRES         6
+#define        FBSD_FPE_FLTINV         7
+#define        FBSD_FPE_FLTSUB         8
+
+#define        FBSD_TRAP_BRKPT         1
+#define        FBSD_TRAP_TRACE         2
+#define        FBSD_TRAP_DTRACE        3
+#define        FBSD_TRAP_CAP           4
+
+#define        FBSD_CLD_EXITED         1
+#define        FBSD_CLD_KILLED         2
+#define        FBSD_CLD_DUMPED         3
+#define        FBSD_CLD_TRAPPED        4
+#define        FBSD_CLD_STOPPED        5
+#define        FBSD_CLD_CONTINUED      6
+
+#define        FBSD_POLL_IN            1
+#define        FBSD_POLL_OUT           2
+#define        FBSD_POLL_MSG           3
+#define        FBSD_POLL_ERR           4
+#define        FBSD_POLL_PRI           5
+#define        FBSD_POLL_HUP           6
+
 /* FreeBSD kernels 12.0 and later include a copy of the
    'ptrace_lwpinfo' structure returned by the PT_LWPINFO ptrace
    operation in an ELF core note (NT_FREEBSD_PTLWPINFO) for each LWP.
@@ -453,6 +510,13 @@ struct fbsd_pspace_data
   LONGEST off_linkmap = 0;
   LONGEST off_tlsindex = 0;
   bool rtld_offsets_valid = false;
+
+  /* vDSO mapping range.  */
+  struct mem_range vdso_range {};
+
+  /* Zero if the range hasn't been searched for, > 0 if a range was
+     found, or < 0 if a range was not found.  */
+  int vdso_range_p = 0;
 };
 
 /* Per-program-space data for FreeBSD architectures.  */
@@ -554,7 +618,7 @@ fbsd_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf,
                                 LWPINFO_OFFSET + LWPINFO_PL_FLAGS, 4))
     return -1;
 
-  int pl_flags = extract_signed_integer (buf, 4, gdbarch_byte_order (gdbarch));
+  int pl_flags = extract_signed_integer (buf, gdbarch_byte_order (gdbarch));
   if (!(pl_flags & PL_FLAG_SI))
     return -1;
 
@@ -577,7 +641,7 @@ fbsd_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf,
 static int
 find_signalled_thread (struct thread_info *info, void *data)
 {
-  if (info->suspend.stop_signal != GDB_SIGNAL_0
+  if (info->stop_signal () != GDB_SIGNAL_0
       && info->ptid.pid () == inferior_ptid.pid ())
     return 1;
 
@@ -593,7 +657,7 @@ static gdb::optional<gdb::byte_vector>
 fbsd_make_note_desc (enum target_object object, uint32_t structsize)
 {
   gdb::optional<gdb::byte_vector> buf =
-    target_read_alloc (current_top_target (), object, NULL);
+    target_read_alloc (current_inferior ()->top_target (), object, NULL);
   if (!buf || buf->empty ())
     return {};
 
@@ -627,9 +691,9 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
       const char *fname = lbasename (get_exec_file (0));
       std::string psargs = fname;
 
-      const char *infargs = get_inferior_args ();
-      if (infargs != NULL)
-       psargs = psargs + " " + infargs;
+      const std::string &infargs = current_inferior ()->args ();
+      if (!infargs.empty ())
+       psargs += ' ' + infargs;
 
       note_data.reset (elfcore_write_prpsinfo (obfd, note_data.release (),
                                               note_size, fname,
@@ -651,7 +715,7 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
      In case there's more than one signalled thread, prefer the
      current thread, if it is signalled.  */
   curr_thr = inferior_thread ();
-  if (curr_thr->suspend.stop_signal != GDB_SIGNAL_0)
+  if (curr_thr->stop_signal () != GDB_SIGNAL_0)
     signalled_thr = curr_thr;
   else
     {
@@ -660,7 +724,7 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
        signalled_thr = curr_thr;
     }
 
-  enum gdb_signal stop_signal = signalled_thr->suspend.stop_signal;
+  enum gdb_signal stop_signal = signalled_thr->stop_signal ();
   gcore_elf_build_thread_register_notes (gdbarch, signalled_thr, stop_signal,
                                         obfd, &note_data, note_size);
   for (thread_info *thr : current_inferior ()->non_exited_threads ())
@@ -857,8 +921,8 @@ fbsd_print_sockaddr_in (const void *sockaddr)
 
   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]);
+  gdb_printf ("%s:%u", buf,
+             (sin->sin_port[0] << 8) | sin->sin_port[1]);
 }
 
 /* Helper function to print out an IPv6 socket address.  */
@@ -872,8 +936,8 @@ fbsd_print_sockaddr_in6 (const void *sockaddr)
 
   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]);
+  gdb_printf ("%s.%u", buf,
+             (sin6->sin6_port[0] << 8) | sin6->sin6_port[1]);
 }
 
 /* See fbsd-tdep.h.  */
@@ -881,9 +945,9 @@ fbsd_print_sockaddr_in6 (const void *sockaddr)
 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");
+  gdb_printf (_("Open files:\n\n"));
+  gdb_printf ("  %6s %6s %10s %9s %s\n",
+             "FD", "Type", "Offset", "Flags  ", "Name");
 }
 
 /* See fbsd-tdep.h.  */
@@ -895,11 +959,11 @@ fbsd_info_proc_files_entry (int kf_type, int kf_fd, int kf_flags,
                            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));
+  gdb_printf ("  %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)
@@ -909,16 +973,16 @@ fbsd_info_proc_files_entry (int kf_type, int kf_fd, int kf_flags,
            switch (kf_sock_type)
              {
              case FBSD_SOCK_STREAM:
-               printf_filtered ("unix stream:");
+               gdb_printf ("unix stream:");
                break;
              case FBSD_SOCK_DGRAM:
-               printf_filtered ("unix dgram:");
+               gdb_printf ("unix dgram:");
                break;
              case FBSD_SOCK_SEQPACKET:
-               printf_filtered ("unix seqpacket:");
+               gdb_printf ("unix seqpacket:");
                break;
              default:
-               printf_filtered ("unix <%d>:", kf_sock_type);
+               gdb_printf ("unix <%d>:", kf_sock_type);
                break;
              }
 
@@ -929,26 +993,26 @@ fbsd_info_proc_files_entry (int kf_type, int kf_fd, int kf_flags,
            if (saddr_un->sun_path[0] == 0)
              saddr_un = reinterpret_cast<const struct fbsd_sockaddr_un *>
                (kf_sa_peer);
-           printf_filtered ("%s", saddr_un->sun_path);
+           gdb_printf ("%s", saddr_un->sun_path);
            break;
          }
        case FBSD_AF_INET:
-         printf_filtered ("%s4 ", fbsd_ipproto (kf_sock_protocol));
+         gdb_printf ("%s4 ", fbsd_ipproto (kf_sock_protocol));
          fbsd_print_sockaddr_in (kf_sa_local);
-         printf_filtered (" -> ");
+         gdb_printf (" -> ");
          fbsd_print_sockaddr_in (kf_sa_peer);
          break;
        case FBSD_AF_INET6:
-         printf_filtered ("%s6 ", fbsd_ipproto (kf_sock_protocol));
+         gdb_printf ("%s6 ", fbsd_ipproto (kf_sock_protocol));
          fbsd_print_sockaddr_in6 (kf_sa_local);
-         printf_filtered (" -> ");
+         gdb_printf (" -> ");
          fbsd_print_sockaddr_in6 (kf_sa_peer);
          break;
        }
     }
   else
-    printf_filtered ("%s", reinterpret_cast<const char *> (kf_path));
-  printf_filtered ("\n");
+    gdb_printf ("%s", reinterpret_cast<const char *> (kf_path));
+  gdb_printf ("\n");
 }
 
 /* Implement "info proc files" for a corefile.  */
@@ -1034,20 +1098,20 @@ fbsd_vm_map_entry_flags (int kve_flags, int kve_protection)
 void
 fbsd_info_proc_mappings_header (int addr_bit)
 {
-  printf_filtered (_("Mapped address spaces:\n\n"));
+  gdb_printf (_("Mapped address spaces:\n\n"));
   if (addr_bit == 64)
     {
-      printf_filtered ("  %18s %18s %10s %10s %9s %s\n",
-                      "Start Addr",
-                      "  End Addr",
-                      "      Size", "    Offset", "Flags  ", "File");
+      gdb_printf ("  %18s %18s %10s %10s %9s %s\n",
+                 "Start Addr",
+                 "  End Addr",
+                 "      Size", "    Offset", "Flags  ", "File");
     }
   else
     {
-      printf_filtered ("\t%10s %10s %10s %10s %9s %s\n",
-                      "Start Addr",
-                      "  End Addr",
-                      "      Size", "    Offset", "Flags  ", "File");
+      gdb_printf ("\t%10s %10s %10s %10s %9s %s\n",
+                 "Start Addr",
+                 "  End Addr",
+                 "      Size", "    Offset", "Flags  ", "File");
     }
 }
 
@@ -1061,23 +1125,23 @@ fbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start,
 {
   if (addr_bit == 64)
     {
-      printf_filtered ("  %18s %18s %10s %10s %9s %s\n",
-                      hex_string (kve_start),
-                      hex_string (kve_end),
-                      hex_string (kve_end - kve_start),
-                      hex_string (kve_offset),
-                      fbsd_vm_map_entry_flags (kve_flags, kve_protection),
-                      reinterpret_cast<const char *> (kve_path));
+      gdb_printf ("  %18s %18s %10s %10s %9s %s\n",
+                 hex_string (kve_start),
+                 hex_string (kve_end),
+                 hex_string (kve_end - kve_start),
+                 hex_string (kve_offset),
+                 fbsd_vm_map_entry_flags (kve_flags, kve_protection),
+                 reinterpret_cast<const char *> (kve_path));
     }
   else
     {
-      printf_filtered ("\t%10s %10s %10s %10s %9s %s\n",
-                      hex_string (kve_start),
-                      hex_string (kve_end),
-                      hex_string (kve_end - kve_start),
-                      hex_string (kve_offset),
-                      fbsd_vm_map_entry_flags (kve_flags, kve_protection),
-                      reinterpret_cast<const char *> (kve_path));
+      gdb_printf ("\t%10s %10s %10s %10s %9s %s\n",
+                 hex_string (kve_start),
+                 hex_string (kve_end),
+                 hex_string (kve_end - kve_start),
+                 hex_string (kve_offset),
+                 fbsd_vm_map_entry_flags (kve_flags, kve_protection),
+                 reinterpret_cast<const char *> (kve_path));
     }
 }
 
@@ -1208,11 +1272,11 @@ fbsd_core_fetch_timeval (struct gdbarch *gdbarch, unsigned char *data,
 static void
 fbsd_print_sigset (const char *descr, unsigned char *sigset)
 {
-  printf_filtered ("%s: ", descr);
+  gdb_printf ("%s: ", descr);
   for (int i = 0; i < SIG_WORDS; i++)
-    printf_filtered ("%08x ",
-                    (unsigned int) bfd_get_32 (core_bfd, sigset + i * 4));
-  printf_filtered ("\n");
+    gdb_printf ("%08x ",
+               (unsigned int) bfd_get_32 (core_bfd, sigset + i * 4));
+  gdb_printf ("\n");
 }
 
 /* Implement "info proc status" for a corefile.  */
@@ -1272,15 +1336,15 @@ fbsd_core_info_proc_status (struct gdbarch *gdbarch)
       return;
     }
 
-  printf_filtered ("Name: %.19s\n", descdata + kp->ki_comm);
-  printf_filtered ("Process ID: %s\n",
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_pid)));
-  printf_filtered ("Parent process: %s\n",
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_ppid)));
-  printf_filtered ("Process group: %s\n",
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_pgid)));
-  printf_filtered ("Session id: %s\n",
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_sid)));
+  gdb_printf ("Name: %.19s\n", descdata + kp->ki_comm);
+  gdb_printf ("Process ID: %s\n",
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_pid)));
+  gdb_printf ("Parent process: %s\n",
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_ppid)));
+  gdb_printf ("Process group: %s\n",
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_pgid)));
+  gdb_printf ("Session id: %s\n",
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_sid)));
 
   /* FreeBSD 12.0 and later store a 64-bit dev_t at 'ki_tdev'.  Older
      kernels store a 32-bit dev_t at 'ki_tdev_freebsd11'.  In older
@@ -1291,76 +1355,76 @@ fbsd_core_info_proc_status (struct gdbarch *gdbarch)
   value = bfd_get_64 (core_bfd, descdata + kp->ki_tdev);
   if (value == 0)
     value = bfd_get_32 (core_bfd, descdata + kp->ki_tdev_freebsd11);
-  printf_filtered ("TTY: %s\n", pulongest (value));
-  printf_filtered ("TTY owner process group: %s\n",
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_tpgid)));
-  printf_filtered ("User IDs (real, effective, saved): %s %s %s\n",
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_ruid)),
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_uid)),
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_svuid)));
-  printf_filtered ("Group IDs (real, effective, saved): %s %s %s\n",
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_rgid)),
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_groups)),
-                  pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_svgid)));
-  printf_filtered ("Groups: ");
+  gdb_printf ("TTY: %s\n", pulongest (value));
+  gdb_printf ("TTY owner process group: %s\n",
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_tpgid)));
+  gdb_printf ("User IDs (real, effective, saved): %s %s %s\n",
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_ruid)),
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_uid)),
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_svuid)));
+  gdb_printf ("Group IDs (real, effective, saved): %s %s %s\n",
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_rgid)),
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_groups)),
+             pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_svgid)));
+  gdb_printf ("Groups: ");
   uint16_t ngroups = bfd_get_16 (core_bfd, descdata + kp->ki_ngroups);
   for (int i = 0; i < ngroups; i++)
-    printf_filtered ("%s ",
-                    pulongest (bfd_get_32 (core_bfd,
-                                           descdata + kp->ki_groups + i * 4)));
-  printf_filtered ("\n");
+    gdb_printf ("%s ",
+               pulongest (bfd_get_32 (core_bfd,
+                                      descdata + kp->ki_groups + i * 4)));
+  gdb_printf ("\n");
   value = bfd_get (long_bit, core_bfd,
                   descdata + kp->ki_rusage + kp->ru_minflt);
-  printf_filtered ("Minor faults (no memory page): %s\n", pulongest (value));
+  gdb_printf ("Minor faults (no memory page): %s\n", pulongest (value));
   value = bfd_get (long_bit, core_bfd,
                   descdata + kp->ki_rusage_ch + kp->ru_minflt);
-  printf_filtered ("Minor faults, children: %s\n", pulongest (value));
+  gdb_printf ("Minor faults, children: %s\n", pulongest (value));
   value = bfd_get (long_bit, core_bfd,
                   descdata + kp->ki_rusage + kp->ru_majflt);
-  printf_filtered ("Major faults (memory page faults): %s\n",
-                  pulongest (value));
+  gdb_printf ("Major faults (memory page faults): %s\n",
+             pulongest (value));
   value = bfd_get (long_bit, core_bfd,
                   descdata + kp->ki_rusage_ch + kp->ru_majflt);
-  printf_filtered ("Major faults, children: %s\n", pulongest (value));
+  gdb_printf ("Major faults, children: %s\n", pulongest (value));
   fbsd_core_fetch_timeval (gdbarch,
                           descdata + kp->ki_rusage + kp->ru_utime,
                           sec, value);
-  printf_filtered ("utime: %s.%06d\n", plongest (sec), (int) value);
+  gdb_printf ("utime: %s.%06d\n", plongest (sec), (int) value);
   fbsd_core_fetch_timeval (gdbarch,
                           descdata + kp->ki_rusage + kp->ru_stime,
                           sec, value);
-  printf_filtered ("stime: %s.%06d\n", plongest (sec), (int) value);
+  gdb_printf ("stime: %s.%06d\n", plongest (sec), (int) value);
   fbsd_core_fetch_timeval (gdbarch,
                           descdata + kp->ki_rusage_ch + kp->ru_utime,
                           sec, value);
-  printf_filtered ("utime, children: %s.%06d\n", plongest (sec), (int) value);
+  gdb_printf ("utime, children: %s.%06d\n", plongest (sec), (int) value);
   fbsd_core_fetch_timeval (gdbarch,
                           descdata + kp->ki_rusage_ch + kp->ru_stime,
                           sec, value);
-  printf_filtered ("stime, children: %s.%06d\n", plongest (sec), (int) value);
-  printf_filtered ("'nice' value: %d\n",
-                  (int) bfd_get_signed_8 (core_bfd, descdata + kp->ki_nice));
+  gdb_printf ("stime, children: %s.%06d\n", plongest (sec), (int) value);
+  gdb_printf ("'nice' value: %d\n",
+             (int) bfd_get_signed_8 (core_bfd, descdata + kp->ki_nice));
   fbsd_core_fetch_timeval (gdbarch, descdata + kp->ki_start, sec, value);
-  printf_filtered ("Start time: %s.%06d\n", plongest (sec), (int) value);
-  printf_filtered ("Virtual memory size: %s kB\n",
-                  pulongest (bfd_get (addr_bit, core_bfd,
-                                      descdata + kp->ki_size) / 1024));
-  printf_filtered ("Data size: %s pages\n",
-                  pulongest (bfd_get (addr_bit, core_bfd,
-                                      descdata + kp->ki_dsize)));
-  printf_filtered ("Stack size: %s pages\n",
-                  pulongest (bfd_get (addr_bit, core_bfd,
-                                      descdata + kp->ki_ssize)));
-  printf_filtered ("Text size: %s pages\n",
-                  pulongest (bfd_get (addr_bit, core_bfd,
-                                      descdata + kp->ki_tsize)));
-  printf_filtered ("Resident set size: %s pages\n",
-                  pulongest (bfd_get (addr_bit, core_bfd,
-                                      descdata + kp->ki_rssize)));
-  printf_filtered ("Maximum RSS: %s pages\n",
-                  pulongest (bfd_get (long_bit, core_bfd,
-                                      descdata + kp->ki_rusage
-                                      + kp->ru_maxrss)));
+  gdb_printf ("Start time: %s.%06d\n", plongest (sec), (int) value);
+  gdb_printf ("Virtual memory size: %s kB\n",
+             pulongest (bfd_get (addr_bit, core_bfd,
+                                 descdata + kp->ki_size) / 1024));
+  gdb_printf ("Data size: %s pages\n",
+             pulongest (bfd_get (addr_bit, core_bfd,
+                                 descdata + kp->ki_dsize)));
+  gdb_printf ("Stack size: %s pages\n",
+             pulongest (bfd_get (addr_bit, core_bfd,
+                                 descdata + kp->ki_ssize)));
+  gdb_printf ("Text size: %s pages\n",
+             pulongest (bfd_get (addr_bit, core_bfd,
+                                 descdata + kp->ki_tsize)));
+  gdb_printf ("Resident set size: %s pages\n",
+             pulongest (bfd_get (addr_bit, core_bfd,
+                                 descdata + kp->ki_rssize)));
+  gdb_printf ("Maximum RSS: %s pages\n",
+             pulongest (bfd_get (long_bit, core_bfd,
+                                 descdata + kp->ki_rusage
+                                 + kp->ru_maxrss)));
   fbsd_print_sigset ("Ignored Signals", descdata + kp->ki_sigignore);
   fbsd_print_sigset ("Caught Signals", descdata + kp->ki_sigcatch);
 }
@@ -1419,7 +1483,7 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args,
 
   pid = bfd_core_file_pid (core_bfd);
   if (pid != 0)
-    printf_filtered (_("process %d\n"), pid);
+    gdb_printf (_("process %d\n"), pid);
 
   if (do_cmdline)
     {
@@ -1427,7 +1491,7 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args,
 
       cmdline = bfd_core_file_failing_command (core_bfd);
       if (cmdline)
-       printf_filtered ("cmdline = '%s'\n", cmdline);
+       gdb_printf ("cmdline = '%s'\n", cmdline);
       else
        warning (_("Command line unavailable"));
     }
@@ -1436,7 +1500,7 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args,
       gdb::unique_xmalloc_ptr<char> cwd =
        fbsd_core_vnode_path (gdbarch, KINFO_FILE_FD_TYPE_CWD);
       if (cwd)
-       printf_filtered ("cwd = '%s'\n", cwd.get ());
+       gdb_printf ("cwd = '%s'\n", cwd.get ());
       else
        warning (_("unable to read current working directory"));
     }
@@ -1445,7 +1509,7 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args,
       gdb::unique_xmalloc_ptr<char> exe =
        fbsd_core_vnode_path (gdbarch, KINFO_FILE_FD_TYPE_TEXT);
       if (exe)
-       printf_filtered ("exe = '%s'\n", exe.get ());
+       gdb_printf ("exe = '%s'\n", exe.get ());
       else
        warning (_("unable to read executable path name"));
     }
@@ -1508,6 +1572,8 @@ fbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
       TAG (ENVC, _("Environment count"), AUXV_FORMAT_DEC);
       TAG (ENVV, _("Environment vector"), AUXV_FORMAT_HEX);
       TAG (PS_STRINGS, _("Pointer to ps_strings"), AUXV_FORMAT_HEX);
+      TAG (FXRNG, _("Pointer to root RNG seed version"), AUXV_FORMAT_HEX);
+      TAG (KPRELOAD, _("Base address of vDSO"), AUXV_FORMAT_HEX);
     }
 
   fprint_auxv_entry (file, name, description, format, type, val);
@@ -1873,10 +1939,10 @@ fbsd_read_integer_by_name (struct gdbarch *gdbarch, const char *name)
     error (_("Unable to resolve symbol '%s'"), name);
 
   gdb_byte buf[4];
-  if (target_read_memory (BMSYMBOL_VALUE_ADDRESS (ms), buf, sizeof buf) != 0)
+  if (target_read_memory (ms.value_address (), buf, sizeof buf) != 0)
     error (_("Unable to read value of '%s'"), name);
 
-  return extract_signed_integer (buf, sizeof buf, gdbarch_byte_order (gdbarch));
+  return extract_signed_integer (buf, gdbarch_byte_order (gdbarch));
 }
 
 /* Lookup offsets of fields in the runtime linker's 'Obj_Entry'
@@ -1893,9 +1959,9 @@ fbsd_fetch_rtld_offsets (struct gdbarch *gdbarch, struct fbsd_pspace_data *data)
                                     language_c, NULL).symbol;
       if (obj_entry_sym == NULL)
        error (_("Unable to find Struct_Obj_Entry symbol"));
-      data->off_linkmap = lookup_struct_elt (SYMBOL_TYPE (obj_entry_sym),
+      data->off_linkmap = lookup_struct_elt (obj_entry_sym->type (),
                                             "linkmap", 0).offset / 8;
-      data->off_tlsindex = lookup_struct_elt (SYMBOL_TYPE (obj_entry_sym),
+      data->off_tlsindex = lookup_struct_elt (obj_entry_sym->type (),
                                              "tlsindex", 0).offset / 8;
       data->rtld_offsets_valid = true;
       return;
@@ -1947,7 +2013,7 @@ fbsd_get_tls_index (struct gdbarch *gdbarch, CORE_ADDR lm_addr)
     throw_error (TLS_GENERIC_ERROR,
                 _("Cannot find thread-local variables on this target"));
 
-  return extract_signed_integer (buf, sizeof buf, gdbarch_byte_order (gdbarch));
+  return extract_signed_integer (buf, gdbarch_byte_order (gdbarch));
 }
 
 /* See fbsd-tdep.h.  */
@@ -1982,12 +2048,328 @@ CORE_ADDR
 fbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   struct bound_minimal_symbol msym = lookup_bound_minimal_symbol ("_rtld_bind");
-  if (msym.minsym != nullptr && BMSYMBOL_VALUE_ADDRESS (msym) == pc)
+  if (msym.minsym != nullptr && msym.value_address () == pc)
     return frame_unwind_caller_pc (get_current_frame ());
 
   return 0;
 }
 
+/* Return description of signal code or nullptr.  */
+
+static const char *
+fbsd_signal_cause (enum gdb_signal siggnal, int code)
+{
+  /* Signal-independent causes.  */
+  switch (code)
+    {
+    case FBSD_SI_USER:
+      return _("Sent by kill()");
+    case FBSD_SI_QUEUE:
+      return _("Sent by sigqueue()");
+    case FBSD_SI_TIMER:
+      return _("Timer expired");
+    case FBSD_SI_ASYNCIO:
+      return _("Asynchronous I/O request completed");
+    case FBSD_SI_MESGQ:
+      return _("Message arrived on empty message queue");
+    case FBSD_SI_KERNEL:
+      return _("Sent by kernel");
+    case FBSD_SI_LWP:
+      return _("Sent by thr_kill()");
+    }
+
+  switch (siggnal)
+    {
+    case GDB_SIGNAL_ILL:
+      switch (code)
+       {
+       case FBSD_ILL_ILLOPC:
+         return _("Illegal opcode");
+       case FBSD_ILL_ILLOPN:
+         return _("Illegal operand");
+       case FBSD_ILL_ILLADR:
+         return _("Illegal addressing mode");
+       case FBSD_ILL_ILLTRP:
+         return _("Illegal trap");
+       case FBSD_ILL_PRVOPC:
+         return _("Privileged opcode");
+       case FBSD_ILL_PRVREG:
+         return _("Privileged register");
+       case FBSD_ILL_COPROC:
+         return _("Coprocessor error");
+       case FBSD_ILL_BADSTK:
+         return _("Internal stack error");
+       }
+      break;
+    case GDB_SIGNAL_BUS:
+      switch (code)
+       {
+       case FBSD_BUS_ADRALN:
+         return _("Invalid address alignment");
+       case FBSD_BUS_ADRERR:
+         return _("Address not present");
+       case FBSD_BUS_OBJERR:
+         return _("Object-specific hardware error");
+       case FBSD_BUS_OOMERR:
+         return _("Out of memory");
+       }
+      break;
+    case GDB_SIGNAL_SEGV:
+      switch (code)
+       {
+       case FBSD_SEGV_MAPERR:
+         return _("Address not mapped to object");
+       case FBSD_SEGV_ACCERR:
+         return _("Invalid permissions for mapped object");
+       case FBSD_SEGV_PKUERR:
+         return _("PKU violation");
+       }
+      break;
+    case GDB_SIGNAL_FPE:
+      switch (code)
+       {
+       case FBSD_FPE_INTOVF:
+         return _("Integer overflow");
+       case FBSD_FPE_INTDIV:
+         return _("Integer divide by zero");
+       case FBSD_FPE_FLTDIV:
+         return _("Floating point divide by zero");
+       case FBSD_FPE_FLTOVF:
+         return _("Floating point overflow");
+       case FBSD_FPE_FLTUND:
+         return _("Floating point underflow");
+       case FBSD_FPE_FLTRES:
+         return _("Floating point inexact result");
+       case FBSD_FPE_FLTINV:
+         return _("Invalid floating point operation");
+       case FBSD_FPE_FLTSUB:
+         return _("Subscript out of range");
+       }
+      break;
+    case GDB_SIGNAL_TRAP:
+      switch (code)
+       {
+       case FBSD_TRAP_BRKPT:
+         return _("Breakpoint");
+       case FBSD_TRAP_TRACE:
+         return _("Trace trap");
+       case FBSD_TRAP_DTRACE:
+         return _("DTrace-induced trap");
+       case FBSD_TRAP_CAP:
+         return _("Capability violation");
+       }
+      break;
+    case GDB_SIGNAL_CHLD:
+      switch (code)
+       {
+       case FBSD_CLD_EXITED:
+         return _("Child has exited");
+       case FBSD_CLD_KILLED:
+         return _("Child has terminated abnormally");
+       case FBSD_CLD_DUMPED:
+         return _("Child has dumped core");
+       case FBSD_CLD_TRAPPED:
+         return _("Traced child has trapped");
+       case FBSD_CLD_STOPPED:
+         return _("Child has stopped");
+       case FBSD_CLD_CONTINUED:
+         return _("Stopped child has continued");
+       }
+      break;
+    case GDB_SIGNAL_POLL:
+      switch (code)
+       {
+       case FBSD_POLL_IN:
+         return _("Data input available");
+       case FBSD_POLL_OUT:
+         return _("Output buffers available");
+       case FBSD_POLL_MSG:
+         return _("Input message available");
+       case FBSD_POLL_ERR:
+         return _("I/O error");
+       case FBSD_POLL_PRI:
+         return _("High priority input available");
+       case FBSD_POLL_HUP:
+         return _("Device disconnected");
+       }
+      break;
+    }
+
+  return nullptr;
+}
+
+/* Report additional details for a signal stop.  */
+
+static void
+fbsd_report_signal_info (struct gdbarch *gdbarch, struct ui_out *uiout,
+                        enum gdb_signal siggnal)
+{
+  LONGEST code, mqd, pid, status, timerid, uid;
+
+  try
+    {
+      code = parse_and_eval_long ("$_siginfo.si_code");
+      pid = parse_and_eval_long ("$_siginfo.si_pid");
+      uid = parse_and_eval_long ("$_siginfo.si_uid");
+      status = parse_and_eval_long ("$_siginfo.si_status");
+      timerid = parse_and_eval_long ("$_siginfo._reason._timer.si_timerid");
+      mqd = parse_and_eval_long ("$_siginfo._reason._mesgq.si_mqd");
+    }
+  catch (const gdb_exception_error &e)
+    {
+      return;
+    }
+
+  const char *meaning = fbsd_signal_cause (siggnal, code);
+  if (meaning == nullptr)
+    return;
+
+  uiout->text (".\n");
+  uiout->field_string ("sigcode-meaning", meaning);
+
+  switch (code)
+    {
+    case FBSD_SI_USER:
+    case FBSD_SI_QUEUE:
+    case FBSD_SI_LWP:
+      uiout->text (" from pid ");
+      uiout->field_string ("sending-pid", plongest (pid));
+      uiout->text (" and user ");
+      uiout->field_string ("sending-uid", plongest (uid));
+      return;
+    case FBSD_SI_TIMER:
+      uiout->text (": timerid ");
+      uiout->field_string ("timerid", plongest (timerid));
+      return;
+    case FBSD_SI_MESGQ:
+      uiout->text (": message queue ");
+      uiout->field_string ("message-queue", plongest (mqd));
+      return;
+    case FBSD_SI_ASYNCIO:
+      return;
+    }
+
+  if (siggnal == GDB_SIGNAL_CHLD)
+    {
+      uiout->text (": pid ");
+      uiout->field_string ("child-pid", plongest (pid));
+      uiout->text (", uid ");
+      uiout->field_string ("child-uid", plongest (uid));
+      if (code == FBSD_CLD_EXITED)
+       {
+         uiout->text (", exit status ");
+         uiout->field_string ("exit-status", plongest (status));
+       }
+      else
+       {
+         uiout->text (", signal ");
+         uiout->field_string ("signal", plongest (status));
+       }
+    }
+}
+
+/* Search a list of struct kinfo_vmmap entries in the ENTRIES buffer
+   of LEN bytes to find the length of the entry starting at ADDR.
+   Returns the length of the entry or zero if no entry was found.  */
+
+static ULONGEST
+fbsd_vmmap_length (struct gdbarch *gdbarch, unsigned char *entries, size_t len,
+                  CORE_ADDR addr)
+{
+      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+      unsigned char *descdata = entries;
+      unsigned char *descend = descdata + len;
+
+      /* Skip over the structure size.  */
+      descdata += 4;
+
+      while (descdata + KVE_PATH < descend)
+       {
+         ULONGEST structsize = extract_unsigned_integer (descdata
+                                                         + KVE_STRUCTSIZE, 4,
+                                                         byte_order);
+         if (structsize < KVE_PATH)
+           return false;
+
+         ULONGEST start = extract_unsigned_integer (descdata + KVE_START, 8,
+                                                    byte_order);
+         ULONGEST end = extract_unsigned_integer (descdata + KVE_END, 8,
+                                                  byte_order);
+         if (start == addr)
+           return end - start;
+
+         descdata += structsize;
+       }
+      return 0;
+}
+
+/* Helper for fbsd_vsyscall_range that does the real work of finding
+   the vDSO's address range.  */
+
+static bool
+fbsd_vdso_range (struct gdbarch *gdbarch, struct mem_range *range)
+{
+  struct target_ops *ops = current_inferior ()->top_target ();
+
+  if (target_auxv_search (ops, AT_FREEBSD_KPRELOAD, &range->start) <= 0)
+    return false;
+
+  if (!target_has_execution ())
+    {
+      /* Search for the ending address in the NT_PROCSTAT_VMMAP note. */
+      asection *section = bfd_get_section_by_name (core_bfd,
+                                                  ".note.freebsdcore.vmmap");
+      if (section == nullptr)
+       return false;
+
+      size_t note_size = bfd_section_size (section);
+      if (note_size < 4)
+       return false;
+
+      gdb::def_vector<unsigned char> contents (note_size);
+      if (!bfd_get_section_contents (core_bfd, section, contents.data (),
+                                    0, note_size))
+       return false;
+
+      range->length = fbsd_vmmap_length (gdbarch, contents.data (), note_size,
+                                        range->start);
+    }
+  else
+    {
+      /* Fetch the list of address space entries from the running target. */
+      gdb::optional<gdb::byte_vector> buf =
+       target_read_alloc (ops, TARGET_OBJECT_FREEBSD_VMMAP, nullptr);
+      if (!buf || buf->empty ())
+       return false;
+
+      range->length = fbsd_vmmap_length (gdbarch, buf->data (), buf->size (),
+                                        range->start);
+    }
+  return range->length != 0;
+}
+
+/* Return the address range of the vDSO for the current inferior.  */
+
+static int
+fbsd_vsyscall_range (struct gdbarch *gdbarch, struct mem_range *range)
+{
+  struct fbsd_pspace_data *data = get_fbsd_pspace_data (current_program_space);
+
+  if (data->vdso_range_p == 0)
+    {
+      if (fbsd_vdso_range (gdbarch, &data->vdso_range))
+       data->vdso_range_p = 1;
+      else
+       data->vdso_range_p = -1;
+    }
+
+  if (data->vdso_range_p < 0)
+    return 0;
+
+  *range = data->vdso_range;
+  return 1;
+}
+
 /* To be called from GDB_OSABI_FREEBSD handlers. */
 
 void
@@ -2002,7 +2384,9 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_get_siginfo_type (gdbarch, fbsd_get_siginfo_type);
   set_gdbarch_gdb_signal_from_target (gdbarch, fbsd_gdb_signal_from_target);
   set_gdbarch_gdb_signal_to_target (gdbarch, fbsd_gdb_signal_to_target);
+  set_gdbarch_report_signal_info (gdbarch, fbsd_report_signal_info);
   set_gdbarch_skip_solib_resolver (gdbarch, fbsd_skip_solib_resolver);
+  set_gdbarch_vsyscall_range (gdbarch, fbsd_vsyscall_range);
 
   /* `catch syscall' */
   set_xml_syscall_file_name (gdbarch, "syscalls/freebsd.xml");