/* 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, 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_SECTION_OFFSETS);
  memcpy (offs, objfile->section_offsets, SIZEOF_SECTION_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);
}
