⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 remote-vx.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	{	  errno = ptrace_out.errno;	  perror_with_name ("net_ptrace_clnt_call(PTRACE_GETFPREGS)");	}    }  else    {      bzero (&registers[REGISTER_BYTE (FP0_REGNUM)],      	     8 * REGISTER_RAW_SIZE (FP0_REGNUM));      bzero (&registers[REGISTER_BYTE (FPC_REGNUM)],	     3 * sizeof (REGISTER_TYPE));    }#endif  /* various architectures */}/* Prepare to store registers.  Since we will store all of them,   read out their current values now.  */static voidvx_prepare_to_store (){  /* Fetch all registers, if any of them are not yet fetched.  */  read_register_bytes (0, NULL, REGISTER_BYTES);}/* 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 voidvx_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;  bzero ((char *) &ptrace_in, sizeof (ptrace_in));  bzero ((char *) &ptrace_out, sizeof (ptrace_out));  ptrace_in.pid = inferior_pid;  ptrace_in.info.ttype     = DATA;  ptrace_in.info.more_data = (caddr_t) &in_data;  in_data.bytes = registers;#ifdef I80960  in_data.len = (16 + 16 + 3) * sizeof (REGISTER_TYPE);#else  /* not 960 -- assume 68k -- FIXME */  in_data.len = 18 * sizeof (REGISTER_TYPE);#endif  /* Different register sets */  /* 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;      perror_with_name ("net_ptrace_clnt_call(PTRACE_SETREGS)");    }  /* Store floating point registers if the target has them.  */  if (target_has_fp)    {      ptrace_in.pid = inferior_pid;      ptrace_in.info.ttype     = DATA;      ptrace_in.info.more_data = (caddr_t) &in_data;#ifdef I80960#if 0 /* @@ Not supported by target.  */      in_data.bytes = &registers[REGISTER_BYTE (FP0_REGNUM)];      in_data.len = 4 * REGISTER_RAW_SIZE (FP0_REGNUM);#endif#else  /* not 960 -- assume 68k -- FIXME */      in_data.bytes = &registers[REGISTER_BYTE (FP0_REGNUM)];      in_data.len = (8 * REGISTER_RAW_SIZE (FP0_REGNUM)                      + (3 * sizeof (REGISTER_TYPE)));#endif  /* Different register sets */      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)");	}    }}/* 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 intvx_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;  bzero ((char *) &ptrace_in, sizeof (ptrace_in));  bzero ((char *) &ptrace_out, 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) */      /* 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;      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);    }  if (status)      error (rpcerr);  if (ptrace_out.status == -1)    {      return 0;		/* No bytes moved */    }  return len;		/* Moved *all* the bytes */}static voidvx_files_info (){  printf ("\tAttached to host `%s'", vx_host);  printf (", which has %sfloating point", target_has_fp? "": "no ");  printf (".\n");}static voidvx_run_files_info (){  printf ("\tRunning %s VxWorks process %s", 	  vx_running? "child": "attached",	  local_hex_string(inferior_pid));  if (vx_running)    printf (", function `%s'", vx_running);  printf(".\n");}static voidvx_resume (step, siggnal)     int step;     int siggnal;{  int status;  Rptrace ptrace_in;  Ptrace_return ptrace_out;  if (siggnal != 0 && siggnal != stop_signal)    error ("Cannot send signals to VxWorks processes");  bzero ((char *) &ptrace_in, sizeof (ptrace_in));  bzero ((char *) &ptrace_out, sizeof (ptrace_out));  ptrace_in.pid = inferior_pid;  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)    {      errno = ptrace_out.errno;      perror_with_name ("Resuming remote process");    }}static voidvx_mourn_inferior (){  pop_target ();		/* Pop back to no-child state */  generic_mourn_inferior ();}/* This function allows the addition of incrementally linked object files.  */static voidvx_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 ();  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);}#ifdef FIXME  /* Not ready for prime time *//* Single step the target program at the source or machine level.   Takes an error exit if rpc fails.   Returns -1 if remote single-step operation fails, else 0.  */static intnet_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);}#endif/* Emulate ptrace using RPC calls to the VxWorks target system.   Returns nonzero (-1) if RPC status to VxWorks is bad, 0 otherwise.  */static intnet_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 intnet_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 intnet_get_symbols (pLoadTable)     ldtabl *pLoadTable;		/* return pointer to ldtabl here */{  enum clnt_stat status;  bzero ((char *) pLoadTable, 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 intvx_lookup_symbol (name, pAddr)     char *name;		/* symbol name */     CORE_ADDR *pAddr;{  enum clnt_stat status;  SYMBOL_ADDR symbolAddr;  *pAddr = 0;  bzero ((char *) &symbolAddr, sizeof (symbolAddr));  status = net_clnt_call (VX_SYMBOL_INQ, xdr_wrapstring, &name,			  xdr_SYMBOL_ADDR, &symbolAddr);  if (status != RPC_SUCCESS) {      complain (&cant_contact_target, 0);      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 intnet_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 voidnet_connect (host)     char *host;{  struct sockaddr_in destAddr;  struct hostent *destHost;  /* get the internet address for the given host */  if ((destHost = (struct hostent *) gethostbyname (host)) == NULL)      error ("Invalid hostname.  Couldn't find remote host address.");  bzero (&destAddr, sizeof (destAddr));  destAddr.sin_addr.s_addr = * (u_long *) destHost->h_addr;  destAddr.sin_family      = AF_INET;  destAddr.sin_port        = 0;	/* set to actual port that remote			           ptrace is listening on.  */  /* 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 voidsleep_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");}/* 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -