#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 */
extern struct target_ops vx_ops, vx_run_ops; /* Forward declaration */
/* Nonzero means target that is being debugged remotely has a floating
point processor. */
-int target_has_fp;
+static int target_has_fp;
/* Default error message when the network is forking up. */
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);
+ return (status == RPC_SUCCESS)? pEvent->status: -1;
}
/* Suspend the remote task.
/* Read a register or registers from the remote system. */
static void
-net_read_registers (reg_buf, len, procnum)
- char *reg_buf;
- int len;
- u_long procnum;
+vx_read_register (regno)
+ int regno;
{
int status;
Rptrace ptrace_in;
Ptrace_return ptrace_out;
+ C_bytes in_data;
C_bytes out_data;
- char message[100];
+ extern char registers[];
- bzero ((char *) &ptrace_in, sizeof (ptrace_in));
- bzero ((char *) &ptrace_out, sizeof (ptrace_out));
-
- /* Initialize RPC input argument structure. */
+ memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+ memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+ /* FIXME, eventually only get the ones we need. */
+ registers_fetched ();
+
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);
+ out_data.len = VX_NUM_REGS * REGISTER_RAW_SIZE (0);
+ out_data.bytes = (caddr_t) registers;
+
+ status = net_ptrace_clnt_call (PTRACE_GETREGS, &ptrace_in, &ptrace_out);
if (status)
error (rpcerr);
if (ptrace_out.status == -1)
{
- errno = ptrace_out.errno_val;
- sprintf (message, "reading %s registers", (procnum == PTRACE_GETREGS)
- ? "general-purpose"
- : "floating-point");
- perror_with_name (message);
+ errno = ptrace_out.errno;
+ perror_with_name ("net_ptrace_clnt_call(PTRACE_GETREGS)");
+ }
+
+#ifdef VX_SIZE_FPREGS
+ /* 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. */
+
+ if (target_has_fp)
+ {
+ ptrace_in.pid = inferior_pid;
+ ptrace_out.info.more_data = (caddr_t) &out_data;
+ out_data.len = VX_SIZE_FPREGS;
+ out_data.bytes = (caddr_t) ®isters[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
+ {
+ memset (®isters[REGISTER_BYTE (FP0_REGNUM)], '\0', VX_SIZE_FPREGS);
}
+#endif /* VX_SIZE_FPREGS */
+}
+
+/* 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 (). */
-void
-net_write_registers (reg_buf, len, procnum)
- char *reg_buf;
- int len;
- u_long procnum;
+/* 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;
{
+ 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));
-
- /* Initialize RPC input argument structure. */
- in_data.bytes = reg_buf;
- in_data.len = len;
+ memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+ memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
ptrace_in.pid = inferior_pid;
- ptrace_in.info.ttype = DATA;
+ ptrace_in.info.ttype = DATA;
ptrace_in.info.more_data = (caddr_t) &in_data;
- /* Call RPC; take an error exit if appropriate. */
+ in_data.bytes = registers;
+
+ in_data.len = VX_NUM_REGS * REGISTER_SIZE;
- status = net_ptrace_clnt_call (procnum, &ptrace_in, &ptrace_out);
+ /* XXX change second param to be a proc number */
+ status = net_ptrace_clnt_call (PTRACE_SETREGS, &ptrace_in, &ptrace_out);
if (status)
error (rpcerr);
if (ptrace_out.status == -1)
{
- errno = ptrace_out.errno_val;
- sprintf (message, "writing %s registers", (procnum == PTRACE_SETREGS)
- ? "general-purpose"
- : "floating-point");
- perror_with_name (message);
+ errno = ptrace_out.errno;
+ perror_with_name ("net_ptrace_clnt_call(PTRACE_SETREGS)");
}
-}
-/* Prepare to store registers. Since we will store all of them,
- read out their current values now. */
+#ifdef VX_SIZE_FPREGS
+ /* Store floating point registers if the target has them. */
-static void
-vx_prepare_to_store ()
-{
- /* Fetch all registers, if any of them are not yet fetched. */
- read_register_bytes (0, NULL, REGISTER_BYTES);
+ if (target_has_fp)
+ {
+ ptrace_in.pid = inferior_pid;
+ ptrace_in.info.ttype = DATA;
+ ptrace_in.info.more_data = (caddr_t) &in_data;
+
+
+ in_data.bytes = ®isters[REGISTER_BYTE (FP0_REGNUM)];
+ in_data.len = VX_SIZE_FPREGS;
+
+ 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)");
+ }
+ }
+#endif /* VX_SIZE_FPREGS */
}
/* Copy LEN bytes to or from remote inferior's memory starting at MEMADDR
Rptrace ptrace_in;
Ptrace_return ptrace_out;
C_bytes data;
- enum ptracereq request;
memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
data.bytes = (caddr_t) myaddr; /* Where from */
data.len = len; /* How many bytes (again, for XDR) */
- request = PTRACE_WRITEDATA;
+
+ /* XXX change second param to be a proc number */
+ status = net_ptrace_clnt_call (PTRACE_WRITEDATA, &ptrace_in,
+ &ptrace_out);
}
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. */
+ data.bytes = myaddr; /* Where to */
+ data.len = len; /* How many (again, for XDR) */
- nleft = len;
- status = 0;
+ /* XXX change second param to be a proc number */
+ status = net_ptrace_clnt_call (PTRACE_READDATA, &ptrace_in, &ptrace_out);
+ }
- while (nleft > 0 && status == 0)
+ if (status)
+ error (rpcerr);
+ if (ptrace_out.status == -1)
{
- 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_val;
- }
+ return 0; /* No bytes moved */
}
-
- /* Return the number of bytes transferred. */
-
- return (len - nleft);
+ return len; /* Moved *all* the bytes */
}
static void
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);
+ ptrace_in.addr = 1; /* Target side insists on this, or it panics. */
+ /* 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);
if (ptrace_out.status == -1)
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)
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. */
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. */
in order for other parts of GDB to work correctly. */
inferior_pid = pid;
vx_running = 0;
-#if defined (START_INFERIOR_HOOK)
- START_INFERIOR_HOOK ();
-#endif
-
- mark_breakpoints_out ();
-
- /* 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 ();
-
- /* We will get a task spawn event immediately. */
-
- init_wait_for_inferior ();
- clear_proceed_status ();
- stop_soon_quietly = 1;
- wait_for_inferior ();
- stop_soon_quietly = 0;
- normal_stop ();
}