X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fremote-vx.c;h=c471373bd585102bbc232b70f74f499fcaf810af;hb=a14ed312fd86dd2c862847230931451da2e49942;hp=5c1aeaaf0fadc76143fa19f4184b56526cf422b1;hpb=833e0d94ccb34e8ac566a574fd5a75fb967434a5;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/remote-vx.c b/gdb/remote-vx.c index 5c1aeaaf0f..c471373bd5 100644 --- a/gdb/remote-vx.c +++ b/gdb/remote-vx.c @@ -1,35 +1,40 @@ /* Memory-access and commands for remote VxWorks processes, for GDB. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. + 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 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 "gdb_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 +#include "gdb_string.h" #include #include #include @@ -52,39 +57,54 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include +/* 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 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 */ +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). @@ -92,91 +112,91 @@ static char *find_white_space (); static int net_load (filename, pTextAddr, pDataAddr, pBssAddr) - char *filename; - CORE_ADDR *pTextAddr; - CORE_ADDR *pDataAddr; - CORE_ADDR *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) { - 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; + 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? */ + 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; + 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 = inferior_pid; - 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); - } + 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); - } + 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. @@ -184,7 +204,7 @@ vx_remove_breakpoint (addr) 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; @@ -249,9 +269,9 @@ parse_args (arg_string, 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; @@ -291,7 +311,7 @@ skip_white_space (p) 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. */ @@ -318,182 +338,153 @@ 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; + RDB_EVENT *pEvent; { - int pid; - enum clnt_stat status; + int pid; + enum clnt_stat status; - memset ((char *) pEvent, '\0', 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 = inferior_pid; + 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 () { - 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 = inferior_pid) == 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 (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; C_bytes out_data; - extern char registers[]; + char message[100]; 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 (); - + /* Initialize RPC input argument structure. */ + ptrace_in.pid = inferior_pid; - ptrace_out.info.more_data = (caddr_t) &out_data; - 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); + 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 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); + errno = ptrace_out.errno_num; + sprintf (message, "reading %s registers", (procnum == PTRACE_GETREGS) + ? "general-purpose" + : "floating-point"); + perror_with_name (message); } -#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 (). */ -/* 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 (reg_buf, len, procnum) + 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]; 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.more_data = (caddr_t) &in_data; + /* Initialize RPC input argument structure. */ - in_data.bytes = registers; + in_data.bytes = reg_buf; + in_data.len = len; - in_data.len = VX_NUM_REGS * REGISTER_SIZE; + 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. */ - /* 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); } +} -#ifdef VX_SIZE_FPREGS - /* 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; - - - in_data.bytes = ®isters[REGISTER_BYTE (FP0_REGNUM)]; - in_data.len = VX_SIZE_FPREGS; +/* 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)"); - } - } -#endif /* VX_SIZE_FPREGS */ +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 @@ -510,67 +501,97 @@ vx_xfer_memory (memaddr, myaddr, len, write, target) char *myaddr; int len; int write; - struct target_ops *target; /* ignored */ + 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.pid = inferior_pid; /* 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 () { printf_unfiltered ("\tAttached to host `%s'", vx_host); - printf_unfiltered (", which has %sfloating point", target_has_fp? "": "no "); + 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", + 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"); + printf_unfiltered (".\n"); } static void @@ -582,6 +603,7 @@ vx_resume (pid, step, siggnal) int status; Rptrace ptrace_in; Ptrace_return ptrace_out; + CORE_ADDR cont_addr; if (pid == -1) pid = inferior_pid; @@ -589,20 +611,34 @@ vx_resume (pid, step, siggnal) 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 = 1; /* Target side insists on this, or it panics. */ + 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"); } } @@ -613,19 +649,90 @@ vx_mourn_inferior () pop_target (); /* Pop back to no-child state */ generic_mourn_inferior (); } - + +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 (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 (so->objfile)) = text_addr - ss.text_start; + ANOFFSET (offs, SECT_OFF_DATA (so->objfile)) = data_addr - ss.data_start; + ANOFFSET (offs, SECT_OFF_BSS (so->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; + 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"); @@ -634,17 +741,31 @@ vx_load_command (arg_string, from_tty) 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--; - /* 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. */ @@ -674,19 +795,18 @@ 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; + enum ptracereq request; + Rptrace *pPtraceIn; + Ptrace_return *pPtraceOut; { enum clnt_stat status; @@ -694,7 +814,7 @@ net_ptrace_clnt_call (request, pPtraceIn, pPtraceOut) pPtraceOut); if (status != RPC_SUCCESS) - return -1; + return -1; return 0; } @@ -723,7 +843,7 @@ net_get_boot_file (pBootFile) static int net_get_symbols (pLoadTable) - ldtabl *pLoadTable; /* return pointer to ldtabl here */ + ldtabl *pLoadTable; /* return pointer to ldtabl here */ { enum clnt_stat status; @@ -738,7 +858,7 @@ net_get_symbols (pLoadTable) Returns -1 and complain()s if rpc fails. */ struct complaint cant_contact_target = - {"Lost contact with VxWorks target", 0, 0}; +{"Lost contact with VxWorks target", 0, 0}; static int vx_lookup_symbol (name, pAddr) @@ -753,10 +873,11 @@ vx_lookup_symbol (name, pAddr) status = net_clnt_call (VX_SYMBOL_INQ, xdr_wrapstring, &name, xdr_SYMBOL_ADDR, &symbolAddr); - if (status != RPC_SUCCESS) { + if (status != RPC_SUCCESS) + { complain (&cant_contact_target); return -1; - } + } *pAddr = symbolAddr.addr; return symbolAddr.status; @@ -770,13 +891,13 @@ static int net_check_for_fp () { 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. @@ -789,7 +910,7 @@ net_connect (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. */ @@ -798,24 +919,28 @@ net_connect (host) { 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; + 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. */ + 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"); @@ -839,24 +964,13 @@ 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 (pid_to_wait_for, status) int pid_to_wait_for; @@ -869,7 +983,7 @@ vx_wait (pid_to_wait_for, status) do { /* If CTRL-C is hit during this loop, - suspend the inferior process. */ + suspend the inferior process. */ quit_failed = 0; if (quit_flag) @@ -879,19 +993,19 @@ vx_wait (pid_to_wait_for, 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 @@ -900,16 +1014,17 @@ vx_wait (pid_to_wait_for, 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((unsigned long) pid)); - } while (pid == 0); + 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; @@ -919,7 +1034,7 @@ vx_wait (pid_to_wait_for, status) case EVENT_EXIT: status->kind = TARGET_WAITKIND_EXITED; /* FIXME is it possible to distinguish between a - normal vs abnormal exit in VxWorks? */ + normal vs abnormal exit in VxWorks? */ status->value.integer = 0; break; @@ -937,11 +1052,11 @@ vx_wait (pid_to_wait_for, status) status->value.sig = TARGET_SIGNAL_TRAP; break; - case EVENT_SUSPEND: /* Task was suspended, probably by ^C. */ + 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. */ + case EVENT_BUS_ERR: /* Task made evil nasty reference. */ status->value.sig = TARGET_SIGNAL_BUS; break; @@ -954,14 +1069,14 @@ vx_wait (pid_to_wait_for, status) 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. */ + 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 */ + } /* switch */ return pid; } @@ -977,10 +1092,11 @@ static int add_symbol_stub (arg) char *arg; { - struct ldfile *pLoadFile = (struct ldfile *)arg; + struct ldfile *pLoadFile = (struct ldfile *) arg; - printf_unfiltered("\t%s: ", pLoadFile->name); - symbol_file_add (pLoadFile->name, 0, pLoadFile->txt_addr, 0, 0, 0); + 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; } @@ -1002,12 +1118,13 @@ 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_unfiltered ("Attaching remote machine across net...\n"); gdb_flush (gdb_stdout); @@ -1037,13 +1154,19 @@ 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", RETURN_MASK_ALL)) - puts_filtered ("ok\n"); - } else if (from_tty) + 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 @@ -1054,36 +1177,43 @@ 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, - RETURN_MASK_ALL); + /* 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. @@ -1094,7 +1224,7 @@ vx_attach (args, from_tty) char *args; int from_tty; { - int pid; + unsigned long pid; char *cptr = 0; Rptrace ptrace_in; Ptrace_return ptrace_out; @@ -1103,16 +1233,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_unfiltered ("Attaching pid %s.\n", - local_hex_string((unsigned long) pid)); + 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)); + 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); @@ -1120,17 +1250,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... */ - push_target (&vx_run_ops); + 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 @@ -1154,14 +1287,14 @@ vx_detach (args, from_tty) error ("Argument given to VxWorks \"detach\"."); if (from_tty) - printf_unfiltered ("Detaching pid %s.\n", - local_hex_string((unsigned long) inferior_pid)); + printf_unfiltered ("Detaching pid %s.\n", + local_hex_string ((unsigned long) inferior_pid)); - if (args) /* FIXME, should be possible to leave suspended */ + 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)); + + 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); @@ -1169,12 +1302,12 @@ vx_detach (args, from_tty) 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 */ + pop_target (); /* go back to non-executing VxWorks connection */ } /* vx_kill -- takes a running task and wipes it out. */ @@ -1186,10 +1319,10 @@ vx_kill () Ptrace_return ptrace_out; int status; - printf_unfiltered ("Killing pid %s.\n", local_hex_string((unsigned long) inferior_pid)); + 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)); + 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); @@ -1197,14 +1330,14 @@ vx_kill () 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 */ + pop_target (); /* go back to non-executing VxWorks connection */ } /* Clean up from the VxWorks process target as it goes away. */ @@ -1224,18 +1357,18 @@ vx_proc_close (quitting) 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 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; } @@ -1256,7 +1389,7 @@ vx_close (quitting) } /* A vxprocess target should be started via "run" not "target". */ -/*ARGSUSED*/ +/*ARGSUSED */ static void vx_proc_open (name, from_tty) char *name; @@ -1265,68 +1398,69 @@ vx_proc_open (name, 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 () +{ + 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 () +{ + 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 () { - - add_show_from_set + 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); - - add_target (&vx_ops); - add_target (&vx_run_ops); }