gdb/
authorPedro Alves <palves@redhat.com>
Wed, 24 Mar 2010 01:12:13 +0000 (01:12 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 24 Mar 2010 01:12:13 +0000 (01:12 +0000)
* 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/ChangeLog
gdb/remote.c
gdb/target.c
gdb/target.h

index 21a1c38..fdd2b2c 100644 (file)
@@ -1,3 +1,14 @@
+2010-03-24  Pedro Alves  <pedro@codesourcery.com>
+
+       * 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.
+
 2010-03-24  Vladimir Prus  <vladimir@codesourcery.com>
 
        Implement -trace-save.
index bb19b72..0c791aa 100644 (file)
@@ -173,8 +173,6 @@ static CORE_ADDR remote_address_masked (CORE_ADDR);
 
 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, unsigned int crc)
   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, int from_tty)
 
       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 connected to\n\
   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 24d2985..5657f89 100644 (file)
@@ -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 9e87440..0d16139 100644 (file)
@@ -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_ADDR start_addr,
 
 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.