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]

Re: [RFA] gdbserver support for qCRC: (compare-sections)


On Tuesday 23 March 2010 18:32:12, Pedro Alves wrote:
> If you connect with "target extended-remote"
> instead of "target remote", and do "compare-sections" before
> issueing "run" or "attach" from gdb, hence gdbserver has no
> inferior process to debug yet, you want gdbserver to reply
> error (E01) instead of trying to read from a non-existing
> inferior process (and possibly crashing).

Actually, the compare-sections command is busted in that
is doesn't work with extended-remote at all:

 (top-gdb) tar extended-remote :9999
 Remote debugging using :9999
 ...
 (top-gdb) compare-sections
 command can only be used with remote target


Note:

> /* FIXME: cagney/1999-10-26: This command should be broken down into a
>   target method (target verify memory) and generic version of the
>   actual command.  This will allow other high-level code (especially
>   generic_load()) to make use of this target functionality.  */

and:

>  if (!current_target.to_shortname ||
>      strcmp (current_target.to_shortname, "remote") != 0)
>    error (_("command can only be used with remote target"));

Ugh!

This patch fixes it.  I've applied it.

-- 
Pedro Alves
2010-03-24  Pedro Alves  <pedro@codesourcery.com>

	gdb/
	* remote.c (crc32): Constify `buf' parameter.
	(remote_verify_memory): New, abstracted out from...
	(compare_sections_command): ... this.  Remove hardcoded target
	checks.
	(init_remote_ops): Install remote_verify_memory.
	* target.c (target_verify_memory): New.
	* target.h (struct target_ops) <to_verify_memory>: New field.
	(target_verify_memory): Declare.

---
 gdb/remote.c |   71 +++++++++++++++++++++++++++++++++--------------------------
 gdb/target.c |   22 ++++++++++++++++++
 gdb/target.h |   15 ++++++++++++
 3 files changed, 77 insertions(+), 31 deletions(-)

Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2010-03-24 00:38:23.000000000 +0000
+++ src/gdb/remote.c	2010-03-24 01:03:14.000000000 +0000
@@ -173,8 +173,6 @@ static CORE_ADDR remote_address_masked (
 
 static void print_packet (char *);
 
-static unsigned long crc32 (unsigned char *, int, unsigned int);
-
 static void compare_sections_command (char *, int);
 
 static void packet_command (char *, int);
@@ -7542,7 +7540,7 @@ static unsigned long crc32_table[256] =
 {0, 0};
 
 static unsigned long
-crc32 (unsigned char *buf, int len, unsigned int crc)
+crc32 (const unsigned char *buf, int len, unsigned int crc)
 {
   if (!crc32_table[1])
     {
@@ -7566,38 +7564,59 @@ crc32 (unsigned char *buf, int len, unsi
   return crc;
 }
 
+/* Verify memory using the "qCRC:" request.  */
+
+static int
+remote_verify_memory (struct target_ops *ops,
+		      const gdb_byte *data, CORE_ADDR lma, ULONGEST size)
+{
+  struct remote_state *rs = get_remote_state ();
+  unsigned long host_crc, target_crc;
+  char *tmp;
+
+  /* FIXME: assumes lma can fit into long.  */
+  xsnprintf (rs->buf, get_remote_packet_size (), "qCRC:%lx,%lx",
+	     (long) lma, (long) size);
+  putpkt (rs->buf);
+
+  /* Be clever; compute the host_crc before waiting for target
+     reply.  */
+  host_crc = crc32 (data, size, 0xffffffff);
+
+  getpkt (&rs->buf, &rs->buf_size, 0);
+  if (rs->buf[0] == 'E')
+    return -1;
+
+  if (rs->buf[0] != 'C')
+    error (_("remote target does not support this operation"));
+
+  for (target_crc = 0, tmp = &rs->buf[1]; *tmp; tmp++)
+    target_crc = target_crc * 16 + fromhex (*tmp);
+
+  return (host_crc == target_crc);
+}
+
 /* compare-sections command
 
    With no arguments, compares each loadable section in the exec bfd
    with the same memory range on the target, and reports mismatches.
-   Useful for verifying the image on the target against the exec file.
-   Depends on the target understanding the new "qCRC:" request.  */
-
-/* FIXME: cagney/1999-10-26: This command should be broken down into a
-   target method (target verify memory) and generic version of the
-   actual command.  This will allow other high-level code (especially
-   generic_load()) to make use of this target functionality.  */
+   Useful for verifying the image on the target against the exec file.  */
 
 static void
 compare_sections_command (char *args, int from_tty)
 {
-  struct remote_state *rs = get_remote_state ();
   asection *s;
-  unsigned long host_crc, target_crc;
   struct cleanup *old_chain;
-  char *tmp;
   char *sectdata;
   const char *sectname;
   bfd_size_type size;
   bfd_vma lma;
   int matched = 0;
   int mismatched = 0;
+  int res;
 
   if (!exec_bfd)
     error (_("command cannot be used without an exec file"));
-  if (!current_target.to_shortname ||
-      strcmp (current_target.to_shortname, "remote") != 0)
-    error (_("command can only be used with remote target"));
 
   for (s = exec_bfd->sections; s; s = s->next)
     {
@@ -7614,33 +7633,22 @@ compare_sections_command (char *args, in
 
       matched = 1;		/* do this section */
       lma = s->lma;
-      /* FIXME: assumes lma can fit into long.  */
-      xsnprintf (rs->buf, get_remote_packet_size (), "qCRC:%lx,%lx",
-		 (long) lma, (long) size);
-      putpkt (rs->buf);
 
-      /* Be clever; compute the host_crc before waiting for target
-	 reply.  */
       sectdata = xmalloc (size);
       old_chain = make_cleanup (xfree, sectdata);
       bfd_get_section_contents (exec_bfd, s, sectdata, 0, size);
-      host_crc = crc32 ((unsigned char *) sectdata, size, 0xffffffff);
 
-      getpkt (&rs->buf, &rs->buf_size, 0);
-      if (rs->buf[0] == 'E')
+      res = target_verify_memory (sectdata, lma, size);
+
+      if (res == -1)
 	error (_("target memory fault, section %s, range %s -- %s"), sectname,
 	       paddress (target_gdbarch, lma),
 	       paddress (target_gdbarch, lma + size));
-      if (rs->buf[0] != 'C')
-	error (_("remote target does not support this operation"));
-
-      for (target_crc = 0, tmp = &rs->buf[1]; *tmp; tmp++)
-	target_crc = target_crc * 16 + fromhex (*tmp);
 
       printf_filtered ("Section %s, range %s -- %s: ", sectname,
 		       paddress (target_gdbarch, lma),
 		       paddress (target_gdbarch, lma + size));
-      if (host_crc == target_crc)
+      if (res)
 	printf_filtered ("matched.\n");
       else
 	{
@@ -9756,6 +9764,7 @@ Specify the serial device it is connecte
   remote_ops.to_set_disconnected_tracing = remote_set_disconnected_tracing;
   remote_ops.to_set_circular_trace_buffer = remote_set_circular_trace_buffer;
   remote_ops.to_core_of_thread = remote_core_of_thread;
+  remote_ops.to_verify_memory = remote_verify_memory;
 }
 
 /* Set up the extended remote vector by making a copy of the standard
Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2010-03-24 01:04:17.000000000 +0000
+++ src/gdb/target.c	2010-03-24 01:04:25.000000000 +0000
@@ -3073,6 +3073,28 @@ target_core_of_thread (ptid_t ptid)
   return -1;
 }
 
+int
+target_verify_memory (const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_verify_memory != NULL)
+	{
+	  int retval = t->to_verify_memory (t, data, memaddr, size);
+	  if (targetdebug)
+	    fprintf_unfiltered (gdb_stdlog, "target_verify_memory (%s, %s) = %d\n",
+				paddress (target_gdbarch, memaddr),
+				pulongest (size),
+				retval);
+	  return retval;
+	}
+    }
+
+  tcomplain ();
+}
+
 static void
 debug_to_prepare_to_store (struct regcache *regcache)
 {
Index: src/gdb/target.h
===================================================================
--- src.orig/gdb/target.h	2010-03-24 01:04:17.000000000 +0000
+++ src/gdb/target.h	2010-03-24 01:05:54.000000000 +0000
@@ -675,6 +675,13 @@ struct target_ops
        right now, or in this debug session, or for this target -- return -1.  */
     int (*to_core_of_thread) (struct target_ops *, ptid_t ptid);
 
+    /* Verify that the memory in the [MEMADDR, MEMADDR+SIZE) range
+       matches the contents of [DATA,DATA+SIZE).  Returns 1 if there's
+       a match, 0 if there's a mismatch, and -1 if an error is
+       encountered while reading memory.  */
+    int (*to_verify_memory) (struct target_ops *, const gdb_byte *data,
+			     CORE_ADDR memaddr, ULONGEST size);
+
     int to_magic;
     /* Need sub-structure for target machine related rather than comm related?
      */
@@ -1375,6 +1382,14 @@ extern int target_search_memory (CORE_AD
 
 extern int target_core_of_thread (ptid_t ptid);
 
+/* Verify that the memory in the [MEMADDR, MEMADDR+SIZE) range matches
+   the contents of [DATA,DATA+SIZE).  Returns 1 if there's a match, 0
+   if there's a mismatch, and -1 if an error is encountered while
+   reading memory.  Throws an error if the functionality is found not
+   to be supported by the current target.  */
+int target_verify_memory (const gdb_byte *data,
+			  CORE_ADDR memaddr, ULONGEST size);
+
 /* Routines for maintenance of the target structures...
 
    add_target:   Add a target to the list of all possible targets.


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