]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2008-06-21 Michael Snyder <msnyder@specifix.com>
authorMichael Snyder <msnyder@vmware.com>
Sun, 22 Jun 2008 01:51:05 +0000 (01:51 +0000)
committerMichael Snyder <msnyder@vmware.com>
Sun, 22 Jun 2008 01:51:05 +0000 (01:51 +0000)
Add support for 'O' packet output.
* remote-breakpoint.h (PLAY_O_PACKETS): New enum const.
* gdbfreeplay-back.c (StopFrame): Discard gpos, replace with Opos.
(scan_gdbreplay_file): Record Opos for frame if 'O' packet found.
(frame_replay_O_packets): New function.
(freeplay_find_event): Call frame_replay_O_packets.
(handle_special_case): Pass PLAY_O_PACKETS to freeplay_find_event.
Add temporary support for "monitor gdbfreeplay-echo" command
(just for testing).

gdb/gdbserver/ChangeLog
gdb/gdbserver/gdbfreeplay-back.c
gdb/gdbserver/remote-breakpoint.h

index beb3d9151a3ee02c8c82e4556c4d29e6b5d2e5e4..a748f2858e07b49af8e597f3707b76c477ffae90 100644 (file)
@@ -1,5 +1,15 @@
 2008-06-21  Michael Snyder  <msnyder@specifix.com>
 
+       Add support for 'O' packet output.
+       * remote-breakpoint.h (PLAY_O_PACKETS): New enum const.
+       * gdbfreeplay-back.c (StopFrame): Discard gpos, replace with Opos.
+       (scan_gdbreplay_file): Record Opos for frame if 'O' packet found.
+       (frame_replay_O_packets): New function.
+       (freeplay_find_event): Call frame_replay_O_packets.
+       (handle_special_case): Pass PLAY_O_PACKETS to freeplay_find_event.
+       Add temporary support for "monitor gdbfreeplay-echo" command
+       (just for testing).
+
        * gdbfreeplay-back.c: Clean up round, comments, remove #if 0 etc.
        * gdbfreeplay-i386.c: Ditto.
 
index 5944ec5bab583386c3d91b95110c08a21569bc6e..0cc65fe4dc26bb5658486280b48e1d6ed36bda70 100644 (file)
@@ -27,7 +27,7 @@ typedef struct STOPFRAME {
      DECR_PC_AFTER_BREAK.  */
   unsigned long predecr_pc;
   unsigned long eventpos;
-  unsigned long gpos;
+  unsigned long Opos;
 } StopFrame;
 
 StopFrame *stopframe;
@@ -77,9 +77,6 @@ scan_gdbreplay_file (FILE *infile)
     /* 'g' packet message?  */
     if (strstr (line, "$g#67") != NULL)
       {
-       /* Record position of 'g' packet (next line).  */
-       stopframe[last_cached_frame].gpos = ftell (infile);
-
        /* See if we need to grab the PC from this packet.  */
        if (stopframe[last_cached_frame].pc == 0 ||
            stopframe[last_cached_frame].pc == (unsigned long) -1)
@@ -109,6 +106,15 @@ scan_gdbreplay_file (FILE *infile)
          }
       }
 
+    /* 'O' packet(s)?  Watch out for "$OK", we don't want that.  */
+    else if ((p = strstr (line, "$O")) != NULL &&
+            strstr (p, "$OK#9a") == NULL)
+      {
+       /* If we know these, we can feed them back to gdb
+          during 'continue'.  */
+       stopframe[last_cached_frame].Opos = nextpos;
+      }
+
     /* Stop event message?  */
     else if ((p = strstr (line, "$T")) != NULL ||
             (p = strstr (line, "$S")) != NULL)
@@ -142,6 +148,9 @@ scan_gdbreplay_file (FILE *infile)
        /* Since we now have a known frame, default to using it.  */
        cur_frame = 0;
        stopframe[last_cached_frame].eventpos = nextpos + p - line;
+       /* The frame for this event will default to not having 
+          any 'O' packets, until we recognize one.  */
+       stopframe[last_cached_frame].Opos = 0;
 
        if (p[1] == 'T')
          stopframe[last_cached_frame].pc = target_pc_from_T (p);
@@ -505,12 +514,43 @@ stopframe_signal (FILE *infile, int id)
       (p = strstr (line, "$S")) != NULL)
     {
       /* Signal value is two ascii/hex bytes following "$S" or "$T".  */
-      sig = (hex_to_int (p[2]) << 8) + hex_to_int (p[3]);
+      sig = (hex_to_int (p[2]) << 4) + hex_to_int (p[3]);
       return sig;
     }
   return 0;
 }
 
+/*
+ * freeplay_play_O_packets
+ *
+ * Send one or more 'O' packets back to gdb.
+ * Returns void.
+ */
+
+static void
+freeplay_play_O_packets (FILE *infile, int fd, unsigned long filepos)
+{
+  char *line, *p;
+
+  fseek (infile, filepos, SEEK_SET);
+
+  while ((line = fgets (inbuf, sizeof (inbuf), infile)) != NULL)
+    {
+      if ((p = strstr (line, "$O")) != NULL)
+       {
+         /* FIXME: do I need to send an ACK?  */
+         gdb_ack (fd);
+         gdbwriteline (fd, p);
+       }
+      /* When we reach the next stop event, we're done.  */
+      else if (strstr (line, "$T") != NULL ||
+              strstr (line, "$S") != NULL)
+       {
+         return;       /* done */
+       }
+    }
+}
+
 /*
  * freeplay_find_event
  *
@@ -522,7 +562,11 @@ stopframe_signal (FILE *infile, int id)
  */
 
 static int
-freeplay_find_event (FILE *infile, int start, enum direction_code direction)
+freeplay_find_event (FILE *infile, 
+                    int gdb_fd, 
+                    int start, 
+                    enum direction_code direction,
+                    enum direction_code play_O_packets)
 {
   int i;
   int signum;
@@ -546,6 +590,8 @@ freeplay_find_event (FILE *infile, int start, enum direction_code direction)
             FIXME need some DECR_PC_AFTER_BREAK handling.  */
          return i;
        }
+      if (play_O_packets && stopframe[i].Opos != 0)
+       freeplay_play_O_packets (infile, gdb_fd, stopframe[i].Opos);
     }
   /* Found no reason to stop.  */
   return -1;
@@ -609,9 +655,14 @@ handle_special_case (FILE *infile, int fd, char *request)
 {
   unsigned long addr;
   unsigned long len;
-  int next_event_frame;
+  int next_event_frame, c;
   char *p;
 
+  static char *monitor_verbose_off = "$qRcmd,766572626f7365206f6666#13";
+  static char *monitor_verbose_on  = "$qRcmd,766572626f7365206f6e#d6";
+  static char *monitor_echo = "$qRcmd,67646266726565706c61792d6563686f";
+
+
   /* Handle 'k' (kill) request by exiting.  */
   if (strstr (request, "$k#6b") != NULL)
     {
@@ -636,19 +687,39 @@ handle_special_case (FILE *infile, int fd, char *request)
     }
 
   /* Handle "monitor verbose on".  */
-  if (strstr (request, "$qRcmd,766572626f7365206f6e#d6") != NULL)
+  if (strstr (request, monitor_verbose_on) != NULL)
     {
       verbose = 1;
       return OK;
     }
 
   /* Handle "monitor verbose off".  */
-  if (strstr (request, "$qRcmd,766572626f7365206f6666#13") != NULL)
+  if (strstr (request, monitor_verbose_off) != NULL)
     {
       verbose = 0;
       return OK;
     }
 
+  /* Handle "monitor gdbfreeplay-echo"
+     (just to get a handle on the 'O' message).  */
+  if ((p = strstr (request, monitor_echo)) != NULL)
+    {
+      /* OK, this will be an ascii-fied string.  */
+      p += strlen (monitor_echo);
+      /* Skip spaces */
+      while (p[0] == '2' && p[1] == '0')
+       p += 2; /* skip a space */
+
+      while (p[0] && p[0] != '#')
+       {
+         c  = hex_to_int (*p++) << 4;
+         c += hex_to_int (*p++);
+         fputc (c, stdout);
+       }
+      fprintf (stdout, "\n");
+      return OK;
+    }
+
   /* Handle 's' (step) by advancing the cur_frame index.  */
   if (strstr (request, "$s#73") != NULL)
     {
@@ -688,7 +759,10 @@ handle_special_case (FILE *infile, int fd, char *request)
   /* Handle 'c' (continue) by searching the cache for a stop event.  */
   if (strstr (request, "$c#63") != NULL)
     {
-      next_event_frame = freeplay_find_event (infile, cur_frame, DIR_FORWARD);
+      next_event_frame = freeplay_find_event (infile, fd, 
+                                             cur_frame, 
+                                             DIR_FORWARD,
+                                             PLAY_O_PACKETS);
       if (next_event_frame != -1)
        {
          /* Got a stop event.  Make it the current frame, and tell gdb.
@@ -717,7 +791,10 @@ handle_special_case (FILE *infile, int fd, char *request)
   /* Handle 'bc' (revese continue) by searching the cache for a stop event.  */
   if (strstr (request, "$bc#c5") != NULL)
     {
-      next_event_frame = freeplay_find_event (infile, cur_frame, DIR_BACKWARD);
+      next_event_frame = freeplay_find_event (infile, fd, 
+                                             cur_frame, 
+                                             DIR_BACKWARD,
+                                             PLAY_O_PACKETS);
       if (next_event_frame != -1)
        {
          /* Got a stop event.  Make it the current frame, and tell gdb.
@@ -726,6 +803,12 @@ handle_special_case (FILE *infile, int fd, char *request)
        }
       else
        {
+         /* WTF? */
+         gdb_ack (fd);
+         strcpy (inbuf, "$O5768617420746865206675636b3f");
+         if (verbose)
+           fprintf (stdout, "WTF? %s\n", add_checksum (inbuf));
+         gdbwriteline (fd, add_checksum (inbuf));
          cur_frame = 0;
        }
 
index 1ee1b5c44dd102b6d4911a09b6149b522c9ae0c1..d98a659b6e01fcaf633247ad46546f195c375dbf 100644 (file)
@@ -26,7 +26,8 @@ enum successcode {
 
 enum direction_code {
   DIR_FORWARD = 0,
-  DIR_BACKWARD
+  DIR_BACKWARD,
+  PLAY_O_PACKETS
 };
 
 extern enum successcode remote_remove_breakpoint (enum breakpoint_type,