]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/procfs.c
[binutils, ARM, 4/16] BF insns infrastructure with array of relocs in struct arm_it
[thirdparty/binutils-gdb.git] / gdb / procfs.c
index 51c9ae8f00de158effd0a2bc89b83272c46be5c1..020336e5ba4b3bcf320e59a6a3192dcdeb9f7ad3 100644 (file)
@@ -1,6 +1,6 @@
 /* Machine independent support for Solaris /proc (process file system) for GDB.
 
-   Copyright (C) 1999-2018 Free Software Foundation, Inc.
+   Copyright (C) 1999-2019 Free Software Foundation, Inc.
 
    Written by Michael Snyder at Cygnus Solutions.
    Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
 #include "regcache.h"
 #include "inf-child.h"
 #include "nat/fork-inferior.h"
-#include "filestuff.h"
+#include "common/filestuff.h"
 
 #define _STRUCTURED_PROC 1     /* Should be done by configure script.  */
 
 #include <sys/procfs.h>
 #include <sys/fault.h>
 #include <sys/syscall.h>
-#include "gdb_wait.h"
+#include "common/gdb_wait.h"
 #include <signal.h>
 #include <ctype.h>
 #include "gdb_bfd.h"
@@ -47,6 +47,7 @@
 #include "procfs.h"
 #include "observable.h"
 #include "common/scoped_fd.h"
+#include "common/pathstuff.h"
 
 /* This module provides the interface between GDB and the
    /proc file system, which is used on many versions of Unix
 
 /* This module defines the GDB target vector and its methods.  */
 
-static void procfs_attach (struct target_ops *, const char *, int);
-static void procfs_detach (struct target_ops *, inferior *, int);
-static void procfs_resume (struct target_ops *,
-                          ptid_t, int, enum gdb_signal);
-static void procfs_files_info (struct target_ops *);
-static void procfs_fetch_registers (struct target_ops *,
-                                   struct regcache *, int);
-static void procfs_store_registers (struct target_ops *,
-                                   struct regcache *, int);
-static void procfs_pass_signals (struct target_ops *self,
-                                int, unsigned char *);
-static void procfs_kill_inferior (struct target_ops *ops);
-static void procfs_mourn_inferior (struct target_ops *ops);
-static void procfs_create_inferior (struct target_ops *, const char *,
-                                   const std::string &, char **, int);
-static ptid_t procfs_wait (struct target_ops *,
-                          ptid_t, struct target_waitstatus *, int);
+
 static enum target_xfer_status procfs_xfer_memory (gdb_byte *,
                                                   const gdb_byte *,
                                                   ULONGEST, ULONGEST,
                                                   ULONGEST *);
-static target_xfer_partial_ftype procfs_xfer_partial;
 
-static int procfs_thread_alive (struct target_ops *ops, ptid_t);
+class procfs_target final : public inf_child_target
+{
+public:
+  void create_inferior (const char *, const std::string &,
+                       char **, int) override;
+
+  void kill () override;
+
+  void mourn_inferior () override;
+
+  void attach (const char *, int) override;
+  void detach (inferior *inf, int) override;
 
-static void procfs_update_thread_list (struct target_ops *ops);
-static const char *procfs_pid_to_str (struct target_ops *, ptid_t);
+  void resume (ptid_t, int, enum gdb_signal) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
 
-static int proc_find_memory_regions (struct target_ops *self,
-                                    find_memory_region_ftype, void *);
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
 
-static char *procfs_make_note_section (struct target_ops *self,
-                                      bfd *, int *);
+  enum target_xfer_status xfer_partial (enum target_object object,
+                                       const char *annex,
+                                       gdb_byte *readbuf,
+                                       const gdb_byte *writebuf,
+                                       ULONGEST offset, ULONGEST len,
+                                       ULONGEST *xfered_len) override;
 
-static int procfs_can_use_hw_breakpoint (struct target_ops *self,
-                                        enum bptype, int, int);
+  void pass_signals (gdb::array_view<const unsigned char>) override;
 
-static void procfs_info_proc (struct target_ops *, const char *,
-                             enum info_proc_what);
+  void files_info () override;
 
-static int procfs_stopped_by_watchpoint (struct target_ops *);
+  void update_thread_list () override;
 
-static int procfs_insert_watchpoint (struct target_ops *,
-                                    CORE_ADDR, int,
-                                    enum target_hw_bp_type,
-                                    struct expression *);
+  bool thread_alive (ptid_t ptid) override;
 
-static int procfs_remove_watchpoint (struct target_ops *,
-                                    CORE_ADDR, int,
-                                    enum target_hw_bp_type,
-                                    struct expression *);
+  std::string pid_to_str (ptid_t) override;
 
-static int procfs_region_ok_for_hw_watchpoint (struct target_ops *,
-                                              CORE_ADDR, int);
-static int procfs_stopped_data_address (struct target_ops *, CORE_ADDR *);
+  char *pid_to_exec_file (int pid) override;
 
-#if defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+  thread_control_capabilities get_thread_control_capabilities () override
+  { return tc_schedlock; }
+
+  /* find_memory_regions support method for gcore */
+  int find_memory_regions (find_memory_region_ftype func, void *data)
+    override;
+
+  char *make_corefile_notes (bfd *, int *) override;
+
+  bool info_proc (const char *, enum info_proc_what) override;
+
+#if PR_MODEL_NATIVE == PR_MODEL_LP64
+  int auxv_parse (gdb_byte **readptr,
+                 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+    override;
+#endif
+
+  bool stopped_by_watchpoint () override;
+
+  int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+                        struct expression *) override;
+
+  int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+                        struct expression *) override;
+
+  int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
+
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+  bool stopped_data_address (CORE_ADDR *) override;
+};
+
+static procfs_target the_procfs_target;
+
+#if PR_MODEL_NATIVE == PR_MODEL_LP64
 /* When GDB is built as 64-bit application on Solaris, the auxv data
    is presented in 64-bit format.  We need to provide a custom parser
    to handle that.  */
-static int
-procfs_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
-                  gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+int
+procfs_target::auxv_parse (gdb_byte **readptr,
+                          gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   gdb_byte *ptr = *readptr;
@@ -171,51 +193,6 @@ procfs_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
 }
 #endif
 
-/* Create a procfs target.  */
-
-static struct target_ops *
-procfs_target (void)
-{
-  struct target_ops *t = inf_child_target ();
-
-  t->to_create_inferior = procfs_create_inferior;
-  t->to_kill = procfs_kill_inferior;
-  t->to_mourn_inferior = procfs_mourn_inferior;
-  t->to_attach = procfs_attach;
-  t->to_detach = procfs_detach;
-  t->to_wait = procfs_wait;
-  t->to_resume = procfs_resume;
-  t->to_fetch_registers = procfs_fetch_registers;
-  t->to_store_registers = procfs_store_registers;
-  t->to_xfer_partial = procfs_xfer_partial;
-  t->to_pass_signals = procfs_pass_signals;
-  t->to_files_info = procfs_files_info;
-
-  t->to_update_thread_list = procfs_update_thread_list;
-  t->to_thread_alive = procfs_thread_alive;
-  t->to_pid_to_str = procfs_pid_to_str;
-
-  t->to_has_thread_control = tc_schedlock;
-  t->to_find_memory_regions = proc_find_memory_regions;
-  t->to_make_corefile_notes = procfs_make_note_section;
-  t->to_info_proc = procfs_info_proc;
-
-#if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
-  t->to_auxv_parse = procfs_auxv_parse;
-#endif
-
-  t->to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
-  t->to_insert_watchpoint = procfs_insert_watchpoint;
-  t->to_remove_watchpoint = procfs_remove_watchpoint;
-  t->to_region_ok_for_hw_watchpoint = procfs_region_ok_for_hw_watchpoint;
-  t->to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
-  t->to_stopped_data_address = procfs_stopped_data_address;
-
-  t->to_magic = OPS_MAGIC;
-
-  return t;
-}
-
 /* =================== END, TARGET_OPS "MODULE" =================== */
 
 /* World Unification:
@@ -257,7 +234,7 @@ enum { READ_WATCHFLAG  = WA_READ,
 #define AS_PROC_NAME_FMT     "/proc/%d/as"
 #define MAP_PROC_NAME_FMT    "/proc/%d/map"
 #define STATUS_PROC_NAME_FMT "/proc/%d/status"
-#define MAX_PROC_NAME_SIZE sizeof("/proc/99999/lwp/8096/lstatus")
+#define MAX_PROC_NAME_SIZE sizeof("/proc/999999/lwp/0123456789/lwpstatus")
 
 typedef struct procinfo {
   struct procinfo *next;
@@ -298,11 +275,9 @@ static procinfo *find_procinfo_or_die (int pid, int tid);
 static procinfo *find_procinfo (int pid, int tid);
 static procinfo *create_procinfo (int pid, int tid);
 static void destroy_procinfo (procinfo *p);
-static void do_destroy_procinfo_cleanup (void *);
 static void dead_procinfo (procinfo *p, const char *msg, int killp);
 static int open_procinfo_files (procinfo *p, int which);
 static void close_procinfo_files (procinfo *p);
-static sysset_t *sysset_t_alloc (procinfo *pi);
 
 static int iterate_over_mappings
   (procinfo *pi, find_memory_region_ftype child_func, void *data,
@@ -481,7 +456,8 @@ create_procinfo (int pid, int tid)
 {
   procinfo *pi, *parent = NULL;
 
-  if ((pi = find_procinfo (pid, tid)))
+  pi = find_procinfo (pid, tid);
+  if (pi != NULL)
     return pi;                 /* Already exists, nothing to do.  */
 
   /* Find parent before doing malloc, to save having to cleanup.  */
@@ -495,19 +471,20 @@ create_procinfo (int pid, int tid)
   pi->pid = pid;
   pi->tid = tid;
 
-  pi->saved_entryset = sysset_t_alloc (pi);
-  pi->saved_exitset = sysset_t_alloc (pi);
+  pi->saved_entryset = XNEW (sysset_t);
+  pi->saved_exitset = XNEW (sysset_t);
 
   /* Chain into list.  */
   if (tid == 0)
     {
-      sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid);
+      xsnprintf (pi->pathname, sizeof (pi->pathname), MAIN_PROC_NAME_FMT, pid);
       pi->next = procinfo_list;
       procinfo_list = pi;
     }
   else
     {
-      sprintf (pi->pathname, "/proc/%05d/lwp/%d", pid, tid);
+      xsnprintf (pi->pathname, sizeof (pi->pathname), "/proc/%d/lwp/%d",
+                pid, tid);
       pi->next = parent->thread_list;
       parent->thread_list = pi;
     }
@@ -575,11 +552,16 @@ destroy_procinfo (procinfo *pi)
     }
 }
 
-static void
-do_destroy_procinfo_cleanup (void *pi)
+/* A deleter that calls destroy_procinfo.  */
+struct procinfo_deleter
 {
-  destroy_procinfo ((procinfo *) pi);
-}
+  void operator() (procinfo *pi) const
+  {
+    destroy_procinfo (pi);
+  }
+};
+
+typedef std::unique_ptr<procinfo, procinfo_deleter> procinfo_up;
 
 enum { NOKILL, KILL };
 
@@ -593,12 +575,10 @@ dead_procinfo (procinfo *pi, const char *msg, int kill_p)
   char procfile[80];
 
   if (pi->pathname)
-    {
-      print_sys_errmsg (pi->pathname, errno);
-    }
+    print_sys_errmsg (pi->pathname, errno);
   else
     {
-      sprintf (procfile, "process %d", pi->pid);
+      xsnprintf (procfile, sizeof (procfile), "process %d", pi->pid);
       print_sys_errmsg (procfile, errno);
     }
   if (kill_p == KILL)
@@ -608,14 +588,6 @@ dead_procinfo (procinfo *pi, const char *msg, int kill_p)
   error ("%s", msg);
 }
 
-/* Allocate and (partially) initialize a sysset_t struct.  */
-
-static sysset_t *
-sysset_t_alloc (procinfo *pi)
-{
-  return (sysset_t *) xmalloc (sizeof (sysset_t));
-}
-
 /* =================== END, STRUCT PROCINFO "MODULE" =================== */
 
 /* ===================  /proc  "MODULE" =================== */
@@ -643,14 +615,16 @@ static int proc_iterate_over_threads
 static void
 proc_warn (procinfo *pi, const char *func, int line)
 {
-  sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
+  xsnprintf (errmsg, sizeof (errmsg), "procfs: %s line %d, %s",
+            func, line, pi->pathname);
   print_sys_errmsg (errmsg, errno);
 }
 
 static void
 proc_error (procinfo *pi, const char *func, int line)
 {
-  sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
+  xsnprintf (errmsg, sizeof (errmsg), "procfs: %s line %d, %s",
+            func, line, pi->pathname);
   perror_with_name (errmsg);
 }
 
@@ -664,8 +638,7 @@ static int
 proc_get_status (procinfo *pi)
 {
   /* Status file descriptor is opened "lazily".  */
-  if (pi->status_fd == 0 &&
-      open_procinfo_files (pi, FD_STATUS) == 0)
+  if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0)
     {
       pi->status_valid = 0;
       return 0;
@@ -906,8 +879,7 @@ proc_stop_process (procinfo *pi)
   /* We might conceivably apply this operation to an LWP, and the
      LWP's ctl file descriptor might not be open.  */
 
-  if (pi->ctl_fd == 0 &&
-      open_procinfo_files (pi, FD_CTL) == 0)
+  if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
     return 0;
   else
     {
@@ -937,7 +909,12 @@ proc_wait_for_stop (procinfo *pi)
 
   procfs_ctl_t cmd = PCWSTOP;
 
+  set_sigint_trap ();
+
   win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
+
+  clear_sigint_trap ();
+
   /* We been runnin' and we stopped -- need to update status.  */
   pi->status_valid = 0;
 
@@ -972,11 +949,8 @@ proc_run_process (procinfo *pi, int step, int signo)
   /* We will probably have to apply this operation to individual
      threads, so make sure the control file descriptor is open.  */
 
-  if (pi->ctl_fd == 0 &&
-      open_procinfo_files (pi, FD_CTL) == 0)
-    {
-      return 0;
-    }
+  if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
+    return 0;
 
   runflags    = PRCFAULT;      /* Always clear current fault.  */
   if (step)
@@ -1079,20 +1053,16 @@ proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset)
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
-  struct gdb_proc_ctl_pcsentry {
+  struct {
     procfs_ctl_t cmd;
     /* Use char array to avoid alignment issues.  */
     char sysset[sizeof (sysset_t)];
-  } *argp;
-  int argp_size = sizeof (struct gdb_proc_ctl_pcsentry);
-
-  argp = (struct gdb_proc_ctl_pcsentry *) xmalloc (argp_size);
+  } arg;
 
-  argp->cmd = PCSENTRY;
-  memcpy (&argp->sysset, sysset, sizeof (sysset_t));
+  arg.cmd = PCSENTRY;
+  memcpy (&arg.sysset, sysset, sizeof (sysset_t));
 
-  win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
-  xfree (argp);
+  win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
 
   /* The above operation renders the procinfo's cached pstatus
      obsolete.  */
@@ -1121,16 +1091,12 @@ proc_set_traced_sysexit (procinfo *pi, sysset_t *sysset)
     procfs_ctl_t cmd;
     /* Use char array to avoid alignment issues.  */
     char sysset[sizeof (sysset_t)];
-  } *argp;
-  int argp_size = sizeof (struct gdb_proc_ctl_pcsexit);
-
-  argp = (struct gdb_proc_ctl_pcsexit *) xmalloc (argp_size);
+  } arg;
 
-  argp->cmd = PCSEXIT;
-  memcpy (&argp->sysset, sysset, sizeof (sysset_t));
+  arg.cmd = PCSEXIT;
+  memcpy (&arg.sysset, sysset, sizeof (sysset_t));
 
-  win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
-  xfree (argp);
+  win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
 
   /* The above operation renders the procinfo's cached pstatus
      obsolete.  */
@@ -1362,7 +1328,7 @@ proc_set_current_signal (procinfo *pi, int signo)
 
   /* The pointer is just a type alias.  */
   get_last_target_status (&wait_ptid, &wait_status);
-  if (ptid_equal (wait_ptid, inferior_ptid)
+  if (wait_ptid == inferior_ptid
       && wait_status.kind == TARGET_WAITKIND_STOPPED
       && wait_status.value.sig == gdb_signal_from_host (signo)
       && proc_get_status (pi)
@@ -1465,9 +1431,7 @@ proc_set_gregs (procinfo *pi)
     return 0;                  /* proc_get_regs has already warned.  */
 
   if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
-    {
-      return 0;
-    }
+    return 0;
   else
     {
       struct {
@@ -1501,9 +1465,7 @@ proc_set_fpregs (procinfo *pi)
     return 0;                  /* proc_get_fpregs has already warned.  */
 
   if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
-    {
-      return 0;
-    }
+    return 0;
   else
     {
       struct {
@@ -1533,11 +1495,8 @@ proc_kill (procinfo *pi, int signo)
   /* We might conceivably apply this operation to an LWP, and the
      LWP's ctl file descriptor might not be open.  */
 
-  if (pi->ctl_fd == 0 &&
-      open_procinfo_files (pi, FD_CTL) == 0)
-    {
-      return 0;
-    }
+  if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
+    return 0;
   else
     {
       procfs_ctl_t cmd[2];
@@ -1615,7 +1574,7 @@ proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
    matching ssh struct (LDT entry).  */
 
 static struct ssd *
-proc_get_LDT_entry (procinfo *pi, int key)
+proc_get_LDT_entry (procinfo *pi, int key)     /* ARI: editCase function */
 {
   static struct ssd *ldt_entry = NULL;
   char pathname[MAX_PROC_NAME_SIZE];
@@ -1626,7 +1585,7 @@ proc_get_LDT_entry (procinfo *pi, int key)
     ldt_entry = XNEW (struct ssd);
 
   /* Open the file descriptor for the LDT table.  */
-  sprintf (pathname, "/proc/%d/ldt", pi->pid);
+  xsnprintf (pathname, sizeof (pathname), "/proc/%d/ldt", pi->pid);
   scoped_fd fd (open_with_retry (pathname, O_RDONLY));
   if (fd.get () < 0)
     {
@@ -1638,10 +1597,10 @@ proc_get_LDT_entry (procinfo *pi, int key)
   while (read (fd.get (), ldt_entry, sizeof (struct ssd))
         == sizeof (struct ssd))
     {
-      if (ldt_entry->sel == 0 &&
-         ldt_entry->bo  == 0 &&
-         ldt_entry->acc1 == 0 &&
-         ldt_entry->acc2 == 0)
+      if (ldt_entry->sel == 0
+         && ldt_entry->bo  == 0
+         && ldt_entry->acc1 == 0
+         && ldt_entry->acc2 == 0)
        break;  /* end of table */
       /* If key matches, return this entry.  */
       if (ldt_entry->sel == key)
@@ -1654,24 +1613,26 @@ proc_get_LDT_entry (procinfo *pi, int key)
 /* Returns the pointer to the LDT entry of PTID.  */
 
 struct ssd *
-procfs_find_LDT_entry (ptid_t ptid)
+procfs_find_LDT_entry (ptid_t ptid)    /* ARI: editCase function */
 {
   gdb_gregset_t *gregs;
   int            key;
   procinfo      *pi;
 
   /* Find procinfo for the lwp.  */
-  if ((pi = find_procinfo (ptid_get_pid (ptid), ptid_get_lwp (ptid))) == NULL)
+  pi = find_procinfo (ptid.pid (), ptid.lwp ());
+  if (pi == NULL)
     {
       warning (_("procfs_find_LDT_entry: could not find procinfo for %d:%ld."),
-              ptid_get_pid (ptid), ptid_get_lwp (ptid));
+              ptid.pid (), ptid.lwp ());
       return NULL;
     }
   /* get its general registers.  */
-  if ((gregs = proc_get_gregs (pi)) == NULL)
+  gregs = proc_get_gregs (pi);
+  if (gregs == NULL)
     {
       warning (_("procfs_find_LDT_entry: could not read gregs for %d:%ld."),
-              ptid_get_pid (ptid), ptid_get_lwp (ptid));
+              ptid.pid (), ptid.lwp ());
       return NULL;
     }
   /* Now extract the GS register's lower 16 bits.  */
@@ -1748,20 +1709,13 @@ proc_delete_dead_threads (procinfo *parent, procinfo *thread, void *ignore)
   return 0;    /* keep iterating */
 }
 
-static void
-do_closedir_cleanup (void *dir)
-{
-  closedir ((DIR *) dir);
-}
-
 static int
 proc_update_threads (procinfo *pi)
 {
   char pathname[MAX_PROC_NAME_SIZE + 16];
   struct dirent *direntry;
-  struct cleanup *old_chain = NULL;
   procinfo *thread;
-  DIR *dirp;
+  gdb_dir_up dirp;
   int lwpid;
 
   /* We should never have to apply this operation to any procinfo
@@ -1782,19 +1736,19 @@ proc_update_threads (procinfo *pi)
 
   strcpy (pathname, pi->pathname);
   strcat (pathname, "/lwp");
-  if ((dirp = opendir (pathname)) == NULL)
+  dirp.reset (opendir (pathname));
+  if (dirp == NULL)
     proc_error (pi, "update_threads, opendir", __LINE__);
 
-  old_chain = make_cleanup (do_closedir_cleanup, dirp);
-  while ((direntry = readdir (dirp)) != NULL)
+  while ((direntry = readdir (dirp.get ())) != NULL)
     if (direntry->d_name[0] != '.')            /* skip '.' and '..' */
       {
        lwpid = atoi (&direntry->d_name[0]);
-       if ((thread = create_procinfo (pi->pid, lwpid)) == NULL)
+       thread = create_procinfo (pi->pid, lwpid);
+       if (thread == NULL)
          proc_error (pi, "update_threads, create_procinfo", __LINE__);
       }
   pi->threads_valid = 1;
-  do_cleanups (old_chain);
   return 1;
 }
 
@@ -1830,7 +1784,8 @@ proc_iterate_over_threads (procinfo *pi,
   for (thread = pi->thread_list; thread != NULL; thread = next)
     {
       next = thread->next;     /* In case thread is destroyed.  */
-      if ((retval = (*func) (pi, thread, ptr)) != 0)
+      retval = (*func) (pi, thread, ptr);
+      if (retval != 0)
        break;
     }
 
@@ -1879,7 +1834,7 @@ procfs_debug_inferior (procinfo *pi)
 
 
   /* Register to trace the 'exit' system call (on entry).  */
-  traced_syscall_entries = sysset_t_alloc (pi);
+  traced_syscall_entries = XNEW (sysset_t);
   premptyset (traced_syscall_entries);
   praddset (traced_syscall_entries, SYS_exit);
   praddset (traced_syscall_entries, SYS_lwp_exit);
@@ -1895,7 +1850,7 @@ procfs_debug_inferior (procinfo *pi)
      names.  On the SGI, for example, there is no SYS_exec, but there
      *is* a SYS_execv.  So, we try to account for that.  */
 
-  traced_syscall_exits = sysset_t_alloc (pi);
+  traced_syscall_exits = XNEW (sysset_t);
   premptyset (traced_syscall_exits);
 #ifdef SYS_exec
   praddset (traced_syscall_exits, SYS_exec);
@@ -1912,8 +1867,8 @@ procfs_debug_inferior (procinfo *pi)
   return 0;
 }
 
-static void
-procfs_attach (struct target_ops *ops, const char *args, int from_tty)
+void
+procfs_target::attach (const char *args, int from_tty)
 {
   char *exec_file;
   int   pid;
@@ -1929,22 +1884,22 @@ procfs_attach (struct target_ops *ops, const char *args, int from_tty)
 
       if (exec_file)
        printf_filtered (_("Attaching to program `%s', %s\n"),
-                        exec_file, target_pid_to_str (pid_to_ptid (pid)));
+                        exec_file, target_pid_to_str (ptid_t (pid)).c_str ());
       else
        printf_filtered (_("Attaching to %s\n"),
-                        target_pid_to_str (pid_to_ptid (pid)));
+                        target_pid_to_str (ptid_t (pid)).c_str ());
 
       fflush (stdout);
     }
-  inferior_ptid = do_attach (pid_to_ptid (pid));
-  if (!target_is_pushed (ops))
-    push_target (ops);
+  inferior_ptid = do_attach (ptid_t (pid));
+  if (!target_is_pushed (this))
+    push_target (this);
 }
 
-static void
-procfs_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+procfs_target::detach (inferior *inf, int from_tty)
 {
-  int pid = ptid_get_pid (inferior_ptid);
+  int pid = inferior_ptid.pid ();
 
   if (from_tty)
     {
@@ -1955,15 +1910,14 @@ procfs_detach (struct target_ops *ops, inferior *inf, int from_tty)
        exec_file = "";
 
       printf_filtered (_("Detaching from program: %s, %s\n"), exec_file,
-                      target_pid_to_str (pid_to_ptid (pid)));
-      gdb_flush (gdb_stdout);
+                      target_pid_to_str (ptid_t (pid)).c_str ());
     }
 
   do_detach ();
 
   inferior_ptid = null_ptid;
-  detach_inferior (pid);
-  inf_child_maybe_unpush_target (ops);
+  detach_inferior (inf);
+  maybe_unpush_target ();
 }
 
 static ptid_t
@@ -1974,14 +1928,16 @@ do_attach (ptid_t ptid)
   int fail;
   int lwpid;
 
-  if ((pi = create_procinfo (ptid_get_pid (ptid), 0)) == NULL)
+  pi = create_procinfo (ptid.pid (), 0);
+  if (pi == NULL)
     perror (_("procfs: out of memory in 'attach'"));
 
   if (!open_procinfo_files (pi, FD_CTL))
     {
       fprintf_filtered (gdb_stderr, "procfs:%d -- ", __LINE__);
-      sprintf (errmsg, "do_attach: couldn't open /proc file for process %d",
-              ptid_get_pid (ptid));
+      xsnprintf (errmsg, sizeof (errmsg),
+                "do_attach: couldn't open /proc file for process %d",
+                ptid.pid ());
       dead_procinfo (pi, errmsg, NOKILL);
     }
 
@@ -2017,7 +1973,8 @@ do_attach (ptid_t ptid)
   if (!proc_get_held_signals    (pi, &pi->saved_sighold))
     dead_procinfo (pi, "do_attach: couldn't save held signals.", NOKILL);
 
-  if ((fail = procfs_debug_inferior (pi)) != 0)
+  fail = procfs_debug_inferior (pi);
+  if (fail != 0)
     dead_procinfo (pi, "do_attach: failed in procfs_debug_inferior", NOKILL);
 
   inf = current_inferior ();
@@ -2030,7 +1987,7 @@ do_attach (ptid_t ptid)
   create_procinfo (pi->pid, lwpid);
 
   /* Add it to gdb's thread list.  */
-  ptid = ptid_build (pi->pid, lwpid, 0);
+  ptid = ptid_t (pi->pid, lwpid, 0);
   add_thread (ptid);
 
   return ptid;
@@ -2042,7 +1999,7 @@ do_detach ()
   procinfo *pi;
 
   /* Find procinfo for the main process.  */
-  pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid),
+  pi = find_procinfo_or_die (inferior_ptid.pid (),
                             0); /* FIXME: threads */
 
   if (!proc_set_traced_signals (pi, &pi->saved_sigset))
@@ -2092,22 +2049,21 @@ do_detach ()
    registers.  So we cache the results, and mark the cache invalid
    when the process is resumed.  */
 
-static void
-procfs_fetch_registers (struct target_ops *ops,
-                       struct regcache *regcache, int regnum)
+void
+procfs_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   gdb_gregset_t *gregs;
   procinfo *pi;
-  ptid_t ptid = regcache_get_ptid (regcache);
-  int pid = ptid_get_pid (ptid);
-  int tid = ptid_get_lwp (ptid);
+  ptid_t ptid = regcache->ptid ();
+  int pid = ptid.pid ();
+  int tid = ptid.lwp ();
   struct gdbarch *gdbarch = regcache->arch ();
 
   pi = find_procinfo_or_die (pid, tid);
 
   if (pi == NULL)
     error (_("procfs: fetch_registers failed to find procinfo for %s"),
-          target_pid_to_str (ptid));
+          target_pid_to_str (ptid).c_str ());
 
   gregs = proc_get_gregs (pi);
   if (gregs == NULL)
@@ -2142,22 +2098,21 @@ procfs_fetch_registers (struct target_ops *ops,
    FIXME: is that a really bad idea?  Have to think about cases where
    writing one register might affect the value of others, etc.  */
 
-static void
-procfs_store_registers (struct target_ops *ops,
-                       struct regcache *regcache, int regnum)
+void
+procfs_target::store_registers (struct regcache *regcache, int regnum)
 {
   gdb_gregset_t *gregs;
   procinfo *pi;
-  ptid_t ptid = regcache_get_ptid (regcache);
-  int pid = ptid_get_pid (ptid);
-  int tid = ptid_get_lwp (ptid);
+  ptid_t ptid = regcache->ptid ();
+  int pid = ptid.pid ();
+  int tid = ptid.lwp ();
   struct gdbarch *gdbarch = regcache->arch ();
 
   pi = find_procinfo_or_die (pid, tid);
 
   if (pi == NULL)
     error (_("procfs: store_registers: failed to find procinfo for %s"),
-          target_pid_to_str (ptid));
+          target_pid_to_str (ptid).c_str ());
 
   gregs = proc_get_gregs (pi);
   if (gregs == NULL)
@@ -2228,9 +2183,9 @@ syscall_is_lwp_create (procinfo *pi, int scall)
    Returns the id of process (and possibly thread) that incurred the
    event.  Event codes are returned through a pointer parameter.  */
 
-static ptid_t
-procfs_wait (struct target_ops *ops,
-            ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+procfs_target::wait (ptid_t ptid, struct target_waitstatus *status,
+                    int options)
 {
   /* First cut: loosely based on original version 2.1.  */
   procinfo *pi;
@@ -2244,10 +2199,10 @@ wait_again:
 
   retry++;
   wstat    = 0;
-  retval   = pid_to_ptid (-1);
+  retval   = ptid_t (-1);
 
   /* Find procinfo for main process.  */
-  pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+  pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
   if (pi)
     {
       /* We must assume that the status is stale now...  */
@@ -2262,8 +2217,8 @@ wait_again:
        pi->status_valid = 0;   /* re-read again, IMMEDIATELY...  */
 #endif
       /* If child is not stopped, wait for it to stop.  */
-      if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) &&
-         !proc_wait_for_stop (pi))
+      if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
+         && !proc_wait_for_stop (pi))
        {
          /* wait_for_stop failed: has the child terminated?  */
          if (errno == ENOENT)
@@ -2271,16 +2226,16 @@ wait_again:
              int wait_retval;
 
              /* /proc file not found; presumably child has terminated.  */
-             wait_retval = wait (&wstat); /* "wait" for the child's exit.  */
+             wait_retval = ::wait (&wstat); /* "wait" for the child's exit.  */
 
              /* Wrong child?  */
-             if (wait_retval != ptid_get_pid (inferior_ptid))
+             if (wait_retval != inferior_ptid.pid ())
                error (_("procfs: couldn't stop "
                         "process %d: wait returned %d."),
-                      ptid_get_pid (inferior_ptid), wait_retval);
+                      inferior_ptid.pid (), wait_retval);
              /* FIXME: might I not just use waitpid?
                 Or try find_procinfo to see if I know about this child?  */
-             retval = pid_to_ptid (wait_retval);
+             retval = ptid_t (wait_retval);
            }
          else if (errno == EINTR)
            goto wait_again;
@@ -2319,7 +2274,7 @@ wait_again:
 
              /* The 'pid' we will return to GDB is composed of
                 the process ID plus the lwp ID.  */
-             retval = ptid_build (pi->pid, proc_get_current_thread (pi), 0);
+             retval = ptid_t (pi->pid, proc_get_current_thread (pi), 0);
 
              switch (why) {
              case PR_SIGNALLED:
@@ -2330,8 +2285,8 @@ wait_again:
                  {
                    if (print_thread_events)
                      printf_unfiltered (_("[%s exited]\n"),
-                                        target_pid_to_str (retval));
-                   delete_thread (retval);
+                                        target_pid_to_str (retval).c_str ());
+                   delete_thread (find_thread_ptid (retval));
                    status->kind = TARGET_WAITKIND_SPURIOUS;
                    return retval;
                  }
@@ -2364,7 +2319,7 @@ wait_again:
                      }
                    else
                      {
-                       int temp = wait (&wstat);
+                       int temp = ::wait (&wstat);
 
                        /* FIXME: shouldn't I make sure I get the right
                           event from the right process?  If (for
@@ -2376,7 +2331,7 @@ wait_again:
                        /* If wait returns -1, that's what we return
                           to GDB.  */
                        if (temp < 0)
-                         retval = pid_to_ptid (temp);
+                         retval = ptid_t (temp);
                      }
                  }
                else
@@ -2387,8 +2342,10 @@ wait_again:
 
                    long i, nsysargs, *sysargs;
 
-                   if ((nsysargs = proc_nsysarg (pi)) > 0 &&
-                       (sysargs  = proc_sysargs (pi)) != NULL)
+                   nsysargs = proc_nsysarg (pi);
+                   sysargs  = proc_sysargs (pi);
+
+                   if (nsysargs > 0 && sysargs != NULL)
                      {
                        printf_filtered (_("%ld syscall arguments:\n"),
                                         nsysargs);
@@ -2436,7 +2393,7 @@ wait_again:
                    if (!find_procinfo (pi->pid, temp_tid))
                      create_procinfo  (pi->pid, temp_tid);
 
-                   temp_ptid = ptid_build (pi->pid, temp_tid, 0);
+                   temp_ptid = ptid_t (pi->pid, temp_tid, 0);
                    /* If not in GDB's thread list, add it.  */
                    if (!in_thread_list (temp_ptid))
                      add_thread (temp_ptid);
@@ -2449,8 +2406,8 @@ wait_again:
                  {
                    if (print_thread_events)
                      printf_unfiltered (_("[%s exited]\n"),
-                                        target_pid_to_str (retval));
-                   delete_thread (retval);
+                                        target_pid_to_str (retval).c_str ());
+                   delete_thread (find_thread_ptid (retval));
                    status->kind = TARGET_WAITKIND_SPURIOUS;
                    return retval;
                  }
@@ -2471,8 +2428,10 @@ wait_again:
 
                    long i, nsysargs, *sysargs;
 
-                   if ((nsysargs = proc_nsysarg (pi)) > 0 &&
-                       (sysargs  = proc_sysargs (pi)) != NULL)
+                   nsysargs = proc_nsysarg (pi);
+                   sysargs = proc_sysargs (pi);
+
+                   if (nsysargs > 0 && sysargs != NULL)
                      {
                        printf_filtered (_("%ld syscall arguments:\n"),
                                         nsysargs);
@@ -2504,7 +2463,7 @@ wait_again:
                      create_procinfo  (pi->pid, temp_tid);
 
                    /* If not in GDB's thread list, add it.  */
-                   temp_ptid = ptid_build (pi->pid, temp_tid, 0);
+                   temp_ptid = ptid_t (pi->pid, temp_tid, 0);
                    if (!in_thread_list (temp_ptid))
                      add_thread (temp_ptid);
 
@@ -2543,7 +2502,7 @@ wait_again:
                case FLTPAGE:   /* Recoverable page fault */
                default:        /* FIXME: use si_signo if possible for
                                   fault.  */
-                 retval = pid_to_ptid (-1);
+                 retval = ptid_t (-1);
                  printf_filtered ("procfs:%d -- ", __LINE__);
                  printf_filtered (_("child stopped for unknown reason:\n"));
                  proc_prettyprint_why (why, what, 1);
@@ -2560,18 +2519,18 @@ wait_again:
              }
              /* Got this far without error: If retval isn't in the
                 threads database, add it.  */
-             if (ptid_get_pid (retval) > 0 &&
-                 !ptid_equal (retval, inferior_ptid) &&
-                 !in_thread_list (retval))
+             if (retval.pid () > 0
+                 && retval != inferior_ptid
+                 && !in_thread_list (retval))
                {
                  /* We have a new thread.  We need to add it both to
                     GDB's list and to our own.  If we don't create a
                     procinfo, resume may be unhappy later.  */
                  add_thread (retval);
-                 if (find_procinfo (ptid_get_pid (retval),
-                                    ptid_get_lwp (retval)) == NULL)
-                   create_procinfo (ptid_get_pid (retval),
-                                    ptid_get_lwp (retval));
+                 if (find_procinfo (retval.pid (),
+                                    retval.lwp ()) == NULL)
+                   create_procinfo (retval.pid (),
+                                    retval.lwp ());
                }
            }
          else  /* Flags do not indicate STOPPED.  */
@@ -2594,11 +2553,11 @@ wait_again:
 /* Perform a partial transfer to/from the specified object.  For
    memory transfers, fall back to the old memory xfer functions.  */
 
-static enum target_xfer_status
-procfs_xfer_partial (struct target_ops *ops, enum target_object object,
-                    const char *annex, gdb_byte *readbuf,
-                    const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-                    ULONGEST *xfered_len)
+enum target_xfer_status
+procfs_target::xfer_partial (enum target_object object,
+                            const char *annex, gdb_byte *readbuf,
+                            const gdb_byte *writebuf, ULONGEST offset,
+                            ULONGEST len, ULONGEST *xfered_len)
 {
   switch (object)
     {
@@ -2606,13 +2565,13 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object,
       return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
 
     case TARGET_OBJECT_AUXV:
-      return memory_xfer_auxv (ops, object, annex, readbuf, writebuf,
+      return memory_xfer_auxv (this, object, annex, readbuf, writebuf,
                               offset, len, xfered_len);
 
     default:
-      return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-                                           readbuf, writebuf, offset, len,
-                                           xfered_len);
+      return this->beneath ()->xfer_partial (object, annex,
+                                            readbuf, writebuf, offset, len,
+                                            xfered_len);
     }
 }
 
@@ -2627,9 +2586,8 @@ procfs_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
   int nbytes;
 
   /* Find procinfo for main process.  */
-  pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
-  if (pi->as_fd == 0 &&
-      open_procinfo_files (pi, FD_AS) == 0)
+  pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
+  if (pi->as_fd == 0 && open_procinfo_files (pi, FD_AS) == 0)
     {
       proc_warn (pi, "xfer_memory, open_proc_files", __LINE__);
       return TARGET_XFER_E_IO;
@@ -2677,15 +2635,13 @@ invalidate_cache (procinfo *parent, procinfo *pi, void *ptr)
 
 #if 0
   if (pi->gregs_dirty)
-    if (parent == NULL ||
-       proc_get_current_thread (parent) != pi->tid)
+    if (parent == NULL || proc_get_current_thread (parent) != pi->tid)
       if (!proc_set_gregs (pi))        /* flush gregs cache */
        proc_warn (pi, "target_resume, set_gregs",
                   __LINE__);
   if (gdbarch_fp0_regnum (target_gdbarch ()) >= 0)
     if (pi->fpregs_dirty)
-      if (parent == NULL ||
-         proc_get_current_thread (parent) != pi->tid)
+      if (parent == NULL || proc_get_current_thread (parent) != pi->tid)
        if (!proc_set_fpregs (pi))      /* flush fpregs cache */
          proc_warn (pi, "target_resume, set_fpregs",
                     __LINE__);
@@ -2741,9 +2697,8 @@ make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr)
    allow any child thread to run; if non-zero, then allow only the
    indicated thread to run.  (not implemented yet).  */
 
-static void
-procfs_resume (struct target_ops *ops,
-              ptid_t ptid, int step, enum gdb_signal signo)
+void
+procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 {
   procinfo *pi, *thread;
   int native_signo;
@@ -2765,14 +2720,13 @@ procfs_resume (struct target_ops *ops,
      to proc_run_process (for use in the prrun struct by ioctl).  */
 
   /* Find procinfo for main process.  */
-  pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+  pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
 
   /* First cut: ignore pid argument.  */
   errno = 0;
 
   /* Convert signal to host numbering.  */
-  if (signo == 0 ||
-      (signo == GDB_SIGNAL_STOP && pi->ignore_next_sigstop))
+  if (signo == 0 || (signo == GDB_SIGNAL_STOP && pi->ignore_next_sigstop))
     native_signo = 0;
   else
     native_signo = gdb_signal_to_host (signo);
@@ -2785,11 +2739,11 @@ procfs_resume (struct target_ops *ops,
   /* Void the process procinfo's caches.  */
   invalidate_cache (NULL, pi, NULL);
 
-  if (ptid_get_pid (ptid) != -1)
+  if (ptid.pid () != -1)
     {
       /* Resume a specific thread, presumably suppressing the
         others.  */
-      thread = find_procinfo (ptid_get_pid (ptid), ptid_get_lwp (ptid));
+      thread = find_procinfo (ptid.pid (), ptid.lwp ());
       if (thread != NULL)
        {
          if (thread->tid != 0)
@@ -2821,12 +2775,11 @@ procfs_resume (struct target_ops *ops,
 
 /* Set up to trace signals in the child process.  */
 
-static void
-procfs_pass_signals (struct target_ops *self,
-                    int numsigs, unsigned char *pass_signals)
+void
+procfs_target::pass_signals (gdb::array_view<const unsigned char> pass_signals)
 {
   sigset_t signals;
-  procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+  procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
   int signo;
 
   prfillset (&signals);
@@ -2834,7 +2787,7 @@ procfs_pass_signals (struct target_ops *self,
   for (signo = 0; signo < NSIG; signo++)
     {
       int target_signo = gdb_signal_from_host (signo);
-      if (target_signo < numsigs && pass_signals[target_signo])
+      if (target_signo < pass_signals.size () && pass_signals[target_signo])
        prdelset (&signals, signo);
     }
 
@@ -2844,14 +2797,14 @@ procfs_pass_signals (struct target_ops *self,
 
 /* Print status information about the child process.  */
 
-static void
-procfs_files_info (struct target_ops *ignore)
+void
+procfs_target::files_info ()
 {
   struct inferior *inf = current_inferior ();
 
   printf_filtered (_("\tUsing the running image of %s %s via /proc.\n"),
                   inf->attach_flag? "attached": "child",
-                  target_pid_to_str (inferior_ptid));
+                  target_pid_to_str (inferior_ptid).c_str ());
 }
 
 /* Make it die.  Wait for it to die.  Clean up after it.  Note: this
@@ -2887,13 +2840,13 @@ unconditionally_kill_inferior (procinfo *pi)
 /* We're done debugging it, and we want it to go away.  Then we want
    GDB to forget all about it.  */
 
-static void
-procfs_kill_inferior (struct target_ops *ops)
+void
+procfs_target::kill ()
 {
-  if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */
+  if (inferior_ptid != null_ptid) /* ? */
     {
       /* Find procinfo for main process.  */
-      procinfo *pi = find_procinfo (ptid_get_pid (inferior_ptid), 0);
+      procinfo *pi = find_procinfo (inferior_ptid.pid (), 0);
 
       if (pi)
        unconditionally_kill_inferior (pi);
@@ -2903,22 +2856,22 @@ procfs_kill_inferior (struct target_ops *ops)
 
 /* Forget we ever debugged this thing!  */
 
-static void
-procfs_mourn_inferior (struct target_ops *ops)
+void
+procfs_target::mourn_inferior ()
 {
   procinfo *pi;
 
-  if (!ptid_equal (inferior_ptid, null_ptid))
+  if (inferior_ptid != null_ptid)
     {
       /* Find procinfo for main process.  */
-      pi = find_procinfo (ptid_get_pid (inferior_ptid), 0);
+      pi = find_procinfo (inferior_ptid.pid (), 0);
       if (pi)
        destroy_procinfo (pi);
     }
 
   generic_mourn_inferior ();
 
-  inf_child_maybe_unpush_target (ops);
+  maybe_unpush_target ();
 }
 
 /* When GDB forks to create a runnable inferior process, this function
@@ -2930,7 +2883,6 @@ static void
 procfs_init_inferior (struct target_ops *ops, int pid)
 {
   procinfo *pi;
-  sigset_t signals;
   int fail;
   int lwpid;
 
@@ -2939,7 +2891,8 @@ procfs_init_inferior (struct target_ops *ops, int pid)
   if (!target_is_pushed (ops))
     push_target (ops);
 
-  if ((pi = create_procinfo (pid, 0)) == NULL)
+  pi = create_procinfo (pid, 0);
+  if (pi == NULL)
     perror (_("procfs: out of memory in 'init_inferior'"));
 
   if (!open_procinfo_files (pi, FD_CTL))
@@ -2958,8 +2911,7 @@ procfs_init_inferior (struct target_ops *ops, int pid)
     */
 
   /* If not stopped yet, wait for it to stop.  */
-  if (!(proc_flags (pi) & PR_STOPPED) &&
-      !(proc_wait_for_stop (pi)))
+  if (!(proc_flags (pi) & PR_STOPPED) && !(proc_wait_for_stop (pi)))
     dead_procinfo (pi, "init_inferior: wait_for_stop failed", KILL);
 
   /* Save some of the /proc state to be restored if we detach.  */
@@ -2976,7 +2928,8 @@ procfs_init_inferior (struct target_ops *ops, int pid)
   if (!proc_get_traced_sysexit  (pi, pi->saved_exitset))
     proc_error (pi, "init_inferior, get_traced_sysexit", __LINE__);
 
-  if ((fail = procfs_debug_inferior (pi)) != 0)
+  fail = procfs_debug_inferior (pi);
+  if (fail != 0)
     proc_error (pi, "init_inferior (procfs_debug_inferior)", fail);
 
   /* FIXME: logically, we should really be turning OFF run-on-last-close,
@@ -2997,8 +2950,8 @@ procfs_init_inferior (struct target_ops *ops, int pid)
   /* We already have a main thread registered in the thread table at
      this point, but it didn't have any lwp info yet.  Notify the core
      about it.  This changes inferior_ptid as well.  */
-  thread_change_ptid (pid_to_ptid (pid),
-                     ptid_build (pid, lwpid, 0));
+  thread_change_ptid (ptid_t (pid),
+                     ptid_t (pid, lwpid, 0));
 
   gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED);
 }
@@ -3021,7 +2974,8 @@ procfs_set_exec_trap (void)
   procinfo *pi;
   sysset_t *exitset;
 
-  if ((pi = create_procinfo (getpid (), 0)) == NULL)
+  pi = create_procinfo (getpid (), 0);
+  if (pi == NULL)
     perror_with_name (_("procfs: create_procinfo failed in child."));
 
   if (open_procinfo_files (pi, FD_CTL) == 0)
@@ -3039,7 +2993,7 @@ procfs_set_exec_trap (void)
      names.  On the SGI, for example, there is no SYS_exec, but there
      *is* a SYS_execv.  So, we try to account for that.  */
 
-  exitset = sysset_t_alloc (pi);
+  exitset = XNEW (sysset_t);
   premptyset (exitset);
 #ifdef SYS_exec
   praddset (exitset, SYS_exec);
@@ -3081,15 +3035,16 @@ procfs_set_exec_trap (void)
    abstracted out and shared with other unix targets such as
    inf-ptrace?  */
 
-static void
-procfs_create_inferior (struct target_ops *ops, const char *exec_file,
-                       const std::string &allargs, char **env, int from_tty)
+void
+procfs_target::create_inferior (const char *exec_file,
+                               const std::string &allargs,
+                               char **env, int from_tty)
 {
-  char *shell_file = getenv ("SHELL");
+  const char *shell_file = get_shell ();
   char *tryname;
   int pid;
 
-  if (shell_file != NULL && strchr (shell_file, '/') == NULL)
+  if (strchr (shell_file, '/') == NULL)
     {
 
       /* We will be looking down the PATH to find shell_file.  If we
@@ -3163,9 +3118,9 @@ procfs_create_inferior (struct target_ops *ops, const char *exec_file,
   /* We have something that executes now.  We'll be running through
      the shell at this point (if startup-with-shell is true), but the
      pid shouldn't change.  */
-  add_thread_silent (pid_to_ptid (pid));
+  add_thread_silent (ptid_t (pid));
 
-  procfs_init_inferior (ops, pid);
+  procfs_init_inferior (this, pid);
 }
 
 /* An observer for the "inferior_created" event.  */
@@ -3180,9 +3135,10 @@ procfs_inferior_created (struct target_ops *ops, int from_tty)
 static int
 procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
 {
-  ptid_t gdb_threadid = ptid_build (pi->pid, thread->tid, 0);
+  ptid_t gdb_threadid = ptid_t (pi->pid, thread->tid, 0);
 
-  if (!in_thread_list (gdb_threadid) || is_exited (gdb_threadid))
+  thread_info *thr = find_thread_ptid (gdb_threadid);
+  if (thr == NULL || thr->state == THREAD_EXITED)
     add_thread (gdb_threadid);
 
   return 0;
@@ -3191,15 +3147,15 @@ procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
 /* Query all the threads that the target knows about, and give them
    back to GDB to add to its list.  */
 
-static void
-procfs_update_thread_list (struct target_ops *ops)
+void
+procfs_target::update_thread_list ()
 {
   procinfo *pi;
 
   prune_threads ();
 
   /* Find procinfo for main process.  */
-  pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+  pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
   proc_update_threads (pi);
   proc_iterate_over_threads (pi, procfs_notice_thread, NULL);
 }
@@ -3208,42 +3164,67 @@ procfs_update_thread_list (struct target_ops *ops)
    really seem to be doing his job.  Got to investigate how to tell
    when a thread is really gone.  */
 
-static int
-procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
+bool
+procfs_target::thread_alive (ptid_t ptid)
 {
   int proc, thread;
   procinfo *pi;
 
-  proc    = ptid_get_pid (ptid);
-  thread  = ptid_get_lwp (ptid);
+  proc    = ptid.pid ();
+  thread  = ptid.lwp ();
   /* If I don't know it, it ain't alive!  */
-  if ((pi = find_procinfo (proc, thread)) == NULL)
-    return 0;
+  pi = find_procinfo (proc, thread);
+  if (pi == NULL)
+    return false;
 
   /* If I can't get its status, it ain't alive!
      What's more, I need to forget about it!  */
   if (!proc_get_status (pi))
     {
       destroy_procinfo (pi);
-      return 0;
+      return false;
     }
   /* I couldn't have got its status if it weren't alive, so it's
      alive.  */
-  return 1;
+  return true;
 }
 
-/* Convert PTID to a string.  Returns the string in a static
-   buffer.  */
+/* Convert PTID to a string.  */
 
-static const char *
-procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
+std::string
+procfs_target::pid_to_str (ptid_t ptid)
 {
-  static char buf[80];
-
-  if (ptid_get_lwp (ptid) == 0)
-    sprintf (buf, "process %d", ptid_get_pid (ptid));
+  if (ptid.lwp () == 0)
+    return string_printf ("process %d", ptid.pid ());
   else
-    sprintf (buf, "LWP %ld", ptid_get_lwp (ptid));
+    return string_printf ("LWP %ld", ptid.lwp ());
+}
+
+/* Accepts an integer PID; Returns a string representing a file that
+   can be opened to get the symbols for the child process.  */
+
+char *
+procfs_target::pid_to_exec_file (int pid)
+{
+  static char buf[PATH_MAX];
+  char name[PATH_MAX];
+
+  /* Solaris 11 introduced /proc/<proc-id>/execname.  */
+  xsnprintf (name, sizeof (name), "/proc/%d/execname", pid);
+  scoped_fd fd (gdb_open_cloexec (name, O_RDONLY, 0));
+  if (fd.get () < 0 || read (fd.get (), buf, PATH_MAX - 1) < 0)
+    {
+      /* If that fails, fall back to /proc/<proc-id>/path/a.out introduced in
+        Solaris 10.  */
+      ssize_t len;
+
+      xsnprintf (name, sizeof (name), "/proc/%d/path/a.out", pid);
+      len = readlink (name, buf, PATH_MAX - 1);
+      if (len <= 0)
+       strcpy (buf, name);
+      else
+       buf[len] = '\0';
+    }
 
   return buf;
 }
@@ -3257,8 +3238,8 @@ procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag,
   int       pflags = 0;
   procinfo *pi;
 
-  pi = find_procinfo_or_die (ptid_get_pid (ptid) == -1 ?
-                            ptid_get_pid (inferior_ptid) : ptid_get_pid (ptid),
+  pi = find_procinfo_or_die (ptid.pid () == -1 ?
+                            inferior_ptid.pid () : ptid.pid (),
                             0);
 
   /* Translate from GDB's flags to /proc's.  */
@@ -3306,10 +3287,8 @@ procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag,
    procfs.c targets due to the fact that some of them still define
    target_can_use_hardware_watchpoint.  */
 
-static int
-procfs_can_use_hw_breakpoint (struct target_ops *self,
-                             enum bptype type,
-                             int cnt, int othertype)
+int
+procfs_target::can_use_hw_breakpoint (enum bptype type, int cnt, int othertype)
 {
   /* Due to the way that proc_set_watchpoint() is implemented, host
      and target pointers must be of the same size.  If they are not,
@@ -3332,22 +3311,18 @@ procfs_can_use_hw_breakpoint (struct target_ops *self,
 /* Returns non-zero if process is stopped on a hardware watchpoint
    fault, else returns zero.  */
 
-static int
-procfs_stopped_by_watchpoint (struct target_ops *ops)
+bool
+procfs_target::stopped_by_watchpoint ()
 {
   procinfo *pi;
 
-  pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+  pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
 
   if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
-    {
-      if (proc_why (pi) == PR_FAULTED)
-       {
-         if (proc_what (pi) == FLTWATCH)
-           return 1;
-       }
-    }
-  return 0;
+    if (proc_why (pi) == PR_FAULTED)
+      if (proc_what (pi) == FLTWATCH)
+       return true;
+  return false;
 }
 
 /* Returns 1 if the OS knows the position of the triggered watchpoint,
@@ -3356,51 +3331,44 @@ procfs_stopped_by_watchpoint (struct target_ops *ops)
    procfs_stopped_by_watchpoint returned 1, thus no further checks are
    done.  The function also assumes that ADDR is not NULL.  */
 
-static int
-procfs_stopped_data_address (struct target_ops *targ, CORE_ADDR *addr)
+bool
+procfs_target::stopped_data_address (CORE_ADDR *addr)
 {
   procinfo *pi;
 
-  pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+  pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
   return proc_watchpoint_address (pi, addr);
 }
 
-static int
-procfs_insert_watchpoint (struct target_ops *self,
-                         CORE_ADDR addr, int len,
-                         enum target_hw_bp_type type,
-                         struct expression *cond)
+int
+procfs_target::insert_watchpoint (CORE_ADDR addr, int len,
+                                 enum target_hw_bp_type type,
+                                 struct expression *cond)
 {
   if (!target_have_steppable_watchpoint
       && !gdbarch_have_nonsteppable_watchpoint (target_gdbarch ()))
-    {
-      /* When a hardware watchpoint fires off the PC will be left at
-        the instruction following the one which caused the
-        watchpoint.  It will *NOT* be necessary for GDB to step over
-        the watchpoint.  */
-      return procfs_set_watchpoint (inferior_ptid, addr, len, type, 1);
-    }
+    /* When a hardware watchpoint fires off the PC will be left at
+       the instruction following the one which caused the
+       watchpoint.  It will *NOT* be necessary for GDB to step over
+       the watchpoint.  */
+    return procfs_set_watchpoint (inferior_ptid, addr, len, type, 1);
   else
-    {
-      /* When a hardware watchpoint fires off the PC will be left at
-        the instruction which caused the watchpoint.  It will be
-        necessary for GDB to step over the watchpoint.  */
-      return procfs_set_watchpoint (inferior_ptid, addr, len, type, 0);
-    }
+    /* When a hardware watchpoint fires off the PC will be left at
+       the instruction which caused the watchpoint.  It will be
+       necessary for GDB to step over the watchpoint.  */
+    return procfs_set_watchpoint (inferior_ptid, addr, len, type, 0);
 }
 
-static int
-procfs_remove_watchpoint (struct target_ops *self,
-                         CORE_ADDR addr, int len,
-                         enum target_hw_bp_type type,
-                         struct expression *cond)
+int
+procfs_target::remove_watchpoint (CORE_ADDR addr, int len,
+                                 enum target_hw_bp_type type,
+                                 struct expression *cond)
 {
   return procfs_set_watchpoint (inferior_ptid, addr, 0, 0, 0);
 }
 
-static int
-procfs_region_ok_for_hw_watchpoint (struct target_ops *self,
-                                   CORE_ADDR addr, int len)
+int
+procfs_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
   /* The man page for proc(4) on Solaris 2.6 and up says that the
      system can support "thousands" of hardware watchpoints, but gives
@@ -3441,7 +3409,7 @@ iterate_over_mappings (procinfo *pi, find_memory_region_ftype child_func,
   /* Get the number of mappings, allocate space,
      and read the mappings into prmaps.  */
   /* Open map fd.  */
-  sprintf (pathname, "/proc/%d/map", pi->pid);
+  xsnprintf (pathname, sizeof (pathname), "/proc/%d/map", pi->pid);
 
   scoped_fd map_fd (open (pathname, O_RDONLY));
   if (map_fd.get () < 0)
@@ -3459,8 +3427,11 @@ iterate_over_mappings (procinfo *pi, find_memory_region_ftype child_func,
     proc_error (pi, "iterate_over_mappings (read)", __LINE__);
 
   for (prmap = prmaps; nmap > 0; prmap++, nmap--)
-    if ((funcstat = (*func) (prmap, child_func, data)) != 0)
-      return funcstat;
+    {
+      funcstat = (*func) (prmap, child_func, data);
+      if (funcstat != 0)
+       return funcstat;
+    }
 
   return 0;
 }
@@ -3494,11 +3465,10 @@ find_memory_regions_callback (struct prmap *map,
    Stops iterating and returns the first non-zero value returned by
    the callback.  */
 
-static int
-proc_find_memory_regions (struct target_ops *self,
-                         find_memory_region_ftype func, void *data)
+int
+procfs_target::find_memory_regions (find_memory_region_ftype func, void *data)
 {
-  procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+  procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
 
   return iterate_over_mappings (pi, func, data,
                                find_memory_regions_callback);
@@ -3586,11 +3556,9 @@ info_proc_mappings (procinfo *pi, int summary)
 
 /* Implement the "info proc" command.  */
 
-static void
-procfs_info_proc (struct target_ops *ops, const char *args,
-                 enum info_proc_what what)
+bool
+procfs_target::info_proc (const char *args, enum info_proc_what what)
 {
-  struct cleanup *old_chain;
   procinfo *process  = NULL;
   procinfo *thread   = NULL;
   char     *tmp      = NULL;
@@ -3612,7 +3580,6 @@ procfs_info_proc (struct target_ops *ops, const char *args,
       error (_("Not supported on this target."));
     }
 
-  old_chain = make_cleanup (null_cleanup, 0);
   gdb_argv built_argv (args);
   for (char *arg : built_argv)
     {
@@ -3627,8 +3594,10 @@ procfs_info_proc (struct target_ops *ops, const char *args,
          tid = strtoul (arg + 1, NULL, 10);
        }
     }
+
+  procinfo_up temporary_procinfo;
   if (pid == 0)
-    pid = ptid_get_pid (inferior_ptid);
+    pid = inferior_ptid.pid ();
   if (pid == 0)
     error (_("No current process: you must name one."));
   else
@@ -3641,7 +3610,7 @@ procfs_info_proc (struct target_ops *ops, const char *args,
           /* No.  So open a procinfo for it, but
              remember to close it again when finished.  */
           process = create_procinfo (pid, 0);
-          make_cleanup (do_destroy_procinfo_cleanup, process);
+          temporary_procinfo.reset (process);
           if (!open_procinfo_files (process, FD_CTL))
             proc_error (process, "info proc, open_procinfo_files", __LINE__);
         }
@@ -3668,11 +3637,9 @@ procfs_info_proc (struct target_ops *ops, const char *args,
     }
 
   if (mappings)
-    {
-      info_proc_mappings (process, 0);
-    }
+    info_proc_mappings (process, 0);
 
-  do_cleanups (old_chain);
+  return true;
 }
 
 /* Modify the status of the system call identified by SYSCALLNUM in
@@ -3720,13 +3687,13 @@ proc_trace_syscalls (const char *args, int from_tty, int entry_or_exit, int mode
 {
   procinfo *pi;
 
-  if (ptid_get_pid (inferior_ptid) <= 0)
+  if (inferior_ptid.pid () <= 0)
     error (_("you must be debugging a process to use this command."));
 
   if (args == NULL || args[0] == 0)
     error_no_arg (_("system call to trace"));
 
-  pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+  pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
   if (isdigit (args[0]))
     {
       const int syscallnum = atoi (args);
@@ -3773,7 +3740,7 @@ _initialize_procfs (void)
   add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd,
           _("Cancel a trace of exits from the syscall."));
 
-  add_target (procfs_target ());
+  add_inf_child_target (&the_procfs_target);
 }
 
 /* =================== END, GDB  "MODULE" =================== */
@@ -3791,7 +3758,7 @@ _initialize_procfs (void)
 ptid_t
 procfs_first_available (void)
 {
-  return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1);
+  return ptid_t (procinfo_list ? procinfo_list->pid : -1);
 }
 
 /* ===================  GCORE .NOTE "MODULE" =================== */
@@ -3806,7 +3773,7 @@ procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
   gdb_fpregset_t fpregs;
   unsigned long merged_pid;
 
-  merged_pid = ptid_get_lwp (ptid) << 16 | ptid_get_pid (ptid);
+  merged_pid = ptid.lwp () << 16 | ptid.pid ();
 
   /* This part is the old method for fetching registers.
      It should be replaced by the newer one using regsets
@@ -3849,7 +3816,7 @@ procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data)
 
   if (pi != NULL)
     {
-      ptid_t ptid = ptid_build (pi->pid, thread->tid, 0);
+      ptid_t ptid = ptid_t (pi->pid, thread->tid, 0);
 
       args->note_data = procfs_do_thread_registers (args->obfd, ptid,
                                                    args->note_data,
@@ -3863,7 +3830,7 @@ static int
 find_signalled_thread (struct thread_info *info, void *data)
 {
   if (info->suspend.stop_signal != GDB_SIGNAL_0
-      && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
+      && info->ptid.pid () == inferior_ptid.pid ())
     return 1;
 
   return 0;
@@ -3881,20 +3848,16 @@ find_stop_signal (void)
     return GDB_SIGNAL_0;
 }
 
-static char *
-procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size)
+char *
+procfs_target::make_corefile_notes (bfd *obfd, int *note_size)
 {
-  struct cleanup *old_chain;
   gdb_gregset_t gregs;
-  gdb_fpregset_t fpregs;
   char fname[16] = {'\0'};
   char psargs[80] = {'\0'};
-  procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+  procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
   char *note_data = NULL;
-  char *inf_args;
+  const char *inf_args;
   struct procfs_corefile_thread_data thread_args;
-  gdb_byte *auxv;
-  int auxv_len;
   enum gdb_signal stop_signal;
 
   if (get_exec_file (0))
@@ -3905,8 +3868,9 @@ procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size)
       psargs[sizeof (psargs) - 1] = 0;
 
       inf_args = get_inferior_args ();
-      if (inf_args && *inf_args &&
-         strlen (inf_args) < ((int) sizeof (psargs) - (int) strlen (psargs)))
+      if (inf_args && *inf_args
+         && (strlen (inf_args)
+             < ((int) sizeof (psargs) - (int) strlen (psargs))))
        {
          strncat (psargs, " ",
                   sizeof (psargs) - strlen (psargs));
@@ -3925,7 +3889,7 @@ procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size)
 
   fill_gregset (get_current_regcache (), &gregs, -1);
   note_data = elfcore_write_pstatus (obfd, note_data, note_size,
-                                    ptid_get_pid (inferior_ptid),
+                                    inferior_ptid.pid (),
                                     stop_signal, &gregs);
 
   thread_args.obfd = obfd;
@@ -3936,14 +3900,12 @@ procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size)
                             &thread_args);
   note_data = thread_args.note_data;
 
-  auxv_len = target_read_alloc (&current_target, TARGET_OBJECT_AUXV,
-                               NULL, &auxv);
-  if (auxv_len > 0)
-    {
-      note_data = elfcore_write_note (obfd, note_data, note_size,
-                                     "CORE", NT_AUXV, auxv, auxv_len);
-      xfree (auxv);
-    }
+  gdb::optional<gdb::byte_vector> auxv =
+    target_read_alloc (current_top_target (), TARGET_OBJECT_AUXV, NULL);
+  if (auxv && !auxv->empty ())
+    note_data = elfcore_write_note (obfd, note_data, note_size,
+                                   "CORE", NT_AUXV, auxv->data (),
+                                   auxv->size ());
 
   return note_data;
 }