gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / procfs.c
index 749b2b4833f37c37151b0cd17581295eae8d8c43..f6c6b0e71c16224d3e7345ca09e011cdcf06349a 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-2020 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 "gdbarch.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 "gdbsupport/gdb_wait.h"
 #include <signal.h>
 #include <ctype.h>
 #include "gdb_bfd.h"
@@ -46,7 +46,8 @@
 #include "auxv.h"
 #include "procfs.h"
 #include "observable.h"
-#include "common/scoped_fd.h"
+#include "gdbsupport/scoped_fd.h"
+#include "gdbsupport/pathstuff.h"
 
 /* This module provides the interface between GDB and the
    /proc file system, which is used on many versions of Unix
@@ -118,7 +119,7 @@ public:
                                        ULONGEST offset, ULONGEST len,
                                        ULONGEST *xfered_len) override;
 
-  void pass_signals (int, unsigned char *) override;
+  void pass_signals (gdb::array_view<const unsigned char>) override;
 
   void files_info () override;
 
@@ -126,7 +127,9 @@ public:
 
   bool thread_alive (ptid_t ptid) override;
 
-  const char *pid_to_str (ptid_t) override;
+  std::string pid_to_str (ptid_t) override;
+
+  char *pid_to_exec_file (int pid) override;
 
   thread_control_capabilities get_thread_control_capabilities () override
   { return tc_schedlock; }
@@ -139,7 +142,7 @@ public:
 
   bool info_proc (const char *, enum info_proc_what) override;
 
-#if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+#if PR_MODEL_NATIVE == PR_MODEL_LP64
   int auxv_parse (gdb_byte **readptr,
                  gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
     override;
@@ -157,11 +160,13 @@ public:
 
   int can_use_hw_breakpoint (enum bptype, int, int) override;
   bool stopped_data_address (CORE_ADDR *) override;
+
+  void procfs_init_inferior (int pid);
 };
 
 static procfs_target the_procfs_target;
 
-#if defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+#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.  */
@@ -231,7 +236,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;
@@ -272,11 +277,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,
@@ -384,7 +387,7 @@ open_procinfo_files (procinfo *pi, int which)
      several.  Here is some rationale:
 
      There are several file descriptors that may need to be open
-       for any given process or LWP.  The ones we're intereted in are:
+       for any given process or LWP.  The ones we're interested in are:
         - control       (ctl)    write-only    change the state
         - status        (status) read-only     query the state
         - address space (as)     read/write    access memory
@@ -455,7 +458,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.  */
@@ -469,19 +473,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;
     }
@@ -549,11 +554,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 };
 
@@ -567,12 +577,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)
@@ -582,14 +590,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" =================== */
@@ -617,14 +617,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);
 }
 
@@ -638,8 +640,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;
@@ -839,7 +840,7 @@ proc_unset_run_on_last_close (procinfo *pi)
 }
 
 /* Reset inherit_on_fork flag.  If the process forks a child while we
-   are registered for events in the parent, then we will NOT recieve
+   are registered for events in the parent, then we will NOT receive
    events from the child.  Returns non-zero for success, zero for
    failure.  */
 
@@ -880,8 +881,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
     {
@@ -911,7 +911,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;
 
@@ -946,11 +951,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)
@@ -1053,20 +1055,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.  */
@@ -1095,16 +1093,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.  */
@@ -1323,6 +1317,7 @@ proc_set_current_signal (procinfo *pi, int signo)
     char sinfo[sizeof (siginfo_t)];
   } arg;
   siginfo_t mysinfo;
+  process_stratum_target *wait_target;
   ptid_t wait_ptid;
   struct target_waitstatus wait_status;
 
@@ -1335,8 +1330,9 @@ proc_set_current_signal (procinfo *pi, int signo)
     pi = find_procinfo_or_die (pi->pid, 0);
 
   /* The pointer is just a type alias.  */
-  get_last_target_status (&wait_ptid, &wait_status);
-  if (ptid_equal (wait_ptid, inferior_ptid)
+  get_last_target_status (&wait_target, &wait_ptid, &wait_status);
+  if (wait_target == &the_procfs_target
+      && wait_ptid == inferior_ptid
       && wait_status.kind == TARGET_WAITKIND_STOPPED
       && wait_status.value.sig == gdb_signal_from_host (signo)
       && proc_get_status (pi)
@@ -1439,9 +1435,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 {
@@ -1475,9 +1469,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 {
@@ -1507,11 +1499,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];
@@ -1580,83 +1569,6 @@ proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
   return (write (pi->ctl_fd, &arg, sizeof (arg)) == sizeof (arg));
 }
 
-#if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
-
-#include <sys/sysi86.h>
-
-/* The KEY is actually the value of the lower 16 bits of the GS
-   register for the LWP that we're interested in.  Returns the
-   matching ssh struct (LDT entry).  */
-
-static struct ssd *
-proc_get_LDT_entry (procinfo *pi, int key)
-{
-  static struct ssd *ldt_entry = NULL;
-  char pathname[MAX_PROC_NAME_SIZE];
-
-  /* Allocate space for one LDT entry.
-     This alloc must persist, because we return a pointer to it.  */
-  if (ldt_entry == NULL)
-    ldt_entry = XNEW (struct ssd);
-
-  /* Open the file descriptor for the LDT table.  */
-  sprintf (pathname, "/proc/%d/ldt", pi->pid);
-  scoped_fd fd (open_with_retry (pathname, O_RDONLY));
-  if (fd.get () < 0)
-    {
-      proc_warn (pi, "proc_get_LDT_entry (open)", __LINE__);
-      return NULL;
-    }
-
-  /* Now 'read' thru the table, find a match and return it.  */
-  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)
-       break;  /* end of table */
-      /* If key matches, return this entry.  */
-      if (ldt_entry->sel == key)
-       return ldt_entry;
-    }
-  /* Loop ended, match not found.  */
-  return NULL;
-}
-
-/* Returns the pointer to the LDT entry of PTID.  */
-
-struct ssd *
-procfs_find_LDT_entry (ptid_t ptid)
-{
-  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)
-    {
-      warning (_("procfs_find_LDT_entry: could not find procinfo for %d:%ld."),
-              ptid_get_pid (ptid), ptid_get_lwp (ptid));
-      return NULL;
-    }
-  /* get its general registers.  */
-  if ((gregs = proc_get_gregs (pi)) == NULL)
-    {
-      warning (_("procfs_find_LDT_entry: could not read gregs for %d:%ld."),
-              ptid_get_pid (ptid), ptid_get_lwp (ptid));
-      return NULL;
-    }
-  /* Now extract the GS register's lower 16 bits.  */
-  key = (*gregs)[GS] & 0xffff;
-
-  /* Find the matching entry and return it.  */
-  return proc_get_LDT_entry (pi, key);
-}
-
-#endif
-
 /* =============== END, non-thread part of /proc  "MODULE" =============== */
 
 /* =================== Thread "MODULE" =================== */
@@ -1722,20 +1634,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
@@ -1756,19 +1661,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;
 }
 
@@ -1804,7 +1709,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;
     }
 
@@ -1853,7 +1759,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);
@@ -1869,7 +1775,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);
@@ -1889,7 +1795,6 @@ procfs_debug_inferior (procinfo *pi)
 void
 procfs_target::attach (const char *args, int from_tty)
 {
-  char *exec_file;
   int   pid;
 
   pid = parse_pid_to_attach (args);
@@ -1899,18 +1804,18 @@ procfs_target::attach (const char *args, int from_tty)
 
   if (from_tty)
     {
-      exec_file = get_exec_file (0);
+      const char *exec_file = get_exec_file (0);
 
       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));
+  inferior_ptid = do_attach (ptid_t (pid));
   if (!target_is_pushed (this))
     push_target (this);
 }
@@ -1918,7 +1823,7 @@ procfs_target::attach (const char *args, 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)
     {
@@ -1929,14 +1834,13 @@ procfs_target::detach (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);
+  detach_inferior (inf);
   maybe_unpush_target ();
 }
 
@@ -1948,14 +1852,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);
     }
 
@@ -1991,7 +1897,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 ();
@@ -2004,8 +1911,8 @@ do_attach (ptid_t ptid)
   create_procinfo (pi->pid, lwpid);
 
   /* Add it to gdb's thread list.  */
-  ptid = ptid_build (pi->pid, lwpid, 0);
-  add_thread (ptid);
+  ptid = ptid_t (pi->pid, lwpid, 0);
+  add_thread (&the_procfs_target, ptid);
 
   return ptid;
 }
@@ -2016,7 +1923,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))
@@ -2071,16 +1978,16 @@ 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)
@@ -2120,16 +2027,16 @@ 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)
@@ -2216,10 +2123,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...  */
@@ -2234,8 +2141,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)
@@ -2246,13 +2153,13 @@ wait_again:
              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;
@@ -2291,7 +2198,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:
@@ -2302,8 +2209,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 (this, retval));
                    status->kind = TARGET_WAITKIND_SPURIOUS;
                    return retval;
                  }
@@ -2325,7 +2232,7 @@ wait_again:
                    if (!proc_run_process (pi, 0, 0))
                      proc_error (pi, "target_wait, run_process", __LINE__);
 
-                   inf = find_inferior_pid (pi->pid);
+                   inf = find_inferior_pid (this, pi->pid);
                    if (inf->attach_flag)
                      {
                        /* Don't call wait: simulate waiting for exit,
@@ -2348,7 +2255,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
@@ -2359,8 +2266,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);
@@ -2408,10 +2317,10 @@ 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);
+                   if (!in_thread_list (this, temp_ptid))
+                     add_thread (this, temp_ptid);
 
                    /* Return to WFI, but tell it to immediately resume.  */
                    status->kind = TARGET_WAITKIND_SPURIOUS;
@@ -2421,8 +2330,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 (this, retval));
                    status->kind = TARGET_WAITKIND_SPURIOUS;
                    return retval;
                  }
@@ -2443,8 +2352,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);
@@ -2476,9 +2387,9 @@ 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);
-                   if (!in_thread_list (temp_ptid))
-                     add_thread (temp_ptid);
+                   temp_ptid = ptid_t (pi->pid, temp_tid, 0);
+                   if (!in_thread_list (this, temp_ptid))
+                     add_thread (this, temp_ptid);
 
                    status->kind = TARGET_WAITKIND_STOPPED;
                    status->value.sig = GDB_SIGNAL_0;
@@ -2489,40 +2400,12 @@ wait_again:
                wstat = (what << 8) | 0177;
                break;
              case PR_FAULTED:
-               switch (what) {
-               case FLTWATCH:
-                 wstat = (SIGTRAP << 8) | 0177;
-                 break;
-                 /* FIXME: use si_signo where possible.  */
-               case FLTPRIV:
-               case FLTILL:
-                 wstat = (SIGILL << 8) | 0177;
-                 break;
-               case FLTBPT:
-               case FLTTRACE:
-                 wstat = (SIGTRAP << 8) | 0177;
-                 break;
-               case FLTSTACK:
-               case FLTACCESS:
-               case FLTBOUNDS:
-                 wstat = (SIGSEGV << 8) | 0177;
-                 break;
-               case FLTIOVF:
-               case FLTIZDIV:
-               case FLTFPE:
-                 wstat = (SIGFPE << 8) | 0177;
-                 break;
-               case FLTPAGE:   /* Recoverable page fault */
-               default:        /* FIXME: use si_signo if possible for
-                                  fault.  */
-                 retval = pid_to_ptid (-1);
-                 printf_filtered ("procfs:%d -- ", __LINE__);
-                 printf_filtered (_("child stopped for unknown reason:\n"));
-                 proc_prettyprint_why (why, what, 1);
-                 error (_("... giving up..."));
-                 break;
+               {
+                 int signo = pi->prstatus.pr_lwp.pr_info.si_signo;
+                 if (signo != 0)
+                   wstat = (signo << 8) | 0177;
                }
-               break;  /* case PR_FAULTED: */
+               break;
              default:  /* switch (why) unmatched */
                printf_filtered ("procfs:%d -- ", __LINE__);
                printf_filtered (_("child stopped for unknown reason:\n"));
@@ -2532,18 +2415,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 (this, 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));
+                 add_thread (this, retval);
+                 if (find_procinfo (retval.pid (),
+                                    retval.lwp ()) == NULL)
+                   create_procinfo (retval.pid (),
+                                    retval.lwp ());
                }
            }
          else  /* Flags do not indicate STOPPED.  */
@@ -2582,9 +2465,9 @@ procfs_target::xfer_partial (enum target_object object,
                               offset, len, xfered_len);
 
     default:
-      return this->beneath->xfer_partial (object, annex,
-                                         readbuf, writebuf, offset, len,
-                                         xfered_len);
+      return this->beneath ()->xfer_partial (object, annex,
+                                            readbuf, writebuf, offset, len,
+                                            xfered_len);
     }
 }
 
@@ -2599,9 +2482,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;
@@ -2633,7 +2515,7 @@ procfs_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
    File descriptors are also cached.  As they are a limited resource,
    we cannot hold onto them indefinitely.  However, as they are
    expensive to open, we don't want to throw them away
-   indescriminately either.  As a compromise, we will keep the file
+   indiscriminately either.  As a compromise, we will keep the file
    descriptors for the parent process, but discard any file
    descriptors we may have accumulated for the threads.
 
@@ -2649,15 +2531,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__);
@@ -2736,14 +2616,13 @@ procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
      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);
@@ -2756,11 +2635,11 @@ procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
   /* 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)
@@ -2793,10 +2672,10 @@ procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 /* Set up to trace signals in the child process.  */
 
 void
-procfs_target::pass_signals (int numsigs, unsigned char *pass_signals)
+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);
@@ -2804,7 +2683,7 @@ procfs_target::pass_signals (int numsigs, unsigned char *pass_signals)
   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);
     }
 
@@ -2821,7 +2700,7 @@ procfs_target::files_info ()
 
   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
@@ -2860,10 +2739,10 @@ unconditionally_kill_inferior (procinfo *pi)
 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);
@@ -2878,10 +2757,10 @@ 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);
     }
@@ -2896,20 +2775,20 @@ procfs_target::mourn_inferior ()
    whatever is necessary to make the child ready to be debugged, and
    then wait for the child to synchronize.  */
 
-static void
-procfs_init_inferior (struct target_ops *ops, int pid)
+void
+procfs_target::procfs_init_inferior (int pid)
 {
   procinfo *pi;
-  sigset_t signals;
   int fail;
   int lwpid;
 
   /* This routine called on the parent side (GDB side)
      after GDB forks the inferior.  */
-  if (!target_is_pushed (ops))
-    push_target (ops);
+  if (!target_is_pushed (this))
+    push_target (this);
 
-  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))
@@ -2928,8 +2807,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.  */
@@ -2946,7 +2824,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,
@@ -2967,8 +2846,7 @@ 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 (this, ptid_t (pid), ptid_t (pid, lwpid, 0));
 
   gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED);
 }
@@ -2991,7 +2869,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)
@@ -3009,7 +2888,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);
@@ -3056,11 +2935,11 @@ 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
@@ -3134,9 +3013,9 @@ procfs_target::create_inferior (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 (this, ptid_t (pid));
 
-  procfs_init_inferior (this, pid);
+  procfs_init_inferior (pid);
 }
 
 /* An observer for the "inferior_created" event.  */
@@ -3151,10 +3030,11 @@ 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))
-    add_thread (gdb_threadid);
+  thread_info *thr = find_thread_ptid (&the_procfs_target, gdb_threadid);
+  if (thr == NULL || thr->state == THREAD_EXITED)
+    add_thread (&the_procfs_target, gdb_threadid);
 
   return 0;
 }
@@ -3170,7 +3050,7 @@ procfs_target::update_thread_list ()
   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);
 }
@@ -3185,10 +3065,11 @@ 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)
+  pi = find_procinfo (proc, thread);
+  if (pi == NULL)
     return false;
 
   /* If I can't get its status, it ain't alive!
@@ -3203,18 +3084,42 @@ procfs_target::thread_alive (ptid_t ptid)
   return true;
 }
 
-/* Convert PTID to a string.  Returns the string in a static
-   buffer.  */
+/* Convert PTID to a string.  */
 
-const char *
+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;
 }
@@ -3228,8 +3133,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,16 +3211,12 @@ 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 true;
-       }
-    }
+    if (proc_why (pi) == PR_FAULTED)
+      if (proc_what (pi) == FLTWATCH)
+       return true;
   return false;
 }
 
@@ -3330,7 +3231,7 @@ 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);
 }
 
@@ -3341,20 +3242,16 @@ procfs_target::insert_watchpoint (CORE_ADDR addr, int len,
 {
   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);
 }
 
 int
@@ -3407,7 +3304,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)
@@ -3425,8 +3322,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;
 }
@@ -3463,7 +3363,7 @@ find_memory_regions_callback (struct prmap *map,
 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);
@@ -3554,7 +3454,6 @@ info_proc_mappings (procinfo *pi, int summary)
 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;
@@ -3576,7 +3475,6 @@ procfs_target::info_proc (const char *args, enum info_proc_what what)
       error (_("Not supported on this target."));
     }
 
-  old_chain = make_cleanup (null_cleanup, 0);
   gdb_argv built_argv (args);
   for (char *arg : built_argv)
     {
@@ -3591,8 +3489,10 @@ procfs_target::info_proc (const char *args, enum info_proc_what what)
          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
@@ -3605,7 +3505,7 @@ procfs_target::info_proc (const char *args, enum info_proc_what what)
           /* 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__);
         }
@@ -3632,11 +3532,7 @@ procfs_target::info_proc (const char *args, enum info_proc_what what)
     }
 
   if (mappings)
-    {
-      info_proc_mappings (process, 0);
-    }
-
-  do_cleanups (old_chain);
+    info_proc_mappings (process, 0);
 
   return true;
 }
@@ -3686,13 +3582,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);
@@ -3725,8 +3621,9 @@ proc_untrace_sysexit_cmd (const char *args, int from_tty)
   proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET);
 }
 
+void _initialize_procfs ();
 void
-_initialize_procfs (void)
+_initialize_procfs ()
 {
   gdb::observers::inferior_created.attach (procfs_inferior_created);
 
@@ -3739,7 +3636,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 (&the_procfs_target);
+  add_inf_child_target (&the_procfs_target);
 }
 
 /* =================== END, GDB  "MODULE" =================== */
@@ -3757,7 +3654,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" =================== */
@@ -3767,12 +3664,12 @@ procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
                            char *note_data, int *note_size,
                            enum gdb_signal stop_signal)
 {
-  struct regcache *regcache = get_thread_regcache (ptid);
+  struct regcache *regcache = get_thread_regcache (&the_procfs_target, ptid);
   gdb_gregset_t gregs;
   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
@@ -3815,7 +3712,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,
@@ -3829,7 +3726,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;
@@ -3850,17 +3747,13 @@ find_stop_signal (void)
 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))
@@ -3871,8 +3764,9 @@ procfs_target::make_corefile_notes (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));
@@ -3891,7 +3785,7 @@ procfs_target::make_corefile_notes (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;
@@ -3902,14 +3796,12 @@ procfs_target::make_corefile_notes (bfd *obfd, int *note_size)
                             &thread_args);
   note_data = thread_args.note_data;
 
-  auxv_len = target_read_alloc (target_stack, 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;
 }
This page took 0.049961 seconds and 4 git commands to generate.