* config/tc-xtensa.c (xtensa_mark_literal_pool_location): Remove
[deliverable/binutils-gdb.git] / gdb / remote-vx.c
index 1f862a61ea253eb4b6d00a55ab6bb38b1e3853ce..d21025c78a92907c332c80de7805ebf709ddd19c 100644 (file)
@@ -1,34 +1,43 @@
 /* Memory-access and commands for remote VxWorks processes, for GDB.
-   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999,
+   2000, 2001, 2002 Free Software Foundation, Inc.
+
    Contributed by Wind River Systems and Cygnus Support.
 
-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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   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.  */
 
 #include "defs.h"
 #include "frame.h"
 #include "inferior.h"
-#include "wait.h"
 #include "target.h"
 #include "gdbcore.h"
 #include "command.h"
 #include "symtab.h"
-#include "symfile.h"           /* for struct complaint */
-
-#include <string.h>
+#include "complaints.h"
+#include "gdbcmd.h"
+#include "bfd.h"               /* Required by objfiles.h.  */
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "regcache.h"
+
+#include "gdb_string.h"
 #include <errno.h>
 #include <signal.h>
 #include <fcntl.h>
@@ -51,151 +60,156 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include <symtab.h>
 
+/* Maximum number of bytes to transfer in a single
+   PTRACE_{READ,WRITE}DATA request.  */
+#define VX_MEMXFER_MAX 4096
+
+extern void vx_read_register ();
+extern void vx_write_register ();
 extern void symbol_file_command ();
-extern int stop_soon_quietly;          /* for wait_for_inferior */
+extern enum stop_kind stop_soon;       /* for wait_for_inferior */
 
+static int net_step ();
 static int net_ptrace_clnt_call ();    /* Forward decl */
-static enum clnt_stat net_clnt_call ();        /* Forward decl */
-extern struct target_ops vx_ops, vx_run_ops;   /* Forward declaration */
+static enum clnt_stat net_clnt_call ();                /* Forward decl */
+
+/* Target ops structure for accessing memory and such over the net */
+
+static struct target_ops vx_ops;
+
+/* Target ops structure for accessing VxWorks child processes over the net */
+
+static struct target_ops vx_run_ops;
 
 /* Saved name of target host and called function for "info files".
    Both malloc'd.  */
 
 static char *vx_host;
-static char *vx_running;               /* Called function */
+static char *vx_running;       /* Called function */
 
 /* Nonzero means target that is being debugged remotely has a floating
    point processor.  */
 
-static int target_has_fp;
+int target_has_fp;
 
 /* Default error message when the network is forking up.  */
 
 static const char rpcerr[] = "network target debugging:  rpc error";
 
-CLIENT *pClient;         /* client used in net debugging */
+CLIENT *pClient;               /* client used in net debugging */
 static int ptraceSock = RPC_ANYSOCK;
 
-enum clnt_stat net_clnt_call();
+enum clnt_stat net_clnt_call ();
 static void parse_args ();
 
-static struct timeval rpcTimeout = { 10, 0 };
+static struct timeval rpcTimeout =
+{10, 0};
 
 static char *skip_white_space ();
 static char *find_white_space ();
+
 /* Tell the VxWorks target system to download a file.
    The load addresses of the text, data, and bss segments are
    stored in *pTextAddr, *pDataAddr, and *pBssAddr (respectively).
    Returns 0 for success, -1 for failure.  */
 
 static int
-net_load (filename, pTextAddr, pDataAddr, pBssAddr)
-    char *filename;
-    CORE_ADDR *pTextAddr;
-    CORE_ADDR *pDataAddr;
-    CORE_ADDR *pBssAddr;
+net_load (char *filename, CORE_ADDR *pTextAddr, CORE_ADDR *pDataAddr,
+         CORE_ADDR *pBssAddr)
+{
+  enum clnt_stat status;
+  struct ldfile ldstruct;
+  struct timeval load_timeout;
+
+  memset ((char *) &ldstruct, '\0', sizeof (ldstruct));
+
+  /* We invoke clnt_call () here directly, instead of through
+     net_clnt_call (), because we need to set a large timeout value.
+     The load on the target side can take quite a while, easily
+     more than 10 seconds.  The user can kill this call by typing
+     CTRL-C if there really is a problem with the load.  
+
+     Do not change the tv_sec value without checking -- select() imposes
+     a limit of 10**8 on it for no good reason that I can see...  */
+
+  load_timeout.tv_sec = 99999999;      /* A large number, effectively inf. */
+  load_timeout.tv_usec = 0;
+
+  status = clnt_call (pClient, VX_LOAD, xdr_wrapstring, &filename, xdr_ldfile,
+                     &ldstruct, load_timeout);
+
+  if (status == RPC_SUCCESS)
     {
-    enum clnt_stat status;
-    struct ldfile ldstruct;
-    struct timeval load_timeout;
-    bzero ((char *) &ldstruct, sizeof (ldstruct));
-
-    /* We invoke clnt_call () here directly, instead of through
-       net_clnt_call (), because we need to set a large timeout value.
-       The load on the target side can take quite a while, easily
-       more than 10 seconds.  The user can kill this call by typing
-       CTRL-C if there really is a problem with the load.  
-
-       Do not change the tv_sec value without checking -- select() imposes
-       a limit of 10**8 on it for no good reason that I can see...  */
-
-    load_timeout.tv_sec = 99999999;   /* A large number, effectively inf. */
-    load_timeout.tv_usec = 0;
-    status = clnt_call (pClient, VX_LOAD, xdr_wrapstring, &filename, xdr_ldfile,
-                       &ldstruct, load_timeout);
-
-    if (status == RPC_SUCCESS)
-      {
-        if (*ldstruct.name == 0)       /* load failed on VxWorks side */
-          return -1;
-       *pTextAddr = ldstruct.txt_addr;
-       *pDataAddr = ldstruct.data_addr;
-       *pBssAddr = ldstruct.bss_addr;
-       return 0;
-      }
-    else
-        return -1;
+      if (*ldstruct.name == 0) /* load failed on VxWorks side */
+       return -1;
+      *pTextAddr = ldstruct.txt_addr;
+      *pDataAddr = ldstruct.data_addr;
+      *pBssAddr = ldstruct.bss_addr;
+      return 0;
     }
-      
+  else
+    return -1;
+}
+
 /* returns 0 if successful, errno if RPC failed or VxWorks complains. */
 
 static int
-net_break (addr, procnum)
-    int addr;
-    u_long procnum;
-    {
-    enum clnt_stat status;
-    int break_status;
-    Rptrace ptrace_in;  /* XXX This is stupid.  It doesn't need to be a ptrace
-                           structure.  How about something smaller? */
+net_break (int addr, u_long procnum)
+{
+  enum clnt_stat status;
+  int break_status;
+  Rptrace ptrace_in;           /* XXX This is stupid.  It doesn't need to be a ptrace
+                                  structure.  How about something smaller? */
 
-    bzero ((char *) &ptrace_in, sizeof (ptrace_in));
-    break_status = 0;
+  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+  break_status = 0;
 
-    ptrace_in.addr = addr;
-    ptrace_in.pid = inferior_pid;
+  ptrace_in.addr = addr;
+  ptrace_in.pid = PIDGET (inferior_ptid);
 
-    status = net_clnt_call (procnum, xdr_rptrace, &ptrace_in, xdr_int,
-                           &break_status);
+  status = net_clnt_call (procnum, xdr_rptrace, &ptrace_in, xdr_int,
+                         &break_status);
 
-    if (status != RPC_SUCCESS)
-       return errno;
+  if (status != RPC_SUCCESS)
+    return errno;
+
+  if (break_status == -1)
+    return ENOMEM;
+  return break_status;         /* probably (FIXME) zero */
+}
 
-    if (break_status == -1)
-      return ENOMEM;
-    return break_status;       /* probably (FIXME) zero */
-    }
 /* returns 0 if successful, errno otherwise */
 
 static int
-vx_insert_breakpoint (addr)
-    int addr;
-    {
-    return net_break (addr, VX_BREAK_ADD);
-    }
+vx_insert_breakpoint (int addr)
+{
+  return net_break (addr, VX_BREAK_ADD);
+}
 
 /* returns 0 if successful, errno otherwise */
 
 static int
-vx_remove_breakpoint (addr)
-    int addr;
-    {
-    return net_break (addr, VX_BREAK_DELETE);
-    }
+vx_remove_breakpoint (int addr)
+{
+  return net_break (addr, VX_BREAK_DELETE);
+}
 
-/* Start an inferior process and sets inferior_pid to its pid.
+/* Start an inferior process and sets inferior_ptid to its pid.
    EXEC_FILE is the file to run.
    ALLARGS is a string containing the arguments to the program.
    ENV is the environment vector to pass.
    Returns process id.  Errors reported with error().
    On VxWorks, we ignore exec_file.  */
+
 static void
-vx_create_inferior (exec_file, args, env)
-     char *exec_file;
-     char *args;
-     char **env;
+vx_create_inferior (char *exec_file, char *args, char **env)
 {
   enum clnt_stat status;
   arg_array passArgs;
   TASK_START taskStart;
 
-  bzero ((char *) &passArgs, sizeof (passArgs));
-  bzero ((char *) &taskStart, sizeof (taskStart));
+  memset ((char *) &passArgs, '\0', sizeof (passArgs));
+  memset ((char *) &taskStart, '\0', sizeof (taskStart));
 
   /* parse arguments, put them in passArgs */
 
@@ -214,12 +228,8 @@ vx_create_inferior (exec_file, args, env)
   vx_running = savestring (passArgs.arg_array_val[0],
                           strlen (passArgs.arg_array_val[0]));
 
-#ifdef CREATE_INFERIOR_HOOK
-  CREATE_INFERIOR_HOOK (pid);
-#endif  
-
   push_target (&vx_run_ops);
-  inferior_pid = taskStart.pid;
+  inferior_ptid = pid_to_ptid (taskStart.pid);
 
   /* We will get a trace trap after one instruction.
      Insert breakpoints and continue.  */
@@ -233,28 +243,26 @@ vx_create_inferior (exec_file, args, env)
   /* Install inferior's terminal modes.  */
   target_terminal_inferior ();
 
-  stop_soon_quietly = 1;
+  stop_soon = STOP_QUIETLY;
   wait_for_inferior ();                /* Get the task spawn event */
-  stop_soon_quietly = 0;
+  stop_soon = NO_STOP_QUIETLY;
 
   /* insert_step_breakpoint ();  FIXME, do we need this?  */
-  proceed(-1, -1, 0);
+  proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
 }
 
 /* Fill ARGSTRUCT in argc/argv form with the arguments from the
    argument string ARGSTRING.  */
 
 static void
-parse_args (arg_string, arg_struct)
-     register char *arg_string;
-     arg_array *arg_struct;
+parse_args (register char *arg_string, arg_array *arg_struct)
 {
   register int arg_count = 0;  /* number of arguments */
   register int arg_index = 0;
   register char *p0;
-  bzero ((char *) arg_struct, sizeof (arg_array));
+
+  memset ((char *) arg_struct, '\0', sizeof (arg_array));
+
   /* first count how many arguments there are */
 
   p0 = arg_string;
@@ -287,21 +295,19 @@ parse_args (arg_string, arg_struct)
    to the first non-white character.  */
 
 static char *
-skip_white_space (p)
-     register char *p;
+skip_white_space (register char *p)
 {
   while (*p == ' ' || *p == '\t')
     p++;
   return p;
 }
-    
+
 /* Search for the first unquoted whitespace character in a string.
    Returns a pointer to the character, or to the null terminator
    if no whitespace is found.  */
 
 static char *
-find_white_space (p)
-     register char *p;
+find_white_space (register char *p)
 {
   register int c;
 
@@ -321,397 +327,426 @@ find_white_space (p)
     }
   return p;
 }
-    
+
 /* Poll the VxWorks target system for an event related
    to the debugged task.
    Returns -1 if remote wait failed, task status otherwise.  */
 
 static int
-net_wait (pEvent)
-    RDB_EVENT *pEvent;
+net_wait (RDB_EVENT *pEvent)
 {
-    int pid;
-    enum clnt_stat status;
+  int pid;
+  enum clnt_stat status;
 
-    bzero ((char *) pEvent, sizeof (RDB_EVENT));
+  memset ((char *) pEvent, '\0', sizeof (RDB_EVENT));
 
-    pid = inferior_pid;
-    status = net_clnt_call (PROCESS_WAIT, xdr_int, &pid, xdr_RDB_EVENT, pEvent);
+  pid = PIDGET (inferior_ptid);
+  status = net_clnt_call (PROCESS_WAIT, xdr_int, &pid, xdr_RDB_EVENT,
+                         pEvent);
 
-    return (status == RPC_SUCCESS)? pEvent->status: -1;
+  /* return (status == RPC_SUCCESS)? pEvent->status: -1; */
+  if (status == RPC_SUCCESS)
+    return ((pEvent->status) ? 1 : 0);
+  else if (status == RPC_TIMEDOUT)
+    return (1);
+  else
+    return (-1);
 }
-    
+
 /* Suspend the remote task.
    Returns -1 if suspend fails on target system, 0 otherwise.  */
 
 static int
-net_quit ()
+net_quit (void)
 {
-    int pid;
-    int quit_status;
-    enum clnt_stat status;
+  int pid;
+  int quit_status;
+  enum clnt_stat status;
 
-    quit_status = 0;
+  quit_status = 0;
 
-    /* don't let rdbTask suspend itself by passing a pid of 0 */
+  /* don't let rdbTask suspend itself by passing a pid of 0 */
 
-    if ((pid = inferior_pid) == 0)
-       return -1;
+  if ((pid = PIDGET (inferior_ptid)) == 0)
+    return -1;
 
-    status = net_clnt_call (VX_TASK_SUSPEND, xdr_int, &pid, xdr_int,
-                           &quit_status);
+  status = net_clnt_call (VX_TASK_SUSPEND, xdr_int, &pid, xdr_int,
+                         &quit_status);
 
-    return (status == RPC_SUCCESS)? quit_status: -1;
+  return (status == RPC_SUCCESS) ? quit_status : -1;
 }
 
 /* Read a register or registers from the remote system.  */
 
-static void
-vx_read_register (regno)
-     int regno;
+void
+net_read_registers (char *reg_buf, int len, u_long procnum)
 {
   int status;
   Rptrace ptrace_in;
   Ptrace_return ptrace_out;
-  C_bytes in_data;
   C_bytes out_data;
-  extern char registers[];
-
-  bzero ((char *) &ptrace_in, sizeof (ptrace_in));
-  bzero ((char *) &ptrace_out, sizeof (ptrace_out));
-
-  /* FIXME, eventually only get the ones we need.  */
-  registers_fetched ();
-  
-  ptrace_in.pid = inferior_pid;
-  ptrace_out.info.more_data = (caddr_t) &out_data;
-#ifndef I80960
-  out_data.len   = 18 * REGISTER_RAW_SIZE (0);         /* FIXME 68k hack */
-#else
-  out_data.len = (16 + 16 + 3) * REGISTER_RAW_SIZE (0);
-#endif
-  out_data.bytes = (caddr_t) registers;
-  
-  status = net_ptrace_clnt_call (PTRACE_GETREGS, &ptrace_in, &ptrace_out);
+  char message[100];
+
+  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+
+  /* Initialize RPC input argument structure.  */
+
+  ptrace_in.pid = PIDGET (inferior_ptid);
+  ptrace_in.info.ttype = NOINFO;
+
+  /* Initialize RPC return value structure.  */
+
+  out_data.bytes = reg_buf;
+  out_data.len = len;
+  ptrace_out.info.more_data = (caddr_t) & out_data;
+
+  /* Call RPC; take an error exit if appropriate.  */
+
+  status = net_ptrace_clnt_call (procnum, &ptrace_in, &ptrace_out);
   if (status)
     error (rpcerr);
   if (ptrace_out.status == -1)
     {
-      errno = ptrace_out.errno;
-      perror_with_name ("net_ptrace_clnt_call(PTRACE_GETREGS)");
-    }
-  
-#ifdef I80960
-
-  {
-    /* If the target has floating point registers, fetch them.
-       Otherwise, zero the floating point register values in
-       registers[] for good measure, even though we might not
-       need to.  */
-    /* @@ Can't use this -- the rdb library for the 960 target
-       doesn't support setting or retrieving FP regs.  KR  */
-#if 0
-    struct fp_status inferior_fp_registers;
-
-    if (target_has_fp)
-      {
-       ptrace_in.pid = inferior_pid;
-       ptrace_out.info.more_data = (caddr_t) &inferior_fp_registers;
-       status = net_ptrace_clnt_call (PTRACE_GETFPREGS,
-                                      &ptrace_in, &ptrace_out);
-       if (status)
-         error (rpcerr);
-       if (ptrace_out.status == -1)
-         {
-           errno = ptrace_out.errno;
-           perror_with_name ("net_ptrace_clnt_call(PTRACE_GETFPREGS)");
-         }
-
-       bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
-              REGISTER_RAW_SIZE (FP0_REGNUM) * 4);
-      }
-    else
-      {
-       bzero ((char *) &registers[REGISTER_BYTE (FP0_REGNUM)],
-              REGISTER_RAW_SIZE (FP0_REGNUM) * 4);
-      }
-#endif
-  }
-#else  /* not 960, thus must be 68000:  FIXME!  */
-
-  if (target_has_fp)
-    {
-      ptrace_in.pid = inferior_pid;
-      ptrace_out.info.more_data = (caddr_t) &out_data;
-      out_data.len   =  8 * REGISTER_RAW_SIZE (FP0_REGNUM)     /* FIXME */
-                    + (3 * sizeof (REGISTER_TYPE));
-      out_data.bytes = (caddr_t) &registers[REGISTER_BYTE (FP0_REGNUM)];
-  
-      status = net_ptrace_clnt_call (PTRACE_GETFPREGS, &ptrace_in, &ptrace_out);
-      if (status)
-       error (rpcerr);
-      if (ptrace_out.status == -1)
-       {
-         errno = ptrace_out.errno;
-         perror_with_name ("net_ptrace_clnt_call(PTRACE_GETFPREGS)");
-       }
-    }
-  else
-    {
-      bzero (&registers[REGISTER_BYTE (FP0_REGNUM)],
-            8 * REGISTER_RAW_SIZE (FP0_REGNUM));
-      bzero (&registers[REGISTER_BYTE (FPC_REGNUM)],
-            3 * sizeof (REGISTER_TYPE));
+      errno = ptrace_out.errno_num;
+      sprintf (message, "reading %s registers", (procnum == PTRACE_GETREGS)
+              ? "general-purpose"
+              : "floating-point");
+      perror_with_name (message);
     }
-#endif  /* various architectures */
-}
-
-/* Prepare to store registers.  Since we will store all of them,
-   read out their current values now.  */
-
-static void
-vx_prepare_to_store ()
-{
-  /* Fetch all registers, if any of them are not yet fetched.  */
-  read_register_bytes (0, NULL, REGISTER_BYTES);
 }
 
+/* Write register values to a VxWorks target.  REG_BUF points to a buffer
+   containing the raw register values, LEN is the length of REG_BUF in
+   bytes, and PROCNUM is the RPC procedure number (PTRACE_SETREGS or
+   PTRACE_SETFPREGS).  An error exit is taken if the RPC call fails or
+   if an error status is returned by the remote debug server.  This is
+   a utility routine used by vx_write_register ().  */
 
-/* Store our register values back into the inferior.
-   If REGNO is -1, do this for all registers.
-   Otherwise, REGNO specifies which register (so we can save time).  */
-   /* FIXME, look at REGNO to save time here */
-
-static void
-vx_write_register (regno)
-     int regno;
+void
+net_write_registers (char *reg_buf, int len, u_long procnum)
 {
-  C_bytes in_data;
-  C_bytes out_data;
-  extern char registers[];
   int status;
   Rptrace ptrace_in;
   Ptrace_return ptrace_out;
+  C_bytes in_data;
+  char message[100];
 
-  bzero ((char *) &ptrace_in, sizeof (ptrace_in));
-  bzero ((char *) &ptrace_out, sizeof (ptrace_out));
-
-  ptrace_in.pid = inferior_pid;
-  ptrace_in.info.ttype     = DATA;
-  ptrace_in.info.more_data = (caddr_t) &in_data;
-
-  in_data.bytes = registers;
-
-#ifdef I80960
+  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
 
-  in_data.len = (16 + 16 + 3) * sizeof (REGISTER_TYPE);
+  /* Initialize RPC input argument structure.  */
 
-#else  /* not 960 -- assume 68k -- FIXME */
+  in_data.bytes = reg_buf;
+  in_data.len = len;
 
-  in_data.len = 18 * sizeof (REGISTER_TYPE);
+  ptrace_in.pid = PIDGET (inferior_ptid);
+  ptrace_in.info.ttype = DATA;
+  ptrace_in.info.more_data = (caddr_t) & in_data;
 
-#endif  /* Different register sets */
+  /* Call RPC; take an error exit if appropriate.  */
 
-  /* XXX change second param to be a proc number */
-  status = net_ptrace_clnt_call (PTRACE_SETREGS, &ptrace_in, &ptrace_out);
+  status = net_ptrace_clnt_call (procnum, &ptrace_in, &ptrace_out);
   if (status)
-      error (rpcerr);
+    error (rpcerr);
   if (ptrace_out.status == -1)
     {
-      errno = ptrace_out.errno;
-      perror_with_name ("net_ptrace_clnt_call(PTRACE_SETREGS)");
+      errno = ptrace_out.errno_num;
+      sprintf (message, "writing %s registers", (procnum == PTRACE_SETREGS)
+              ? "general-purpose"
+              : "floating-point");
+      perror_with_name (message);
     }
+}
 
-  /* Store floating point registers if the target has them.  */
-
-  if (target_has_fp)
-    {
-      ptrace_in.pid = inferior_pid;
-      ptrace_in.info.ttype     = DATA;
-      ptrace_in.info.more_data = (caddr_t) &in_data;
-
-
-#ifdef I80960
-#if 0 /* @@ Not supported by target.  */
-      in_data.bytes = &registers[REGISTER_BYTE (FP0_REGNUM)];
-      in_data.len = 4 * REGISTER_RAW_SIZE (FP0_REGNUM);
-#endif
-#else  /* not 960 -- assume 68k -- FIXME */
-
-      in_data.bytes = &registers[REGISTER_BYTE (FP0_REGNUM)];
-      in_data.len = (8 * REGISTER_RAW_SIZE (FP0_REGNUM)
-                      + (3 * sizeof (REGISTER_TYPE)));
-
-#endif  /* Different register sets */
+/* Prepare to store registers.  Since we will store all of them,
+   read out their current values now.  */
 
-      status = net_ptrace_clnt_call (PTRACE_SETFPREGS, &ptrace_in, &ptrace_out);
-      if (status)
-         error (rpcerr);
-      if (ptrace_out.status == -1)
-       {
-         errno = ptrace_out.errno;
-         perror_with_name ("net_ptrace_clnt_call(PTRACE_SETFPREGS)");
-       }
-    }
+static void
+vx_prepare_to_store (void)
+{
+  /* Fetch all registers, if any of them are not yet fetched.  */
+  deprecated_read_register_bytes (0, NULL, DEPRECATED_REGISTER_BYTES);
 }
 
 /* Copy LEN bytes to or from remote inferior's memory starting at MEMADDR
    to debugger memory starting at MYADDR.  WRITE is true if writing to the
-   inferior.
+   inferior.  TARGET is unused.
    Result is the number of bytes written or read (zero if error).  The
    protocol allows us to return a negative count, indicating that we can't
    handle the current address but can handle one N bytes further, but
    vxworks doesn't give us that information.  */
 
 static int
-vx_xfer_memory (memaddr, myaddr, len, write, target)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
-     int write;
-     struct target_ops *target;                        /* ignored */
+vx_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+               struct mem_attrib *attrib, struct target_ops *target)
 {
   int status;
   Rptrace ptrace_in;
   Ptrace_return ptrace_out;
   C_bytes data;
+  enum ptracereq request;
+  int nleft, nxfer;
 
-  bzero ((char *) &ptrace_in, sizeof (ptrace_in));
-  bzero ((char *) &ptrace_out, sizeof (ptrace_out));
+  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
 
-  ptrace_in.pid = inferior_pid;                /* XXX pid unnecessary for READDATA */
+  ptrace_in.pid = PIDGET (inferior_ptid); /* XXX pid unnecessary for READDATA */
   ptrace_in.addr = (int) memaddr;      /* Where from */
-  ptrace_in.data = len;                        /* How many bytes */
+  ptrace_in.data = len;                /* How many bytes */
 
   if (write)
     {
-      ptrace_in.info.ttype     = DATA;
-      ptrace_in.info.more_data = (caddr_t) &data;
+      ptrace_in.info.ttype = DATA;
+      ptrace_in.info.more_data = (caddr_t) & data;
 
       data.bytes = (caddr_t) myaddr;   /* Where from */
-      data.len   = len;                        /* How many bytes (again, for XDR) */
-
-      /* XXX change second param to be a proc number */
-      status = net_ptrace_clnt_call (PTRACE_WRITEDATA, &ptrace_in, &ptrace_out);
+      data.len = len;          /* How many bytes (again, for XDR) */
+      request = PTRACE_WRITEDATA;
     }
   else
     {
-      ptrace_out.info.more_data = (caddr_t) &data;
-      data.bytes = myaddr;             /* Where to */
-      data.len   = len;                        /* How many (again, for XDR) */
-
-      /* XXX change second param to be a proc number */
-      status = net_ptrace_clnt_call (PTRACE_READDATA, &ptrace_in, &ptrace_out);
+      ptrace_out.info.more_data = (caddr_t) & data;
+      request = PTRACE_READDATA;
     }
+  /* Loop until the entire request has been satisfied, transferring
+     at most VX_MEMXFER_MAX bytes per iteration.  Break from the loop
+     if an error status is returned by the remote debug server.  */
 
-  if (status)
-      error (rpcerr);
-  if (ptrace_out.status == -1)
+  nleft = len;
+  status = 0;
+
+  while (nleft > 0 && status == 0)
     {
-      return 0;                /* No bytes moved */
+      nxfer = min (nleft, VX_MEMXFER_MAX);
+
+      ptrace_in.addr = (int) memaddr;
+      ptrace_in.data = nxfer;
+      data.bytes = (caddr_t) myaddr;
+      data.len = nxfer;
+
+      /* Request a block from the remote debug server; if RPC fails,
+         report an error and return to debugger command level.  */
+
+      if (net_ptrace_clnt_call (request, &ptrace_in, &ptrace_out))
+       error (rpcerr);
+
+      status = ptrace_out.status;
+      if (status == 0)
+       {
+         memaddr += nxfer;
+         myaddr += nxfer;
+         nleft -= nxfer;
+       }
+      else
+       {
+         /* A target-side error has ocurred.  Set errno to the error
+            code chosen by the target so that a later perror () will
+            say something meaningful.  */
+
+         errno = ptrace_out.errno_num;
+       }
     }
-  return len;          /* Moved *all* the bytes */
+
+  /* Return the number of bytes transferred.  */
+
+  return (len - nleft);
 }
 
 static void
-vx_files_info ()
+vx_files_info (void)
 {
-  printf ("\tAttached to host `%s'", vx_host);
-  printf (", which has %sfloating point", target_has_fp? "": "no ");
-  printf (".\n");
+  printf_unfiltered ("\tAttached to host `%s'", vx_host);
+  printf_unfiltered (", which has %sfloating point", target_has_fp ? "" : "no ");
+  printf_unfiltered (".\n");
 }
 
 static void
-vx_run_files_info ()
+vx_run_files_info (void)
 {
-  printf ("\tRunning %s VxWorks process %s", 
-         vx_running? "child": "attached",
-         local_hex_string(inferior_pid));
+  printf_unfiltered ("\tRunning %s VxWorks process %s",
+                    vx_running ? "child" : "attached",
+                    local_hex_string (PIDGET (inferior_ptid)));
   if (vx_running)
-    printf (", function `%s'", vx_running);
-  printf(".\n");
+    printf_unfiltered (", function `%s'", vx_running);
+  printf_unfiltered (".\n");
 }
 
 static void
-vx_resume (step, siggnal)
-     int step;
-     int siggnal;
+vx_resume (ptid_t ptid, int step, enum target_signal siggnal)
 {
   int status;
   Rptrace ptrace_in;
   Ptrace_return ptrace_out;
+  CORE_ADDR cont_addr;
+
+  if (ptid_equal (ptid, minus_one_ptid))
+    ptid = inferior_ptid;
 
   if (siggnal != 0 && siggnal != stop_signal)
     error ("Cannot send signals to VxWorks processes");
 
-  bzero ((char *) &ptrace_in, sizeof (ptrace_in));
-  bzero ((char *) &ptrace_out, sizeof (ptrace_out));
+  /* Set CONT_ADDR to the address at which we are continuing,
+     or to 1 if we are continuing from where the program stopped.
+     This conforms to traditional ptrace () usage, but at the same
+     time has special meaning for the VxWorks remote debug server.
+     If the address is not 1, the server knows that the target
+     program is jumping to a new address, which requires special
+     handling if there is a breakpoint at the new address.  */
+
+  cont_addr = read_register (PC_REGNUM);
+  if (cont_addr == stop_pc)
+    cont_addr = 1;
 
-  ptrace_in.pid = inferior_pid;
-  ptrace_in.addr = 1;  /* Target side insists on this, or it panics.  */
+  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+
+  ptrace_in.pid = PIDGET (ptid);
+  ptrace_in.addr = cont_addr;  /* Target side insists on this, or it panics.  */
+
+  if (step)
+    status = net_step ();
+  else
+    status = net_ptrace_clnt_call (PTRACE_CONT, &ptrace_in, &ptrace_out);
 
-  /* XXX change second param to be a proc number */
-  status = net_ptrace_clnt_call (step? PTRACE_SINGLESTEP: PTRACE_CONT,
-                                &ptrace_in, &ptrace_out);
   if (status)
-      error (rpcerr);
+    error (rpcerr);
   if (ptrace_out.status == -1)
     {
-      errno = ptrace_out.errno;
+      errno = ptrace_out.errno_num;
       perror_with_name ("Resuming remote process");
     }
 }
 
 static void
-vx_mourn_inferior ()
+vx_mourn_inferior (void)
 {
   pop_target ();               /* Pop back to no-child state */
   generic_mourn_inferior ();
 }
-
 \f
+
+static void vx_add_symbols (char *, int, CORE_ADDR, CORE_ADDR, CORE_ADDR);
+
+struct find_sect_args
+  {
+    CORE_ADDR text_start;
+    CORE_ADDR data_start;
+    CORE_ADDR bss_start;
+  };
+
+static void find_sect (bfd *, asection *, void *);
+
+static void
+find_sect (bfd *abfd, asection *sect, void *obj)
+{
+  struct find_sect_args *args = (struct find_sect_args *) obj;
+
+  if (bfd_get_section_flags (abfd, sect) & (SEC_CODE & SEC_READONLY))
+    args->text_start = bfd_get_section_vma (abfd, sect);
+  else if (bfd_get_section_flags (abfd, sect) & SEC_ALLOC)
+    {
+      if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
+       {
+         /* Exclude .ctor and .dtor sections which have SEC_CODE set but not
+            SEC_DATA.  */
+         if (bfd_get_section_flags (abfd, sect) & SEC_DATA)
+           args->data_start = bfd_get_section_vma (abfd, sect);
+       }
+      else
+       args->bss_start = bfd_get_section_vma (abfd, sect);
+    }
+}
+
+static void
+vx_add_symbols (char *name, int from_tty, CORE_ADDR text_addr,
+               CORE_ADDR data_addr, CORE_ADDR bss_addr)
+{
+  struct section_offsets *offs;
+  struct objfile *objfile;
+  struct find_sect_args ss;
+
+  /* It might be nice to suppress the breakpoint_re_set which happens here
+     because we are going to do one again after the objfile_relocate.  */
+  objfile = symbol_file_add (name, from_tty, NULL, 0, 0);
+
+  /* This is a (slightly cheesy) way of superceding the old symbols.  A less
+     cheesy way would be to find the objfile with the same name and
+     free_objfile it.  */
+  objfile_to_front (objfile);
+
+  offs =
+    (struct section_offsets *)
+    alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
+  memcpy (offs, objfile->section_offsets,
+          SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
+
+  ss.text_start = 0;
+  ss.data_start = 0;
+  ss.bss_start = 0;
+  bfd_map_over_sections (objfile->obfd, find_sect, &ss);
+
+  /* Both COFF and b.out frontends use these SECT_OFF_* values.  */
+  offs->offsets[SECT_OFF_TEXT (objfile)]  = text_addr - ss.text_start;
+  offs->offsets[SECT_OFF_DATA (objfile)] = data_addr - ss.data_start;
+  offs->offsets[SECT_OFF_BSS (objfile)] = bss_addr - ss.bss_start;
+  objfile_relocate (objfile, offs);
+}
+
 /* This function allows the addition of incrementally linked object files.  */
 
 static void
-vx_load_command (arg_string, from_tty)
-     char* arg_string;
-     int from_tty;
+vx_load_command (char *arg_string, int from_tty)
 {
   CORE_ADDR text_addr;
   CORE_ADDR data_addr;
   CORE_ADDR bss_addr;
-  
+
   if (arg_string == 0)
     error ("The load command takes a file name");
 
   arg_string = tilde_expand (arg_string);
-  make_cleanup (free, arg_string);
+  make_cleanup (xfree, arg_string);
 
   dont_repeat ();
 
+  /* Refuse to load the module if a debugged task is running.  Doing so
+     can have a number of unpleasant consequences to the running task.  */
+
+  if (PIDGET (inferior_ptid) != 0 && target_has_execution)
+    {
+      if (query ("You may not load a module while the target task is running.\n\
+Kill the target task? "))
+       target_kill ();
+      else
+       error ("Load canceled.");
+    }
+
   QUIT;
   immediate_quit++;
   if (net_load (arg_string, &text_addr, &data_addr, &bss_addr) == -1)
     error ("Load failed on target machine");
   immediate_quit--;
 
-  /* FIXME, for now we ignore data_addr and bss_addr.  */
-  symbol_file_add (arg_string, from_tty, text_addr, 0, 0, 0);
+  vx_add_symbols (arg_string, from_tty, text_addr, data_addr, bss_addr);
+
+  /* Getting new symbols may change our opinion about what is
+     frameless.  */
+  reinit_frame_cache ();
 }
 
-#ifdef FIXME  /* Not ready for prime time */
 /* Single step the target program at the source or machine level.
    Takes an error exit if rpc fails.
    Returns -1 if remote single-step operation fails, else 0.  */
 
 static int
-net_step ()
+net_step (void)
 {
   enum clnt_stat status;
   int step_status;
   SOURCE_STEP source_step;
 
-  source_step.taskId = inferior_pid;
+  source_step.taskId = PIDGET (inferior_ptid);
 
   if (step_range_end)
     {
@@ -729,19 +764,16 @@ net_step ()
 
   if (status == RPC_SUCCESS)
     return step_status;
-  else 
+  else
     error (rpcerr);
 }
-#endif
 
 /* Emulate ptrace using RPC calls to the VxWorks target system.
    Returns nonzero (-1) if RPC status to VxWorks is bad, 0 otherwise.  */
 
 static int
-net_ptrace_clnt_call (request, pPtraceIn, pPtraceOut)
-    enum ptracereq request;
-    Rptrace *pPtraceIn;
-    Ptrace_return *pPtraceOut;
+net_ptrace_clnt_call (enum ptracereq request, Rptrace *pPtraceIn,
+                     Ptrace_return *pPtraceOut)
 {
   enum clnt_stat status;
 
@@ -749,7 +781,7 @@ net_ptrace_clnt_call (request, pPtraceIn, pPtraceOut)
                          pPtraceOut);
 
   if (status != RPC_SUCCESS)
-      return -1;
+    return -1;
 
   return 0;
 }
@@ -761,8 +793,7 @@ net_ptrace_clnt_call (request, pPtraceIn, pPtraceOut)
    Returns -1 if rpc failed, 0 otherwise.  */
 
 static int
-net_get_boot_file (pBootFile)
-     char **pBootFile;
+net_get_boot_file (char **pBootFile)
 {
   enum clnt_stat status;
 
@@ -771,18 +802,18 @@ net_get_boot_file (pBootFile)
   return (status == RPC_SUCCESS) ? 0 : -1;
 }
 
-/* Fetch a list of loaded object modules from the VxWorks target.
+/* Fetch a list of loaded object modules from the VxWorks target
+   and store in PLOADTABLE.
    Returns -1 if rpc failed, 0 otherwise
    There's no way to check if the returned loadTable is correct.
    VxWorks doesn't check it.  */
 
 static int
-net_get_symbols (pLoadTable)
-     ldtabl *pLoadTable;               /* return pointer to ldtabl here */
+net_get_symbols (ldtabl *pLoadTable)
 {
   enum clnt_stat status;
 
-  bzero ((char *) pLoadTable, sizeof (struct ldtabl));
+  memset ((char *) pLoadTable, '\0', sizeof (struct ldtabl));
 
   status = net_clnt_call (VX_STATE_INQ, xdr_void, 0, xdr_ldtabl, pLoadTable);
   return (status == RPC_SUCCESS) ? 0 : -1;
@@ -792,26 +823,23 @@ net_get_symbols (pLoadTable)
    Returns status of symbol read on target side (0=success, -1=fail)
    Returns -1 and complain()s if rpc fails.  */
 
-struct complaint cant_contact_target =
-  {"Lost contact with VxWorks target", 0, 0};
-
 static int
-vx_lookup_symbol (name, pAddr)
-     char *name;               /* symbol name */
-     CORE_ADDR *pAddr;
+vx_lookup_symbol (char *name,  /* symbol name */
+                 CORE_ADDR *pAddr)
 {
   enum clnt_stat status;
   SYMBOL_ADDR symbolAddr;
 
   *pAddr = 0;
-  bzero ((char *) &symbolAddr, sizeof (symbolAddr));
+  memset ((char *) &symbolAddr, '\0', sizeof (symbolAddr));
 
   status = net_clnt_call (VX_SYMBOL_INQ, xdr_wrapstring, &name,
                          xdr_SYMBOL_ADDR, &symbolAddr);
-  if (status != RPC_SUCCESS) {
-      complain (&cant_contact_target);
+  if (status != RPC_SUCCESS)
+    {
+      complaint (&symfile_complaints, "Lost contact with VxWorks target");
       return -1;
-  }
+    }
 
   *pAddr = symbolAddr.addr;
   return symbolAddr.status;
@@ -822,47 +850,58 @@ vx_lookup_symbol (name, pAddr)
    Calls error() if rpc fails.  */
 
 static int
-net_check_for_fp ()
+net_check_for_fp (void)
 {
   enum clnt_stat status;
-  bool_t fp = 0;       /* true if fp processor is present on target board */
+  bool_t fp = 0;               /* true if fp processor is present on target board */
 
   status = net_clnt_call (VX_FP_INQUIRE, xdr_void, 0, xdr_bool, &fp);
   if (status != RPC_SUCCESS)
-      error (rpcerr);
+    error (rpcerr);
 
-   return (int) fp;
+  return (int) fp;
 }
 
 /* Establish an RPC connection with the VxWorks target system.
    Calls error () if unable to establish connection.  */
 
 static void
-net_connect (host)
-     char *host;
+net_connect (char *host)
 {
   struct sockaddr_in destAddr;
   struct hostent *destHost;
+  unsigned long addr;
 
-  /* get the internet address for the given host */
+  /* Get the internet address for the given host.  Allow a numeric
+     IP address or a hostname.  */
 
-  if ((destHost = (struct hostent *) gethostbyname (host)) == NULL)
-      error ("Invalid hostname.  Couldn't find remote host address.");
+  addr = inet_addr (host);
+  if (addr == -1)
+    {
+      destHost = (struct hostent *) gethostbyname (host);
+      if (destHost == NULL)
+       /* FIXME: Probably should include hostname here in quotes.
+          For example if the user types "target vxworks vx960 " it should
+          say "Invalid host `vx960 '." not just "Invalid hostname".  */
+       error ("Invalid hostname.  Couldn't find remote host address.");
+      addr = *(unsigned long *) destHost->h_addr;
+    }
 
-  bzero (&destAddr, sizeof (destAddr));
+  memset (&destAddr, '\0', sizeof (destAddr));
 
-  destAddr.sin_addr.s_addr = * (u_long *) destHost->h_addr;
-  destAddr.sin_family      = AF_INET;
-  destAddr.sin_port        = 0;        /* set to actual port that remote
-                                  ptrace is listening on.  */
+  destAddr.sin_addr.s_addr = addr;
+  destAddr.sin_family = AF_INET;
+  destAddr.sin_port = 0;       /* set to actual port that remote
+                                  ptrace is listening on.  */
 
   /* Create a tcp client transport on which to issue
      calls to the remote ptrace server.  */
 
   ptraceSock = RPC_ANYSOCK;
   pClient = clnttcp_create (&destAddr, RDBPROG, RDBVERS, &ptraceSock, 0, 0);
-  /* FIXME, here is where we deal with different version numbers of the proto */
-  
+  /* FIXME, here is where we deal with different version numbers of the
+     proto */
+
   if (pClient == NULL)
     {
       clnt_pcreateerror ("\tnet_connect");
@@ -877,8 +916,7 @@ net_connect (host)
  */
 
 static void
-sleep_ms (ms)
-     long ms;
+sleep_ms (long ms)
 {
   struct timeval select_timeout;
   int status;
@@ -886,37 +924,24 @@ sleep_ms (ms)
   select_timeout.tv_sec = 0;
   select_timeout.tv_usec = ms * 1000;
 
-  status = select (0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &select_timeout);
+  status = select (0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0,
+                  &select_timeout);
 
   if (status < 0 && errno != EINTR)
     perror_with_name ("select");
 }
 
-/* Wait for control to return from inferior to debugger.
-   If inferior gets a signal, we may decide to start it up again
-   instead of returning.  That is why there is a loop in this function.
-   When this function actually returns it means the inferior
-   should be left stopped and GDB should read more commands.  */
-
-/* For network debugging with VxWorks.
- * VxWorks knows when tasks hit breakpoints, receive signals, exit, etc,
- * so vx_wait() receives this information directly from
- * VxWorks instead of trying to figure out what happenned via a wait() call.
- */
-
-static int
-vx_wait (status)
-     int *status;
+static ptid_t
+vx_wait (ptid_t ptid_to_wait_for, struct target_waitstatus *status)
 {
   register int pid;
-  WAITTYPE w;
   RDB_EVENT rdbEvent;
   int quit_failed;
 
   do
     {
       /* If CTRL-C is hit during this loop,
-        suspend the inferior process.  */
+         suspend the inferior process.  */
 
       quit_failed = 0;
       if (quit_flag)
@@ -926,19 +951,19 @@ vx_wait (status)
        }
 
       /* If a net_quit () or net_wait () call has failed,
-        allow the user to break the connection with the target.
-        We can't simply error () out of this loop, since the 
-        data structures representing the state of the inferior
-        are in an inconsistent state.  */
+         allow the user to break the connection with the target.
+         We can't simply error () out of this loop, since the 
+         data structures representing the state of the inferior
+         are in an inconsistent state.  */
 
       if (quit_failed || net_wait (&rdbEvent) == -1)
        {
          terminal_ours ();
          if (query ("Can't %s.  Disconnect from target system? ",
                     (quit_failed) ? "suspend remote task"
-                                  : "get status of remote task"))
+                    : "get status of remote task"))
            {
-             target_mourn_inferior();
+             target_mourn_inferior ();
              error ("Use the \"target\" command to reconnect.");
            }
          else
@@ -947,81 +972,89 @@ vx_wait (status)
              continue;
            }
        }
-      
+
       pid = rdbEvent.taskId;
       if (pid == 0)
        {
          sleep_ms (200);       /* FIXME Don't kill the network too badly */
        }
-      else if (pid != inferior_pid)
-       fatal ("Bad pid for debugged task: %s\n", local_hex_string(pid));
-    } while (pid == 0);
+      else if (pid != PIDGET (inferior_ptid))
+       internal_error (__FILE__, __LINE__,
+                       "Bad pid for debugged task: %s\n",
+                       local_hex_string ((unsigned long) pid));
+    }
+  while (pid == 0);
+
+  /* The mostly likely kind.  */
+  status->kind = TARGET_WAITKIND_STOPPED;
 
-  /* FIXME, eventually do more then SIGTRAP on everything...  */
   switch (rdbEvent.eventType)
     {
     case EVENT_EXIT:
-      WSETEXIT (w, 0);
+      status->kind = TARGET_WAITKIND_EXITED;
       /* FIXME is it possible to distinguish between a
-        XXX   normal vs abnormal exit in VxWorks? */
+         normal vs abnormal exit in VxWorks? */
+      status->value.integer = 0;
       break;
 
-    case EVENT_START:          /* Task was just started. */
-      WSETSTOP (w, SIGTRAP);
+    case EVENT_START:
+      /* Task was just started. */
+      status->value.sig = TARGET_SIGNAL_TRAP;
       break;
 
     case EVENT_STOP:
-      WSETSTOP (w, SIGTRAP);
+      status->value.sig = TARGET_SIGNAL_TRAP;
       /* XXX was it stopped by a signal?  act accordingly */
       break;
 
     case EVENT_BREAK:          /* Breakpoint was hit. */
-      WSETSTOP (w, SIGTRAP);
+      status->value.sig = TARGET_SIGNAL_TRAP;
       break;
 
-    case EVENT_SUSPEND:                /* Task was suspended, probably by ^C. */
-      WSETSTOP (w, SIGINT);
+    case EVENT_SUSPEND:        /* Task was suspended, probably by ^C. */
+      status->value.sig = TARGET_SIGNAL_INT;
       break;
 
-    case EVENT_BUS_ERR:                /* Task made evil nasty reference. */
-      WSETSTOP (w, SIGBUS);
+    case EVENT_BUS_ERR:        /* Task made evil nasty reference. */
+      status->value.sig = TARGET_SIGNAL_BUS;
       break;
 
     case EVENT_ZERO_DIV:       /* Division by zero */
-      WSETSTOP (w, SIGFPE);    /* Like Unix, call it a float exception. */
+      status->value.sig = TARGET_SIGNAL_FPE;
       break;
 
     case EVENT_SIGNAL:
-      /* The target is not running Unix, and its
-        faults/traces do not map nicely into Unix signals.
-        Make sure they do not get confused with Unix signals
-        by numbering them with values higher than the highest
-        legal Unix signal.  code in the arch-dependent PRINT_RANDOM_SIGNAL
-        routine will interpret the value for wait_for_inferior.  */
-      WSETSTOP (w, rdbEvent.sigType + NSIG);
+#ifdef I80960
+      status->value.sig = i960_fault_to_signal (rdbEvent.sigType);
+#else
+      /* Back in the old days, before enum target_signal, this code used
+         to add NSIG to the signal number and claim that PRINT_RANDOM_SIGNAL
+         would take care of it.  But PRINT_RANDOM_SIGNAL has never been
+         defined except on the i960, so I don't really know what we are
+         supposed to do on other architectures.  */
+      status->value.sig = TARGET_SIGNAL_UNKNOWN;
+#endif
       break;
-    } /* switch */
-  *status = *(int *)&w;                /* Grumble union wait crap Grumble */
-  return pid;
+    }                          /* switch */
+  return pid_to_ptid (pid);
 }
 \f
 static int
-symbol_stub (arg)
-     char *arg;
+symbol_stub (char *arg)
 {
-  symbol_file_command (arg, 0);
+  symbol_file_add_main (arg, 0);
   return 1;
 }
 
 static int
-add_symbol_stub (arg)
-     char *arg;
+add_symbol_stub (char *arg)
 {
-  struct ldfile *pLoadFile = (struct ldfile *)arg;
+  struct ldfile *pLoadFile = (struct ldfile *) arg;
 
-  printf("\t%s: ", pLoadFile->name);
-  symbol_file_add (pLoadFile->name, 0, pLoadFile->txt_addr, 0, 0, 0);
-  printf ("ok\n");
+  printf_unfiltered ("\t%s: ", pLoadFile->name);
+  vx_add_symbols (pLoadFile->name, 0, pLoadFile->txt_addr,
+                 pLoadFile->data_addr, pLoadFile->bss_addr);
+  printf_unfiltered ("ok\n");
   return 1;
 }
 /* Target command for VxWorks target systems.
@@ -1031,9 +1064,7 @@ add_symbol_stub (arg)
    debugging.  */
 
 static void
-vx_open (args, from_tty)
-     char *args;
-     int from_tty;
+vx_open (char *args, int from_tty)
 {
   extern int close ();
   char *bootFile;
@@ -1042,15 +1073,16 @@ vx_open (args, from_tty)
   struct ldfile *pLoadFile;
   int i;
   extern CLIENT *pClient;
+  int symbols_added = 0;
 
   if (!args)
     error_no_arg ("target machine name");
 
   target_preopen (from_tty);
-  
+
   unpush_target (&vx_ops);
-  printf ("Attaching remote machine across net...\n");
-  fflush (stdout);
+  printf_unfiltered ("Attaching remote machine across net...\n");
+  gdb_flush (gdb_stdout);
 
   /* Allow the user to kill the connect attempt by typing ^C.
      Wait until the call to target_has_fp () completes before
@@ -1077,13 +1109,20 @@ vx_open (args, from_tty)
   bootFile = NULL;
   if (!net_get_boot_file (&bootFile))
     {
-      if (*bootFile) {
-       printf_filtered ("\t%s: ", bootFile);
-       if (catch_errors (symbol_stub, bootFile,
-               "Error while reading symbols from boot file:\n"))
-         puts_filtered ("ok\n");
-      } else if (from_tty)
-       printf ("VxWorks kernel symbols not loaded.\n");
+      if (*bootFile)
+       {
+         printf_filtered ("\t%s: ", bootFile);
+         /* This assumes that the kernel is never relocated.  Hope that is an
+            accurate assumption.  */
+         if (catch_errors
+             (symbol_stub,
+              bootFile,
+              "Error while reading symbols from boot file:\n",
+              RETURN_MASK_ALL))
+           puts_filtered ("ok\n");
+       }
+      else if (from_tty)
+       printf_unfiltered ("VxWorks kernel symbols not loaded.\n");
     }
   else
     error ("Can't retrieve boot file name from target machine.");
@@ -1093,46 +1132,52 @@ vx_open (args, from_tty)
   if (net_get_symbols (&loadTable) != 0)
     error ("Can't read loaded modules from target machine");
 
-  i = 0-1;
+  i = 0 - 1;
   while (++i < loadTable.tbl_size)
     {
-      QUIT;    /* FIXME, avoids clnt_freeres below:  mem leak */
-      pLoadFile = &loadTable.tbl_ent [i];
+      QUIT;                    /* FIXME, avoids clnt_freeres below:  mem leak */
+      pLoadFile = &loadTable.tbl_ent[i];
 #ifdef WRS_ORIG
-  {
-    register int desc;
-    struct cleanup *old_chain;
-    char *fullname = NULL;
-
-    desc = openp (source_path, 0, pLoadFile->name, O_RDONLY, 0, &fullname);
-    if (desc < 0)
-       perror_with_name (pLoadFile->name);
-    old_chain = make_cleanup (close, desc);
-    add_file_at_addr (fullname, desc, pLoadFile->txt_addr, pLoadFile->data_addr,
-                     pLoadFile->bss_addr);
-    do_cleanups (old_chain);
-  }
+      {
+       register int desc;
+       struct cleanup *old_chain;
+       char *fullname = NULL;
+
+       desc = openp (source_path, 0, pLoadFile->name, O_RDONLY, 0, &fullname);
+       if (desc < 0)
+         perror_with_name (pLoadFile->name);
+       old_chain = make_cleanup (close, desc);
+       add_file_at_addr (fullname, desc, pLoadFile->txt_addr, pLoadFile->data_addr,
+                         pLoadFile->bss_addr);
+       do_cleanups (old_chain);
+      }
 #else
-      /* Botches, FIXME:
-        (1)  Searches the PATH, not the source path.
-        (2)  data and bss are assumed to be at the usual offsets from text.  */
-      catch_errors (add_symbol_stub, (char *)pLoadFile, (char *)0);
+      /* FIXME: Is there something better to search than the PATH? (probably
+         not the source path, since source might be in different directories
+         than objects.  */
+
+      if (catch_errors (add_symbol_stub, (char *) pLoadFile, (char *) 0,
+                       RETURN_MASK_ALL))
+       symbols_added = 1;
 #endif
     }
   printf_filtered ("Done.\n");
 
   clnt_freeres (pClient, xdr_ldtabl, &loadTable);
+
+  /* Getting new symbols may change our opinion about what is
+     frameless.  */
+  if (symbols_added)
+    reinit_frame_cache ();
 }
 \f
 /* Takes a task started up outside of gdb and ``attaches'' to it.
    This stops it cold in its tracks and allows us to start tracing it.  */
 
 static void
-vx_attach (args, from_tty)
-     char *args;
-     int from_tty;
+vx_attach (char *args, int from_tty)
 {
-  int pid;
+  unsigned long pid;
   char *cptr = 0;
   Rptrace ptrace_in;
   Ptrace_return ptrace_out;
@@ -1141,15 +1186,16 @@ vx_attach (args, from_tty)
   if (!args)
     error_no_arg ("process-id to attach");
 
-  pid = strtol (args, &cptr, 0);
+  pid = strtoul (args, &cptr, 0);
   if ((cptr == args) || (*cptr != '\0'))
     error ("Invalid process-id -- give a single number in decimal or 0xhex");
 
   if (from_tty)
-      printf ("Attaching pid %s.\n", local_hex_string(pid));
+    printf_unfiltered ("Attaching pid %s.\n",
+                      local_hex_string ((unsigned long) pid));
 
-  bzero ((char *)&ptrace_in,  sizeof (ptrace_in));
-  bzero ((char *)&ptrace_out, sizeof (ptrace_out));
+  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
   ptrace_in.pid = pid;
 
   status = net_ptrace_clnt_call (PTRACE_ATTACH, &ptrace_in, &ptrace_out);
@@ -1157,17 +1203,20 @@ vx_attach (args, from_tty)
     error (rpcerr);
   if (ptrace_out.status == -1)
     {
-      errno = ptrace_out.errno;
+      errno = ptrace_out.errno_num;
       perror_with_name ("Attaching remote process");
     }
 
   /* It worked... */
+
+  inferior_ptid = pid_to_ptid (pid);
   push_target (&vx_run_ops);
-  inferior_pid = pid;
+
+  if (vx_running)
+    xfree (vx_running);
   vx_running = 0;
 }
 
-
 /* detach_command --
    takes a program previously attached to and detaches it.
    The program resumes execution and will no longer stop
@@ -1178,9 +1227,7 @@ vx_attach (args, from_tty)
    started via the normal ptrace (PTRACE_TRACEME).  */
 
 static void
-vx_detach (args, from_tty)
-     char *args;
-     int from_tty;
+vx_detach (char *args, int from_tty)
 {
   Rptrace ptrace_in;
   Ptrace_return ptrace_out;
@@ -1191,67 +1238,68 @@ vx_detach (args, from_tty)
     error ("Argument given to VxWorks \"detach\".");
 
   if (from_tty)
-      printf ("Detaching pid %s.\n", local_hex_string(inferior_pid));
+    printf_unfiltered ("Detaching pid %s.\n",
+                      local_hex_string (
+                        (unsigned long) PIDGET (inferior_ptid)));
 
-  if (args)            /* FIXME, should be possible to leave suspended */
+  if (args)                    /* FIXME, should be possible to leave suspended */
     signal = atoi (args);
-  
-  bzero ((char *)&ptrace_in,  sizeof (ptrace_in));
-  bzero ((char *)&ptrace_out, sizeof (ptrace_out));
-  ptrace_in.pid = inferior_pid;
+
+  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+  ptrace_in.pid = PIDGET (inferior_ptid);
 
   status = net_ptrace_clnt_call (PTRACE_DETACH, &ptrace_in, &ptrace_out);
   if (status == -1)
     error (rpcerr);
   if (ptrace_out.status == -1)
     {
-      errno = ptrace_out.errno;
+      errno = ptrace_out.errno_num;
       perror_with_name ("Detaching VxWorks process");
     }
 
-  inferior_pid = 0;
-  pop_target ();       /* go back to non-executing VxWorks connection */
+  inferior_ptid = null_ptid;
+  pop_target ();               /* go back to non-executing VxWorks connection */
 }
 
 /* vx_kill -- takes a running task and wipes it out.  */
 
 static void
-vx_kill ()
+vx_kill (void)
 {
   Rptrace ptrace_in;
   Ptrace_return ptrace_out;
   int status;
 
-  printf ("Killing pid %s.\n", local_hex_string(inferior_pid));
+  printf_unfiltered ("Killing pid %s.\n", local_hex_string ((unsigned long) PIDGET (inferior_ptid)));
 
-  bzero ((char *)&ptrace_in,  sizeof (ptrace_in));
-  bzero ((char *)&ptrace_out, sizeof (ptrace_out));
-  ptrace_in.pid = inferior_pid;
+  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+  ptrace_in.pid = PIDGET (inferior_ptid);
 
   status = net_ptrace_clnt_call (PTRACE_KILL, &ptrace_in, &ptrace_out);
   if (status == -1)
     warning (rpcerr);
   else if (ptrace_out.status == -1)
     {
-      errno = ptrace_out.errno;
+      errno = ptrace_out.errno_num;
       perror_with_name ("Killing VxWorks process");
     }
 
   /* If it gives good status, the process is *gone*, no events remain.
      If the kill failed, assume the process is gone anyhow.  */
-  inferior_pid = 0;
-  pop_target ();       /* go back to non-executing VxWorks connection */
+  inferior_ptid = null_ptid;
+  pop_target ();               /* go back to non-executing VxWorks connection */
 }
 
 /* Clean up from the VxWorks process target as it goes away.  */
 
 static void
-vx_proc_close (quitting)
-     int quitting;
+vx_proc_close (int quitting)
 {
-  inferior_pid = 0;            /* No longer have a process.  */
+  inferior_ptid = null_ptid;   /* No longer have a process.  */
   if (vx_running)
-    free (vx_running);
+    xfree (vx_running);
   vx_running = 0;
 }
 \f
@@ -1259,19 +1307,15 @@ vx_proc_close (quitting)
    Returns RPC status.  */
 
 static enum clnt_stat
-net_clnt_call (procNum, inProc, in, outProc, out)
-    enum ptracereq procNum;
-    xdrproc_t inProc;
-    char *in;
-    xdrproc_t outProc;
-    char *out;
+net_clnt_call (enum ptracereq procNum, xdrproc_t inProc, char *in,
+              xdrproc_t outProc, char *out)
 {
   enum clnt_stat status;
-  
+
   status = clnt_call (pClient, procNum, inProc, in, outProc, out, rpcTimeout);
 
   if (status != RPC_SUCCESS)
-      clnt_perrno (status);
+    clnt_perrno (status);
 
   return status;
 }
@@ -1279,82 +1323,88 @@ net_clnt_call (procNum, inProc, in, outProc, out)
 /* Clean up before losing control.  */
 
 static void
-vx_close (quitting)
-     int quitting;
+vx_close (int quitting)
 {
   if (pClient)
     clnt_destroy (pClient);    /* The net connection */
   pClient = 0;
 
   if (vx_host)
-    free (vx_host);            /* The hostname */
+    xfree (vx_host);           /* The hostname */
   vx_host = 0;
 }
 
 /* A vxprocess target should be started via "run" not "target".  */
-/*ARGSUSED*/
+/*ARGSUSED */
 static void
-vx_proc_open (name, from_tty)
-     char *name;
-     int from_tty;
+vx_proc_open (char *name, int from_tty)
 {
   error ("Use the \"run\" command to start a VxWorks process.");
 }
 
-/* Target ops structure for accessing memory and such over the net */
-
-struct target_ops vx_ops = {
-       "vxworks", "VxWorks target memory via RPC over TCP/IP",
-       "Use VxWorks target memory.  \n\
-Specify the name of the machine to connect to.",
-       vx_open, vx_close, vx_attach, 0, /* vx_detach, */
-       0, 0, /* resume, wait */
-       0, 0, /* read_reg, write_reg */
-       0, /* prep_to_store, */
-       vx_xfer_memory, vx_files_info,
-       0, 0, /* insert_breakpoint, remove_breakpoint */
-       0, 0, 0, 0, 0,  /* terminal stuff */
-       0, /* vx_kill, */
-       vx_load_command,
-       vx_lookup_symbol,
-       vx_create_inferior, 0,  /* mourn_inferior */
-       0, /* can_run */
-       0, /* notice_signals */
-       core_stratum, 0, /* next */
-       1, 1, 0, 0, 0,  /* all mem, mem, stack, regs, exec */
-       0, 0,                   /* Section pointers */
-       OPS_MAGIC,              /* Always the last thing */
+static void
+init_vx_ops (void)
+{
+  vx_ops.to_shortname = "vxworks";
+  vx_ops.to_longname = "VxWorks target memory via RPC over TCP/IP";
+  vx_ops.to_doc = "Use VxWorks target memory.  \n\
+Specify the name of the machine to connect to.";
+  vx_ops.to_open = vx_open;
+  vx_ops.to_close = vx_close;
+  vx_ops.to_attach = vx_attach;
+  vx_ops.to_xfer_memory = vx_xfer_memory;
+  vx_ops.to_files_info = vx_files_info;
+  vx_ops.to_load = vx_load_command;
+  vx_ops.to_lookup_symbol = vx_lookup_symbol;
+  vx_ops.to_create_inferior = vx_create_inferior;
+  vx_ops.to_stratum = core_stratum;
+  vx_ops.to_has_all_memory = 1;
+  vx_ops.to_has_memory = 1;
+  vx_ops.to_magic = OPS_MAGIC; /* Always the last thing */
 };
 
-/* Target ops structure for accessing VxWorks child processes over the net */
-
-struct target_ops vx_run_ops = {
-       "vxprocess", "VxWorks process",
-       "VxWorks process, started by the \"run\" command.",
-       vx_proc_open, vx_proc_close, 0, vx_detach, /* vx_attach */
-       vx_resume, vx_wait,
-       vx_read_register, vx_write_register,
-       vx_prepare_to_store,
-       vx_xfer_memory, vx_run_files_info,
-       vx_insert_breakpoint, vx_remove_breakpoint,
-       0, 0, 0, 0, 0,  /* terminal stuff */
-       vx_kill,
-       vx_load_command,
-       vx_lookup_symbol,
-       0, vx_mourn_inferior,
-       0,  /* can_run */
-       0, /* notice_signals */
-       process_stratum, 0, /* next */
-       0, 1, 1, 1, 1,  /* all mem, mem, stack, regs, exec */
-                       /* all_mem is off to avoid spurious msg in "i files" */
-       0, 0,                   /* Section pointers */
-       OPS_MAGIC,              /* Always the last thing */
-};
-/* ==> Remember when reading at end of file, there are two "ops" structs here. */
+static void
+init_vx_run_ops (void)
+{
+  vx_run_ops.to_shortname = "vxprocess";
+  vx_run_ops.to_longname = "VxWorks process";
+  vx_run_ops.to_doc = "VxWorks process; started by the \"run\" command.";
+  vx_run_ops.to_open = vx_proc_open;
+  vx_run_ops.to_close = vx_proc_close;
+  vx_run_ops.to_detach = vx_detach;
+  vx_run_ops.to_resume = vx_resume;
+  vx_run_ops.to_wait = vx_wait;
+  vx_run_ops.to_fetch_registers = vx_read_register;
+  vx_run_ops.to_store_registers = vx_write_register;
+  vx_run_ops.to_prepare_to_store = vx_prepare_to_store;
+  vx_run_ops.to_xfer_memory = vx_xfer_memory;
+  vx_run_ops.to_files_info = vx_run_files_info;
+  vx_run_ops.to_insert_breakpoint = vx_insert_breakpoint;
+  vx_run_ops.to_remove_breakpoint = vx_remove_breakpoint;
+  vx_run_ops.to_kill = vx_kill;
+  vx_run_ops.to_load = vx_load_command;
+  vx_run_ops.to_lookup_symbol = vx_lookup_symbol;
+  vx_run_ops.to_mourn_inferior = vx_mourn_inferior;
+  vx_run_ops.to_stratum = process_stratum;
+  vx_run_ops.to_has_memory = 1;
+  vx_run_ops.to_has_stack = 1;
+  vx_run_ops.to_has_registers = 1;
+  vx_run_ops.to_has_execution = 1;
+  vx_run_ops.to_magic = OPS_MAGIC;
+}
 \f
 void
-_initialize_vx ()
+_initialize_vx (void)
 {
+  init_vx_ops ();
   add_target (&vx_ops);
+  init_vx_run_ops ();
   add_target (&vx_run_ops);
+
+  add_show_from_set
+    (add_set_cmd ("vxworks-timeout", class_support, var_uinteger,
+                 (char *) &rpcTimeout.tv_sec,
+                 "Set seconds to wait for rpc calls to return.\n\
+Set the number of seconds to wait for rpc calls to return.", &setlist),
+     &showlist);
 }
This page took 0.048692 seconds and 4 git commands to generate.