* breakpoint.c, breakpoint.h (breakpoint_init_inferior): New function
[deliverable/binutils-gdb.git] / gdb / remote.c
index 43d0f3327ff716abc9a525faeb2a55e87661b78d..d3fef8ba12b440c4b283dec1875f3cb25909dd78 100644 (file)
@@ -90,6 +90,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
                                        AA = signal number
                                        n... = register number
                                        r... = register contents
+       or...           WAA             The process extited, and AA is
+                                       the exit status.  This is only
+                                       applicable for certains sorts of
+                                       targets.
+       or...           NAATT;DD;BB     Relocate the object file.
+                                       AA = signal number
+                                       TT = text address
+                                       DD = data address
+                                       BB = bss address
+                                       This is used by the NLM stub,
+                                       which is why it only has three
+                                       addresses rather than one per
+                                       section: the NLM stub always
+                                       sees only three sections, even
+                                       though gdb may see more.
 
        kill request    k
 
@@ -114,8 +129,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "wait.h"
 #include "terminal.h"
 #include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
 
 #include "dcache.h"
+#include "remote-utils.h"
 
 #if !defined(DONT_USE_REMOTE)
 #ifdef USG
@@ -238,11 +256,14 @@ static int
 remote_start_remote (dummy)
      char *dummy;
 {
+  immediate_quit = 1;          /* Allow user to interrupt it */
+
   /* Ack any packet which the remote side has already sent.  */
   /* I'm not sure this \r is needed; we don't use it any other time we
      send an ack.  */
   SERIAL_WRITE (remote_desc, "+\r", 2);
   putpkt ("?");                        /* initiate a query from remote machine */
+  immediate_quit = 0;
 
   start_remote ();             /* Initialize gdb process mechanisms */
   return 1;
@@ -273,20 +294,18 @@ device is attached to the remote system (e.g. /dev/ttya).");
   if (!remote_desc)
     perror_with_name (name);
 
-  if (baud_rate)
+  if (SERIAL_SETBAUDRATE (remote_desc, sr_get_baud_rate()))
     {
-      int rate;
-
-      if (sscanf (baud_rate, "%d", &rate) == 1)
-       if (SERIAL_SETBAUDRATE (remote_desc, rate))
-         {
-           SERIAL_CLOSE (remote_desc);
-           perror_with_name (name);
-         }
+      SERIAL_CLOSE (remote_desc);
+      perror_with_name (name);
     }
 
   SERIAL_RAW (remote_desc);
 
+  /* If there is something sitting in the buffer we might take it as a
+     response to a command, which would be bad.  */
+  SERIAL_FLUSH_INPUT (remote_desc);
+
   if (from_tty)
     {
       puts_filtered ("Remote debugging using ");
@@ -295,8 +314,9 @@ device is attached to the remote system (e.g. /dev/ttya).");
     }
   push_target (&remote_ops);   /* Switch to using remote target now */
 
-  /* Start the remote connection; if error (0), discard this target. */
-  immediate_quit++;            /* Allow user to interrupt it */
+  /* Start the remote connection; if error (0), discard this target.
+     In particular, if the user quits, be sure to discard it
+     (we'd be in an inconsistent state otherwise).  */
   if (!catch_errors (remote_start_remote, (char *)0, 
        "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
     pop_target();
@@ -389,7 +409,7 @@ remote_interrupt (signo)
   /* If this doesn't work, try more severe steps.  */
   signal (signo, remote_interrupt_twice);
   
-  if (remote_debug)
+  if (sr_get_debug ())
     printf ("remote_interrupt called\n");
 
   SERIAL_WRITE (remote_desc, "\003", 1); /* Send a ^C */
@@ -428,72 +448,143 @@ remote_wait (status)
      WAITTYPE *status;
 {
   unsigned char buf[PBUFSIZ];
-  unsigned char *p;
-  int i;
-  long regno;
-  char regs[MAX_REGISTER_RAW_SIZE];
 
   WSETEXIT ((*status), 0);
 
-  ofunc = (void (*)()) signal (SIGINT, remote_interrupt);
-  getpkt ((char *) buf, 1);
-  signal (SIGINT, ofunc);
-
-  if (buf[0] == 'E')
-    error ("Remote failure reply: %s", buf);
-  if (buf[0] == 'T')
+  while (1)
     {
-      /* Expedited reply, containing Signal, {regno, reg} repeat */
-      /*  format is:  'Tssn...:r...;n...:r...;n...:r...;#cc', where
-         ss = signal number
-         n... = register number
-         r... = register contents
-         */
+      unsigned char *p;
 
-      p = &buf[3];             /* after Txx */
+      ofunc = (void (*)()) signal (SIGINT, remote_interrupt);
+      getpkt ((char *) buf, 1);
+      signal (SIGINT, ofunc);
 
-      while (*p)
+      if (buf[0] == 'E')
+       warning ("Remote failure reply: %s", buf);
+      else if (buf[0] == 'T')
        {
-         unsigned char *p1;
+         int i;
+         long regno;
+         char regs[MAX_REGISTER_RAW_SIZE];
 
-         regno = strtol (p, &p1, 16); /* Read the register number */
+         /* Expedited reply, containing Signal, {regno, reg} repeat */
+         /*  format is:  'Tssn...:r...;n...:r...;n...:r...;#cc', where
+             ss = signal number
+             n... = register number
+             r... = register contents
+             */
 
-         if (p1 == p)
-           error ("Remote sent badly formed register number: %s\nPacket: '%s'\n",
-                  p1, buf);
+         p = &buf[3];          /* after Txx */
 
-         p = p1;
+         while (*p)
+           {
+             unsigned char *p1;
 
-         if (*p++ != ':')
-           error ("Malformed packet (missing colon): %s\nPacket: '%s'\n",
-                  p, buf);
+             regno = strtol (p, &p1, 16); /* Read the register number */
 
-         if (regno >= NUM_REGS)
-           error ("Remote sent bad register number %d: %s\nPacket: '%s'\n",
-                  regno, p, buf);
+             if (p1 == p)
+               warning ("Remote sent badly formed register number: %s\nPacket: '%s'\n",
+                        p1, buf);
 
-         for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
-           {
-             if (p[0] == 0 || p[1] == 0)
-               error ("Remote reply is too short: %s", buf);
-             regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
-             p += 2;
-           }
+             p = p1;
+
+             if (*p++ != ':')
+               warning ("Malformed packet (missing colon): %s\nPacket: '%s'\n",
+                        p, buf);
+
+             if (regno >= NUM_REGS)
+               warning ("Remote sent bad register number %d: %s\nPacket: '%s'\n",
+                        regno, p, buf);
+
+             for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
+               {
+                 if (p[0] == 0 || p[1] == 0)
+                   warning ("Remote reply is too short: %s", buf);
+                 regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
+                 p += 2;
+               }
+
+             if (*p++ != ';')
+               warning ("Remote register badly formatted: %s", buf);
 
-         if (*p++ != ';')
-           error("Remote register badly formatted: %s", buf);
+             supply_register (regno, regs);
+           }
+         break;
+       }
+      else if (buf[0] == 'N')
+       {
+         unsigned char *p1;
+         bfd_vma text_addr, data_addr, bss_addr;
+
+         /* Relocate object file.  Format is NAATT;DD;BB where AA is
+            the signal number, TT is the new text address, DD is the
+            new data address, and BB is the new bss address.  This is
+            used by the NLM stub; gdb may see more sections.  */
+         p = &buf[3];
+         text_addr = strtol (p, &p1, 16);
+         if (p1 == p || *p1 != ';')
+           warning ("Malformed relocation packet: Packet '%s'", buf);
+         p = p1 + 1;
+         data_addr = strtol (p, &p1, 16);
+         if (p1 == p || *p1 != ';')
+           warning ("Malformed relocation packet: Packet '%s'", buf);
+         p = p1 + 1;
+         bss_addr = strtol (p, &p1, 16);
+         if (p1 == p)
+           warning ("Malformed relocation packet: Packet '%s'", buf);
 
-         supply_register (regno, regs);
+         if (symfile_objfile != NULL)
+           {
+             struct section_offsets *offs;
+
+             /* FIXME: This code assumes gdb-stabs.h is being used;
+                it's broken for xcoff, dwarf, sdb-coff, etc.  But
+                there is no simple canonical representation for this
+                stuff.  (Just what does "text" as seen by the stub
+                mean, anyway?).  */
+
+             /* FIXME: Why don't the various symfile_offsets routines
+                in the sym_fns vectors set this?
+                (no good reason -kingdon).  */
+             if (symfile_objfile->num_sections == 0)
+               symfile_objfile->num_sections = SECT_OFF_MAX;
+
+             offs = ((struct section_offsets *)
+                     alloca (sizeof (struct section_offsets)
+                             + (symfile_objfile->num_sections
+                                * sizeof (offs->offsets))));
+             memcpy (offs, symfile_objfile->section_offsets,
+                     (sizeof (struct section_offsets)
+                      + (symfile_objfile->num_sections
+                         * sizeof (offs->offsets))));
+             ANOFFSET (offs, SECT_OFF_TEXT) = text_addr;
+             ANOFFSET (offs, SECT_OFF_DATA) = data_addr;
+             ANOFFSET (offs, SECT_OFF_BSS) = bss_addr;
+
+             objfile_relocate (symfile_objfile, offs);
+           }
+         break;
        }
+      else if (buf[0] == 'W')
+       {
+         /* The remote process exited.  */
+         WSETEXIT (*status, (fromhex (buf[1]) << 4) + fromhex (buf[2]));
+         return 0;
+       }
+      else if (buf[0] == 'S')
+       break;
+      else
+       warning ("Invalid remote reply: %s", buf);
     }
-  else if (buf[0] != 'S')
-    error ("Invalid remote reply: %s", buf);
 
   WSETSTOP ((*status), (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))));
 
   return 0;
 }
 
+/* Number of bytes of registers this stub implements.  */
+static int register_bytes_found;
+
 /* Read the remote registers into the block REGS.  */
 /* Currently we just read all the registers, so we don't use regno.  */
 /* ARGSUSED */
@@ -509,6 +600,9 @@ remote_fetch_registers (regno)
   sprintf (buf, "g");
   remote_send (buf);
 
+  /* Unimplemented registers read as all bits zero.  */
+  memset (regs, 0, REGISTER_BYTES);
+
   /* 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.  */
@@ -516,11 +610,29 @@ remote_fetch_registers (regno)
   p = buf;
   for (i = 0; i < REGISTER_BYTES; i++)
     {
-      if (p[0] == 0 || p[1] == 0)
-       error ("Remote reply is too short: %s", buf);
+      if (p[0] == 0)
+       break;
+      if (p[1] == 0)
+       {
+         warning ("Remote reply is of odd length: %s", buf);
+         /* Don't change register_bytes_found in this case, and don't
+            print a second warning.  */
+         goto supply_them;
+       }
       regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
       p += 2;
     }
+
+  if (i != register_bytes_found)
+    {
+      register_bytes_found = i;
+#ifdef REGISTER_BYTES_OK
+      if (!REGISTER_BYTES_OK (i))
+       warning ("Remote reply is too short: %s", buf);
+#endif
+    }
+
+ supply_them:
   for (i = 0; i < NUM_REGS; i++)
     supply_register (i, &regs[REGISTER_BYTE(i)]);
 }
@@ -553,7 +665,8 @@ remote_store_registers (regno)
      each byte encoded as two hex characters.  */
 
   p = buf + 1;
-  for (i = 0; i < REGISTER_BYTES; i++)
+  /* remote_prepare_to_store insures that register_bytes_found gets set.  */
+  for (i = 0; i < register_bytes_found; i++)
     {
       *p++ = tohex ((registers[i] >> 4) & 0xf);
       *p++ = tohex (registers[i] & 0xf);
@@ -563,10 +676,21 @@ remote_store_registers (regno)
   remote_send (buf);
 }
 
+#if 0
+
+/* Use of the data cache is disabled because it loses for looking at
+   and changing hardware I/O ports and the like.  Accepting `volatile'
+   would perhaps be one way to fix it, but a better way which would
+   win for more cases would be to use the executable file for the text
+   segment, like the `icache' code below but done cleanly (in some
+   target-independent place, perhaps in target_xfer_memory, perhaps
+   based on assigning each target a speed or perhaps by some simpler
+   mechanism).  */
+
 /* Read a word from remote address ADDR and return it.
    This goes through the data cache.  */
 
-int
+static int
 remote_fetch_word (addr)
      CORE_ADDR addr;
 {
@@ -589,14 +713,14 @@ remote_fetch_word (addr)
 /* Write a word WORD into remote address ADDR.
    This goes through the data cache.  */
 
-void
+static void
 remote_store_word (addr, word)
      CORE_ADDR addr;
      int word;
 {
   dcache_poke (remote_dcache, addr, word);
 }
-
+#endif /* 0 */
 \f
 /* Write memory data directly to the remote machine.
    This does not inform the data cache; the data cache uses this.
@@ -816,7 +940,7 @@ putpkt (buf)
 
   while (1)
     {
-      if (remote_debug)
+      if (sr_get_debug ())
        {
          *p = '\0';
          printf ("Sending packet: %s...", buf2);  fflush(stdout);
@@ -832,7 +956,7 @@ putpkt (buf)
          switch (ch)
            {
            case '+':
-             if (remote_debug)
+             if (sr_get_debug ())
                printf("Ack\n");
              return;
            case SERIAL_TIMEOUT:
@@ -842,7 +966,7 @@ putpkt (buf)
            case SERIAL_EOF:
              error ("putpkt: EOF while trying to read ACK");
            default:
-             if (remote_debug)
+             if (sr_get_debug ())
                printf ("%02X %c ", ch&0xFF, ch);
              continue;
            }
@@ -883,7 +1007,7 @@ getpkt (buf, forever)
          if (forever)
            continue;
          if (++retries >= MAX_RETRIES)
-           if (remote_debug) puts_filtered ("Timed out.\n");
+           if (sr_get_debug ()) puts_filtered ("Timed out.\n");
          goto out;
        }
 
@@ -901,13 +1025,13 @@ getpkt (buf, forever)
          c = readchar ();
          if (c == SERIAL_TIMEOUT)
            {
-             if (remote_debug)
+             if (sr_get_debug ())
                puts_filtered ("Timeout in mid-packet, retrying\n");
              goto whole;               /* Start a new packet, count retries */
            } 
          if (c == '$')
            {
-             if (remote_debug)
+             if (sr_get_debug ())
                puts_filtered ("Saw new packet start in middle of old one\n");
              goto whole;               /* Start a new packet, count retries */
            }
@@ -952,7 +1076,7 @@ out:
 
   SERIAL_WRITE (remote_desc, "+", 1);
 
-  if (remote_debug)
+  if (sr_get_debug ())
     fprintf (stderr,"Packet received: %s\n", buf);
 }
 \f
This page took 0.028121 seconds and 4 git commands to generate.