* defs.h (extract_signed_integer, extract_unsigned_integer,
[deliverable/binutils-gdb.git] / gdb / procfs.c
index 090cf73c7b25a3cdedb5068bf7dc64faf6017a50..80479e351709c24a1ee3404f3bfcfc2142a76a09 100644 (file)
@@ -1,26 +1,25 @@
 /* Machine independent support for SVR4 /proc (process file system) for GDB.
 
-   Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
-   Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006, 2007, 2008, 2009
+   Free Software Foundation, Inc.
 
    Written by Michael Snyder at Cygnus Solutions.
    Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
 
-This file is part of GDB.
+   This file is part of GDB.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software Foundation, 
-Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "inferior.h"
@@ -29,6 +28,8 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "elf-bfd.h"           /* for elfcore_write_* */
 #include "gdbcmd.h"
 #include "gdbthread.h"
+#include "regcache.h"
+#include "inf-child.h"
 
 #if defined (NEW_PROC_API)
 #define _STRUCTURED_PROC 1     /* Should be done by configure script. */
@@ -45,10 +46,13 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "gdb_wait.h"
 #include <signal.h>
 #include <ctype.h>
+#include "gdb_string.h"
 #include "gdb_assert.h"
 #include "inflow.h"
+#include "auxv.h"
+#include "procfs.h"
 
-/* 
+/*
  * PROCFS.C
  *
  * This module provides the interface between GDB and the
@@ -73,7 +77,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  * This module has to support both /proc interfaces.  This means
  * that there are two different ways of doing every basic operation.
  *
- * In order to keep most of the code simple and clean, I have 
+ * In order to keep most of the code simple and clean, I have
  * defined an interface "layer" which hides all these system calls.
  * An ifdef (NEW_PROC_API) determines which interface we are using,
  * and most or all occurrances of this ifdef should be confined to
@@ -82,7 +86,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
 /* Determine which /proc API we are using:
-   The ioctl API defines PIOCSTATUS, while 
+   The ioctl API defines PIOCSTATUS, while
    the read/write (multiple fd) API never does.  */
 
 #ifdef NEW_PROC_API
@@ -109,90 +113,115 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  * This module defines the GDB target vector and its methods.
  */
 
-static void procfs_open (char *, int);
-static void procfs_attach (char *, int);
-static void procfs_detach (char *, int);
-static void procfs_resume (ptid_t, int, enum target_signal);
-static int procfs_can_run (void);
-static void procfs_stop (void);
+static void procfs_attach (struct target_ops *, char *, int);
+static void procfs_detach (struct target_ops *, char *, int);
+static void procfs_resume (struct target_ops *,
+                          ptid_t, int, enum target_signal);
+static void procfs_stop (ptid_t);
 static void procfs_files_info (struct target_ops *);
-static void procfs_fetch_registers (int);
-static void procfs_store_registers (int);
+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_notice_signals (ptid_t);
-static void procfs_prepare_to_store (void);
-static void procfs_kill_inferior (void);
-static void procfs_mourn_inferior (void);
-static void procfs_create_inferior (char *, char *, char **);
-static ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
-static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
+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 *, char *, 
+                                   char *, char **, int);
+static ptid_t procfs_wait (struct target_ops *,
+                          ptid_t, struct target_waitstatus *, int);
+static int procfs_xfer_memory (CORE_ADDR, gdb_byte *, int, int,
                               struct mem_attrib *attrib,
                               struct target_ops *);
+static LONGEST procfs_xfer_partial (struct target_ops *ops,
+                                   enum target_object object,
+                                   const char *annex,
+                                   gdb_byte *readbuf, const gdb_byte *writebuf,
+                                   ULONGEST offset, LONGEST len);
 
-static int procfs_thread_alive (ptid_t);
+static int procfs_thread_alive (struct target_ops *ops, ptid_t);
 
-void procfs_find_new_threads (void);
-char *procfs_pid_to_str (ptid_t);
+void procfs_find_new_threads (struct target_ops *ops);
+char *procfs_pid_to_str (struct target_ops *, ptid_t);
 
-static int proc_find_memory_regions (int (*) (CORE_ADDR, 
-                                             unsigned long, 
-                                             int, int, int, 
-                                             void *), 
+static int proc_find_memory_regions (int (*) (CORE_ADDR,
+                                             unsigned long,
+                                             int, int, int,
+                                             void *),
                                     void *);
 
 static char * procfs_make_note_section (bfd *, int *);
 
 static int procfs_can_use_hw_breakpoint (int, int, int);
 
-struct target_ops procfs_ops;          /* the target vector */
+#if defined (PR_MODEL_NATIVE) && (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)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+  gdb_byte *ptr = *readptr;
 
-static void
-init_procfs_ops (void)
+  if (endptr == ptr)
+    return 0;
+  
+  if (endptr - ptr < 8 * 2)
+    return -1;
+
+  *typep = extract_unsigned_integer (ptr, 4, byte_order);
+  ptr += 8;
+  /* The size of data is always 64-bit.  If the application is 32-bit,
+     it will be zero extended, as expected.  */
+  *valp = extract_unsigned_integer (ptr, 8, byte_order);
+  ptr += 8;
+
+  *readptr = ptr;
+  return 1;
+}
+#endif
+
+struct target_ops *
+procfs_target (void)
 {
-  procfs_ops.to_shortname           = "procfs";
-  procfs_ops.to_longname            = "Unix /proc child process";
-  procfs_ops.to_doc                 = 
+  struct target_ops *t = inf_child_target ();
+
+  t->to_shortname           = "procfs";
+  t->to_longname            = "Unix /proc child process";
+  t->to_doc                 =
     "Unix /proc child process (started by the \"run\" command).";
-  procfs_ops.to_open                = procfs_open;
-  procfs_ops.to_can_run             = procfs_can_run;
-  procfs_ops.to_create_inferior     = procfs_create_inferior;
-  procfs_ops.to_kill                = procfs_kill_inferior;
-  procfs_ops.to_mourn_inferior      = procfs_mourn_inferior;
-  procfs_ops.to_attach              = procfs_attach;
-  procfs_ops.to_detach              = procfs_detach;
-  procfs_ops.to_wait                = procfs_wait;
-  procfs_ops.to_resume              = procfs_resume;
-  procfs_ops.to_prepare_to_store    = procfs_prepare_to_store;
-  procfs_ops.to_fetch_registers     = procfs_fetch_registers;
-  procfs_ops.to_store_registers     = procfs_store_registers;
-  procfs_ops.to_xfer_memory         = procfs_xfer_memory;
-  procfs_ops.to_insert_breakpoint   =  memory_insert_breakpoint;
-  procfs_ops.to_remove_breakpoint   =  memory_remove_breakpoint;
-  procfs_ops.to_notice_signals      = procfs_notice_signals;
-  procfs_ops.to_files_info          = procfs_files_info;
-  procfs_ops.to_stop                = procfs_stop;
-
-  procfs_ops.to_terminal_init       = terminal_init_inferior;
-  procfs_ops.to_terminal_inferior   = terminal_inferior;
-  procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
-  procfs_ops.to_terminal_ours       = terminal_ours;
-  procfs_ops.to_terminal_save_ours  = terminal_save_ours;
-  procfs_ops.to_terminal_info       = child_terminal_info;
-
-  procfs_ops.to_find_new_threads    = procfs_find_new_threads;
-  procfs_ops.to_thread_alive        = procfs_thread_alive;
-  procfs_ops.to_pid_to_str          = procfs_pid_to_str;
-
-  procfs_ops.to_has_all_memory      = 1;
-  procfs_ops.to_has_memory          = 1;
-  procfs_ops.to_has_execution       = 1;
-  procfs_ops.to_has_stack           = 1;
-  procfs_ops.to_has_registers       = 1;
-  procfs_ops.to_stratum             = process_stratum;
-  procfs_ops.to_has_thread_control  = tc_schedlock;
-  procfs_ops.to_find_memory_regions = proc_find_memory_regions;
-  procfs_ops.to_make_corefile_notes = procfs_make_note_section;
-  procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
-  procfs_ops.to_magic               = OPS_MAGIC;
+  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->deprecated_xfer_memory = procfs_xfer_memory;
+  t->to_notice_signals      = procfs_notice_signals;
+  t->to_files_info          = procfs_files_info;
+  t->to_stop                = procfs_stop;
+
+  t->to_find_new_threads    = procfs_find_new_threads;
+  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;
+
+#if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+  t->to_auxv_parse = procfs_auxv_parse;
+#endif
+
+  t->to_magic               = OPS_MAGIC;
+
+  return t;
 }
 
 /* =================== END, TARGET_OPS "MODULE" =================== */
@@ -206,14 +235,14 @@ init_procfs_ops (void)
 
 #ifdef NEW_PROC_API            /* Solaris 7 && 8 method for watchpoints */
 #ifdef WA_READ
-     enum { READ_WATCHFLAG  = WA_READ, 
+     enum { READ_WATCHFLAG  = WA_READ,
            WRITE_WATCHFLAG = WA_WRITE,
            EXEC_WATCHFLAG  = WA_EXEC,
            AFTER_WATCHFLAG = WA_TRAPAFTER
      };
 #endif
 #else                          /* Irix method for watchpoints */
-     enum { READ_WATCHFLAG  = MA_READ, 
+     enum { READ_WATCHFLAG  = MA_READ,
            WRITE_WATCHFLAG = MA_WRITE,
            EXEC_WATCHFLAG  = MA_EXEC,
            AFTER_WATCHFLAG = 0         /* trapafter not implemented */
@@ -344,7 +373,7 @@ typedef struct procinfo {
   int was_stopped;
   int ignore_next_sigstop;
 
-  /* The following four fd fields may be identical, or may contain 
+  /* The following four fd fields may be identical, or may contain
      several different fd's, depending on the version of /proc
      (old ioctl or new read/write).  */
 
@@ -352,7 +381,7 @@ typedef struct procinfo {
   /*
    * The next three file descriptors are actually only needed in the
    * read/write, multiple-file-descriptor implemenation (NEW_PROC_API).
-   * However, to avoid a bunch of #ifdefs in the code, we will use 
+   * However, to avoid a bunch of #ifdefs in the code, we will use
    * them uniformly by (in the case of the ioctl single-file-descriptor
    * implementation) filling them with copies of the control fd.
    */
@@ -377,7 +406,7 @@ typedef struct procinfo {
   int num_syscalls;            /* Total number of syscalls */
   char **syscall_names;                /* Syscall number to name map */
 #endif
-  
+
   struct procinfo *thread_list;
 
   int status_valid : 1;
@@ -417,7 +446,7 @@ static procinfo * procinfo_list;
  * Returns: pointer to procinfo, or NULL if not found.
  */
 
-static procinfo * 
+static procinfo *
 find_procinfo (int pid, int tid)
 {
   procinfo *pi;
@@ -458,10 +487,10 @@ find_procinfo_or_die (int pid, int tid)
   if (pi == NULL)
     {
       if (tid)
-       error ("procfs: couldn't find pid %d (kernel thread %d) in procinfo list.", 
+       error (_("procfs: couldn't find pid %d (kernel thread %d) in procinfo list."),
               pid, tid);
       else
-       error ("procfs: couldn't find pid %d in procinfo list.", pid);
+       error (_("procfs: couldn't find pid %d in procinfo list."), pid);
     }
   return pi;
 }
@@ -469,14 +498,14 @@ find_procinfo_or_die (int pid, int tid)
 /* open_with_retry() is a wrapper for open().  The appropriate
    open() call is attempted; if unsuccessful, it will be retried as
    many times as needed for the EAGAIN and EINTR conditions.
-   
+
    For other conditions, open_with_retry() will retry the open() a
    limited number of times.  In addition, a short sleep is imposed
    prior to retrying the open().  The reason for this sleep is to give
    the kernel a chance to catch up and create the file in question in
    the event that GDB "wins" the race to open a file before the kernel
    has created it.  */
-   
+
 static int
 open_with_retry (const char *pathname, int flags)
 {
@@ -523,19 +552,19 @@ open_procinfo_files (procinfo *pi, int which)
 #endif
   int  fd;
 
-  /* 
+  /*
    * This function is getting ALMOST long enough to break up into several.
    * Here is some rationale:
    *
    * NEW_PROC_API (Solaris 2.6, Solaris 2.7, Unixware):
-   *   There are several file descriptors that may need to be open 
+   *   There are several file descriptors that may need to be open
    *   for any given process or LWP.  The ones we're intereted in are:
    *     - control      (ctl)    write-only    change the state
    *     - status       (status) read-only     query the state
    *     - address space (as)     read/write   access memory
    *     - map           (map)    read-only     virtual addr map
    *   Most of these are opened lazily as they are needed.
-   *   The pathnames for the 'files' for an LWP look slightly 
+   *   The pathnames for the 'files' for an LWP look slightly
    *   different from those of a first-class process:
    *     Pathnames for a process (<proc-id>):
    *       /proc/<proc-id>/ctl
@@ -553,12 +582,12 @@ open_procinfo_files (procinfo *pi, int which)
    *   For convenience, we copy the same file descriptor into all
    *   three fields of the procinfo struct (ctl_fd, status_fd, and
    *   as_fd, see NEW_PROC_API above) so that code that uses them
-   *   doesn't need any #ifdef's.  
+   *   doesn't need any #ifdef's.
    *     Pathname for all:
    *       /proc/<proc-id>
    *
    *   Solaris 2.5 LWP's:
-   *     Each LWP has an independent file descriptor, but these 
+   *     Each LWP has an independent file descriptor, but these
    *     are not obtained via the 'open' system call like the rest:
    *     instead, they're obtained thru an ioctl call (PIOCOPENLWP)
    *     to the file descriptor of the parent process.
@@ -617,11 +646,11 @@ open_procinfo_files (procinfo *pi, int which)
    * In this case, there is only one file descriptor for each procinfo
    * (ie. each process or LWP).  In fact, only the file descriptor for
    * the process can actually be opened by an 'open' system call.
-   * The ones for the LWPs have to be obtained thru an IOCTL call 
-   * on the process's file descriptor. 
+   * The ones for the LWPs have to be obtained thru an IOCTL call
+   * on the process's file descriptor.
    *
    * For convenience, we copy each procinfo's single file descriptor
-   * into all of the fields occupied by the several file descriptors 
+   * into all of the fields occupied by the several file descriptors
    * of the NEW_PROC_API implementation.  That way, the code that uses
    * them can be written without ifdefs.
    */
@@ -674,7 +703,7 @@ open_procinfo_files (procinfo *pi, int which)
 static procinfo *
 create_procinfo (int pid, int tid)
 {
-  procinfo *pi, *parent;
+  procinfo *pi, *parent = NULL;
 
   if ((pi = find_procinfo (pid, tid)))
     return pi;                 /* Already exists, nothing to do. */
@@ -751,7 +780,7 @@ destroy_one_procinfo (procinfo **list, procinfo *pi)
   /* Step one: unlink the procinfo from its list */
   if (pi == *list)
     *list = pi->next;
-  else 
+  else
     for (ptr = *list; ptr; ptr = ptr->next)
       if (ptr->next == pi)
        {
@@ -825,7 +854,7 @@ dead_procinfo (procinfo *pi, char *msg, int kill_p)
     kill (pi->pid, SIGKILL);
 
   destroy_procinfo (pi);
-  error (msg);
+  error ("%s", msg);
 }
 
 /*
@@ -849,7 +878,7 @@ sysset_t_size (procinfo * pi)
 }
 
 /* Function: sysset_t_alloc
-  
+
    Allocate and (partially) initialize a sysset_t struct.  */
 
 static sysset_t *
@@ -868,7 +897,7 @@ sysset_t_alloc (procinfo * pi)
 #ifdef DYNAMIC_SYSCALLS
 
 /* Function: load_syscalls
-  
+
    Extract syscall numbers and names from /proc/<pid>/sysent.  Initialize
    pi->num_syscalls with the number of syscalls and pi->syscall_names
    with the names.  (Certain numbers may be skipped in which case the
@@ -894,18 +923,18 @@ load_syscalls (procinfo *pi)
   sysent_fd = open_with_retry (pathname, O_RDONLY);
   if (sysent_fd < 0)
     {
-      error ("load_syscalls: Can't open /proc/%d/sysent", pi->pid);
+      error (_("load_syscalls: Can't open /proc/%d/sysent"), pi->pid);
     }
 
   size = sizeof header - sizeof (prsyscall_t);
   if (read (sysent_fd, &header, size) != size)
     {
-      error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid);
+      error (_("load_syscalls: Error reading /proc/%d/sysent"), pi->pid);
     }
 
   if (header.pr_nsyscalls == 0)
     {
-      error ("load_syscalls: /proc/%d/sysent contains no syscalls!", pi->pid);
+      error (_("load_syscalls: /proc/%d/sysent contains no syscalls!"), pi->pid);
     }
 
   size = header.pr_nsyscalls * sizeof (prsyscall_t);
@@ -914,7 +943,7 @@ load_syscalls (procinfo *pi)
   if (read (sysent_fd, syscalls, size) != size)
     {
       xfree (syscalls);
-      error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid);
+      error (_("load_syscalls: Error reading /proc/%d/sysent"), pi->pid);
     }
 
   /* Find maximum syscall number.  This may not be the same as
@@ -968,13 +997,13 @@ load_syscalls (procinfo *pi)
       strncpy (pi->syscall_names[callnum], namebuf, size-1);
       pi->syscall_names[callnum][size-1] = '\0';
     }
-  
+
   close (sysent_fd);
   xfree (syscalls);
 }
 
 /* Function: free_syscalls
-   
+
    Free the space allocated for the syscall names from the procinfo
    structure.  */
 
@@ -998,7 +1027,7 @@ free_syscalls (procinfo *pi)
 
    Given a name, look up (and return) the corresponding syscall number.
    If no match is found, return -1.  */
-   
+
 static int
 find_syscall (procinfo *pi, char *name)
 {
@@ -1018,7 +1047,7 @@ find_syscall (procinfo *pi, char *name)
 
 /*
  * This "module" is the interface layer between the /proc system API
- * and the gdb target vector functions.  This layer consists of 
+ * and the gdb target vector functions.  This layer consists of
  * access functions that encapsulate each of the basic operations
  * that we need to use from the /proc API.
  *
@@ -1118,16 +1147,16 @@ proc_get_status (procinfo *pi)
     pi->status_valid = 0;                      /* fail */
   else
     {
-      /* Sigh... I have to read a different data structure, 
+      /* Sigh... I have to read a different data structure,
         depending on whether this is a main process or an LWP. */
       if (pi->tid)
-       pi->status_valid = (read (pi->status_fd, 
-                                 (char *) &pi->prstatus.pr_lwp, 
+       pi->status_valid = (read (pi->status_fd,
+                                 (char *) &pi->prstatus.pr_lwp,
                                  sizeof (lwpstatus_t))
                            == sizeof (lwpstatus_t));
       else
        {
-         pi->status_valid = (read (pi->status_fd, 
+         pi->status_valid = (read (pi->status_fd,
                                    (char *) &pi->prstatus,
                                    sizeof (gdb_prstatus_t))
                              == sizeof (gdb_prstatus_t));
@@ -1136,7 +1165,7 @@ proc_get_status (procinfo *pi)
              (pi->prstatus.pr_lwp.pr_flags & PR_ISTOP) &&
              pi->prstatus.pr_lwp.pr_why == PR_REQUESTED)
            /* Unixware peculiarity -- read the damn thing again! */
-           pi->status_valid = (read (pi->status_fd, 
+           pi->status_valid = (read (pi->status_fd,
                                      (char *) &pi->prstatus,
                                      sizeof (gdb_prstatus_t))
                                == sizeof (gdb_prstatus_t));
@@ -1148,7 +1177,7 @@ proc_get_status (procinfo *pi)
   if (pi->tid == 0)    /* main process */
     {
       /* Just read the danged status.  Now isn't that simple? */
-      pi->status_valid = 
+      pi->status_valid =
        (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0);
     }
   else
@@ -1165,7 +1194,7 @@ proc_get_status (procinfo *pi)
       win = (ioctl (pi->status_fd, PIOCTSTATUS, &thread_status) >= 0);
       if (win)
        {
-         memcpy (&pi->prstatus, &thread_status.status, 
+         memcpy (&pi->prstatus, &thread_status.status,
                  sizeof (pi->prstatus));
          pi->status_valid = 1;
        }
@@ -1178,16 +1207,16 @@ proc_get_status (procinfo *pi)
 
   if (pi->status_valid)
     {
-      PROC_PRETTYFPRINT_STATUS (proc_flags (pi), 
+      PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
                                proc_why (pi),
-                               proc_what (pi), 
+                               proc_what (pi),
                                proc_get_current_thread (pi));
     }
 
   /* The status struct includes general regs, so mark them valid too */
   pi->gregs_valid  = pi->status_valid;
 #ifdef NEW_PROC_API
-  /* In the read/write multiple-fd model, 
+  /* In the read/write multiple-fd model,
      the status struct includes the fp regs too, so mark them valid too */
   pi->fpregs_valid = pi->status_valid;
 #endif
@@ -1198,7 +1227,7 @@ proc_get_status (procinfo *pi)
  * Function: proc_flags
  *
  * returns the process flags (pr_flags field).
- */ 
+ */
 
 long
 proc_flags (procinfo *pi)
@@ -1274,7 +1303,7 @@ proc_nsysarg (procinfo *pi)
   if (!pi->status_valid)
     if (!proc_get_status (pi))
       return 0;
-  
+
 #ifdef NEW_PROC_API
   return pi->prstatus.pr_lwp.pr_nsysarg;
 #else
@@ -1294,7 +1323,7 @@ proc_sysargs (procinfo *pi)
   if (!pi->status_valid)
     if (!proc_get_status (pi))
       return NULL;
-  
+
 #ifdef NEW_PROC_API
   return (long *) &pi->prstatus.pr_lwp.pr_sysarg;
 #else
@@ -1314,7 +1343,7 @@ proc_syscall (procinfo *pi)
   if (!pi->status_valid)
     if (!proc_get_status (pi))
       return 0;
-  
+
 #ifdef NEW_PROC_API
   return pi->prstatus.pr_lwp.pr_syscall;
 #else
@@ -1344,9 +1373,9 @@ proc_cursig (struct procinfo *pi)
 }
 
 /*
- * Function: proc_modify_flag 
+ * Function: proc_modify_flag
  *
- *  === I appologize for the messiness of this function. 
+ *  === I appologize for the messiness of this function.
  *  === This is an area where the different versions of
  *  === /proc are more inconsistent than usual.     MVS
  *
@@ -1368,7 +1397,7 @@ proc_cursig (struct procinfo *pi)
  * Note: OSF  does not define PR_KLC.
  * Note: OSF  is the only one that can ONLY use the oldest method.
  *
- * Arguments: 
+ * Arguments:
  *    pi   -- the procinfo
  *    flag -- one of PR_FORK, PR_RLC, or PR_ASYNC
  *    mode -- 1 for set, 0 for reset.
@@ -1383,20 +1412,20 @@ proc_modify_flag (procinfo *pi, long flag, long mode)
 {
   long win = 0;                /* default to fail */
 
-  /* 
-   * These operations affect the process as a whole, and applying 
-   * them to an individual LWP has the same meaning as applying them 
-   * to the main process.  Therefore, if we're ever called with a 
-   * pointer to an LWP's procinfo, let's substitute the process's 
-   * procinfo and avoid opening the LWP's file descriptor 
-   * unnecessarily.  
+  /*
+   * These operations affect the process as a whole, and applying
+   * them to an individual LWP has the same meaning as applying them
+   * to the main process.  Therefore, if we're ever called with a
+   * pointer to an LWP's procinfo, let's substitute the process's
+   * procinfo and avoid opening the LWP's file descriptor
+   * unnecessarily.
    */
 
   if (pi->pid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
 #ifdef NEW_PROC_API    /* Newest method: UnixWare and newer Solarii */
-  /* First normalize the PCUNSET/PCRESET command opcode 
+  /* First normalize the PCUNSET/PCRESET command opcode
      (which for no obvious reason has a different definition
      from one operating system to the next...)  */
 #ifdef  PCUNSET
@@ -1463,7 +1492,7 @@ proc_modify_flag (procinfo *pi, long flag, long mode)
   pi->status_valid = 0;
 
   if (!win)
-    warning ("procfs: modify_flag failed to turn %s %s", 
+    warning (_("procfs: modify_flag failed to turn %s %s"),
             flag == PR_FORK  ? "PR_FORK"  :
             flag == PR_RLC   ? "PR_RLC"   :
 #ifdef PR_ASYNC
@@ -1531,7 +1560,7 @@ proc_set_kill_on_last_close (procinfo *pi)
  * Function: proc_unset_kill_on_last_close
  *
  * Reset the kill_on_last_close flag.
- * Process will NOT be killed when debugger 
+ * Process will NOT be killed when debugger
  * closes its file handles (or exits or dies).
  *
  * Returns non-zero for success, zero for failure.
@@ -1581,7 +1610,7 @@ proc_unset_inherit_on_fork (procinfo *pi)
  * Function: proc_set_async
  *
  * Set PR_ASYNC flag.
- * If one LWP stops because of a debug event (signal etc.), 
+ * If one LWP stops because of a debug event (signal etc.),
  * the remaining LWPs will continue to run.
  *
  * Returns non-zero for success, zero for failure.
@@ -1614,7 +1643,7 @@ proc_unset_async (procinfo *pi)
  * Function: proc_stop_process
  *
  * Request the process/LWP to stop.  Does not wait.
- * Returns non-zero for success, zero for failure. 
+ * Returns non-zero for success, zero for failure.
  */
 
 int
@@ -1641,9 +1670,9 @@ proc_stop_process (procinfo *pi)
       if (win)
        {
          pi->status_valid = 1;
-         PROC_PRETTYFPRINT_STATUS (proc_flags (pi), 
+         PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
                                    proc_why (pi),
-                                   proc_what (pi), 
+                                   proc_what (pi),
                                    proc_get_current_thread (pi));
        }
 #endif
@@ -1656,7 +1685,7 @@ proc_stop_process (procinfo *pi)
  * Function: proc_wait_for_stop
  *
  * Wait for the process or LWP to stop (block until it does).
- * Returns non-zero for success, zero for failure. 
+ * Returns non-zero for success, zero for failure.
  */
 
 int
@@ -1667,10 +1696,10 @@ proc_wait_for_stop (procinfo *pi)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -1687,9 +1716,9 @@ proc_wait_for_stop (procinfo *pi)
   if (win)
     {
       pi->status_valid = 1;
-      PROC_PRETTYFPRINT_STATUS (proc_flags (pi), 
+      PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
                                proc_why (pi),
-                               proc_what (pi), 
+                               proc_what (pi),
                                proc_get_current_thread (pi));
     }
 #endif
@@ -1720,7 +1749,7 @@ proc_wait_for_stop (procinfo *pi)
  *   signo     if zero, clear the current signal if any.
  *             if non-zero, set the current signal to this one.
  *
- * Returns non-zero for success, zero for failure. 
+ * Returns non-zero for success, zero for failure.
  */
 
 int
@@ -1733,7 +1762,7 @@ 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)
     {
@@ -1773,7 +1802,7 @@ proc_run_process (procinfo *pi, int step, int signo)
  * Function: proc_set_traced_signals
  *
  * Register to trace signals in the process or LWP.
- * Returns non-zero for success, zero for failure. 
+ * Returns non-zero for success, zero for failure.
  */
 
 int
@@ -1784,10 +1813,10 @@ proc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -1811,7 +1840,7 @@ proc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset)
   pi->status_valid = 0;
 
   if (!win)
-    warning ("procfs: set_traced_signals failed");
+    warning (_("procfs: set_traced_signals failed"));
   return win;
 }
 
@@ -1819,7 +1848,7 @@ proc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset)
  * Function: proc_set_traced_faults
  *
  * Register to trace hardware faults in the process or LWP.
- * Returns non-zero for success, zero for failure. 
+ * Returns non-zero for success, zero for failure.
  */
 
 int
@@ -1830,10 +1859,10 @@ proc_set_traced_faults (procinfo *pi, fltset_t *fltset)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -1863,7 +1892,7 @@ proc_set_traced_faults (procinfo *pi, fltset_t *fltset)
  * Function: proc_set_traced_sysentry
  *
  * Register to trace entry to system calls in the process or LWP.
- * Returns non-zero for success, zero for failure. 
+ * Returns non-zero for success, zero for failure.
  */
 
 int
@@ -1874,10 +1903,10 @@ proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -1905,7 +1934,7 @@ proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset)
 #endif
   /* The above operation renders the procinfo's cached pstatus obsolete. */
   pi->status_valid = 0;
-     
+
   return win;
 }
 
@@ -1913,7 +1942,7 @@ proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset)
  * Function: proc_set_traced_sysexit
  *
  * Register to trace exit from system calls in the process or LWP.
- * Returns non-zero for success, zero for failure. 
+ * Returns non-zero for success, zero for failure.
  */
 
 int
@@ -1924,10 +1953,10 @@ proc_set_traced_sysexit (procinfo *pi, sysset_t *sysset)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -1963,7 +1992,7 @@ proc_set_traced_sysexit (procinfo *pi, sysset_t *sysset)
  * Function: proc_set_held_signals
  *
  * Specify the set of blocked / held signals in the process or LWP.
- * Returns non-zero for success, zero for failure. 
+ * Returns non-zero for success, zero for failure.
  */
 
 int
@@ -1974,10 +2003,10 @@ proc_set_held_signals (procinfo *pi, gdb_sigset_t *sighold)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2017,10 +2046,10 @@ proc_get_pending_signals (procinfo *pi, gdb_sigset_t *save)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2054,10 +2083,10 @@ proc_get_signal_actions (procinfo *pi, gdb_sigaction_t *save)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2091,10 +2120,10 @@ proc_get_held_signals (procinfo *pi, gdb_sigset_t *save)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2137,10 +2166,10 @@ proc_get_traced_signals (procinfo *pi, gdb_sigset_t *save)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2179,10 +2208,10 @@ proc_trace_signal (procinfo *pi, int signo)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2213,10 +2242,10 @@ proc_ignore_signal (procinfo *pi, int signo)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2247,10 +2276,10 @@ proc_get_traced_faults (procinfo *pi, fltset_t *save)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2289,10 +2318,10 @@ proc_get_traced_sysentry (procinfo *pi, sysset_t *save)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2362,10 +2391,10 @@ proc_get_traced_sysexit (procinfo *pi, sysset_t *save)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2435,10 +2464,10 @@ proc_clear_current_fault (procinfo *pi)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2477,21 +2506,23 @@ proc_set_current_signal (procinfo *pi, int signo)
     char sinfo[sizeof (gdb_siginfo_t)];
   } arg;
   gdb_siginfo_t *mysinfo;
+  ptid_t wait_ptid;
+  struct target_waitstatus wait_status;
 
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
 #ifdef PROCFS_DONT_PIOCSSIG_CURSIG
   /* With Alpha OSF/1 procfs, the kernel gets really confused if it
    * receives a PIOCSSIG with a signal identical to the current signal,
-   * it messes up the current signal. Work around the kernel bug. 
+   * it messes up the current signal. Work around the kernel bug.
    */
   if (signo > 0 &&
       signo == proc_cursig (pi))
@@ -2500,10 +2531,31 @@ proc_set_current_signal (procinfo *pi, int signo)
 
   /* The pointer is just a type alias.  */
   mysinfo = (gdb_siginfo_t *) &arg.sinfo;
-  mysinfo->si_signo = signo;
-  mysinfo->si_code  = 0;
-  mysinfo->si_pid   = getpid ();       /* ?why? */
-  mysinfo->si_uid   = getuid ();       /* ?why? */
+  get_last_target_status (&wait_ptid, &wait_status);
+  if (ptid_equal (wait_ptid, inferior_ptid)
+      && wait_status.kind == TARGET_WAITKIND_STOPPED
+      && wait_status.value.sig == target_signal_from_host (signo)
+      && proc_get_status (pi)
+#ifdef NEW_PROC_API
+      && pi->prstatus.pr_lwp.pr_info.si_signo == signo
+#else
+      && pi->prstatus.pr_info.si_signo == signo
+#endif
+      )
+    /* Use the siginfo associated with the signal being
+       redelivered.  */
+#ifdef NEW_PROC_API
+    memcpy (mysinfo, &pi->prstatus.pr_lwp.pr_info, sizeof (gdb_siginfo_t));
+#else
+    memcpy (mysinfo, &pi->prstatus.pr_info, sizeof (gdb_siginfo_t));
+#endif
+  else
+    {
+      mysinfo->si_signo = signo;
+      mysinfo->si_code  = 0;
+      mysinfo->si_pid   = getpid ();       /* ?why? */
+      mysinfo->si_uid   = getuid ();       /* ?why? */
+    }
 
 #ifdef NEW_PROC_API
   arg.cmd = PCSSIG;
@@ -2531,10 +2583,10 @@ proc_clear_current_signal (procinfo *pi)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2565,12 +2617,8 @@ proc_clear_current_signal (procinfo *pi)
   return win;
 }
 
-/*
- * Function: proc_get_gregs
- *
- * Get the general registers for the process or LWP.
- * Returns non-zero for success, zero for failure.
- */
+/* Return the general-purpose registers for the process or LWP
+   corresponding to PI.  Upon failure, return NULL.  */
 
 gdb_gregset_t *
 proc_get_gregs (procinfo *pi)
@@ -2579,29 +2627,22 @@ proc_get_gregs (procinfo *pi)
     if (!proc_get_status (pi))
       return NULL;
 
-  /*
-   * OK, sorry about the ifdef's.
-   * There's three cases instead of two, because 
-   * in this instance Unixware and Solaris/RW differ.
-   */
+  /* OK, sorry about the ifdef's.  There's three cases instead of two,
+     because in this case Unixware and Solaris/RW differ.  */
 
 #ifdef NEW_PROC_API
-#ifdef UNIXWARE                /* ugh, a true architecture dependency */
+# ifdef UNIXWARE               /* FIXME:  Should be autoconfigured.  */
   return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs;
-#else  /* not Unixware */
+# else
   return &pi->prstatus.pr_lwp.pr_reg;
-#endif /* Unixware */
-#else  /* not NEW_PROC_API */
+# endif
+#else
   return &pi->prstatus.pr_reg;
-#endif /* NEW_PROC_API */
+#endif
 }
 
-/*
- * Function: proc_get_fpregs
- *
- * Get the floating point registers for the process or LWP.
- * Returns non-zero for success, zero for failure.
- */
+/* Return the general-purpose registers for the process or LWP
+   corresponding to PI.  Upon failure, return NULL.  */
 
 gdb_fpregset_t *
 proc_get_fpregs (procinfo *pi)
@@ -2611,25 +2652,24 @@ proc_get_fpregs (procinfo *pi)
     if (!proc_get_status (pi))
       return NULL;
 
-#ifdef UNIXWARE                /* a true architecture dependency */
+# ifdef UNIXWARE               /* FIXME:  Should be autoconfigured.  */
   return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs;
-#else
+# else
   return &pi->prstatus.pr_lwp.pr_fpreg;
-#endif /* Unixware */
+# endif
 
-#else  /* not NEW_PROC_API */
+#else  /* not NEW_PROC_API */
   if (pi->fpregs_valid)
-    return &pi->fpregset;      /* already got 'em */
+    return &pi->fpregset;      /* Already got 'em.  */
   else
     {
-      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 NULL;
        }
       else
        {
-#ifdef PIOCTGFPREG
+# ifdef PIOCTGFPREG
          struct {
            long pr_count;
            tid_t pr_error_thread;
@@ -2639,46 +2679,43 @@ proc_get_fpregs (procinfo *pi)
          thread_fpregs.pr_count = 1;
          thread_fpregs.thread_1.tid = pi->tid;
 
-         if (pi->tid == 0 &&
-             ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0)
+         if (pi->tid == 0
+             && ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0)
            {
              pi->fpregs_valid = 1;
-             return &pi->fpregset;     /* got 'em now! */
+             return &pi->fpregset; /* Got 'em now!  */
            }
-         else if (pi->tid != 0 &&
-                  ioctl (pi->ctl_fd, PIOCTGFPREG, &thread_fpregs) >= 0)
+         else if (pi->tid != 0
+                  && ioctl (pi->ctl_fd, PIOCTGFPREG, &thread_fpregs) >= 0)
            {
              memcpy (&pi->fpregset, &thread_fpregs.thread_1.pr_fpregs,
                      sizeof (pi->fpregset));
              pi->fpregs_valid = 1;
-             return &pi->fpregset;     /* got 'em now! */
+             return &pi->fpregset; /* Got 'em now!  */
            }
          else
            {
              return NULL;
            }
-#else
+# else
          if (ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0)
            {
              pi->fpregs_valid = 1;
-             return &pi->fpregset;     /* got 'em now! */
+             return &pi->fpregset; /* Got 'em now!  */
            }
          else
            {
              return NULL;
            }
-#endif
+# endif
        }
     }
-#endif
+#endif /* NEW_PROC_API */
 }
 
-/*
- * Function: proc_set_gregs
- *
- * Write the general registers back to the process or LWP.
- * Returns non-zero for success, zero for failure.
- */
+/* Write the general-purpose registers back to the process or LWP
+   corresponding to PI.  Return non-zero for success, zero for
+   failure.  */
 
 int
 proc_set_gregs (procinfo *pi)
@@ -2686,11 +2723,11 @@ proc_set_gregs (procinfo *pi)
   gdb_gregset_t *gregs;
   int win;
 
-  if ((gregs = proc_get_gregs (pi)) == NULL)
-    return 0;  /* get_regs has already warned */
+  gregs = proc_get_gregs (pi);
+  if (gregs == NULL)
+    return 0;                  /* proc_get_regs has already warned.  */
 
-  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;
     }
@@ -2703,7 +2740,7 @@ proc_set_gregs (procinfo *pi)
        char gregs[sizeof (gdb_gregset_t)];
       } arg;
 
-      arg.cmd   = PCSREG;
+      arg.cmd = PCSREG;
       memcpy (&arg.gregs, gregs, sizeof (arg.gregs));
       win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
 #else
@@ -2711,17 +2748,14 @@ proc_set_gregs (procinfo *pi)
 #endif
     }
 
-  /* Policy: writing the regs invalidates our cache. */
+  /* Policy: writing the registers invalidates our cache.  */
   pi->gregs_valid = 0;
   return win;
 }
 
-/*
- * Function: proc_set_fpregs
- *
- * Modify the floating point register set of the process or LWP.
- * Returns non-zero for success, zero for failure.
- */
+/* Write the floating-pointer registers back to the process or LWP
+   corresponding to PI.  Return non-zero for success, zero for
+   failure.  */
 
 int
 proc_set_fpregs (procinfo *pi)
@@ -2729,11 +2763,11 @@ proc_set_fpregs (procinfo *pi)
   gdb_fpregset_t *fpregs;
   int win;
 
-  if ((fpregs = proc_get_fpregs (pi)) == NULL)
-    return 0;          /* get_fpregs has already warned */
+  fpregs = proc_get_fpregs (pi);
+  if (fpregs == NULL)
+    return 0;                  /* proc_get_fpregs has already warned.  */
 
-  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;
     }
@@ -2746,11 +2780,11 @@ proc_set_fpregs (procinfo *pi)
        char fpregs[sizeof (gdb_fpregset_t)];
       } arg;
 
-      arg.cmd   = PCSFPREG;
+      arg.cmd = PCSFPREG;
       memcpy (&arg.fpregs, fpregs, sizeof (arg.fpregs));
       win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
 #else
-#ifdef PIOCTSFPREG
+# ifdef PIOCTSFPREG
       if (pi->tid == 0)
        win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0);
       else
@@ -2767,13 +2801,13 @@ proc_set_fpregs (procinfo *pi)
                  sizeof (*fpregs));
          win = (ioctl (pi->ctl_fd, PIOCTSFPREG, &thread_fpregs) >= 0);
        }
-#else
+# else
       win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0);
-#endif /* osf PIOCTSFPREG */
-#endif /* NEW_PROC_API */
+# endif
+#endif /* NEW_PROC_API */
     }
 
-  /* Policy: writing the regs invalidates our cache. */
+  /* Policy: writing the registers invalidates our cache.  */
   pi->fpregs_valid = 0;
   return win;
 }
@@ -2831,10 +2865,10 @@ proc_parent_pid (procinfo *pi)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -2852,10 +2886,12 @@ proc_parent_pid (procinfo *pi)
 static void *
 procfs_address_to_host_pointer (CORE_ADDR addr)
 {
+  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
   void *ptr;
 
-  gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr));
-  ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr);
+  gdb_assert (sizeof (ptr) == TYPE_LENGTH (ptr_type));
+  gdbarch_address_to_pointer (target_gdbarch, ptr_type,
+                             (gdb_byte *) &ptr, addr);
   return ptr;
 }
 
@@ -2867,7 +2903,10 @@ procfs_address_to_host_pointer (CORE_ADDR addr)
 int
 proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
 {
-#if !defined (TARGET_HAS_HARDWARE_WATCHPOINTS)  
+#if !defined (PCWATCH) && !defined (PIOCSWATCH)
+  /* If neither or these is defined, we can't support watchpoints.
+     This just avoids possibly failing to compile the below on such
+     systems.  */
   return 0;
 #else
 /* Horrible hack!  Detect Solaris 2.5, because this doesn't work on 2.5 */
@@ -2905,7 +2944,7 @@ proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
 #endif
 }
 
-#ifdef TM_I386SOL2_H           /* Is it hokey to use this? */
+#if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
 
 #include <sys/sysi86.h>
 
@@ -2975,11 +3014,11 @@ proc_get_LDT_entry (procinfo *pi, int key)
   /* This alloc has to persist, 'cause we return a pointer to it. */
   if (nldt > nalloc)
     {
-      ldt_entry = (struct ssd *) 
+      ldt_entry = (struct ssd *)
        xrealloc (ldt_entry, (nldt + 1) * sizeof (struct ssd));
       nalloc = nldt;
     }
-  
+
   /* Read the whole table in one gulp.  */
   if (ioctl (pi->ctl_fd, PIOCLDT, ldt_entry) < 0)
     {
@@ -2997,7 +3036,45 @@ proc_get_LDT_entry (procinfo *pi, int key)
 #endif
 }
 
-#endif /* TM_I386SOL2_H */
+/*
+ * Function: procfs_find_LDT_entry
+ *
+ * Input:
+ *   ptid_t ptid;      // The GDB-style pid-plus-LWP.
+ *
+ * Return:
+ *   pointer to the corresponding LDT entry.
+ */
+
+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 (PIDGET (ptid), TIDGET (ptid))) == NULL)
+    {
+      warning (_("procfs_find_LDT_entry: could not find procinfo for %d:%ld."),
+              PIDGET (ptid), TIDGET (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."),
+              PIDGET (ptid), TIDGET (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" =============== */
 
@@ -3007,16 +3084,16 @@ proc_get_LDT_entry (procinfo *pi, int key)
    since there is a different way to do threads on every OS.  */
 
 /*
- * Function: proc_get_nthreads 
+ * Function: proc_get_nthreads
  *
- * Return the number of threads for the process 
+ * Return the number of threads for the process
  */
 
 #if defined (PIOCNTHR) && defined (PIOCTLIST)
 /*
  * OSF version
  */
-int 
+int
 proc_get_nthreads (procinfo *pi)
 {
   int nthreads = 0;
@@ -3040,10 +3117,10 @@ proc_get_nthreads (procinfo *pi)
       return 0;
 
   /*
-   * NEW_PROC_API: only works for the process procinfo, 
+   * NEW_PROC_API: only works for the process procinfo,
    * because the LWP procinfos do not get prstatus filled in.
    */
-#ifdef NEW_PROC_API  
+#ifdef NEW_PROC_API
   if (pi->tid != 0)    /* find the parent process procinfo */
     pi = find_procinfo_or_die (pi->pid, 0);
 #endif
@@ -3081,10 +3158,10 @@ proc_get_current_thread (procinfo *pi)
   /*
    * Note: this should be applied to the root procinfo for the process,
    * not to the procinfo for an LWP.  If applied to the procinfo for
-   * an LWP, it will simply return that LWP's ID.  In that case, 
+   * an LWP, it will simply return that LWP's ID.  In that case,
    * find the parent process procinfo.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -3104,7 +3181,7 @@ proc_get_current_thread (procinfo *pi)
 /*
  * OSF version
  */
-int 
+int
 proc_get_current_thread (procinfo *pi)
 {
 #if 0  /* FIXME: not ready for prime time? */
@@ -3118,7 +3195,7 @@ proc_get_current_thread (procinfo *pi)
 /*
  * Default version
  */
-int 
+int
 proc_get_current_thread (procinfo *pi)
 {
   return 0;
@@ -3128,7 +3205,7 @@ proc_get_current_thread (procinfo *pi)
 #endif
 
 /*
- * Function: proc_update_threads 
+ * Function: proc_update_threads
  *
  * Discover the IDs of all the threads within the process, and
  * create a procinfo for each of them (chained to the parent).
@@ -3165,10 +3242,10 @@ proc_update_threads (procinfo *pi)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -3220,10 +3297,10 @@ proc_update_threads (procinfo *pi)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -3232,8 +3309,8 @@ proc_update_threads (procinfo *pi)
   /*
    * Unixware
    *
-   * Note: this brute-force method is the only way I know of 
-   * to accomplish this task on Unixware.  This method will 
+   * Note: this brute-force method is the only way I know of
+   * to accomplish this task on Unixware.  This method will
    * also work on Solaris 2.6 and 2.7.  There is a much simpler
    * and more elegant way to do this on Solaris, but the margins
    * of this manuscript are too small to write it here...  ;-)
@@ -3261,7 +3338,7 @@ proc_update_threads (procinfo *pi)
 /*
  * OSF version
  */
-int 
+int
 proc_update_threads (procinfo *pi)
 {
   int nthreads, i;
@@ -3270,10 +3347,10 @@ proc_update_threads (procinfo *pi)
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -3284,7 +3361,7 @@ proc_update_threads (procinfo *pi)
     return 0;          /* nothing to do for 1 or fewer threads */
 
   threads = xmalloc (nthreads * sizeof (tid_t));
-  
+
   if (ioctl (pi->ctl_fd, PIOCTLIST, threads) < 0)
     proc_error (pi, "procfs: update_threads (PIOCTLIST)", __LINE__);
 
@@ -3322,8 +3399,8 @@ proc_update_threads (procinfo *pi)
  * Note: this function does NOT call update_threads.
  * If you want to discover new threads first, you must
  * call that function explicitly.  This function just makes
- * a quick pass over the currently-known procinfos. 
- * 
+ * a quick pass over the currently-known procinfos.
+ *
  * Arguments:
  *   pi                - parent process procinfo
  *   func      - per-thread function
@@ -3344,10 +3421,10 @@ proc_iterate_over_threads (procinfo *pi,
   /*
    * We should never have to apply this operation to any procinfo
    * except the one for the main process.  If that ever changes
-   * for any reason, then take out the following clause and 
+   * for any reason, then take out the following clause and
    * replace it with one that makes sure the ctl_fd is open.
    */
-  
+
   if (pi->tid != 0)
     pi = find_procinfo_or_die (pi->pid, 0);
 
@@ -3374,6 +3451,17 @@ proc_iterate_over_threads (procinfo *pi,
 static ptid_t do_attach (ptid_t ptid);
 static void do_detach (int signo);
 static int register_gdb_signals (procinfo *, gdb_sigset_t *);
+static void proc_trace_syscalls_1 (procinfo *pi, int syscallnum,
+                                   int entry_or_exit, int mode, int from_tty);
+static int insert_dbx_link_breakpoint (procinfo *pi);
+static void remove_dbx_link_breakpoint (void);
+
+/* On mips-irix, we need to insert a breakpoint at __dbx_link during
+   the startup phase.  The following two variables are used to record
+   the address of the breakpoint, and the code that was replaced by
+   a breakpoint.  */
+static int dbx_link_bpt_addr = 0;
+static void *dbx_link_bpt;
 
 /*
  * Function: procfs_debug_inferior
@@ -3504,72 +3592,80 @@ procfs_debug_inferior (procinfo *pi)
   return 0;
 }
 
-static void 
-procfs_attach (char *args, int from_tty)
+static void
+procfs_attach (struct target_ops *ops, char *args, int from_tty)
 {
   char *exec_file;
   int   pid;
 
   if (!args)
-    error_no_arg ("process-id to attach");
+    error_no_arg (_("process-id to attach"));
 
   pid = atoi (args);
   if (pid == getpid ())
-    error ("Attaching GDB to itself is not a good idea...");
+    error (_("Attaching GDB to itself is not a good idea..."));
 
   if (from_tty)
     {
       exec_file = get_exec_file (0);
 
       if (exec_file)
-       printf_filtered ("Attaching to program `%s', %s\n", 
+       printf_filtered (_("Attaching to program `%s', %s\n"),
                         exec_file, target_pid_to_str (pid_to_ptid (pid)));
       else
-       printf_filtered ("Attaching to %s\n",
+       printf_filtered (_("Attaching to %s\n"),
                         target_pid_to_str (pid_to_ptid (pid)));
 
       fflush (stdout);
     }
   inferior_ptid = do_attach (pid_to_ptid (pid));
-  push_target (&procfs_ops);
+  push_target (ops);
 }
 
-static void 
-procfs_detach (char *args, int from_tty)
+static void
+procfs_detach (struct target_ops *ops, char *args, int from_tty)
 {
-  char *exec_file;
-  int   signo = 0;
+  int sig = 0;
+  int pid = PIDGET (inferior_ptid);
+
+  if (args)
+    sig = atoi (args);
 
   if (from_tty)
     {
+      char *exec_file;
+
       exec_file = get_exec_file (0);
-      if (exec_file == 0)
+      if (exec_file == NULL)
        exec_file = "";
-      printf_filtered ("Detaching from program: %s %s\n",
-             exec_file, target_pid_to_str (inferior_ptid));
-      fflush (stdout);
+
+      printf_filtered (_("Detaching from program: %s, %s\n"), exec_file,
+                      target_pid_to_str (pid_to_ptid (pid)));
+      gdb_flush (gdb_stdout);
     }
-  if (args)
-    signo = atoi (args);
-  
-  do_detach (signo);
+
+  do_detach (sig);
+
   inferior_ptid = null_ptid;
-  unpush_target (&procfs_ops);         /* Pop out of handling an inferior */
+  detach_inferior (pid);
+  unpush_target (ops);
 }
 
 static ptid_t
 do_attach (ptid_t ptid)
 {
   procinfo *pi;
+  struct inferior *inf;
   int fail;
+  int lwpid;
 
   if ((pi = create_procinfo (PIDGET (ptid), 0)) == NULL)
-    perror ("procfs: out of memory in 'attach'");
+    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", 
+      sprintf (errmsg, "do_attach: couldn't open /proc file for process %d",
               PIDGET (ptid));
       dead_procinfo (pi, errmsg, NOKILL);
     }
@@ -3601,7 +3697,7 @@ do_attach (ptid_t ptid)
     dead_procinfo (pi, "do_attach: couldn't save traced syscall entries.",
                   NOKILL);
   if (!proc_get_traced_sysexit  (pi, pi->saved_exitset))
-    dead_procinfo (pi, "do_attach: couldn't save traced syscall exits.", 
+    dead_procinfo (pi, "do_attach: couldn't save traced syscall exits.",
                   NOKILL);
   if (!proc_get_held_signals    (pi, &pi->saved_sighold))
     dead_procinfo (pi, "do_attach: couldn't save held signals.", NOKILL);
@@ -3609,9 +3705,19 @@ do_attach (ptid_t ptid)
   if ((fail = procfs_debug_inferior (pi)) != 0)
     dead_procinfo (pi, "do_attach: failed in procfs_debug_inferior", NOKILL);
 
+  inf = add_inferior (pi->pid);
   /* Let GDB know that the inferior was attached.  */
-  attach_flag = 1;
-  return MERGEPID (pi->pid, proc_get_current_thread (pi));
+  inf->attach_flag = 1;
+
+  /* Create a procinfo for the current lwp.  */
+  lwpid = proc_get_current_thread (pi);
+  create_procinfo (pi->pid, lwpid);
+
+  /* Add it to gdb's thread list.  */
+  ptid = MERGEPID (pi->pid, lwpid);
+  add_thread (ptid);
+
+  return ptid;
 }
 
 static void
@@ -3642,7 +3748,7 @@ do_detach (int signo)
 
   if (signo || (proc_flags (pi) & (PR_STOPPED | PR_ISTOP)))
     if (signo || !(pi->was_stopped) ||
-       query ("Was stopped when attached, make it runnable again? "))
+       query (_("Was stopped when attached, make it runnable again? ")))
       {
        /* Clear any pending signal.  */
        if (!proc_clear_current_fault (pi))
@@ -3655,137 +3761,110 @@ do_detach (int signo)
          proc_warn (pi, "do_detach, set_rlc", __LINE__);
       }
 
-  attach_flag = 0;
   destroy_procinfo (pi);
 }
 
-/*
- * fetch_registers
- *
- * Since the /proc interface cannot give us individual registers,
- * we pay no attention to the (regno) argument, and just fetch them all.
- * This results in the possibility that we will do unnecessarily many
- * fetches, since we may be called repeatedly for individual registers.
- * So we cache the results, and mark the cache invalid when the process
- * is resumed.
- */
+/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
+   for all registers.
 
-static void
-procfs_fetch_registers (int regno)
-{
-  gdb_fpregset_t *fpregs;
-  gdb_gregset_t  *gregs;
-  procinfo       *pi;
-  int            pid;
-  int            tid;
+   ??? Is the following note still relevant?  We can't get individual
+   registers with the PT_GETREGS ptrace(2) request either, yet we
+   don't bother with caching at all in that case.
 
-  pid = PIDGET (inferior_ptid);
-  tid = TIDGET (inferior_ptid);
+   NOTE: Since the /proc interface cannot give us individual
+   registers, we pay no attention to REGNUM, and just fetch them all.
+   This results in the possibility that we will do unnecessarily many
+   fetches, since we may be called repeatedly for individual
+   registers.  So we cache the results, and mark the cache invalid
+   when the process is resumed.  */
 
-  /* First look up procinfo for the main process. */
-  pi  = find_procinfo_or_die (pid, 0);
+static void
+procfs_fetch_registers (struct target_ops *ops,
+                       struct regcache *regcache, int regnum)
+{
+  gdb_gregset_t *gregs;
+  procinfo *pi;
+  int pid = PIDGET (inferior_ptid);
+  int tid = TIDGET (inferior_ptid);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
-  /* If the event thread is not the same as GDB's requested thread 
-     (ie. inferior_ptid), then look up procinfo for the requested 
-     thread.  */
-  if ((tid != 0) && 
-      (tid != proc_get_current_thread (pi)))
-    pi = find_procinfo_or_die (pid, tid);
+  pi = find_procinfo_or_die (pid, tid);
 
   if (pi == NULL)
-    error ("procfs: fetch_registers failed to find procinfo for %s", 
+    error (_("procfs: fetch_registers failed to find procinfo for %s"),
           target_pid_to_str (inferior_ptid));
 
-  if ((gregs = proc_get_gregs (pi)) == NULL)
+  gregs = proc_get_gregs (pi);
+  if (gregs == NULL)
     proc_error (pi, "fetch_registers, get_gregs", __LINE__);
 
-  supply_gregset (gregs);
+  supply_gregset (regcache, (const gdb_gregset_t *) gregs);
 
-  if (FP0_REGNUM >= 0) /* need floating point? */
+  if (gdbarch_fp0_regnum (gdbarch) >= 0) /* Do we have an FPU?  */
     {
-      if ((regno >= 0 && regno < FP0_REGNUM)
-         || regno == PC_REGNUM
-         || regno == DEPRECATED_FP_REGNUM
-         || regno == SP_REGNUM)
-       return;                 /* not a floating point register */
+      gdb_fpregset_t *fpregs;
+
+      if ((regnum >= 0 && regnum < gdbarch_fp0_regnum (gdbarch))
+         || regnum == gdbarch_pc_regnum (gdbarch)
+         || regnum == gdbarch_sp_regnum (gdbarch))
+       return;                 /* Not a floating point register.  */
 
-      if ((fpregs = proc_get_fpregs (pi)) == NULL)
+      fpregs = proc_get_fpregs (pi);
+      if (fpregs == NULL)
        proc_error (pi, "fetch_registers, get_fpregs", __LINE__);
 
-      supply_fpregset (fpregs);
+      supply_fpregset (regcache, (const gdb_fpregset_t *) fpregs);
     }
 }
 
-/* Get ready to modify the registers array.  On machines which store
-   individual registers, this doesn't need to do anything.  On
-   machines which store all the registers in one fell swoop, such as
-   /proc, this makes sure that registers contains all the registers
-   from the program being debugged.  */
+/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
+   this for all registers.
 
-static void
-procfs_prepare_to_store (void)
-{
-#ifdef CHILD_PREPARE_TO_STORE
-  CHILD_PREPARE_TO_STORE ();
-#endif
-}
-
-/*
- * store_registers
- *
- * Since the /proc interface will not read individual registers, 
- * we will cache these requests until the process is resumed, and
- * only then write them back to the inferior process.
- *
- * FIXME: is that a really bad idea?  Have to think about cases
- * where writing one register might affect the value of others, etc.
- */
+   NOTE: Since the /proc interface will not read individual registers,
+   we will cache these requests until the process is resumed, and only
+   then write them back to the inferior process.
+   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 (int regno)
+procfs_store_registers (struct target_ops *ops,
+                       struct regcache *regcache, int regnum)
 {
-  gdb_fpregset_t *fpregs;
-  gdb_gregset_t  *gregs;
-  procinfo       *pi;
-  int            pid;
-  int            tid;
-
-  pid = PIDGET (inferior_ptid);
-  tid = TIDGET (inferior_ptid);
-
-  /* First find procinfo for main process */
-  pi  = find_procinfo_or_die (pid, 0);
-
-  /* If current lwp for process is not the same as requested thread
-     (ie. inferior_ptid), then find procinfo for the requested thread.  */
+  gdb_gregset_t *gregs;
+  procinfo *pi;
+  int pid = PIDGET (inferior_ptid);
+  int tid = TIDGET (inferior_ptid);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
-  if ((tid != 0) && 
-      (tid != proc_get_current_thread (pi)))
-    pi = find_procinfo_or_die (pid, tid);
+  pi = find_procinfo_or_die (pid, tid);
 
   if (pi == NULL)
-    error ("procfs: store_registers: failed to find procinfo for %s",
+    error (_("procfs: store_registers: failed to find procinfo for %s"),
           target_pid_to_str (inferior_ptid));
 
-  if ((gregs = proc_get_gregs (pi)) == NULL)
+  gregs = proc_get_gregs (pi);
+  if (gregs == NULL)
     proc_error (pi, "store_registers, get_gregs", __LINE__);
 
-  fill_gregset (gregs, regno);
+  fill_gregset (regcache, gregs, regnum);
   if (!proc_set_gregs (pi))
     proc_error (pi, "store_registers, set_gregs", __LINE__);
 
-  if (FP0_REGNUM >= 0)         /* need floating point? */
+  if (gdbarch_fp0_regnum (gdbarch) >= 0) /* Do we have an FPU?  */
     {
-      if ((regno >= 0 && regno < FP0_REGNUM)
-         || regno == PC_REGNUM
-         || regno == DEPRECATED_FP_REGNUM
-         || regno == SP_REGNUM)
-       return;                 /* not a floating point register */
+      gdb_fpregset_t *fpregs;
 
-      if ((fpregs = proc_get_fpregs (pi)) == NULL)
+      if ((regnum >= 0 && regnum < gdbarch_fp0_regnum (gdbarch))
+         || regnum == gdbarch_pc_regnum (gdbarch)
+         || regnum == gdbarch_sp_regnum (gdbarch))
+       return;                 /* Not a floating point register.  */
+
+      fpregs = proc_get_fpregs (pi);
+      if (fpregs == NULL)
        proc_error (pi, "store_registers, get_fpregs", __LINE__);
 
-      fill_fpregset (fpregs, regno);
+      fill_fpregset (regcache, fpregs, regnum);
       if (!proc_set_fpregs (pi))
        proc_error (pi, "store_registers, set_fpregs", __LINE__);
     }
@@ -3871,7 +3950,8 @@ syscall_is_lwp_create (procinfo *pi, int scall)
  */
 
 static ptid_t
-procfs_wait (ptid_t ptid, struct target_waitstatus *status)
+procfs_wait (struct target_ops *ops,
+            ptid_t ptid, struct target_waitstatus *status, int options)
 {
   /* First cut: loosely based on original version 2.1 */
   procinfo *pi;
@@ -3915,7 +3995,7 @@ wait_again:
              wait_retval = wait (&wstat); /* "wait" for the child's exit  */
 
              if (wait_retval != PIDGET (inferior_ptid)) /* wrong child? */
-               error ("procfs: couldn't stop process %d: wait returned %d\n",
+               error (_("procfs: couldn't stop process %d: wait returned %d."),
                       PIDGET (inferior_ptid), wait_retval);
              /* FIXME: might I not just use waitpid?
                 Or try find_procinfo to see if I know about this child? */
@@ -3938,7 +4018,7 @@ wait_again:
             into a waitstatus for GDB.
 
             If we actually had to call wait because the /proc file
-            is gone (child terminated), then we skip this block, 
+            is gone (child terminated), then we skip this block,
             because we already have a waitstatus.  */
 
          flags = proc_flags (pi);
@@ -3969,30 +4049,35 @@ wait_again:
              case PR_SYSENTRY:
                if (syscall_is_lwp_exit (pi, what))
                  {
-                   printf_filtered ("[%s exited]\n",
-                                    target_pid_to_str (retval));
+                   if (print_thread_events)
+                     printf_unfiltered (_("[%s exited]\n"),
+                                        target_pid_to_str (retval));
                    delete_thread (retval);
                    status->kind = TARGET_WAITKIND_SPURIOUS;
                    return retval;
                  }
                else if (syscall_is_exit (pi, what))
                  {
+                   struct inferior *inf;
+
                    /* Handle SYS_exit call only */
                    /* Stopped at entry to SYS_exit.
-                      Make it runnable, resume it, then use 
+                      Make it runnable, resume it, then use
                       the wait system call to get its exit code.
-                      Proc_run_process always clears the current 
+                      Proc_run_process always clears the current
                       fault and signal.
                       Then return its exit status.  */
                    pi->status_valid = 0;
                    wstat = 0;
-                   /* FIXME: what we should do is return 
+                   /* FIXME: what we should do is return
                       TARGET_WAITKIND_SPURIOUS.  */
                    if (!proc_run_process (pi, 0, 0))
                      proc_error (pi, "target_wait, run_process", __LINE__);
-                   if (attach_flag)
+
+                   inf = find_inferior_pid (pi->pid);
+                   if (inf->attach_flag)
                      {
-                       /* Don't call wait: simulate waiting for exit, 
+                       /* Don't call wait: simulate waiting for exit,
                           return a "success" exit code.  Bogus: what if
                           it returns something else?  */
                        wstat = 0;
@@ -4016,7 +4101,7 @@ wait_again:
                  }
                else
                  {
-                   printf_filtered ("procfs: trapped on entry to ");
+                   printf_filtered (_("procfs: trapped on entry to "));
                    proc_prettyprint_syscall (proc_what (pi), 0);
                    printf_filtered ("\n");
 #ifndef PIOCSSPCACT
@@ -4026,9 +4111,9 @@ wait_again:
                      if ((nsysargs = proc_nsysarg (pi)) > 0 &&
                          (sysargs  = proc_sysargs (pi)) != NULL)
                        {
-                         printf_filtered ("%ld syscall arguments:\n", nsysargs);
+                         printf_filtered (_("%ld syscall arguments:\n"), nsysargs);
                          for (i = 0; i < nsysargs; i++)
-                           printf_filtered ("#%ld: 0x%08lx\n", 
+                           printf_filtered ("#%ld: 0x%08lx\n",
                                             i, sysargs[i]);
                        }
 
@@ -4057,6 +4142,22 @@ wait_again:
                       address. */
                    wstat = (SIGTRAP << 8) | 0177;
                  }
+#ifdef SYS_syssgi
+                else if (what == SYS_syssgi)
+                  {
+                    /* see if we can break on dbx_link().  If yes, then
+                       we no longer need the SYS_syssgi notifications.  */
+                    if (insert_dbx_link_breakpoint (pi))
+                      proc_trace_syscalls_1 (pi, SYS_syssgi, PR_SYSEXIT,
+                                             FLAG_RESET, 0);
+
+                    /* This is an internal event and should be transparent
+                       to wfi, so resume the execution and wait again.  See
+                       comment in procfs_init_inferior() for more details.  */
+                    target_resume (ptid, 0, TARGET_SIGNAL_0);
+                    goto wait_again;
+                  }
+#endif
                else if (syscall_is_lwp_create (pi, what))
                  {
                    /*
@@ -4076,19 +4177,17 @@ wait_again:
                    temp_ptid = MERGEPID (pi->pid, temp_tid);
                    /* If not in GDB's thread list, add it.  */
                    if (!in_thread_list (temp_ptid))
-                     {
-                       printf_filtered ("[New %s]\n",
-                                        target_pid_to_str (temp_ptid));
-                       add_thread (temp_ptid);
-                     }
+                     add_thread (temp_ptid);
+
                    /* Return to WFI, but tell it to immediately resume. */
                    status->kind = TARGET_WAITKIND_SPURIOUS;
                    return inferior_ptid;
                  }
                else if (syscall_is_lwp_exit (pi, what))
                  {
-                   printf_filtered ("[%s exited]\n",
-                                    target_pid_to_str (retval));
+                   if (print_thread_events)
+                     printf_unfiltered (_("[%s exited]\n"),
+                                        target_pid_to_str (retval));
                    delete_thread (retval);
                    status->kind = TARGET_WAITKIND_SPURIOUS;
                    return retval;
@@ -4099,12 +4198,12 @@ wait_again:
                       SYS_fork, or SYS_vfork here?  The old procfs
                       seemed to use this event to handle threads on
                       older (non-LWP) systems, where I'm assuming
-                      that threads were actually separate processes. 
+                      that threads were actually separate processes.
                       Irix, maybe?  Anyway, low priority for now.  */
                  }
                else
                  {
-                   printf_filtered ("procfs: trapped on exit from ");
+                   printf_filtered (_("procfs: trapped on exit from "));
                    proc_prettyprint_syscall (proc_what (pi), 0);
                    printf_filtered ("\n");
 #ifndef PIOCSSPCACT
@@ -4114,9 +4213,9 @@ wait_again:
                      if ((nsysargs = proc_nsysarg (pi)) > 0 &&
                          (sysargs  = proc_sysargs (pi)) != NULL)
                        {
-                         printf_filtered ("%ld syscall arguments:\n", nsysargs);
+                         printf_filtered (_("%ld syscall arguments:\n"), nsysargs);
                          for (i = 0; i < nsysargs; i++)
-                           printf_filtered ("#%ld: 0x%08lx\n", 
+                           printf_filtered ("#%ld: 0x%08lx\n",
                                             i, sysargs[i]);
                        }
                    }
@@ -4132,7 +4231,7 @@ wait_again:
 #else
                if (retry < 5)
                  {
-                   printf_filtered ("Retry #%d:\n", retry);
+                   printf_filtered (_("Retry #%d:\n"), retry);
                    pi->status_valid = 0;
                    goto wait_again;
                  }
@@ -4146,11 +4245,7 @@ wait_again:
                    /* If not in GDB's thread list, add it.  */
                    temp_ptid = MERGEPID (pi->pid, temp_tid);
                    if (!in_thread_list (temp_ptid))
-                     {
-                       printf_filtered ("[New %s]\n", 
-                                        target_pid_to_str (temp_ptid));
-                       add_thread (temp_ptid);
-                     }
+                     add_thread (temp_ptid);
 
                    status->kind = TARGET_WAITKIND_STOPPED;
                    status->value.sig = 0;
@@ -4183,6 +4278,14 @@ wait_again:
 #if (FLTTRACE != FLTBPT)       /* avoid "duplicate case" error */
                case FLTTRACE:
 #endif
+                  /* If we hit our __dbx_link() internal breakpoint,
+                     then remove it.  See comments in procfs_init_inferior()
+                     for more details.  */
+                  if (dbx_link_bpt_addr != 0
+                      && dbx_link_bpt_addr
+                        == regcache_read_pc (get_current_regcache ()))
+                    remove_dbx_link_breakpoint ();
+
                  wstat = (SIGTRAP << 8) | 0177;
                  break;
                case FLTSTACK:
@@ -4203,17 +4306,17 @@ wait_again:
                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");
+                 printf_filtered (_("child stopped for unknown reason:\n"));
                  proc_prettyprint_why (why, what, 1);
-                 error ("... giving up...");
+                 error (_("... giving up..."));
                  break;
                }
                break;  /* case PR_FAULTED: */
              default:  /* switch (why) unmatched */
                printf_filtered ("procfs:%d -- ", __LINE__);
-               printf_filtered ("child stopped for unknown reason:\n");
+               printf_filtered (_("child stopped for unknown reason:\n"));
                proc_prettyprint_why (why, what, 1);
-               error ("... giving up...");
+               error (_("... giving up..."));
                break;
              }
              /*
@@ -4225,29 +4328,14 @@ wait_again:
                  !in_thread_list (retval))
                {
                  /*
-                  * We have a new thread.  
+                  * 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 
+                  * If we don't create a procinfo, resume may be unhappy
                   * later.
                   */
-                 printf_filtered ("[New %s]\n", target_pid_to_str (retval));
                  add_thread (retval);
                  if (find_procinfo (PIDGET (retval), TIDGET (retval)) == NULL)
                    create_procinfo (PIDGET (retval), TIDGET (retval));
-
-                 /* In addition, it's possible that this is the first
-                  * new thread we've seen, in which case we may not 
-                  * have created entries for inferior_ptid yet.
-                  */
-                 if (TIDGET (inferior_ptid) != 0)
-                   {
-                     if (!in_thread_list (inferior_ptid))
-                       add_thread (inferior_ptid);
-                     if (find_procinfo (PIDGET (inferior_ptid), 
-                                        TIDGET (inferior_ptid)) == NULL)
-                       create_procinfo (PIDGET (inferior_ptid), 
-                                        TIDGET (inferior_ptid));
-                   }
                }
            }
          else  /* flags do not indicate STOPPED */
@@ -4256,7 +4344,7 @@ wait_again:
              printf_filtered ("procfs:%d -- process not stopped.\n",
                               __LINE__);
              proc_prettyprint_flags (flags, 1);
-             error ("procfs: ...giving up...");
+             error (_("procfs: ...giving up..."));
            }
        }
 
@@ -4267,6 +4355,40 @@ wait_again:
   return retval;
 }
 
+/* Perform a partial transfer to/from the specified object.  For
+   memory transfers, fall back to the old memory xfer functions.  */
+
+static LONGEST
+procfs_xfer_partial (struct target_ops *ops, enum target_object object,
+                    const char *annex, gdb_byte *readbuf,
+                    const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
+{
+  switch (object)
+    {
+    case TARGET_OBJECT_MEMORY:
+      if (readbuf)
+       return (*ops->deprecated_xfer_memory) (offset, readbuf,
+                                              len, 0/*read*/, NULL, ops);
+      if (writebuf)
+       return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf,
+                                              len, 1/*write*/, NULL, ops);
+      return -1;
+
+#ifdef NEW_PROC_API
+    case TARGET_OBJECT_AUXV:
+      return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf,
+                              offset, len);
+#endif
+
+    default:
+      if (ops->beneath != NULL)
+       return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+                                             readbuf, writebuf, offset, len);
+      return -1;
+    }
+}
+
+
 /* Transfer LEN bytes between GDB address MYADDR and target address
    MEMADDR.  If DOWRITE is non-zero, transfer them to the target,
    otherwise transfer them from the target.  TARGET is unused.
@@ -4278,7 +4400,7 @@ wait_again:
    negative values, but this capability isn't implemented here.) */
 
 static int
-procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
+procfs_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int dowrite,
                    struct mem_attrib *attrib, struct target_ops *target)
 {
   procinfo *pi;
@@ -4325,7 +4447,7 @@ procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
  * If there are "dirty" caches that need to be written back
  * to the child process, do that.
  *
- * File descriptors are also cached.  
+ * 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
@@ -4333,7 +4455,7 @@ procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
  * descriptors we may have accumulated for the threads.
  *
  * Return value:
- * As this function is called by iterate_over_threads, it always 
+ * As this function is called by iterate_over_threads, it always
  * returns zero (so that iterate_over_threads will keep iterating).
  */
 
@@ -4352,19 +4474,19 @@ invalidate_cache (procinfo *parent, procinfo *pi, void *ptr)
       if (!proc_set_gregs (pi))        /* flush gregs cache */
        proc_warn (pi, "target_resume, set_gregs",
                   __LINE__);
-  if (FP0_REGNUM >= 0)
+  if (gdbarch_fp0_regnum (target_gdbarch) >= 0)
     if (pi->fpregs_dirty)
       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", 
+         proc_warn (pi, "target_resume, set_fpregs",
                     __LINE__);
 #endif
 
   if (parent != NULL)
     {
       /* The presence of a parent indicates that this is an LWP.
-        Close any file descriptors that it might have open.  
+        Close any file descriptors that it might have open.
         We don't do this to the master (parent) procinfo.  */
 
       close_procinfo_files (pi);
@@ -4412,10 +4534,10 @@ make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr)
  * procfs_wait and wait for it to stop again (unles gdb is async).
  *
  * Arguments:
- *  step:  if true, then arrange for the child to stop again 
+ *  step:  if true, then arrange for the child to stop again
  *         after executing a single instruction.
  *  signo: if zero, then cancel any pending signal.
- *         If non-zero, then arrange for the indicated signal 
+ *         If non-zero, then arrange for the indicated signal
  *         to be delivered to the child when it runs.
  *  pid:   if -1, then allow any child thread to run.
  *         if non-zero, then allow only the indicated thread to run.
@@ -4423,16 +4545,17 @@ make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr)
  */
 
 static void
-procfs_resume (ptid_t ptid, int step, enum target_signal signo)
+procfs_resume (struct target_ops *ops,
+              ptid_t ptid, int step, enum target_signal signo)
 {
   procinfo *pi, *thread;
   int native_signo;
 
-  /* 2.1: 
+  /* 2.1:
      prrun.prflags |= PRSVADDR;
-     prrun.pr_vaddr = $PC;        set resume address 
+     prrun.pr_vaddr = $PC;        set resume address
      prrun.prflags |= PRSTRACE;    trace signals in pr_trace (all)
-     prrun.prflags |= PRSFAULT;    trace faults in pr_fault (all but PAGE) 
+     prrun.prflags |= PRSFAULT;    trace faults in pr_fault (all but PAGE)
      prrun.prflags |= PRCFAULT;    clear current fault.
 
      PRSTRACE and PRSFAULT can be done by other means
@@ -4461,7 +4584,7 @@ procfs_resume (ptid_t ptid, int step, enum target_signal signo)
 
   /* Running the process voids all cached registers and status. */
   /* Void the threads' caches first */
-  proc_iterate_over_threads (pi, invalidate_cache, NULL); 
+  proc_iterate_over_threads (pi, invalidate_cache, NULL);
   /* Void the process procinfo's caches.  */
   invalidate_cache (NULL, pi, NULL);
 
@@ -4481,7 +4604,7 @@ procfs_resume (ptid_t ptid, int step, enum target_signal signo)
                proc_error (pi, "target_resume, set_async", __LINE__);
 #endif
 #if 0
-             proc_iterate_over_threads (pi, 
+             proc_iterate_over_threads (pi,
                                         make_signal_thread_runnable,
                                         NULL);
 #endif
@@ -4493,7 +4616,7 @@ procfs_resume (ptid_t ptid, int step, enum target_signal signo)
   if (!proc_run_process (pi, step, native_signo))
     {
       if (errno == EBUSY)
-       warning ("resume: target already running.  Pretend to resume, and hope for the best!\n");
+       warning (_("resume: target already running.  Pretend to resume, and hope for the best!"));
       else
        proc_error (pi, "target_resume", __LINE__);
     }
@@ -4502,7 +4625,7 @@ procfs_resume (ptid_t ptid, int step, enum target_signal signo)
 /*
  * Function: register_gdb_signals
  *
- * Traverse the list of signals that GDB knows about 
+ * Traverse the list of signals that GDB knows about
  * (see "handle" command), and arrange for the target
  * to be stopped or not, according to these settings.
  *
@@ -4553,49 +4676,12 @@ procfs_notice_signals (ptid_t ptid)
 static void
 procfs_files_info (struct target_ops *ignore)
 {
-  printf_filtered ("\tUsing the running image of %s %s via /proc.\n",
-                  attach_flag? "attached": "child", 
+  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));
 }
 
-/*
- * Function: target_open
- *
- * A dummy: you don't open procfs.
- */
-
-static void
-procfs_open (char *args, int from_tty)
-{
-  error ("Use the \"run\" command to start a Unix child process.");
-}
-
-/*
- * Function: target_can_run
- *
- * This tells GDB that this target vector can be invoked 
- * for "run" or "attach".
- */
-
-int procfs_suppress_run = 0;   /* Non-zero if procfs should pretend not to
-                                  be a runnable target.  Used by targets
-                                  that can sit atop procfs, such as solaris
-                                  thread support.  */
-
-
-static int
-procfs_can_run (void)
-{
-  /* This variable is controlled by modules that sit atop procfs that
-     may layer their own process structure atop that provided here.
-     sol-thread.c does this because of the Solaris two-level thread
-     model.  */
-  
-  /* NOTE: possibly obsolete -- use the thread_stratum approach instead. */
-
-  return !procfs_suppress_run;
-}
-
 /*
  * Function: target_stop
  *
@@ -4606,16 +4692,16 @@ procfs_can_run (void)
  */
 
 static void
-procfs_stop (void)
+procfs_stop (ptid_t ptid)
 {
-  kill (-inferior_process_group, SIGINT);
+  kill (-inferior_process_group (), SIGINT);
 }
 
 /*
  * Function: unconditionally_kill_inferior
  *
  * Make it die.  Wait for it to die.  Clean up after it.
- * Note: this should only be applied to the real process, 
+ * Note: this should only be applied to the real process,
  * not to an LWP, because of the check for parent-process.
  * If we need this to work for an LWP, it needs some more logic.
  */
@@ -4662,7 +4748,7 @@ unconditionally_kill_inferior (procinfo *pi)
 
   /* If pi is GDB's child, wait for it to die.  */
   if (parent_pid == getpid ())
-    /* FIXME: should we use waitpid to make sure we get the right event?  
+    /* FIXME: should we use waitpid to make sure we get the right event?
        Should we check the returned event?  */
     {
 #if 0
@@ -4682,8 +4768,8 @@ unconditionally_kill_inferior (procinfo *pi)
  * Then we want GDB to forget all about it.
  */
 
-static void 
-procfs_kill_inferior (void)
+static void
+procfs_kill_inferior (struct target_ops *ops)
 {
   if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */
     {
@@ -4702,8 +4788,8 @@ procfs_kill_inferior (void)
  * Forget we ever debugged this thing!
  */
 
-static void 
-procfs_mourn_inferior (void)
+static void
+procfs_mourn_inferior (struct target_ops *ops)
 {
   procinfo *pi;
 
@@ -4714,30 +4800,38 @@ procfs_mourn_inferior (void)
       if (pi)
        destroy_procinfo (pi);
     }
-  unpush_target (&procfs_ops);
+  unpush_target (ops);
+
+  if (dbx_link_bpt != NULL)
+    {
+      deprecated_remove_raw_breakpoint (target_gdbarch, dbx_link_bpt);
+      dbx_link_bpt_addr = 0;
+      dbx_link_bpt = NULL;
+    }
+
   generic_mourn_inferior ();
 }
 
 /*
  * Function: init_inferior
  *
- * When GDB forks to create a runnable inferior process, 
+ * When GDB forks to create a runnable inferior process,
  * this function is called on the parent side of the fork.
  * It's job is to do whatever is necessary to make the child
  * ready to be debugged, and then wait for the child to synchronize.
  */
 
-static void 
-procfs_init_inferior (int pid)
+static void
+procfs_init_inferior (struct target_ops *ops, int pid)
 {
   procinfo *pi;
   gdb_sigset_t signals;
   int fail;
+  int lwpid;
 
   /* This routine called on the parent side (GDB side)
      after GDB forks the inferior.  */
-
-  push_target (&procfs_ops);
+  push_target (ops);
 
   if ((pi = create_procinfo (pid, 0)) == NULL)
     perror ("procfs: out of memory in 'init_inferior'");
@@ -4793,16 +4887,46 @@ procfs_init_inferior (int pid)
   if (!proc_set_run_on_last_close (pi))
     proc_error (pi, "init_inferior, set_RLC", __LINE__);
 
-  /* The 'process ID' we return to GDB is composed of
-     the actual process ID plus the lwp ID. */
-  inferior_ptid = MERGEPID (pi->pid, proc_get_current_thread (pi));
+  /* We now have have access to the lwpid of the main thread/lwp.  */
+  lwpid = proc_get_current_thread (pi);
 
-#ifdef START_INFERIOR_TRAPS_EXPECTED
+  /* Create a procinfo for the main lwp.  */
+  create_procinfo (pid, lwpid);
+
+  /* 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),
+                     MERGEPID (pid, lwpid));
+
+  /* Typically two, one trap to exec the shell, one to exec the
+     program being debugged.  Defined by "inferior.h".  */
   startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
-#else
-  /* One trap to exec the shell, one to exec the program being debugged.  */
-  startup_inferior (2);
-#endif /* START_INFERIOR_TRAPS_EXPECTED */
+
+#ifdef SYS_syssgi
+  /* On mips-irix, we need to stop the inferior early enough during
+     the startup phase in order to be able to load the shared library
+     symbols and insert the breakpoints that are located in these shared
+     libraries.  Stopping at the program entry point is not good enough
+     because the -init code is executed before the execution reaches
+     that point.
+
+     So what we need to do is to insert a breakpoint in the runtime
+     loader (rld), more precisely in __dbx_link().  This procedure is
+     called by rld once all shared libraries have been mapped, but before
+     the -init code is executed. Unfortuantely, this is not straightforward,
+     as rld is not part of the executable we are running, and thus we need
+     the inferior to run until rld itself has been mapped in memory.
+     
+     For this, we trace all syssgi() syscall exit events.  Each time
+     we detect such an event, we iterate over each text memory maps,
+     get its associated fd, and scan the symbol table for __dbx_link().
+     When found, we know that rld has been mapped, and that we can insert
+     the breakpoint at the symbol address.  Once the dbx_link() breakpoint
+     has been inserted, the syssgi() notifications are no longer necessary,
+     so they should be canceled.  */
+  proc_trace_syscalls_1 (pi, SYS_syssgi, PR_SYSEXIT, FLAG_SET, 0);
+#endif
 }
 
 /*
@@ -4828,7 +4952,7 @@ procfs_set_exec_trap (void)
   sysset_t *exitset;
 
   if ((pi = create_procinfo (getpid (), 0)) == NULL)
-    perror_with_name ("procfs: create_procinfo failed in child.");
+    perror_with_name (_("procfs: create_procinfo failed in child."));
 
   if (open_procinfo_files (pi, FD_CTL) == 0)
     {
@@ -4912,7 +5036,7 @@ procfs_set_exec_trap (void)
   if (!proc_unset_run_on_last_close (pi))
     proc_warn (pi, "set_exec_trap, unset_RLC", __LINE__);
 
-  /* FIXME: No need to destroy the procinfo -- 
+  /* FIXME: No need to destroy the procinfo --
      we have our own address space, and we're about to do an exec! */
   /*destroy_procinfo (pi);*/
 }
@@ -4921,10 +5045,10 @@ procfs_set_exec_trap (void)
  * Function: create_inferior
  *
  * This function is called BEFORE gdb forks the inferior process.
- * Its only real responsibility is to set things up for the fork, 
+ * Its only real responsibility is to set things up for the fork,
  * and tell GDB which two functions to call after the fork (one
  * for the parent, and one for the child).
- * 
+ *
  * This function does a complicated search for a unix shell program,
  * which it then uses to parse arguments and environment variables
  * to be sent to the child.  I wonder whether this code could not
@@ -4933,10 +5057,13 @@ procfs_set_exec_trap (void)
  */
 
 static void
-procfs_create_inferior (char *exec_file, char *allargs, char **env)
+procfs_create_inferior (struct target_ops *ops, char *exec_file,
+                       char *allargs, char **env, int from_tty)
 {
   char *shell_file = getenv ("SHELL");
   char *tryname;
+  int pid;
+
   if (shell_file != NULL && strchr (shell_file, '/') == NULL)
     {
 
@@ -4999,19 +5126,26 @@ procfs_create_inferior (char *exec_file, char *allargs, char **env)
        /* Not found.  This must be an error rather than merely passing
           the file to execlp(), because execlp() would try all the
           exec()s, causing GDB to get confused.  */
-       error ("procfs:%d -- Can't find shell %s in PATH",
+       error (_("procfs:%d -- Can't find shell %s in PATH"),
               __LINE__, shell_file);
 
       shell_file = tryname;
     }
 
-  fork_inferior (exec_file, allargs, env, procfs_set_exec_trap, 
-                procfs_init_inferior, NULL, shell_file);
+  pid = fork_inferior (exec_file, allargs, env, procfs_set_exec_trap,
+                      NULL, NULL, shell_file);
 
-  /* We are at the first instruction we care about.  */
-  /* Pedal to the metal... */
+  procfs_init_inferior (ops, pid);
 
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+#ifdef SYS_syssgi
+  /* Make sure to cancel the syssgi() syscall-exit notifications.  
+     They should normally have been removed by now, but they may still
+     be activated if the inferior doesn't use shared libraries, or if
+     we didn't locate __dbx_link, or if we never stopped in __dbx_link.
+     See procfs_init_inferior() for more details.  */
+  proc_trace_syscalls_1 (find_procinfo_or_die (PIDGET (inferior_ptid), 0),
+                         SYS_syssgi, PR_SYSEXIT, FLAG_RESET, 0);
+#endif
 }
 
 /*
@@ -5026,7 +5160,7 @@ procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
 {
   ptid_t gdb_threadid = MERGEPID (pi->pid, thread->tid);
 
-  if (!in_thread_list (gdb_threadid))
+  if (!in_thread_list (gdb_threadid) || is_exited (gdb_threadid))
     add_thread (gdb_threadid);
 
   return 0;
@@ -5035,12 +5169,12 @@ procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
 /*
  * Function: target_find_new_threads
  *
- * Query all the threads that the target knows about, 
+ * Query all the threads that the target knows about,
  * and give them back to GDB to add to its list.
  */
 
 void
-procfs_find_new_threads (void)
+procfs_find_new_threads (struct target_ops *ops)
 {
   procinfo *pi;
 
@@ -5050,7 +5184,7 @@ procfs_find_new_threads (void)
   proc_iterate_over_threads (pi, procfs_notice_thread, NULL);
 }
 
-/* 
+/*
  * Function: target_thread_alive
  *
  * Return true if the thread is still 'alive'.
@@ -5060,7 +5194,7 @@ procfs_find_new_threads (void)
  */
 
 static int
-procfs_thread_alive (ptid_t ptid)
+procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   int proc, thread;
   procinfo *pi;
@@ -5082,29 +5216,19 @@ procfs_thread_alive (ptid_t ptid)
   return 1;
 }
 
-/*
- * Function: target_pid_to_str
- *
- * Return a string to be used to identify the thread in 
- * the "info threads" display.
- */
+/* Convert PTID to a string.  Returns the string in a static buffer.  */
 
 char *
-procfs_pid_to_str (ptid_t ptid)
+procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
   static char buf[80];
-  int proc, thread;
-  procinfo *pi;
 
-  proc    = PIDGET (ptid);
-  thread  = TIDGET (ptid);
-  pi      = find_procinfo (proc, thread);
-
-  if (thread == 0)
-    sprintf (buf, "Process %d", proc);
+  if (TIDGET (ptid) == 0)
+    sprintf (buf, "process %d", PIDGET (ptid));
   else
-    sprintf (buf, "LWP %d", thread);
-  return &buf[0];
+    sprintf (buf, "LWP %ld", TIDGET (ptid));
+
+  return buf;
 }
 
 /*
@@ -5112,16 +5236,16 @@ procfs_pid_to_str (ptid_t ptid)
  * Insert a watchpoint
  */
 
-int 
+int
 procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag,
                        int after)
 {
 #ifndef UNIXWARE
 #ifndef AIX5
   int       pflags = 0;
-  procinfo *pi; 
+  procinfo *pi;
 
-  pi = find_procinfo_or_die (PIDGET (ptid) == -1 ? 
+  pi = find_procinfo_or_die (PIDGET (ptid) == -1 ?
                             PIDGET (inferior_ptid) : PIDGET (ptid), 0);
 
   /* Translate from GDB's flags to /proc's */
@@ -5166,17 +5290,14 @@ procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag,
    is one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint,
    or bp_hardware_watchpoint.  CNT is the number of watchpoints used so
    far.
-   
+
    Note:  procfs_can_use_hw_breakpoint() is not yet used by all
    procfs.c targets due to the fact that some of them still define
-   TARGET_CAN_USE_HARDWARE_WATCHPOINT.  */
+   target_can_use_hardware_watchpoint.  */
 
 static int
 procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
 {
-#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS
-  return 0;
-#else
   /* Due to the way that proc_set_watchpoint() is implemented, host
      and target pointers must be of the same size.  If they are not,
      we can't use hardware watchpoints.  This limitation is due to the
@@ -5185,13 +5306,13 @@ procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
      procfs_address_to_host_pointer will reveal that an internal error
      will be generated when the host and target pointer sizes are
      different.  */
-  if (sizeof (void *) != TYPE_LENGTH (builtin_type_void_data_ptr))
+  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+  if (sizeof (void *) != TYPE_LENGTH (ptr_type))
     return 0;
 
   /* Other tests here???  */
 
   return 1;
-#endif
 }
 
 /*
@@ -5201,13 +5322,12 @@ procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
  * else returns zero.
  */
 
-int
-procfs_stopped_by_watchpoint (ptid_t ptid)
+static int
+procfs_stopped_by_watchpoint (void)
 {
   procinfo *pi;
 
-  pi = find_procinfo_or_die (PIDGET (ptid) == -1 ? 
-                            PIDGET (inferior_ptid) : PIDGET (ptid), 0);
+  pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
 
   if (!pi)     /* If no process, then not stopped by watchpoint!  */
     return 0;
@@ -5215,7 +5335,7 @@ procfs_stopped_by_watchpoint (ptid_t ptid)
   if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
     {
       if (proc_why (pi) == PR_FAULTED)
-       {       
+       {
 #ifdef FLTWATCH
          if (proc_what (pi) == FLTWATCH)
            return 1;
@@ -5229,51 +5349,59 @@ procfs_stopped_by_watchpoint (ptid_t ptid)
   return 0;
 }
 
-#ifdef TM_I386SOL2_H
-/*
- * Function: procfs_find_LDT_entry 
- *
- * Input:
- *   ptid_t ptid;      // The GDB-style pid-plus-LWP.
- *
- * Return:
- *   pointer to the corresponding LDT entry.
- */
-
-struct ssd *
-procfs_find_LDT_entry (ptid_t ptid)
+static int
+procfs_insert_watchpoint (CORE_ADDR addr, int len, int type)
 {
-  gdb_gregset_t *gregs;
-  int            key;
-  procinfo      *pi;
-
-  /* Find procinfo for the lwp. */
-  if ((pi = find_procinfo (PIDGET (ptid), TIDGET (ptid))) == NULL)
+  if (!target_have_steppable_watchpoint
+      && !gdbarch_have_nonsteppable_watchpoint (target_gdbarch))
     {
-      warning ("procfs_find_LDT_entry: could not find procinfo for %d:%d.",
-              PIDGET (ptid), TIDGET (ptid));
-      return NULL;
+      /* 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);
     }
-  /* get its general registers. */
-  if ((gregs = proc_get_gregs (pi)) == NULL)
+  else
     {
-      warning ("procfs_find_LDT_entry: could not read gregs for %d:%d.",
-              PIDGET (ptid), TIDGET (ptid));
-      return NULL;
+      /* 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);
     }
-  /* 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);
+static int
+procfs_remove_watchpoint (CORE_ADDR addr, int len, int type)
+{
+  return procfs_set_watchpoint (inferior_ptid, addr, 0, 0, 0);
+}
+
+static int
+procfs_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
+     no method for finding out how many; It doesn't say anything about
+     the allowed size for the watched area either.  So we just tell
+     GDB 'yes'.  */
+  return 1;
+}
+
+void
+procfs_use_watchpoints (struct target_ops *t)
+{
+  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;
 }
-#endif /* TM_I386SOL2_H */
 
 /*
  * Memory Mappings Functions:
  */
 
-/* 
+/*
  * Function: iterate_over_mappings
  *
  * Call a callback function once for each mapping, passing it the mapping,
@@ -5287,14 +5415,14 @@ procfs_find_LDT_entry (ptid_t ptid)
  *   child_func -- optional secondary function pointer to be passed
  *                 to the child function.
  *
- * Return: First non-zero return value from the callback function, 
+ * Return: First non-zero return value from the callback function,
  *         or zero.
  */
 
 static int
-iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data, 
-                      int (*func) (struct prmap *map, 
-                                   int (*child_func) (), 
+iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data,
+                      int (*func) (struct prmap *map,
+                                   int (*child_func) (),
                                    void *data))
 {
   char pathname[MAX_PROC_NAME_SIZE];
@@ -5307,7 +5435,7 @@ iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data,
   struct stat sbuf;
 #endif
 
-  /* Get the number of mappings, allocate space, 
+  /* Get the number of mappings, allocate space,
      and read the mappings into prmaps.  */
 #ifdef NEW_PROC_API
   /* Open map fd. */
@@ -5318,7 +5446,7 @@ iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data,
   /* Make sure it gets closed again. */
   make_cleanup_close (map_fd);
 
-  /* Use stat to determine the file size, and compute 
+  /* Use stat to determine the file size, and compute
      the number of prmap_t objects it contains.  */
   if (fstat (map_fd, &sbuf) != 0)
     proc_error (pi, "iterate_over_mappings (fstat)", __LINE__);
@@ -5348,10 +5476,10 @@ iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data,
 /*
  * Function: solib_mappings_callback
  *
- * Calls the supplied callback function once for each mapped address 
- * space in the process.  The callback function  receives an open 
- * file descriptor for the file corresponding to that mapped 
- * address space (if there is one), and the base address of the 
+ * Calls the supplied callback function once for each mapped address
+ * space in the process.  The callback function  receives an open
+ * file descriptor for the file corresponding to that mapped
+ * address space (if there is one), and the base address of the
  * mapped space.  Quit when the callback function returns a
  * nonzero value, or at teh end of the mappings.
  *
@@ -5359,7 +5487,7 @@ iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data,
  * or zero.
  */
 
-int solib_mappings_callback (struct prmap *map, 
+int solib_mappings_callback (struct prmap *map,
                             int (*func) (int, CORE_ADDR),
                             void *data)
 {
@@ -5382,45 +5510,20 @@ int solib_mappings_callback (struct prmap *map,
       /* Note: caller's responsibility to close this fd!  */
       fd = open_with_retry (name, O_RDONLY);
       /* Note: we don't test the above call for failure;
-        we just pass the FD on as given.  Sometimes there is 
+        we just pass the FD on as given.  Sometimes there is
         no file, so the open may return failure, but that's
         not a problem.  */
     }
 #else
   fd = ioctl (pi->ctl_fd, PIOCOPENM, &map->pr_vaddr);
   /* Note: we don't test the above call for failure;
-     we just pass the FD on as given.  Sometimes there is 
+     we just pass the FD on as given.  Sometimes there is
      no file, so the ioctl may return failure, but that's
      not a problem.  */
 #endif
   return (*func) (fd, (CORE_ADDR) map->pr_vaddr);
 }
 
-/*
- * Function: proc_iterate_over_mappings
- *
- * Uses the unified "iterate_over_mappings" function
- * to implement the exported interface to solib-svr4.c.
- *
- * Given a pointer to a function, call that function once for every
- * mapped address space in the process.  The callback function 
- * receives an open file descriptor for the file corresponding to
- * that mapped address space (if there is one), and the base address
- * of the mapped space.  Quit when the callback function returns a
- * nonzero value, or at teh end of the mappings.
- *
- * Returns: the first non-zero return value of the callback function,
- * or zero.
- */
-
-int
-proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
-{
-  procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
-
-  return iterate_over_mappings (pi, func, pi, solib_mappings_callback);
-}
-
 /*
  * Function: find_memory_regions_callback
  *
@@ -5428,27 +5531,27 @@ proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
  * Calls an external function for each memory region.
  * External function will have the signiture:
  *
- *   int callback (CORE_ADDR vaddr, 
- *                 unsigned long size, 
- *                 int read, int write, int execute, 
+ *   int callback (CORE_ADDR vaddr,
+ *                 unsigned long size,
+ *                 int read, int write, int execute,
  *                 void *data);
  *
  * Returns the integer value returned by the callback.
  */
 
 static int
-find_memory_regions_callback (struct prmap *map, 
-                             int (*func) (CORE_ADDR, 
-                                          unsigned long, 
-                                          int, int, int, 
+find_memory_regions_callback (struct prmap *map,
+                             int (*func) (CORE_ADDR,
+                                          unsigned long,
+                                          int, int, int,
                                           void *),
                              void *data)
 {
   return (*func) ((CORE_ADDR) map->pr_vaddr,
-                 map->pr_size, 
+                 map->pr_size,
                  (map->pr_mflags & MA_READ) != 0,
                  (map->pr_mflags & MA_WRITE) != 0,
-                 (map->pr_mflags & MA_EXEC) != 0, 
+                 (map->pr_mflags & MA_EXEC) != 0,
                  data);
 }
 
@@ -5458,28 +5561,155 @@ find_memory_regions_callback (struct prmap *map,
  * External interface.  Calls a callback function once for each
  * mapped memory region in the child process, passing as arguments
  *     CORE_ADDR virtual_address,
- *     unsigned long size, 
+ *     unsigned long size,
  *     int read,       TRUE if region is readable by the child
  *     int write,      TRUE if region is writable by the child
  *     int execute     TRUE if region is executable by the child.
- * 
+ *
  * Stops iterating and returns the first non-zero value
  * returned by the callback.
  */
 
 static int
-proc_find_memory_regions (int (*func) (CORE_ADDR, 
-                                      unsigned long, 
-                                      int, int, int, 
-                                      void *), 
+proc_find_memory_regions (int (*func) (CORE_ADDR,
+                                      unsigned long,
+                                      int, int, int,
+                                      void *),
                          void *data)
 {
   procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
 
-  return iterate_over_mappings (pi, func, data, 
+  return iterate_over_mappings (pi, func, data,
                                find_memory_regions_callback);
 }
 
+/* Remove the breakpoint that we inserted in __dbx_link().
+   Does nothing if the breakpoint hasn't been inserted or has already
+   been removed.  */
+
+static void
+remove_dbx_link_breakpoint (void)
+{
+  if (dbx_link_bpt_addr == 0)
+    return;
+
+  if (deprecated_remove_raw_breakpoint (target_gdbarch, dbx_link_bpt) != 0)
+    warning (_("Unable to remove __dbx_link breakpoint."));
+
+  dbx_link_bpt_addr = 0;
+  dbx_link_bpt = NULL;
+}
+
+/* Return the address of the __dbx_link() function in the file
+   refernced by ABFD by scanning its symbol table.  Return 0 if
+   the symbol was not found.  */
+
+static CORE_ADDR
+dbx_link_addr (bfd *abfd)
+{
+  long storage_needed;
+  asymbol **symbol_table;
+  long number_of_symbols;
+  long i;
+
+  storage_needed = bfd_get_symtab_upper_bound (abfd);
+  if (storage_needed <= 0)
+    return 0;
+
+  symbol_table = (asymbol **) xmalloc (storage_needed);
+  make_cleanup (xfree, symbol_table);
+
+  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
+
+  for (i = 0; i < number_of_symbols; i++)
+    {
+      asymbol *sym = symbol_table[i];
+
+      if ((sym->flags & BSF_GLOBAL)
+          && sym->name != NULL && strcmp (sym->name, "__dbx_link") == 0)
+        return (sym->value + sym->section->vma);
+    }
+
+  /* Symbol not found, return NULL.  */
+  return 0;
+}
+
+/* Search the symbol table of the file referenced by FD for a symbol
+   named __dbx_link(). If found, then insert a breakpoint at this location,
+   and return nonzero.  Return zero otherwise.  */
+
+static int
+insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored)
+{
+  bfd *abfd;
+  long storage_needed;
+  CORE_ADDR sym_addr;
+
+  abfd = bfd_fdopenr ("unamed", 0, fd);
+  if (abfd == NULL)
+    {
+      warning (_("Failed to create a bfd: %s."), bfd_errmsg (bfd_get_error ()));
+      return 0;
+    }
+
+  if (!bfd_check_format (abfd, bfd_object))
+    {
+      /* Not the correct format, so we can not possibly find the dbx_link
+         symbol in it.  */
+      bfd_close (abfd);
+      return 0;
+    }
+
+  sym_addr = dbx_link_addr (abfd);
+  if (sym_addr != 0)
+    {
+      /* Insert the breakpoint.  */
+      dbx_link_bpt_addr = sym_addr;
+      dbx_link_bpt = deprecated_insert_raw_breakpoint (target_gdbarch,
+                                                      sym_addr);
+      if (dbx_link_bpt == NULL)
+        {
+          warning (_("Failed to insert dbx_link breakpoint."));
+          bfd_close (abfd);
+          return 0;
+        }
+      bfd_close (abfd);
+      return 1;
+    }
+
+  bfd_close (abfd);
+  return 0;
+} 
+
+/* If the given memory region MAP contains a symbol named __dbx_link,
+   insert a breakpoint at this location and return nonzero.  Return
+   zero otherwise.  */
+
+static int
+insert_dbx_link_bpt_in_region (struct prmap *map,
+                               int (*child_func) (),
+                               void *data)
+{     
+  procinfo *pi = (procinfo *) data;
+        
+  /* We know the symbol we're looking for is in a text region, so
+     only look for it if the region is a text one.  */
+  if (map->pr_mflags & MA_EXEC)
+    return solib_mappings_callback (map, insert_dbx_link_bpt_in_file, pi);
+  return 0;
+}           
+
+/* Search all memory regions for a symbol named __dbx_link.  If found,
+   insert a breakpoint at its location, and return nonzero.  Return zero
+   otherwise.  */
+
+static int
+insert_dbx_link_breakpoint (procinfo *pi)
+{
+  return iterate_over_mappings (pi, NULL, pi, insert_dbx_link_bpt_in_region);
+}
+
 /*
  * Function: mappingflags
  *
@@ -5520,23 +5750,28 @@ mappingflags (long flags)
 static int
 info_mappings_callback (struct prmap *map, int (*ignore) (), void *unused)
 {
-  char *data_fmt_string;
-
-  if (TARGET_ADDR_BIT == 32)
-    data_fmt_string   = "\t%#10lx %#10lx %#10x %#10x %7s\n";
-  else
-    data_fmt_string   = "  %#18lx %#18lx %#10x %#10x %7s\n";
+  unsigned int pr_off;
 
-  printf_filtered (data_fmt_string, 
-                  (unsigned long) map->pr_vaddr,
-                  (unsigned long) map->pr_vaddr + map->pr_size - 1,
-                  map->pr_size,
 #ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */
-                  (unsigned int) map->pr_offset, 
+  pr_off = (unsigned int) map->pr_offset;
 #else
-                  map->pr_off,
+  pr_off = map->pr_off;
 #endif
-                  mappingflags (map->pr_mflags));
+
+  if (gdbarch_addr_bit (target_gdbarch) == 32)
+    printf_filtered ("\t%#10lx %#10lx %#10lx %#10x %7s\n",
+                    (unsigned long) map->pr_vaddr,
+                    (unsigned long) map->pr_vaddr + map->pr_size - 1,
+                    (unsigned long) map->pr_size,
+                    pr_off,
+                    mappingflags (map->pr_mflags));
+  else
+    printf_filtered ("  %#18lx %#18lx %#10lx %#10x %7s\n",
+                    (unsigned long) map->pr_vaddr,
+                    (unsigned long) map->pr_vaddr + map->pr_size - 1,
+                    (unsigned long) map->pr_size,
+                    pr_off,
+                    mappingflags (map->pr_mflags));
 
   return 0;
 }
@@ -5550,23 +5785,24 @@ info_mappings_callback (struct prmap *map, int (*ignore) (), void *unused)
 static void
 info_proc_mappings (procinfo *pi, int summary)
 {
-  char *header_fmt_string;
-
-  if (TARGET_PTR_BIT == 32)
-    header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
-  else
-    header_fmt_string = "  %18s %18s %10s %10s %7s\n";
-
   if (summary)
     return;    /* No output for summary mode. */
 
-  printf_filtered ("Mapped address spaces:\n\n");
-  printf_filtered (header_fmt_string, 
-                  "Start Addr",
-                  "  End Addr",
-                  "      Size",
-                  "    Offset",
-                  "Flags");
+  printf_filtered (_("Mapped address spaces:\n\n"));
+  if (gdbarch_ptr_bit (target_gdbarch) == 32)
+    printf_filtered ("\t%10s %10s %10s %10s %7s\n",
+                    "Start Addr",
+                    "  End Addr",
+                    "      Size",
+                    "    Offset",
+                    "Flags");
+  else
+    printf_filtered ("  %18s %18s %10s %10s %7s\n",
+                    "Start Addr",
+                    "  End Addr",
+                    "      Size",
+                    "    Offset",
+                    "Flags");
 
   iterate_over_mappings (pi, NULL, NULL, info_mappings_callback);
   printf_filtered ("\n");
@@ -5593,10 +5829,8 @@ info_proc_cmd (char *args, int from_tty)
   old_chain = make_cleanup (null_cleanup, 0);
   if (args)
     {
-      if ((argv = buildargv (args)) == NULL)
-       nomem (0);
-      else
-       make_cleanup_freeargv (argv);
+      argv = gdb_buildargv (args);
+      make_cleanup_freeargv (argv);
     }
   while (argv != NULL && *argv != NULL)
     {
@@ -5623,7 +5857,7 @@ info_proc_cmd (char *args, int from_tty)
   if (pid == 0)
     pid = PIDGET (inferior_ptid);
   if (pid == 0)
-    error ("No current process: you must name one.");
+    error (_("No current process: you must name one."));
   else
     {
       /* Have pid, will travel.
@@ -5631,7 +5865,7 @@ info_proc_cmd (char *args, int from_tty)
       process = find_procinfo (pid, 0);
        if (process == NULL)
         {
-          /* No.  So open a procinfo for it, but 
+          /* 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);
@@ -5644,17 +5878,17 @@ info_proc_cmd (char *args, int from_tty)
 
   if (process)
     {
-      printf_filtered ("process %d flags:\n", process->pid);
+      printf_filtered (_("process %d flags:\n"), process->pid);
       proc_prettyprint_flags (proc_flags (process), 1);
       if (proc_flags (process) & (PR_STOPPED | PR_ISTOP))
        proc_prettyprint_why (proc_why (process), proc_what (process), 1);
       if (proc_get_nthreads (process) > 1)
-       printf_filtered ("Process has %d threads.\n", 
+       printf_filtered ("Process has %d threads.\n",
                         proc_get_nthreads (process));
     }
   if (thread)
     {
-      printf_filtered ("thread %d flags:\n", thread->tid);
+      printf_filtered (_("thread %d flags:\n"), thread->tid);
       proc_prettyprint_flags (proc_flags (thread), 1);
       if (proc_flags (thread) & (PR_STOPPED | PR_ISTOP))
        proc_prettyprint_why (proc_why (thread), proc_what (thread), 1);
@@ -5668,68 +5902,85 @@ info_proc_cmd (char *args, int from_tty)
   do_cleanups (old_chain);
 }
 
+/* Modify the status of the system call identified by SYSCALLNUM in
+   the set of syscalls that are currently traced/debugged.
+
+   If ENTRY_OR_EXIT is set to PR_SYSENTRY, then the entry syscalls set
+   will be updated. Otherwise, the exit syscalls set will be updated.
+
+   If MODE is FLAG_SET, then traces will be enabled. Otherwise, they
+   will be disabled.  */
+
+static void
+proc_trace_syscalls_1 (procinfo *pi, int syscallnum, int entry_or_exit,
+                      int mode, int from_tty)
+{
+  sysset_t *sysset;
+  
+  if (entry_or_exit == PR_SYSENTRY)
+    sysset = proc_get_traced_sysentry (pi, NULL);
+  else
+    sysset = proc_get_traced_sysexit (pi, NULL);
+
+  if (sysset == NULL)
+    proc_error (pi, "proc-trace, get_traced_sysset", __LINE__);
+
+  if (mode == FLAG_SET)
+    gdb_praddsysset (sysset, syscallnum);
+  else
+    gdb_prdelsysset (sysset, syscallnum);
+
+  if (entry_or_exit == PR_SYSENTRY)
+    {
+      if (!proc_set_traced_sysentry (pi, sysset))
+        proc_error (pi, "proc-trace, set_traced_sysentry", __LINE__);
+    }
+  else
+    {
+      if (!proc_set_traced_sysexit (pi, sysset))
+        proc_error (pi, "proc-trace, set_traced_sysexit", __LINE__);
+    }
+}
+
 static void
 proc_trace_syscalls (char *args, int from_tty, int entry_or_exit, int mode)
 {
   procinfo *pi;
-  sysset_t *sysset;
-  int       syscallnum = 0;
 
   if (PIDGET (inferior_ptid) <= 0)
-    error ("you must be debugging a process to use this command.");
+    error (_("you must be debugging a process to use this command."));
 
   if (args == NULL || args[0] == 0)
-    error_no_arg ("system call to trace");
+    error_no_arg (_("system call to trace"));
 
   pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
   if (isdigit (args[0]))
     {
-      syscallnum = atoi (args);
-      if (entry_or_exit == PR_SYSENTRY)
-       sysset = proc_get_traced_sysentry (pi, NULL);
-      else
-       sysset = proc_get_traced_sysexit (pi, NULL);
-
-      if (sysset == NULL)
-       proc_error (pi, "proc-trace, get_traced_sysset", __LINE__);
-
-      if (mode == FLAG_SET)
-       gdb_praddsysset (sysset, syscallnum);
-      else
-       gdb_prdelsysset (sysset, syscallnum);
+      const int syscallnum = atoi (args);
 
-      if (entry_or_exit == PR_SYSENTRY)
-       {
-         if (!proc_set_traced_sysentry (pi, sysset))
-           proc_error (pi, "proc-trace, set_traced_sysentry", __LINE__);
-       }
-      else
-       {
-         if (!proc_set_traced_sysexit (pi, sysset))
-           proc_error (pi, "proc-trace, set_traced_sysexit", __LINE__);
-       }
+      proc_trace_syscalls_1 (pi, syscallnum, entry_or_exit, mode, from_tty);
     }
 }
 
-static void 
+static void
 proc_trace_sysentry_cmd (char *args, int from_tty)
 {
   proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_SET);
 }
 
-static void 
+static void
 proc_trace_sysexit_cmd (char *args, int from_tty)
 {
   proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_SET);
 }
 
-static void 
+static void
 proc_untrace_sysentry_cmd (char *args, int from_tty)
 {
   proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_RESET);
 }
 
-static void 
+static void
 proc_untrace_sysexit_cmd (char *args, int from_tty)
 {
   proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET);
@@ -5739,20 +5990,18 @@ proc_untrace_sysexit_cmd (char *args, int from_tty)
 void
 _initialize_procfs (void)
 {
-  init_procfs_ops ();
-  add_target (&procfs_ops);
-  add_info ("proc", info_proc_cmd, 
-           "Show /proc process information about any running process.\n\
+  add_info ("proc", info_proc_cmd, _("\
+Show /proc process information about any running process.\n\
 Specify process id, or use the program being debugged by default.\n\
-Specify keyword 'mappings' for detailed info on memory mappings.");
-  add_com ("proc-trace-entry", no_class, proc_trace_sysentry_cmd, 
-          "Give a trace of entries into the syscall.");
-  add_com ("proc-trace-exit", no_class, proc_trace_sysexit_cmd, 
-          "Give a trace of exits from the syscall.");
-  add_com ("proc-untrace-entry", no_class, proc_untrace_sysentry_cmd, 
-          "Cancel a trace of entries into the syscall.");
-  add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd, 
-          "Cancel a trace of exits from the syscall.");
+Specify keyword 'mappings' for detailed info on memory mappings."));
+  add_com ("proc-trace-entry", no_class, proc_trace_sysentry_cmd,
+          _("Give a trace of entries into the syscall."));
+  add_com ("proc-trace-exit", no_class, proc_trace_sysexit_cmd,
+          _("Give a trace of exits from the syscall."));
+  add_com ("proc-untrace-entry", no_class, proc_untrace_sysentry_cmd,
+          _("Cancel a trace of entries into the syscall."));
+  add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd,
+          _("Cancel a trace of exits from the syscall."));
 }
 
 /* =================== END, GDB  "MODULE" =================== */
@@ -5775,37 +6024,61 @@ procfs_first_available (void)
   return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1);
 }
 
+static int
+find_signalled_thread (struct thread_info *info, void *data)
+{
+  if (info->stop_signal != TARGET_SIGNAL_0
+      && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
+    return 1;
+
+  return 0;
+}
+
+static enum target_signal
+find_stop_signal (void)
+{
+  struct thread_info *info =
+    iterate_over_threads (find_signalled_thread, NULL);
+
+  if (info)
+    return info->stop_signal;
+  else
+    return TARGET_SIGNAL_0;
+}
+
 /* ===================  GCORE .NOTE "MODULE" =================== */
 #if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)
 /* gcore only implemented on solaris and unixware (so far) */
 
 static char *
-procfs_do_thread_registers (bfd *obfd, ptid_t ptid, 
-                           char *note_data, int *note_size)
+procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
+                           char *note_data, int *note_size,
+                           enum target_signal stop_signal)
 {
+  struct regcache *regcache = get_thread_regcache (ptid);
   gdb_gregset_t gregs;
   gdb_fpregset_t fpregs;
   unsigned long merged_pid;
 
   merged_pid = TIDGET (ptid) << 16 | PIDGET (ptid);
 
-  fill_gregset (&gregs, -1);
+  fill_gregset (regcache, &gregs, -1);
 #if defined (UNIXWARE)
   note_data = (char *) elfcore_write_lwpstatus (obfd,
                                                note_data,
                                                note_size,
-                                               merged_pid, 
+                                               merged_pid,
                                                stop_signal,
                                                &gregs);
 #else
   note_data = (char *) elfcore_write_prstatus (obfd,
                                               note_data,
                                               note_size,
-                                              merged_pid, 
+                                              merged_pid,
                                               stop_signal,
                                               &gregs);
 #endif
-  fill_fpregset (&fpregs, -1);
+  fill_fpregset (regcache, &fpregs, -1);
   note_data = (char *) elfcore_write_prfpreg (obfd,
                                              note_data,
                                              note_size,
@@ -5818,6 +6091,7 @@ struct procfs_corefile_thread_data {
   bfd *obfd;
   char *note_data;
   int *note_size;
+  enum target_signal stop_signal;
 };
 
 static int
@@ -5825,13 +6099,14 @@ procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data)
 {
   struct procfs_corefile_thread_data *args = data;
 
-  if (pi != NULL && thread->tid != 0)
+  if (pi != NULL)
     {
       ptid_t saved_ptid = inferior_ptid;
       inferior_ptid = MERGEPID (pi->pid, thread->tid);
-      args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid, 
-                                                   args->note_data, 
-                                                   args->note_size);
+      args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid,
+                                                   args->note_data,
+                                                   args->note_size,
+                                                   args->stop_signal);
       inferior_ptid = saved_ptid;
     }
   return 0;
@@ -5849,52 +6124,56 @@ procfs_make_note_section (bfd *obfd, int *note_size)
   char *note_data = NULL;
   char *inf_args;
   struct procfs_corefile_thread_data thread_args;
+  gdb_byte *auxv;
+  int auxv_len;
 
   if (get_exec_file (0))
     {
       strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
-      strncpy (psargs, get_exec_file (0), 
+      strncpy (psargs, get_exec_file (0),
               sizeof (psargs));
 
       inf_args = get_inferior_args ();
       if (inf_args && *inf_args &&
          strlen (inf_args) < ((int) sizeof (psargs) - (int) strlen (psargs)))
        {
-         strncat (psargs, " ", 
+         strncat (psargs, " ",
                   sizeof (psargs) - strlen (psargs));
-         strncat (psargs, inf_args, 
+         strncat (psargs, inf_args,
                   sizeof (psargs) - strlen (psargs));
        }
     }
 
-  note_data = (char *) elfcore_write_prpsinfo (obfd, 
-                                              note_data, 
-                                              note_size, 
-                                              fname, 
+  note_data = (char *) elfcore_write_prpsinfo (obfd,
+                                              note_data,
+                                              note_size,
+                                              fname,
                                               psargs);
 
 #ifdef UNIXWARE
-  fill_gregset (&gregs, -1);
-  note_data = elfcore_write_pstatus (obfd, note_data, note_size, 
-                                    PIDGET (inferior_ptid), 
+  fill_gregset (get_current_regcache (), &gregs, -1);
+  note_data = elfcore_write_pstatus (obfd, note_data, note_size,
+                                    PIDGET (inferior_ptid),
                                     stop_signal, &gregs);
 #endif
 
   thread_args.obfd = obfd;
   thread_args.note_data = note_data;
   thread_args.note_size = note_size;
+  thread_args.stop_signal = find_stop_signal ();
   proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args);
 
-  if (thread_args.note_data == note_data)
-    {
-      /* iterate_over_threads didn't come up with any threads;
-        just use inferior_ptid. */
-      note_data = procfs_do_thread_registers (obfd, inferior_ptid, 
-                                             note_data, note_size);
-    }
-  else
+  /* There should be always at least one thread.  */
+  gdb_assert (thread_args.note_data != note_data);
+  note_data = thread_args.note_data;
+
+  auxv_len = target_read_alloc (&current_target, TARGET_OBJECT_AUXV,
+                               NULL, &auxv);
+  if (auxv_len > 0)
     {
-      note_data = thread_args.note_data;
+      note_data = elfcore_write_note (obfd, note_data, note_size,
+                                     "CORE", NT_AUXV, auxv, auxv_len);
+      xfree (auxv);
     }
 
   make_cleanup (xfree, note_data);
@@ -5904,7 +6183,7 @@ procfs_make_note_section (bfd *obfd, int *note_size)
 static char *
 procfs_make_note_section (bfd *obfd, int *note_size)
 {
-  error ("gcore not implemented for this host.");
+  error (_("gcore not implemented for this host."));
   return NULL; /* lint */
 }
 #endif /* Solaris or Unixware */
This page took 0.075468 seconds and 4 git commands to generate.