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);
{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])
{
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)
{
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
{
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
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?
*/
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.