* mips-tdep.c (init_extra_frame_info): Use frame relative stack
[deliverable/binutils-gdb.git] / gdb / remote.c
index e073853afb7b589b64144a8abb98784f7cbc4c42..87437a177981bef7d81d91ef76a5591eed6bc6b3 100644 (file)
@@ -191,7 +191,7 @@ static int
 readchar PARAMS ((void));
 
 static int
-remote_wait PARAMS ((WAITTYPE *status));
+remote_wait PARAMS ((int pid, WAITTYPE *status));
 
 static int
 tohex PARAMS ((int nib));
@@ -208,6 +208,9 @@ remote_interrupt PARAMS ((int signo));
 static void
 remote_interrupt_twice PARAMS ((int signo));
 
+static void
+interrupt_query PARAMS ((void));
+
 extern struct target_ops remote_ops;   /* Forward decl */
 
 /* This was 5 seconds, which is a long time to sit and wait.
@@ -225,7 +228,12 @@ int icache;
    starts.  */
 serial_t remote_desc = NULL;
 
-#define        PBUFSIZ 1024
+/* Having this larger than 400 causes us to be incompatible with m68k-stub.c
+   and i386-stub.c.  Normally, no one would notice because it only matters
+   for writing large chunks of memory (e.g. in downloads).  Also, this needs
+   to be more than 400 if required to hold the registers (see below, where
+   we round it up based on REGISTER_BYTES).  */
+#define        PBUFSIZ 400
 
 /* Maximum number of bytes to read/write at once.  The value here
    is chosen to fill up a packet (the headers account for the 32).  */
@@ -293,20 +301,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, 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 ");
@@ -411,7 +417,7 @@ remote_interrupt (signo)
   signal (signo, remote_interrupt_twice);
   
   if (remote_debug)
-    printf ("remote_interrupt called\n");
+    printf_unfiltered ("remote_interrupt called\n");
 
   SERIAL_WRITE (remote_desc, "\003", 1); /* Send a ^C */
 }
@@ -425,18 +431,26 @@ remote_interrupt_twice (signo)
 {
   signal (signo, ofunc);
   
+  interrupt_query ();
+
+  signal (signo, remote_interrupt);
+}
+
+/* Ask the user what to do when an interrupt is received.  */
+
+static void
+interrupt_query ()
+{
   target_terminal_ours ();
+
   if (query ("Interrupted while waiting for the program.\n\
 Give up (and stop debugging it)? "))
     {
       target_mourn_inferior ();
       return_to_top_level (RETURN_QUIT);
     }
-  else
-    {
-      signal (signo, remote_interrupt);
-      target_terminal_inferior ();
-    }
+
+  target_terminal_inferior ();
 }
 
 /* Wait until the remote machine stops, then return,
@@ -445,128 +459,178 @@ Give up (and stop debugging it)? "))
    means in the case of this target).  */
 
 static int
-remote_wait (status)
+remote_wait (pid, status)
+     int pid;
      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++ != ';')
-           error("Remote register badly formatted: %s", buf);
+             if (*p++ != ':')
+               warning ("Malformed packet (missing colon): %s\nPacket: '%s'\n",
+                        p, buf);
 
-         supply_register (regno, regs);
+             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);
+
+             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 != ';')
-       error ("Malformed relocation packet: Packet '%s'", buf);
-      p = p1 + 1;
-      data_addr = strtol (p, &p1, 16);
-      if (p1 == p || *p1 != ';')
-       error ("Malformed relocation packet: Packet '%s'", buf);
-      p = p1 + 1;
-      bss_addr = strtol (p, &p1, 16);
-      if (p1 == p)
-       error ("Malformed relocation packet: Packet '%s'", buf);
-
-      if (symfile_objfile != NULL)
+      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 = strtoul (p, &p1, 16);
+         if (p1 == p || *p1 != ';')
+           warning ("Malformed relocation packet: Packet '%s'", buf);
+         p = p1 + 1;
+         data_addr = strtoul (p, &p1, 16);
+         if (p1 == p || *p1 != ';')
+           warning ("Malformed relocation packet: Packet '%s'", buf);
+         p = p1 + 1;
+         bss_addr = strtoul (p, &p1, 16);
+         if (p1 == p)
+           warning ("Malformed relocation packet: Packet '%s'", buf);
+
+         if (symfile_objfile != NULL
+             && (ANOFFSET (symfile_objfile->section_offsets,
+                           SECT_OFF_TEXT) != text_addr
+                 || ANOFFSET (symfile_objfile->section_offsets,
+                              SECT_OFF_DATA) != data_addr
+                 || ANOFFSET (symfile_objfile->section_offsets,
+                              SECT_OFF_BSS) != bss_addr))
+           {
+             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?).  */
+
+             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);
+             {
+               struct obj_section *s;
+               bfd *abfd;
+
+               abfd = symfile_objfile->obfd;
+
+               for (s = symfile_objfile->sections;
+                    s < symfile_objfile->sections_end; ++s)
+                 {
+                   flagword flags;
+
+                   flags = bfd_get_section_flags (abfd, s->sec_ptr);
+
+                   if (flags & SEC_CODE)
+                     {
+                       s->addr += text_addr;
+                       s->endaddr += text_addr;
+                     }
+                   else if (flags & (SEC_DATA | SEC_LOAD))
+                     {
+                       s->addr += data_addr;
+                       s->endaddr += data_addr;
+                     }
+                   else if (flags & SEC_ALLOC)
+                     {
+                       s->addr += bss_addr;
+                       s->endaddr += bss_addr;
+                     }
+                 }
+             }
+           }
+         break;
+       }
+      else if (buf[0] == 'W')
        {
-         struct section_offsets *offs;
-
-         /* FIXME: Why don't the various symfile_offsets routines in
-            the sym_fns vectors set this?  */
-         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);
+         /* 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] == 'W')
-    {
-      /* The remote process exited.  */
-      WSETEXIT (*status, (fromhex (buf[1]) << 4) + fromhex (buf[2]));
-      return 0;
-    }
-  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 */
@@ -582,6 +646,20 @@ remote_fetch_registers (regno)
   sprintf (buf, "g");
   remote_send (buf);
 
+  /* Unimplemented registers read as all bits zero.  */
+  memset (regs, 0, REGISTER_BYTES);
+
+  /* We can get out of synch in various cases.  If the first character
+     in the buffer is not a hex character, assume that has happened
+     and try to fetch another packet to read.  */
+  while ((buf[0] < '0' || buf[0] > '9')
+        && (buf[0] < 'a' || buf[0] > 'f'))
+    {
+      if (remote_debug)
+       printf_unfiltered ("Bad register packet; fetching a new packet\n");
+      getpkt (buf, 0);
+    }
+
   /* 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.  */
@@ -589,11 +667,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)]);
 }
@@ -626,7 +722,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);
@@ -700,9 +797,6 @@ remote_write_bytes (memaddr, myaddr, len)
   int i;
   char *p;
 
-  if (len > PBUFSIZ / 2 - 20)
-    abort ();
-
   sprintf (buf, "M%x,%x:", memaddr, len);
 
   /* We send target system values byte by byte, in increasing byte addresses,
@@ -903,7 +997,7 @@ putpkt (buf)
       if (remote_debug)
        {
          *p = '\0';
-         printf ("Sending packet: %s...", buf2);  fflush(stdout);
+         printf_unfiltered ("Sending packet: %s...", buf2);  gdb_flush(gdb_stdout);
        }
       if (SERIAL_WRITE (remote_desc, buf2, p - buf2))
        perror_with_name ("putpkt: write failed");
@@ -917,7 +1011,7 @@ putpkt (buf)
            {
            case '+':
              if (remote_debug)
-               printf("Ack\n");
+               printf_unfiltered("Ack\n");
              return;
            case SERIAL_TIMEOUT:
              break;            /* Retransmit buffer */
@@ -927,11 +1021,17 @@ putpkt (buf)
              error ("putpkt: EOF while trying to read ACK");
            default:
              if (remote_debug)
-               printf ("%02X %c ", ch&0xFF, ch);
+               printf_unfiltered ("%02X %c ", ch&0xFF, ch);
              continue;
            }
          break;                /* Here to retransmit */
        }
+
+      if (quit_flag)
+       {
+         quit_flag = 0;
+         interrupt_query ();
+       }
     }
 }
 
@@ -954,6 +1054,12 @@ getpkt (buf, forever)
 
   while (1)
     {
+      if (quit_flag)
+       {
+         quit_flag = 0;
+         interrupt_query ();
+       }
+
       /* This can loop forever if the remote side sends us characters
         continuously, but if it pauses, we'll get a zero from readchar
         because of timeout.  Then we'll count that as a retry.  */
@@ -1027,7 +1133,7 @@ whole:
        }
       else
        {
-         printf ("Ignoring packet error, continuing...\n");
+         printf_unfiltered ("Ignoring packet error, continuing...\n");
          break;
        }
     }
@@ -1037,7 +1143,7 @@ out:
   SERIAL_WRITE (remote_desc, "+", 1);
 
   if (remote_debug)
-    fprintf (stderr,"Packet received: %s\n", buf);
+    fprintf_unfiltered (gdb_stderr,"Packet received: %s\n", buf);
 }
 \f
 static void
@@ -1149,10 +1255,12 @@ Specify the serial device it is connected to (e.g. /dev/ttya).",  /* to_doc */
   NULL,                                /* sections_end */
   OPS_MAGIC                    /* to_magic */
 };
+#endif /* Use remote.  */
 
 void
 _initialize_remote ()
 {
+#if !defined(DONT_USE_REMOTE)
   add_target (&remote_ops);
-}
 #endif
+}
This page took 0.029994 seconds and 4 git commands to generate.