/* Memory-access and commands for remote VxWorks processes, for GDB.
   Copyright (C) 1990-95, 1997-98, 1999 Free Software Foundation, Inc.
   Contributed by Wind River Systems and Cygnus Support.

   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 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.  */

#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 "complaints.h"
#include "gdbcmd.h"
#include "bfd.h"		/* Required by objfiles.h.  */
#include "symfile.h"		/* Required by objfiles.h.  */
#include "objfiles.h"
#include "gdb-stabs.h"

#include "gdb_string.h"
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#define malloc bogon_malloc	/* Sun claims "char *malloc()" not void * */
#define free bogon_free		/* Sun claims "int free()" not void */
#define realloc bogon_realloc	/* Sun claims "char *realloc()", not void * */
#include <rpc/rpc.h>
#undef malloc
#undef free
#undef realloc
#include <sys/time.h>		/* UTek's <rpc/rpc.h> doesn't #incl this */
#include <netdb.h>
#include "vx-share/ptrace.h"
#include "vx-share/xdr_ptrace.h"
#include "vx-share/xdr_ld.h"
#include "vx-share/xdr_rdb.h"
#include "vx-share/dbgRpcLib.h"

#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 */

static int net_step ();
static int net_ptrace_clnt_call ();	/* Forward decl */
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 */

/* Nonzero means target that is being debugged remotely has a floating
   point processor.  */

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 */
static int ptraceSock = RPC_ANYSOCK;

enum clnt_stat net_clnt_call ();
static void parse_args ();

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;
{
  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)
    {
      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? */

  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
  break_status = 0;

  ptrace_in.addr = addr;
  ptrace_in.pid = inferior_pid;

  status = net_clnt_call (procnum, xdr_rptrace, &ptrace_in, xdr_int,
			  &break_status);

  if (status != RPC_SUCCESS)
    return errno;

  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);
}

/* returns 0 if successful, errno otherwise */

static int
vx_remove_breakpoint (addr)
     int addr;
{
  return net_break (addr, VX_BREAK_DELETE);
}

/* Start an inferior process and sets inferior_pid 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;
{
  enum clnt_stat status;
  arg_array passArgs;
  TASK_START taskStart;

  memset ((char *) &passArgs, '\0', sizeof (passArgs));
  memset ((char *) &taskStart, '\0', sizeof (taskStart));

  /* parse arguments, put them in passArgs */

  parse_args (args, &passArgs);

  if (passArgs.arg_array_len == 0)
    error ("You must specify a function name to run, and arguments if any");

  status = net_clnt_call (PROCESS_START, xdr_arg_array, &passArgs,
			  xdr_TASK_START, &taskStart);

  if ((status != RPC_SUCCESS) || (taskStart.status == -1))
    error ("Can't create process on remote target machine");

  /* Save the name of the running function */
  vx_running = savestring (passArgs.arg_array_val[0],
			   strlen (passArgs.arg_array_val[0]));

  push_target (&vx_run_ops);
  inferior_pid = taskStart.pid;

  /* We will get a trace trap after one instruction.
     Insert breakpoints and continue.  */

  init_wait_for_inferior ();

  /* Set up the "saved terminal modes" of the inferior
     based on what modes we are starting it with.  */
  target_terminal_init ();

  /* Install inferior's terminal modes.  */
  target_terminal_inferior ();

  stop_soon_quietly = 1;
  wait_for_inferior ();		/* Get the task spawn event */
  stop_soon_quietly = 0;

  /* insert_step_breakpoint ();  FIXME, do we need this?  */
  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;
{
  register int arg_count = 0;	/* number of arguments */
  register int arg_index = 0;
  register char *p0;

  memset ((char *) arg_struct, '\0', sizeof (arg_array));

  /* first count how many arguments there are */

  p0 = arg_string;
  while (*p0 != '\0')
    {
      if (*(p0 = skip_white_space (p0)) == '\0')
	break;
      p0 = find_white_space (p0);
      arg_count++;
    }

  arg_struct->arg_array_len = arg_count;
  arg_struct->arg_array_val = (char **) xmalloc ((arg_count + 1)
						 * sizeof (char *));

  /* now copy argument strings into arg_struct.  */

  while (*(arg_string = skip_white_space (arg_string)))
    {
      p0 = find_white_space (arg_string);
      arg_struct->arg_array_val[arg_index++] = savestring (arg_string,
							   p0 - arg_string);
      arg_string = p0;
    }

  arg_struct->arg_array_val[arg_count] = NULL;
}

/* Advance a string pointer across whitespace and return a pointer
   to the first non-white character.  */

static char *
skip_white_space (p)
     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;
{
  register int c;

  while ((c = *p) != ' ' && c != '\t' && c)
    {
      if (c == '\'' || c == '"')
	{
	  while (*++p != c && *p)
	    {
	      if (*p == '\\')
		p++;
	    }
	  if (!*p)
	    break;
	}
      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;
{
  int pid;
  enum clnt_stat status;

  memset ((char *) pEvent, '\0', sizeof (RDB_EVENT));

  pid = inferior_pid;
  status = net_clnt_call (PROCESS_WAIT, xdr_int, &pid, xdr_RDB_EVENT,
			  pEvent);

  /* 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 ()
{
  int pid;
  int quit_status;
  enum clnt_stat status;

  quit_status = 0;

  /* don't let rdbTask suspend itself by passing a pid of 0 */

  if ((pid = inferior_pid) == 0)
    return -1;

  status = net_clnt_call (VX_TASK_SUSPEND, xdr_int, &pid, xdr_int,
			  &quit_status);

  return (status == RPC_SUCCESS) ? quit_status : -1;
}

/* Read a register or registers from the remote system.  */

void
net_read_registers (reg_buf, len, procnum)
     char *reg_buf;
     int len;
     u_long procnum;
{
  int status;
  Rptrace ptrace_in;
  Ptrace_return ptrace_out;
  C_bytes out_data;
  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 = inferior_pid;
  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_num;
      sprintf (message, "reading %s registers", (procnum == PTRACE_GETREGS)
	       ? "general-purpose"
	       : "floating-point");
      perror_with_name (message);
    }
}

/* 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 ().  */

void
net_write_registers (reg_buf, len, procnum)
     char *reg_buf;
     int len;
     u_long procnum;
{
  int status;
  Rptrace ptrace_in;
  Ptrace_return ptrace_out;
  C_bytes in_data;
  char message[100];

  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));

  /* Initialize RPC input argument structure.  */

  in_data.bytes = reg_buf;
  in_data.len = len;

  ptrace_in.pid = inferior_pid;
  ptrace_in.info.ttype = DATA;
  ptrace_in.info.more_data = (caddr_t) & in_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_num;
      sprintf (message, "writing %s registers", (procnum == PTRACE_SETREGS)
	       ? "general-purpose"
	       : "floating-point");
      perror_with_name (message);
    }
}

/* 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);
}

/* 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.
   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 */
{
  int status;
  Rptrace ptrace_in;
  Ptrace_return ptrace_out;
  C_bytes data;
  enum ptracereq request;
  int nleft, nxfer;

  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.addr = (int) memaddr;	/* Where from */
  ptrace_in.data = len;		/* How many bytes */

  if (write)
    {
      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) */
      request = PTRACE_WRITEDATA;
    }
  else
    {
      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.  */

  nleft = len;
  status = 0;

  while (nleft > 0 && status == 0)
    {
      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 the number of bytes transferred.  */

  return (len - nleft);
}

static void
vx_files_info ()
{
  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 ()
{
  printf_unfiltered ("\tRunning %s VxWorks process %s",
		     vx_running ? "child" : "attached",
		     local_hex_string (inferior_pid));
  if (vx_running)
    printf_unfiltered (", function `%s'", vx_running);
  printf_unfiltered (".\n");
}

static void
vx_resume (pid, step, siggnal)
     int pid;
     int step;
     enum target_signal siggnal;
{
  int status;
  Rptrace ptrace_in;
  Ptrace_return ptrace_out;
  CORE_ADDR cont_addr;

  if (pid == -1)
    pid = inferior_pid;

  if (siggnal != 0 && siggnal != stop_signal)
    error ("Cannot send signals to VxWorks processes");

  /* 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;

  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));

  ptrace_in.pid = pid;
  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);

  if (status)
    error (rpcerr);
  if (ptrace_out.status == -1)
    {
      errno = ptrace_out.errno_num;
      perror_with_name ("Resuming remote process");
    }
}

static void
vx_mourn_inferior ()
{
  pop_target ();		/* Pop back to no-child state */
  generic_mourn_inferior ();
}


static void vx_add_symbols PARAMS ((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 PARAMS ((bfd *, asection *, void *));

static void
find_sect (abfd, sect, obj)
     bfd *abfd;
     asection *sect;
     PTR 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 (name, from_tty, text_addr, data_addr, bss_addr)
     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, 0, 0, 0, 0, 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 (struct section_offsets)
	    + objfile->num_sections * sizeof (offs->offsets));
  memcpy (offs, objfile->section_offsets,
	  sizeof (struct section_offsets)
	  + objfile->num_sections * sizeof (offs->offsets));

  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.  */
  ANOFFSET (offs, SECT_OFF_TEXT) = text_addr - ss.text_start;
  ANOFFSET (offs, SECT_OFF_DATA) = data_addr - ss.data_start;
  ANOFFSET (offs, SECT_OFF_BSS) = 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;
{
  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);

  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 (inferior_pid != 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 cancelled.");
    }

  QUIT;
  immediate_quit++;
  if (net_load (arg_string, &text_addr, &data_addr, &bss_addr) == -1)
    error ("Load failed on target machine");
  immediate_quit--;

  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 ();
}

/* 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 ()
{
  enum clnt_stat status;
  int step_status;
  SOURCE_STEP source_step;

  source_step.taskId = inferior_pid;

  if (step_range_end)
    {
      source_step.startAddr = step_range_start;
      source_step.endAddr = step_range_end;
    }
  else
    {
      source_step.startAddr = 0;
      source_step.endAddr = 0;
    }

  status = net_clnt_call (VX_SOURCE_STEP, xdr_SOURCE_STEP, &source_step,
			  xdr_int, &step_status);

  if (status == RPC_SUCCESS)
    return step_status;
  else
    error (rpcerr);
}

/* 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;
{
  enum clnt_stat status;

  status = net_clnt_call (request, xdr_rptrace, pPtraceIn, xdr_ptrace_return,
			  pPtraceOut);

  if (status != RPC_SUCCESS)
    return -1;

  return 0;
}

/* Query the target for the name of the file from which VxWorks was
   booted.  pBootFile is the address of a pointer to the buffer to
   receive the file name; if the pointer pointed to by pBootFile is 
   NULL, memory for the buffer will be allocated by XDR.
   Returns -1 if rpc failed, 0 otherwise.  */

static int
net_get_boot_file (pBootFile)
     char **pBootFile;
{
  enum clnt_stat status;

  status = net_clnt_call (VX_BOOT_FILE_INQ, xdr_void, (char *) 0,
			  xdr_wrapstring, pBootFile);
  return (status == RPC_SUCCESS) ? 0 : -1;
}

/* Fetch a list of loaded object modules from the VxWorks target.
   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 */
{
  enum clnt_stat status;

  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;
}

/* Look up a symbol in the VxWorks target's symbol table.
   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;
{
  enum clnt_stat status;
  SYMBOL_ADDR symbolAddr;

  *pAddr = 0;
  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);
      return -1;
    }

  *pAddr = symbolAddr.addr;
  return symbolAddr.status;
}

/* Check to see if the VxWorks target has a floating point coprocessor.
   Returns 1 if target has floating point processor, 0 otherwise.
   Calls error() if rpc fails.  */

static int
net_check_for_fp ()
{
  enum clnt_stat status;
  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);

  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;
{
  struct sockaddr_in destAddr;
  struct hostent *destHost;
  unsigned long addr;

  /* Get the internet address for the given host.  Allow a numeric
     IP address or a hostname.  */

  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;
    }

  memset (&destAddr, '\0', sizeof (destAddr));

  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 */

  if (pClient == NULL)
    {
      clnt_pcreateerror ("\tnet_connect");
      error ("Couldn't connect to remote target.");
    }
}

/* Sleep for the specified number of milliseconds 
 * (assumed to be less than 1000).
 * If select () is interrupted, returns immediately;
 * takes an error exit if select () fails for some other reason.
 */

static void
sleep_ms (ms)
     long ms;
{
  struct timeval select_timeout;
  int status;

  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);

  if (status < 0 && errno != EINTR)
    perror_with_name ("select");
}

static int
vx_wait (pid_to_wait_for, status)
     int pid_to_wait_for;
     struct target_waitstatus *status;
{
  register int pid;
  RDB_EVENT rdbEvent;
  int quit_failed;

  do
    {
      /* If CTRL-C is hit during this loop,
         suspend the inferior process.  */

      quit_failed = 0;
      if (quit_flag)
	{
	  quit_failed = (net_quit () == -1);
	  quit_flag = 0;
	}

      /* 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.  */

      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"))
	    {
	      target_mourn_inferior ();
	      error ("Use the \"target\" command to reconnect.");
	    }
	  else
	    {
	      terminal_inferior ();
	      continue;
	    }
	}

      pid = rdbEvent.taskId;
      if (pid == 0)
	{
	  sleep_ms (200);	/* FIXME Don't kill the network too badly */
	}
      else if (pid != inferior_pid)
	internal_error ("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;

  switch (rdbEvent.eventType)
    {
    case EVENT_EXIT:
      status->kind = TARGET_WAITKIND_EXITED;
      /* FIXME is it possible to distinguish between a
         normal vs abnormal exit in VxWorks? */
      status->value.integer = 0;
      break;

    case EVENT_START:
      /* Task was just started. */
      status->value.sig = TARGET_SIGNAL_TRAP;
      break;

    case EVENT_STOP:
      status->value.sig = TARGET_SIGNAL_TRAP;
      /* XXX was it stopped by a signal?  act accordingly */
      break;

    case EVENT_BREAK:		/* Breakpoint was hit. */
      status->value.sig = TARGET_SIGNAL_TRAP;
      break;

    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. */
      status->value.sig = TARGET_SIGNAL_BUS;
      break;

    case EVENT_ZERO_DIV:	/* Division by zero */
      status->value.sig = TARGET_SIGNAL_FPE;
      break;

    case EVENT_SIGNAL:
#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 */
  return pid;
}

static int
symbol_stub (arg)
     char *arg;
{
  symbol_file_command (arg, 0);
  return 1;
}

static int
add_symbol_stub (arg)
     char *arg;
{
  struct ldfile *pLoadFile = (struct ldfile *) arg;

  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.

   Used in vxgdb.  Takes the name of a remote target machine
   running vxWorks and connects to it to initialize remote network
   debugging.  */

static void
vx_open (args, from_tty)
     char *args;
     int from_tty;
{
  extern int close ();
  char *bootFile;
  extern char *source_path;
  struct ldtabl loadTable;
  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_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
     disallowing an immediate quit, since even if net_connect ()
     is successful, the remote debug server might be hung.  */

  immediate_quit++;

  net_connect (args);
  target_has_fp = net_check_for_fp ();
  printf_filtered ("Connected to %s.\n", args);

  immediate_quit--;

  push_target (&vx_ops);

  /* Save a copy of the target host's name.  */
  vx_host = savestring (args, strlen (args));

  /* Find out the name of the file from which the target was booted
     and load its symbol table.  */

  printf_filtered ("Looking in Unix path for all loaded modules:\n");
  bootFile = NULL;
  if (!net_get_boot_file (&bootFile))
    {
      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.");

  clnt_freeres (pClient, xdr_wrapstring, &bootFile);

  if (net_get_symbols (&loadTable) != 0)
    error ("Can't read loaded modules from target machine");

  i = 0 - 1;
  while (++i < loadTable.tbl_size)
    {
      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);
      }
#else
      /* 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 ();
}

/* 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;
{
  unsigned long pid;
  char *cptr = 0;
  Rptrace ptrace_in;
  Ptrace_return ptrace_out;
  int status;

  if (!args)
    error_no_arg ("process-id to attach");

  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_unfiltered ("Attaching pid %s.\n",
		       local_hex_string ((unsigned long) pid));

  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);
  if (status == -1)
    error (rpcerr);
  if (ptrace_out.status == -1)
    {
      errno = ptrace_out.errno_num;
      perror_with_name ("Attaching remote process");
    }

  /* It worked... */

  inferior_pid = pid;
  push_target (&vx_run_ops);

  if (vx_running)
    free (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
   on signals, etc.  We better not have left any breakpoints
   in the program or it'll die when it hits one.  For this
   to work, it may be necessary for the process to have been
   previously attached.  It *might* work if the program was
   started via the normal ptrace (PTRACE_TRACEME).  */

static void
vx_detach (args, from_tty)
     char *args;
     int from_tty;
{
  Rptrace ptrace_in;
  Ptrace_return ptrace_out;
  int signal = 0;
  int status;

  if (args)
    error ("Argument given to VxWorks \"detach\".");

  if (from_tty)
    printf_unfiltered ("Detaching pid %s.\n",
		       local_hex_string ((unsigned long) inferior_pid));

  if (args)			/* FIXME, should be possible to leave suspended */
    signal = atoi (args);

  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
  ptrace_in.pid = inferior_pid;

  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_num;
      perror_with_name ("Detaching VxWorks process");
    }

  inferior_pid = 0;
  pop_target ();		/* go back to non-executing VxWorks connection */
}

/* vx_kill -- takes a running task and wipes it out.  */

static void
vx_kill ()
{
  Rptrace ptrace_in;
  Ptrace_return ptrace_out;
  int status;

  printf_unfiltered ("Killing pid %s.\n", local_hex_string ((unsigned long) inferior_pid));

  memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
  memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
  ptrace_in.pid = inferior_pid;

  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_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 */
}

/* Clean up from the VxWorks process target as it goes away.  */

static void
vx_proc_close (quitting)
     int quitting;
{
  inferior_pid = 0;		/* No longer have a process.  */
  if (vx_running)
    free (vx_running);
  vx_running = 0;
}

/* Make an RPC call to the VxWorks target.
   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;
{
  enum clnt_stat status;

  status = clnt_call (pClient, procNum, inProc, in, outProc, out, rpcTimeout);

  if (status != RPC_SUCCESS)
    clnt_perrno (status);

  return status;
}

/* Clean up before losing control.  */

static void
vx_close (quitting)
     int quitting;
{
  if (pClient)
    clnt_destroy (pClient);	/* The net connection */
  pClient = 0;

  if (vx_host)
    free (vx_host);		/* The hostname */
  vx_host = 0;
}

/* A vxprocess target should be started via "run" not "target".  */
/*ARGSUSED */
static void
vx_proc_open (name, from_tty)
     char *name;
     int from_tty;
{
  error ("Use the \"run\" command to start a VxWorks process.");
}

static void
init_vx_ops ()
{
  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 */
};

static void
init_vx_run_ops ()
{
  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;
}

void
_initialize_vx ()
{
  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);
}
