* 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.
This commit is contained in:
Pedro Alves 2010-03-24 01:12:13 +00:00
parent 2280c721d8
commit 4a5e7a5b0a
4 changed files with 88 additions and 31 deletions

View 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.

View 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

View 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)
{

View 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.