* infrun.c (wait_for_inferior): Don't check if the PC is in a
[deliverable/binutils-gdb.git] / gdb / remote.c
index 5bf5768b0e9b79035cbe0c36e775e2fd7c4d9200..821524392ade8d955ae13464c644b305ec59a80b 100644 (file)
@@ -1,5 +1,5 @@
 /* Memory-access and commands for inferior process, for GDB.
-   Copyright (C)  1988, 1989 Free Software Foundation, Inc.
+   Copyright (C) 1988-1991 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -67,35 +67,27 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 */
 
 #include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
 #include "defs.h"
 #include "param.h"
 #include "frame.h"
 #include "inferior.h"
-
+#include "target.h"
 #include "wait.h"
+#include "terminal.h"
 
 #ifdef USG
 #include <sys/types.h>
-#include <fcntl.h>
 #endif
 
 #include <signal.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
 
-#ifdef HAVE_TERMIO
-#include <termio.h>
-#undef TIOCGETP
-#define TIOCGETP TCGETA
-#undef TIOCSETN
-#define TIOCSETN TCSETA
-#undef TIOCSETP
-#define TIOCSETP TCSETAF
-#define TERMINAL struct termio
-#else
-#include <sgtty.h>
-#define TERMINAL struct sgttyb
-#endif
+extern void add_syms_addr_command ();
+extern struct value *call_function_by_hand();
+extern void start_remote ();
+
+extern struct target_ops remote_ops;   /* Forward decl */
 
 static int kiodebug;
 static int timeout = 5;
@@ -135,6 +127,25 @@ remote_timer ()
 }
 #endif
 
+/* Initialize remote connection */
+
+void
+remote_start()
+{
+}
+
+/* Clean up connection to a remote debugger.  */
+
+/* ARGSUSED */
+void
+remote_close (quitting)
+     int quitting;
+{
+  if (remote_desc >= 0)
+    close (remote_desc);
+  remote_desc = -1;
+}
+
 /* Open a connection to a remote debugger.
    NAME is the filename used for communication.  */
 
@@ -145,10 +156,15 @@ remote_open (name, from_tty)
 {
   TERMINAL sg;
 
-  if (remote_desc >= 0)
-    close (remote_desc);
+  if (name == 0)
+    error (
+"To open a remote debug connection, you need to specify what serial\n\
+device is attached to the remote system (e.g. /dev/ttya).");
+
+  target_preopen (from_tty);
+
+  remote_close (0);
 
-  remote_debugging = 0;
 #if 0
   dcache_init ();
 #endif
@@ -169,7 +185,7 @@ remote_open (name, from_tty)
 
   if (from_tty)
     printf ("Remote debugging using %s\n", name);
-  remote_debugging = 1;
+  push_target (&remote_ops);   /* Switch to using remote target now */
 
 #ifndef HAVE_TERMIO
 #ifndef NO_SIGINTERRUPT
@@ -179,36 +195,38 @@ remote_open (name, from_tty)
 #endif
 
   /* Set up read timeout timer.  */
-  if ((void (*)) signal (SIGALRM, remote_timer) == (void (*)) -1)
+  if ((void (*)()) signal (SIGALRM, remote_timer) == (void (*)()) -1)
     perror ("remote_open: error in signal");
 #endif
 
+  /* Ack any packet which the remote side has already sent.  */
+  write (remote_desc, "+", 1);
   putpkt ("?");                        /* initiate a query from remote machine */
+
+  start_remote ();             /* Initialize gdb process mechanisms */
 }
 
-/* Close the open connection to the remote debugger.
+/* remote_detach()
+   takes a program previously attached to and detaches it.
+   We better not have left any breakpoints
+   in the program or it'll die when it hits one.
+   Close the open connection to the remote debugger.
    Use this when you want to detach and do something else
    with your gdb.  */
-void
-remote_close (from_tty)
+
+static void
+remote_detach (args, from_tty)
+     char *args;
      int from_tty;
 {
-  if (!remote_debugging)
-    error ("Can't close remote connection: not debugging remotely.");
+  if (args)
+    error ("Argument given to \"detach\" when remotely debugging.");
   
-  close (remote_desc);         /* This should never be called if
-                                  there isn't something valid in
-                                  remote_desc.  */
-
-  /* Do not try to close remote_desc again, later in the program.  */
-  remote_desc = -1;
-
+  pop_target ();
   if (from_tty)
-    printf ("Ending remote debugging\n");
-
-  remote_debugging = 0;
+    printf ("Ending remote debugging.\n");
 }
+
 /* Convert hex digit A to a number.  */
 
 static int
@@ -221,6 +239,7 @@ fromhex (a)
     return a - 'a' + 10;
   else
     error ("Reply contains invalid hex digit");
+  return -1;
 }
 
 /* Convert number NIB to a hex digit.  */
@@ -237,12 +256,15 @@ tohex (nib)
 \f
 /* Tell the remote machine to resume.  */
 
-int
-remote_resume (step, signal)
-     int step, signal;
+void
+remote_resume (step, siggnal)
+     int step, siggnal;
 {
   char buf[PBUFSIZ];
 
+  if (siggnal)
+    error ("Can't send signals to a remote system.");
+
 #if 0
   dcache_flush ();
 #endif
@@ -253,7 +275,9 @@ remote_resume (step, signal)
 }
 
 /* Wait until the remote machine stops, then return,
-   storing status in STATUS just as `wait' would.  */
+   storing status in STATUS just as `wait' would.
+   Returns "pid" (though it's not clear what, if anything, that
+   means in the case of this target).  */
 
 int
 remote_wait (status)
@@ -268,23 +292,28 @@ remote_wait (status)
   if (buf[0] != 'S')
     error ("Invalid remote reply: %s", buf);
   WSETSTOP ((*status), (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))));
+  return 0;
 }
 
 /* Read the remote registers into the block REGS.  */
 
+/* Currently we just read all the registers, so we don't use regno.  */
+/* ARGSUSED */
 void
-remote_fetch_registers (regs)
-     char *regs;
+remote_fetch_registers (regno)
+     int regno;
 {
   char buf[PBUFSIZ];
   int i;
   char *p;
+  char regs[REGISTER_BYTES];
 
   sprintf (buf, "g");
   remote_send (buf);
 
-  /* Reply describes registers byte by byte,
-     each byte encoded as two hex characters.  */
+  /* Reply describes registers byte by byte, each byte encoded as two
+     hex characters.  Suck them all up, then supply them to the
+     register cacheing/storage mechanism.  */
 
   p = buf;
   for (i = 0; i < REGISTER_BYTES; i++)
@@ -294,13 +323,26 @@ remote_fetch_registers (regs)
       regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
       p += 2;
     }
+  for (i = 0; i < NUM_REGS; i++)
+    supply_register (i, &regs[REGISTER_BYTE(i)]);
 }
 
-/* Store the remote registers from the contents of the block REGS.  */
+/* Prepare to store registers.  Since we send them all, we have to
+   read out the ones we don't want to change first.  */
 
-void
-remote_store_registers (regs)
-     char *regs;
+void 
+remote_prepare_to_store ()
+{
+  remote_fetch_registers (-1);
+}
+
+/* Store the remote registers from the contents of the block REGISTERS. 
+   FIXME, eventually just store one register if that's all that is needed.  */
+
+/* ARGSUSED */
+int
+remote_store_registers (regno)
+     int regno;
 {
   char buf[PBUFSIZ];
   int i;
@@ -314,12 +356,13 @@ remote_store_registers (regs)
   p = buf + 1;
   for (i = 0; i < REGISTER_BYTES; i++)
     {
-      *p++ = tohex ((regs[i] >> 4) & 0xf);
-      *p++ = tohex (regs[i] & 0xf);
+      *p++ = tohex ((registers[i] >> 4) & 0xf);
+      *p++ = tohex (registers[i] & 0xf);
     }
   *p = '\0';
 
   remote_send (buf);
+  return 0;
 }
 
 #if 0
@@ -354,18 +397,7 @@ remote_store_word (addr, word)
 {
   dcache_poke (addr, word);
 }
-#else /* not 0 */
-void remote_fetch_word (addr)
-     CORE_ADDR addr;
-{
-  error ("Internal error: remote_fetch_word is obsolete.\n");
-}
-void remote_store_word (addr)
-     CORE_ADDR addr;
-{
-  error ("Internal error: remote_store_word is obsolete.\n");
-}
-#endif /* not 0 */
+#endif /* 0 */
 \f
 /* Write memory data directly to the remote machine.
    This does not inform the data cache; the data cache uses this.
@@ -437,14 +469,18 @@ remote_read_bytes (memaddr, myaddr, len)
     }
 }
 \f
-/* Read LEN bytes from inferior memory at MEMADDR.  Put the result
-   at debugger address MYADDR.  Returns errno value.  */
+/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
+   to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
+   nonzero.  Returns length of data written or read; 0 for error.  */
+
 int
-remote_read_inferior_memory(memaddr, myaddr, len)
+remote_xfer_inferior_memory(memaddr, myaddr, len, should_write)
      CORE_ADDR memaddr;
      char *myaddr;
      int len;
+     int should_write;
 {
+  int origlen = len;
   int xfersize;
   while (len > 0)
     {
@@ -453,37 +489,21 @@ remote_read_inferior_memory(memaddr, myaddr, len)
       else
        xfersize = len;
 
-      remote_read_bytes (memaddr, myaddr, xfersize);
+      if (should_write)
+        remote_write_bytes(memaddr, myaddr, xfersize);
+      else
+       remote_read_bytes (memaddr, myaddr, xfersize);
       memaddr += xfersize;
       myaddr  += xfersize;
       len     -= xfersize;
     }
-  return 0; /* no error */
+  return origlen; /* no error possible */
 }
 
-/* Copy LEN bytes of data from debugger memory at MYADDR
-   to inferior's memory at MEMADDR.  Returns errno value.  */
-int
-remote_write_inferior_memory (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
+void
+remote_files_info ()
 {
-  int xfersize;
-  while (len > 0)
-    {
-      if (len > MAXBUFBYTES)
-       xfersize = MAXBUFBYTES;
-      else
-       xfersize = len;
-      
-      remote_write_bytes(memaddr, myaddr, xfersize);
-      
-      memaddr += xfersize;
-      myaddr  += xfersize;
-      len     -= xfersize;
-    }
-  return 0; /* no error */
+  printf ("remote files info missing here.  FIXME.\n");
 }
 \f
 /*
@@ -533,7 +553,7 @@ static void
 remote_send (buf)
      char *buf;
 {
-  int i;
+
   putpkt (buf);
   getpkt (buf);
 
@@ -551,7 +571,6 @@ putpkt (buf)
   int i;
   unsigned char csum = 0;
   char buf2[500];
-  char buf3[1];
   int cnt = strlen (buf);
   char ch;
   char *p;
@@ -599,10 +618,21 @@ getpkt (buf)
   unsigned char csum;
   int c;
   unsigned char c1, c2;
-  extern kiodebug;
+
+#if 0
+  /* Sorry, this will cause all hell to break loose, i.e. we'll end
+     up in the command loop with an inferior, but (at least if this
+     happens in remote_wait or some such place) without a current_frame,
+     having set up prev_* in wait_for_inferior, etc.
+
+     If it is necessary to have such an "emergency exit", seems like
+     the only plausible thing to do is to say the inferior died, and
+     make the user reattach if they want to.  Perhaps with a prompt
+     asking for confirmation.  */
 
   /* allow immediate quit while reading from device, it could be hung */
   immediate_quit++;
+#endif /* 0 */
 
   while (1)
     {
@@ -631,7 +661,9 @@ getpkt (buf)
       write (remote_desc, "-", 1);
     }
 
+#if 0
   immediate_quit--;
+#endif
 
   write (remote_desc, "+", 1);
 
@@ -791,3 +823,32 @@ dcache_init ()
     insque (db, &dcache_free);
 }
 #endif /* 0 */
+
+/* Define the target subroutine names */
+
+struct target_ops remote_ops = {
+       "remote", "Remote serial target in gdb-specific protocol",
+       "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+       remote_open, remote_close,
+       0, remote_detach, remote_resume, remote_wait,  /* attach */
+       remote_fetch_registers, remote_store_registers,
+       remote_prepare_to_store, 0, 0, /* conv_from, conv_to */
+       remote_xfer_inferior_memory, remote_files_info,
+       0, 0, /* insert_breakpoint, remove_breakpoint, */
+       0, 0, 0, 0, 0,  /* Terminal crud */
+       0, /* kill */
+       0, add_syms_addr_command,  /* load */
+       call_function_by_hand,
+       0, /* lookup_symbol */
+       0, 0, /* create_inferior FIXME, mourn_inferior FIXME */
+       process_stratum, 0, /* next */
+       1, 1, 1, 1, 1,  /* all mem, mem, stack, regs, exec */
+       OPS_MAGIC,              /* Always the last thing */
+};
+
+void
+_initialize_remote ()
+{
+  add_target (&remote_ops);
+}
This page took 0.027326 seconds and 4 git commands to generate.