This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

gdbserver pipe, xml and monitor changes


This patch adds support for the GDB remote pipe, plus new handlers so the back-end can handle XML files and add custom monitor commands. I have used the gdbserver code to implement a remote server for the Coldfire BDM interface.

The XML back-end handler allows the back-end to detect the type of processor and then provide the suitable XML file.

I have also added support to detect if a register in the cache is dirty when collected by the back-end.

The 'z' and 'Z' watchpoint type filtering now allows type 1 through to the back-end. I checked the current back-ends in the gdbserver code and where not effected.

I have run make check but I could not see a gdbserver test run. Is there one ?

The various low level back-ends have not be changed to printf_filtered or warning. Should they ?

Regards
Chris

2007-11-05 Chris Johns <chrisj@rtems.org>

        * regcache.h (collect_register): Return true if the register is
        dirty.

        * regcache.c (struct inferior_regcache_data): Add a
        shadow copy of the registers.
        (new_register_cache): Allocate memory for the shadow.
        (free_register_cache): Free the shadow memory.
        (registers_from_string): Use warning.
        (register_shadow_data): New.
        (register_dirty): New.
        (supply_register): Write the register to the shadow.
        (collect_register): Return true if the register is dirty. Copy to
        the shadow once copied to the user.

        * utils.h (my_stdout): New.
        (my_stderr): New.
        (warning_prefix): New.
        (printf_filtered): New.
        (error): Use my_stdout and my_stderr.
        (fatal): Use my_stdout and my_stderr. Print the warning_prefix
        rather than the fixed gdbserver.
        (warning): Use my_stdout and my_stderr. Print the warning_prefix
        rather than the fixed gdbserver.

* target.h (struct target_ops): Added xml_file and commands.

        * server.h (my_stderr): New extern.
        (my_stdout): New extern.
        (monitor_output): Changed to printf type variable arguments.
        (printf_filtered): New.

        * server.c (start_inferior, attach_inferior, gdbserver_version)
        (gdbserver_usage): Use printf_filtered.
        (get_features_xml): If USE_XML is not defined check to the backend
        has supplied the xml_file handler and call it if it has.
        (handle_query): Added NO_PASS_SIGNALS and NO_LIBRARIES to control
        the supported string returned to GDB. The default is signals are
        passed and libraries is supported. Externed the monitor command
        handling to check of the backend has defined a command handler.
        (myname): New global for the program name. It may not be
        gdbserver.
        (main): Initialise my_stdout, my_stderr, and myname. If the COMM
        is pipe set my_stdout to be stderr. Use warning. If error is
        called in the main loop return an error to GDB. Merged the 'z' and
        'Z' code together and allowed type 1 watchpoints to be passed to
        the backend.

        * remote-utils.c (remote_piping): New.
        (WRITE_FD): New.
        (remote_open): Use warning and printf_filtered. Check if port_str
        is a pipe and set the remote_desc to STDOUT_FILENO. Allow async to
        be compiled out. The default is on.
        (remote_write): New. Flush stdout when pipe is being used.
        (putpkt_binary, getpkt): Use remote_write. Use warning and
        printf_filtered.
        (input_interrupt, readchar): Use warning.
        (prepare_resume_reply): Use printf_filtered.
        (monitor_output): Changed to printf type variable arguments.

Index: regcache.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/regcache.c,v
retrieving revision 1.11
diff -u -r1.11 regcache.c
--- regcache.c	23 Aug 2007 18:08:48 -0000	1.11
+++ regcache.c	6 Nov 2007 01:37:35 -0000
@@ -30,6 +30,7 @@
 {
   int registers_valid;
   unsigned char *registers;
+  unsigned char *shadow; /* handle a register being dirty */
 };
 
 static int register_bytes;
@@ -102,7 +103,8 @@
      in case there are registers the target never fetches.  This way they'll
      read as zero instead of garbage.  */
   regcache->registers = calloc (1, register_bytes);
-  if (regcache->registers == NULL)
+  regcache->shadow = calloc (1, register_bytes);
+  if (regcache->registers == NULL || regcache->shadow == NULL)
     fatal ("Could not allocate register cache.");
 
   regcache->registers_valid = 0;
@@ -116,6 +118,7 @@
   struct inferior_regcache_data *regcache
     = (struct inferior_regcache_data *) regcache_p;
 
+  free (regcache->shadow);
   free (regcache->registers);
   free (regcache);
 }
@@ -154,11 +157,13 @@
 
   if (len != register_bytes * 2)
     {
-      warning ("Wrong sized register packet (expected %d bytes, got %d)", 2*register_bytes, len);
+      warning ("Wrong sized register packet (expected %d bytes, got %d)",
+               2*register_bytes, len);
       if (len > register_bytes * 2)
-	len = register_bytes * 2;
+        len = register_bytes * 2;
     }
-  convert_ascii_to_int (buf, registers, len / 2);
+  
+  convert_ascii_to_int (buf, registers, len / 2);  
 }
 
 struct reg *
@@ -206,10 +211,30 @@
   return registers + (reg_defs[n].offset / 8);
 }
 
+static unsigned char *
+register_shadow_data (int n)
+{
+  unsigned char *registers
+    = get_regcache (current_inferior, 0)->shadow;
+
+  return registers + (reg_defs[n].offset / 8);
+}
+
+static int
+register_dirty (int n)
+{
+  struct inferior_regcache_data *regcache = get_regcache (current_inferior, 0);
+  return memcmp (regcache->registers + (reg_defs[n].offset / 8),
+                 regcache->shadow + (reg_defs[n].offset / 8),
+                 register_size (n)) != 0;
+}
+
 void
 supply_register (int n, const void *buf)
 {
   memcpy (register_data (n, 0), buf, register_size (n));
+  /* backend places the register into the cache so it is not dirty */
+  memcpy (register_shadow_data (n), buf, register_size (n));
 }
 
 void
@@ -218,10 +243,14 @@
   supply_register (find_regno (name), buf);
 }
 
-void
+int
 collect_register (int n, void *buf)
 {
+  int dirty = register_dirty (n);
   memcpy (buf, register_data (n, 1), register_size (n));
+  /* backend takes the register and places it into the inferior so it is not dirty */
+  memcpy (register_shadow_data (n), register_data (n, 0), register_size (n));
+  return dirty;
 }
 
 void
Index: regcache.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/regcache.h,v
retrieving revision 1.8
diff -u -r1.8 regcache.h
--- regcache.h	23 Aug 2007 18:08:48 -0000	1.8
+++ regcache.h	6 Nov 2007 01:37:35 -0000
@@ -61,7 +61,7 @@
 
 void supply_register_by_name (const char *name, const void *buf);
 
-void collect_register (int n, void *buf);
+int collect_register (int n, void *buf);
 
 void collect_register_as_string (int n, char *buf);
 
Index: remote-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/remote-utils.c,v
retrieving revision 1.50
diff -u -r1.50 remote-utils.c
--- remote-utils.c	23 Aug 2007 18:08:48 -0000	1.50
+++ remote-utils.c	6 Nov 2007 01:37:35 -0000
@@ -94,6 +94,8 @@
 
 static int remote_desc = INVALID_DESCRIPTOR;
 
+static int remote_piping;
+
 /* FIXME headerize? */
 extern int using_threads;
 extern int debug_threads;
@@ -101,6 +103,9 @@
 #ifdef USE_WIN32API
 # define read(fd, buf, len) recv (fd, (char *) buf, len, 0)
 # define write(fd, buf, len) send (fd, (char *) buf, len, 0)
+# define WRITE_FD SOCKET
+#else
+# define WRITE_FD int
 #endif
 
 /* Open a connection to a remote debugger.
@@ -109,77 +114,88 @@
 void
 remote_open (char *name)
 {
+#ifndef NO_REMOTE_ASYNC
 #if defined(F_SETFL) && defined (FASYNC)
   int save_fcntl_flags;
 #endif
+#endif
   char *port_str;
 
   port_str = strchr (name, ':');
-  if (port_str == NULL)
+  
+  if ((port_str == NULL) || (strcmp (name, "pipe") == 0))
     {
+      if (strcmp (name, "pipe") == 0)
+        {
+          my_stdout = stderr;
+          remote_desc = STDOUT_FILENO;
+          remote_piping = 1;
+        }
+      else
+        {
 #ifdef USE_WIN32API
-      error ("Only <host>:<port> is supported on this platform.");
+          error ("Only <host>:<port> and 'pipe' is supported on this platform.");
 #else
-      struct stat statbuf;
+	  struct stat statbuf;
 
-      if (stat (name, &statbuf) == 0
-	  && (S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode)))
-	remote_desc = open (name, O_RDWR);
-      else
-	{
-	  errno = EINVAL;
-	  remote_desc = -1;
-	}
+	  if (stat (name, &statbuf) == 0
+	      && (S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode)))
+	    remote_desc = open (name, O_RDWR);
+	  else
+	    {
+	      errno = EINVAL;
+	      remote_desc = -1;
+	    }
 
-      if (remote_desc < 0)
-	perror_with_name ("Could not open remote device");
+	  if (remote_desc < 0)
+	    perror_with_name ("Could not open remote device");
 
 #ifdef HAVE_TERMIOS
-      {
-	struct termios termios;
-	tcgetattr (remote_desc, &termios);
-
-	termios.c_iflag = 0;
-	termios.c_oflag = 0;
-	termios.c_lflag = 0;
-	termios.c_cflag &= ~(CSIZE | PARENB);
-	termios.c_cflag |= CLOCAL | CS8;
-	termios.c_cc[VMIN] = 1;
-	termios.c_cc[VTIME] = 0;
+          {
+	    struct termios termios;
+	    tcgetattr (remote_desc, &termios);
+
+	    termios.c_iflag = 0;
+	    termios.c_oflag = 0;
+	    termios.c_lflag = 0;
+	    termios.c_cflag &= ~(CSIZE | PARENB);
+	    termios.c_cflag |= CLOCAL | CS8;
+	    termios.c_cc[VMIN] = 1;
+	    termios.c_cc[VTIME] = 0;
 
-	tcsetattr (remote_desc, TCSANOW, &termios);
-      }
+	    tcsetattr (remote_desc, TCSANOW, &termios);
+	  }
 #endif
 
 #ifdef HAVE_TERMIO
-      {
-	struct termio termio;
-	ioctl (remote_desc, TCGETA, &termio);
+	  {
+	    struct termio termio;
+	    ioctl (remote_desc, TCGETA, &termio);
+
+	    termio.c_iflag = 0;
+	    termio.c_oflag = 0;
+	    termio.c_lflag = 0;
+	    termio.c_cflag &= ~(CSIZE | PARENB);
+	    termio.c_cflag |= CLOCAL | CS8;
+	    termio.c_cc[VMIN] = 1;
+	    termio.c_cc[VTIME] = 0;
 
-	termio.c_iflag = 0;
-	termio.c_oflag = 0;
-	termio.c_lflag = 0;
-	termio.c_cflag &= ~(CSIZE | PARENB);
-	termio.c_cflag |= CLOCAL | CS8;
-	termio.c_cc[VMIN] = 1;
-	termio.c_cc[VTIME] = 0;
-
-	ioctl (remote_desc, TCSETA, &termio);
-      }
+	    ioctl (remote_desc, TCSETA, &termio);
+	  }
 #endif
 
 #ifdef HAVE_SGTTY
-      {
-	struct sgttyb sg;
+          {
+	    struct sgttyb sg;
 
-	ioctl (remote_desc, TIOCGETP, &sg);
-	sg.sg_flags = RAW;
-	ioctl (remote_desc, TIOCSETP, &sg);
-      }
+	    ioctl (remote_desc, TIOCGETP, &sg);
+	    sg.sg_flags = RAW;
+	    ioctl (remote_desc, TIOCSETP, &sg);
+	  }
 #endif
-
-      fprintf (stderr, "Remote debugging using %s\n", name);
+	  printf_filtered ("Remote debugging using %s\n", name);
 #endif /* USE_WIN32API */
+	}
     }
   else
     {
@@ -234,8 +250,7 @@
 	  port = ntohs (sockaddr.sin_port);
 	}
 
-      fprintf (stderr, "Listening on port %d\n", port);
-      fflush (stderr);
+      printf_filtered ("gdbserver: Listening on port %d\n", port);
 
       tmp = sizeof (sockaddr);
       remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp);
@@ -264,10 +279,11 @@
 #endif
 
       /* Convert IP address to string.  */
-      fprintf (stderr, "Remote debugging from host %s\n", 
-         inet_ntoa (sockaddr.sin_addr));
+      printf_filtered ("Remote debugging from host %s\n", 
+		       inet_ntoa (sockaddr.sin_addr));
     }
 
+#ifndef NO_REMOTE_ASYNC
 #if defined(F_SETFL) && defined (FASYNC)
   save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
   fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
@@ -276,6 +292,7 @@
 #endif
 #endif
   disable_async_io ();
+#endif
 }
 
 void
@@ -288,6 +305,15 @@
 #endif
 }
 
+ssize_t
+remote_write (WRITE_FD fd, const void *buf, size_t count)
+{
+  ssize_t written = write (fd, buf, count);
+  if (remote_piping)
+    fflush (stdout);
+  return written;
+}
+
 /* Convert hex digit A to a number.  */
 
 static int
@@ -544,7 +570,7 @@
     {
       int cc;
 
-      if (write (remote_desc, buf2, p - buf2) != p - buf2)
+      if (remote_write (remote_desc, buf2, p - buf2) != p - buf2)
 	{
 	  perror ("putpkt(write)");
 	  free (buf2);
@@ -553,22 +579,20 @@
 
       if (remote_debug)
 	{
-	  fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
-	  fflush (stderr);
+	  printf_filtered ("gdbserver: putpkt (\"%s\"); [looking for ack]\n", buf2);
 	}
       cc = read (remote_desc, buf3, 1);
       if (remote_debug)
 	{
-	  fprintf (stderr, "[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
-	  fflush (stderr);
+          printf_filtered ("gdbserver: putpkt [received '%c' (0x%x)]\n", buf3[0], buf3[0]);
 	}
 
       if (cc <= 0)
 	{
 	  if (cc == 0)
-	    fprintf (stderr, "putpkt(read): Got EOF\n");
+	    printf_filtered ("gdbserver: putpkt(read): Got EOF\n");
 	  else
-	    perror ("putpkt(read)");
+	    perror ("gdbserver: putpkt putpkt(read)");
 
 	  free (buf2);
 	  return -1;
@@ -619,7 +643,7 @@
 
       if (cc != 1 || c != '\003')
 	{
-	  fprintf (stderr, "input_interrupt, count = %d c = %d ('%c')\n",
+	  warning ("gdbserver: input_interrupt, count = %d c = %d ('%c')\n",
 		   cc, c, c);
 	  return;
 	}
@@ -713,7 +737,7 @@
   if (bufcnt <= 0)
     {
       if (bufcnt == 0)
-	fprintf (stderr, "readchar: Got EOF\n");
+	warning ("gdbserver: readchar: Got EOF\n");
       else
 	perror ("readchar");
 
@@ -746,8 +770,7 @@
 	    break;
 	  if (remote_debug)
 	    {
-	      fprintf (stderr, "[getpkt: discarding char '%c']\n", c);
-	      fflush (stderr);
+	      printf_filtered ("gdbserver: [getpkt: discarding char '%c']\n", c);
 	    }
 
 	  if (c < 0)
@@ -773,23 +796,21 @@
       if (csum == (c1 << 4) + c2)
 	break;
 
-      fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
+      warning ("gdbserver: Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
 	       (c1 << 4) + c2, csum, buf);
-      write (remote_desc, "-", 1);
+      remote_write (remote_desc, "-", 1);
     }
 
   if (remote_debug)
     {
-      fprintf (stderr, "getpkt (\"%s\");  [sending ack] \n", buf);
-      fflush (stderr);
+      printf_filtered ("gdbserver: getpkt (\"%s\");  [sending ack] \n", buf);
     }
 
-  write (remote_desc, "+", 1);
+  remote_write (remote_desc, "+", 1);
 
   if (remote_debug)
     {
-      fprintf (stderr, "[sent ack]\n");
-      fflush (stderr);
+      printf_filtered ("gdbserver: [sent ack]\n");
     }
 
   return bp - buf;
@@ -952,7 +973,7 @@
 	  gdb_id_from_wait = thread_to_gdb_id (current_inferior);
 
 	  if (debug_threads)
-	    fprintf (stderr, "Writing resume reply for %ld\n\n", thread_from_wait);
+	    printf_filtered ("Writing resume reply for %ld\n\n", thread_from_wait);
 	  /* This if (1) ought to be unnecessary.  But remote_wait in GDB
 	     will claim this event belongs to inferior_ptid if we do not
 	     specify a thread, and there's no way for gdbserver to know
@@ -1169,12 +1190,22 @@
 }
 
 void
-monitor_output (const char *msg)
+monitor_output (const char *string,...)
 {
-  char *buf = malloc (strlen (msg) * 2 + 2);
+  static char buffer[256];
+  va_list args;
+  int len;
+  char *buf;
+  
+  va_start (args, string);
+
+  buffer[sizeof (buffer) - 1] = '\0';
+  len = vsnprintf (buffer, sizeof (buffer) - 1, string, args);
+  
+  buf = malloc (len * 2 + 2);
 
   buf[0] = 'O';
-  hexify (buf + 1, msg, 0);
+  hexify (buf + 1, buffer, 0);
 
   putpkt (buf);
   free (buf);
Index: server.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.c,v
retrieving revision 1.56
diff -u -r1.56 server.c
--- server.c	23 Aug 2007 18:08:48 -0000	1.56
+++ server.c	6 Nov 2007 01:37:35 -0000
@@ -80,9 +80,8 @@
 
   /* FIXME: we don't actually know at this point that the create
      actually succeeded.  We won't know that until we wait.  */
-  fprintf (stderr, "Process %s created; pid = %ld\n", argv[0],
-	   signal_pid);
-  fflush (stderr);
+  printf_filtered ("Process %s created; pid = %ld\n", argv[0],
+                   signal_pid);
 
 #ifdef SIGTTOU
   signal (SIGTTOU, SIG_IGN);
@@ -107,8 +106,7 @@
   if (myattach (pid) != 0)
     return -1;
 
-  fprintf (stderr, "Attached; pid = %d\n", pid);
-  fflush (stderr);
+  printf_filtered ("Attached; pid = %d\n", pid);
 
   /* FIXME - It may be that we should get the SIGNAL_PID from the
      attach function, so that it can be the main thread instead of
@@ -218,6 +216,13 @@
 
   if (xml_builtin[i][0] != NULL)
     return xml_builtin[i][1];
+#else
+  if (the_target->xml_file != NULL)
+    {
+      const char *xml_file = (*the_target->xml_file) (annex);
+      if (xml_file)
+        return xml_file;
+    }        
 #endif
 
   if (strcmp (annex, "target.xml") != 0)
@@ -527,11 +532,16 @@
   if (strncmp ("qSupported", own_buf, 10) == 0
       && (own_buf[10] == ':' || own_buf[10] == '\0'))
     {
-      sprintf (own_buf, "PacketSize=%x;QPassSignals+", PBUFSIZ - 1);
-
+	sprintf (own_buf, "PacketSize=%x", PBUFSIZ - 1);
+#ifndef NO_PASS_SIGNALS
+	strcat (own_buf, ";QPassSignals+");
+#endif
+#ifndef NO_LIBRARIES
       /* We do not have any hook to indicate whether the target backend
 	 supports qXfer:libraries:read, so always report it.  */
       strcat (own_buf, ";qXfer:libraries:read+");
+#endif
+      strcat (own_buf, ";qXfer:memory map:read+");
 
       if (the_target->read_auxv != NULL)
 	strcat (own_buf, ";qXfer:auxv:read+");
@@ -644,9 +654,16 @@
 	monitor_show_help ();
       else
 	{
-	  monitor_output ("Unknown monitor command.\n\n");
-	  monitor_show_help ();
-	  write_enn (own_buf);
+          int ok = 0;
+	  if (the_target->commands)
+            ok = (*the_target->commands) (mon, len);
+          else
+	    monitor_output ("Unknown monitor command.\n\n");
+          if (!ok)
+            {
+	      monitor_show_help ();
+	      write_enn (own_buf);
+	    }
 	}
 
       free (mon);
@@ -816,25 +833,27 @@
 }
 
 static int attached;
+static char *myname;
 
 static void
 gdbserver_version (void)
 {
-  printf ("GNU gdbserver %s\n"
-	  "Copyright (C) 2007 Free Software Foundation, Inc.\n"
-	  "gdbserver is free software, covered by the GNU General Public License.\n"
-	  "This gdbserver was configured as \"%s\"\n",
-	  version, host_name);
+  printf_filtered ("GNU gdbserver %s\n"
+		   "Copyright (C) 2007 Free Software Foundation, Inc.\n"
+		   "gdbserver is free software, covered by the GNU General Public License.\n"
+		   "This gdbserver was configured as \"%s\"\n",
+                   version, host_name);
 }
 
 static void
 gdbserver_usage (void)
 {
-  printf ("Usage:\tgdbserver COMM PROG [ARGS ...]\n"
-	  "\tgdbserver COMM --attach PID\n"
-	  "\n"
-	  "COMM may either be a tty device (for serial debugging), or \n"
-	  "HOST:PORT to listen for a TCP connection.\n");
+  warning ("Usage:\t%s COMM PROG [ARGS ...]\n"
+           "\t%s COMM --attach PID\n"
+	   "\n"
+	   "COMM may either be a tty device (for serial debugging), or \n"
+           "HOST:PORT to listen for a TCP connection.",
+           myname, myname);
 }
 
 int
@@ -850,6 +869,11 @@
   int pid;
   char *arg_end;
 
+  my_stdout = stdout;
+  my_stderr = stderr;
+  
+  myname = argv[0];
+  
   if (argc >= 2 && strcmp (argv[1], "--version") == 0)
     {
       gdbserver_version ();
@@ -864,7 +888,7 @@
 
   if (setjmp (toplevel))
     {
-      fprintf (stderr, "Exiting\n");
+      warning ("Exiting");
       exit (1);
     }
 
@@ -890,6 +914,11 @@
       exit (1);
     }
 
+  if (strcmp (argv[1], "pipe") == 0)
+    {
+      my_stdout = my_stderr = stderr;
+    }
+
   initialize_low ();
 
   own_buf = malloc (PBUFSIZ + 1);
@@ -923,14 +952,14 @@
 
   if (setjmp (toplevel))
     {
-      fprintf (stderr, "Killing inferior\n");
+      warning ("Killing inferior");
       kill_inferior ();
       exit (1);
     }
 
   if (status == 'W' || status == 'X')
     {
-      fprintf (stderr, "No inferior, GDBserver exiting.\n");
+      warning ("No inferior, GDBserver exiting.");
       exit (1);
     }
 
@@ -939,7 +968,14 @@
       remote_open (argv[1]);
 
     restart:
-      setjmp (toplevel);
+      if (setjmp (toplevel))
+        {
+          if (remote_debug)
+            printf_filtered ("gdbserver: error returned to main loop\n");
+          write_enn (own_buf);
+          putpkt (own_buf);
+        }
+      
       while (1)
 	{
 	  unsigned char sig;
@@ -961,7 +997,7 @@
 	      handle_general_set (own_buf);
 	      break;
 	    case 'D':
-	      fprintf (stderr, "Detaching from inferior\n");
+	      warning ("Detaching from inferior");
 	      if (detach_inferior () != 0)
 		{
 		  write_enn (own_buf);
@@ -1095,6 +1131,7 @@
 	      signal = mywait (&status, 1);
 	      prepare_resume_reply (own_buf, status, signal);
 	      break;
+	    case 'z':
 	    case 'Z':
 	      {
 		char *lenptr;
@@ -1104,37 +1141,8 @@
 		char type = own_buf[1];
 
 		if (the_target->insert_watchpoint == NULL
-		    || (type < '2' || type > '4'))
-		  {
-		    /* No watchpoint support or not a watchpoint command;
-		       unrecognized either way.  */
-		    own_buf[0] = '\0';
-		  }
-		else
-		  {
-		    int res;
-
-		    res = (*the_target->insert_watchpoint) (type, addr, len);
-		    if (res == 0)
-		      write_ok (own_buf);
-		    else if (res == 1)
-		      /* Unsupported.  */
-		      own_buf[0] = '\0';
-		    else
-		      write_enn (own_buf);
-		  }
-		break;
-	      }
-	    case 'z':
-	      {
-		char *lenptr;
-		char *dataptr;
-		CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
-		int len = strtol (lenptr + 1, &dataptr, 16);
-		char type = own_buf[1];
-
-		if (the_target->remove_watchpoint == NULL
-		    || (type < '2' || type > '4'))
+		    || the_target->remove_watchpoint == NULL
+		    || (type < '1' || type > '4'))
 		  {
 		    /* No watchpoint support or not a watchpoint command;
 		       unrecognized either way.  */
@@ -1143,8 +1151,10 @@
 		else
 		  {
 		    int res;
-
+		    if (ch == 'z')
 		    res = (*the_target->remove_watchpoint) (type, addr, len);
+		    else
+		      res = (*the_target->insert_watchpoint) (type, addr, len);
 		    if (res == 0)
 		      write_ok (own_buf);
 		    else if (res == 1)
@@ -1156,7 +1166,7 @@
 		break;
 	      }
 	    case 'k':
-	      fprintf (stderr, "Killing inferior\n");
+	      warning ("Killing inferior");
 	      kill_inferior ();
 	      /* When using the extended protocol, we start up a new
 	         debugging session.   The traditional protocol will
@@ -1164,7 +1174,7 @@
 	      if (extended_protocol)
 		{
 		  write_ok (own_buf);
-		  fprintf (stderr, "GDBserver restarting\n");
+		  warning ("GDBserver restarting");
 
 		  /* Wait till we are at 1st instruction in prog.  */
 		  signal = start_inferior (&argv[2], &status);
@@ -1201,7 +1211,7 @@
 		{
 		  kill_inferior ();
 		  write_ok (own_buf);
-		  fprintf (stderr, "GDBserver restarting\n");
+		  warning ("GDBserver restarting");
 
 		  /* Wait till we are at 1st instruction in prog.  */
 		  signal = start_inferior (&argv[2], &status);
@@ -1234,20 +1244,19 @@
 	    putpkt (own_buf);
 
 	  if (status == 'W')
-	    fprintf (stderr,
-		     "\nChild exited with status %d\n", signal);
+	    warning ("\nChild exited with status %d", signal);
 	  if (status == 'X')
-	    fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n",
+	    warning ("\nChild terminated with signal = 0x%x (%s)",
 		     target_signal_to_host (signal),
 		     target_signal_to_name (signal));
 	  if (status == 'W' || status == 'X')
 	    {
 	      if (extended_protocol)
 		{
-		  fprintf (stderr, "Killing inferior\n");
+		  warning ("Killing inferior");
 		  kill_inferior ();
 		  write_ok (own_buf);
-		  fprintf (stderr, "GDBserver restarting\n");
+		  warning ("GDBserver restarting");
 
 		  /* Wait till we are at 1st instruction in prog.  */
 		  signal = start_inferior (&argv[2], &status);
@@ -1256,7 +1265,7 @@
 		}
 	      else
 		{
-		  fprintf (stderr, "GDBserver exiting\n");
+		  warning ("GDBserver exiting");
 		  exit (0);
 		}
 	    }
@@ -1276,8 +1285,8 @@
 	}
       else
 	{
-	  fprintf (stderr, "Remote side has terminated connection.  "
-			   "GDBserver will reopen the connection.\n");
+	  warning ("Remote side has terminated connection.  "
+                   "GDBserver will reopen the connection.");
 	  remote_close ();
 	}
     }
Index: server.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.h,v
retrieving revision 1.36
diff -u -r1.36 server.h
--- server.h	23 Oct 2007 20:05:03 -0000	1.36
+++ server.h	6 Nov 2007 01:37:35 -0000
@@ -156,6 +156,11 @@
 
 extern jmp_buf toplevel;
 
+/* The stdout and stderr descriptors. They can be remapped if
+   the remote is a pipe. */
+extern FILE *my_stderr;
+extern FILE *my_stdout;
+
 /* From remote-utils.c */
 
 extern int remote_debug;
@@ -199,7 +204,7 @@
 
 int look_up_one_symbol (const char *name, CORE_ADDR *addrp);
 
-void monitor_output (const char *msg);
+void monitor_output (const char *string,...) ATTR_FORMAT (printf, 1, 2);
 
 char *xml_escape_text (const char *text);
 
@@ -211,6 +216,7 @@
 
 /* Functions from utils.c */
 
+int printf_filtered (const char *format,...) ATTR_FORMAT (printf, 1, 2);
 void perror_with_name (char *string);
 void error (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
 void fatal (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/target.h,v
retrieving revision 1.25
diff -u -r1.25 target.h
--- target.h	23 Aug 2007 18:08:48 -0000	1.25
+++ target.h	6 Nov 2007 01:37:35 -0000
@@ -187,6 +187,14 @@
    /* Read/Write from/to spufs using qXfer packets.  */
   int (*qxfer_spu) (const char *annex, unsigned char *readbuf,
 		    unsigned const char *writebuf, CORE_ADDR offset, int len);
+
+  /* Return a pointer to the requested XML file, or NULL if the file was
+     not found.  */
+  const char *(*xml_file) (const char *annex);
+
+  /* If set the target can accept monitor commands. Return false
+     to return an error code. */
+  int (*commands) (const char *cmd, int len);
 };
 
 extern struct target_ops *the_target;
Index: utils.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/utils.c,v
retrieving revision 1.13
diff -u -r1.13 utils.c
--- utils.c	23 Oct 2007 20:05:03 -0000	1.13
+++ utils.c	6 Nov 2007 01:37:35 -0000
@@ -28,8 +28,28 @@
 #include <malloc.h>
 #endif
 
+FILE *my_stderr;
+FILE *my_stdout;
+const char* warning_prefix = "gdbserver";
+
 /* Generally useful subroutines used throughout the program.  */
 
+/* Print via our stdout descriptor. This allows us to move
+   the stdout to stderr when using the the gdb server via
+   the gdb remote pipe target. */
+
+/* VARARGS */
+int
+printf_filtered (const char *format,...)
+{
+  int ret;
+  va_list args;
+  va_start (args, format);
+  ret =  vfprintf (my_stdout, format, args);
+  fflush (my_stdout);
+  return ret;
+}
+
 /* Print the system error message for errno, and also mention STRING
    as the file name for which the error was encountered.
    Then return to command level.  */
@@ -56,15 +76,17 @@
    STRING is the error message, used as a fprintf string,
    and ARG is passed as an argument to it.  */
 
+/* VARARGS */
 void
 error (const char *string,...)
 {
   extern jmp_buf toplevel;
   va_list args;
   va_start (args, string);
-  fflush (stdout);
-  vfprintf (stderr, string, args);
-  fprintf (stderr, "\n");
+  fflush (my_stdout);
+  vfprintf (my_stderr, string, args);
+  fprintf (my_stderr, "\n");
+  fflush (my_stderr);
   longjmp (toplevel, 1);
 }
 
@@ -78,9 +100,11 @@
 {
   va_list args;
   va_start (args, string);
-  fprintf (stderr, "gdbserver: ");
-  vfprintf (stderr, string, args);
-  fprintf (stderr, "\n");
+  fprintf (my_stderr, warning_prefix);
+  fprintf (my_stderr, ": ");
+  vfprintf (my_stderr, string, args);
+  fprintf (my_stderr, "\n");
+  fflush (my_stderr);
   va_end (args);
   exit (1);
 }
@@ -91,8 +115,10 @@
 {
   va_list args;
   va_start (args, string);
-  fprintf (stderr, "gdbserver: ");
-  vfprintf (stderr, string, args);
-  fprintf (stderr, "\n");
+  fprintf (my_stderr, warning_prefix);
+  fprintf (my_stderr, ": ");
+  vfprintf (my_stderr, string, args);
+  fprintf (my_stderr, "\n");
+  fflush (my_stderr);
   va_end (args);
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]