This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] Add -verify option to load command
- From: Luis Machado <lgustavo at codesourcery dot com>
- To: <gdb-patches at sourceware dot org>
- Date: Fri, 6 Jan 2017 10:41:52 -0600
- Subject: [PATCH] Add -verify option to load command
- Authentication-results: sourceware.org; auth=none
This is also a leftover bit from flash programming that can also be used by
other targets as needed. GDB already has some minimal memory verification
functionality.
The following patch adds a new -verify parameter to the load command that
forces GDB to verify all the memory written during the load operation.
This is useful to make sure bare-metal targets have had the program and data
loaded successfully. I wouldn't say this is too useful for hosted
environments, but not harmful either.
What do you think?
gdb/doc/ChangeLog:
2017-01-05 Mike Wrighton <mike_wrighton@codesourcery.com>
Luis Machado <lgustavo@codesourcery.com>
gdb/doc/
* gdb.texinfo (load): Added verify flag to load command description.
gdb/ChangeLog:
2017-01-05 Mike Wrighton <mike_wrighton@codesourcery.com>
Luis Machado <lgustavo@codesourcery.com>
* symfile.c (generic_load): Add -verify arg.
(_initialize_symfile): Document new -verify option in the load
command's help text.
* target-memory.c (target_write_memory_blocks): Add verify parameter
and handle it.
* target.h (target_write_memory_blocks): Add verify argument and
document it.
---
gdb/doc/gdb.texinfo | 5 ++++-
gdb/symfile.c | 35 ++++++++++++++++++++++++-----------
gdb/target-memory.c | 20 +++++++++++++++++++-
gdb/target.h | 5 ++++-
4 files changed, 51 insertions(+), 14 deletions(-)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 44ae068..39de23c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -19592,7 +19592,7 @@ Show the current status of displaying communications between
@table @code
@kindex load @var{filename}
-@item load @var{filename}
+@item load @var{filename} [-verify]
@anchor{load}
Depending on what remote debugging facilities are configured into
@value{GDBN}, the @code{load} command may be available. Where it exists, it
@@ -19614,6 +19614,9 @@ specifies a fixed address.
Depending on the remote side capabilities, @value{GDBN} may be able to
load programs into flash memory.
+The optional @code{-verify} argument enables verification of the data that was
+loaded to the target's memory.
+
@code{load} does not repeat if you press @key{RET} again after using it.
@end table
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 0af1900..4fdde17 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -2080,6 +2080,8 @@ generic_load (const char *args, int from_tty)
struct load_section_data cbdata;
struct load_progress_data total_progress;
struct ui_out *uiout = current_uiout;
+ int arg_idx;
+ int verify = 0;
CORE_ADDR entry;
char **argv;
@@ -2099,19 +2101,30 @@ generic_load (const char *args, int from_tty)
filename = tilde_expand (argv[0]);
make_cleanup (xfree, filename);
- if (argv[1] != NULL)
+ arg_idx = 1;
+ if (argv[arg_idx] != NULL)
{
const char *endptr;
- cbdata.load_offset = strtoulst (argv[1], &endptr, 0);
+ if (strcmp (argv[arg_idx], "-verify") == 0)
+ {
+ verify = 1;
+ arg_idx++;
+ }
+
+ if (argv[arg_idx] != NULL)
+ {
+ cbdata.load_offset = strtoul ((const char *) argv[arg_idx],
+ (char **) &endptr, 0);
- /* If the last word was not a valid number then
- treat it as a file name with spaces in. */
- if (argv[1] == endptr)
- error (_("Invalid download offset:%s."), argv[1]);
+ /* If the last word was not a valid number then
+ treat it as a file name with spaces in. */
+ if (argv[arg_idx] == endptr)
+ error (_("Invalid download offset:%s."), argv[arg_idx]);
- if (argv[2] != NULL)
- error (_("Too many parameters."));
+ if (argv[arg_idx + 1] != NULL)
+ error (_("Too many parameters."));
+ }
}
/* Open the file for loading. */
@@ -2140,7 +2153,7 @@ generic_load (const char *args, int from_tty)
steady_clock::time_point start_time = steady_clock::now ();
if (target_write_memory_blocks (cbdata.requests, flash_discard,
- load_progress) != 0)
+ load_progress, verify) != 0)
error (_("Load failed"));
steady_clock::time_point end_time = steady_clock::now ();
@@ -3952,8 +3965,8 @@ that lies within the boundaries of this symbol file in memory."),
c = add_cmd ("load", class_files, load_command, _("\
Dynamically load FILE into the running program, and record its symbols\n\
for access from GDB.\n\
-A load offset may also be given.\n\
-Usage: load [FILE] [offset expression]"), &cmdlist);
+A load offset and write verification option may also be given.\n\
+Usage: load [FILE] [-verify] [offset expression]"), &cmdlist);
set_cmd_completer (c, filename_completer);
add_prefix_cmd ("overlay", class_support, overlay_command,
diff --git a/gdb/target-memory.c b/gdb/target-memory.c
index 1c8faa8..615bab8 100644
--- a/gdb/target-memory.c
+++ b/gdb/target-memory.c
@@ -310,7 +310,8 @@ cleanup_write_requests_vector (void *p)
int
target_write_memory_blocks (VEC(memory_write_request_s) *requests,
enum flash_preserve_mode preserve_flash_p,
- void (*progress_cb) (ULONGEST, void *))
+ void (*progress_cb) (ULONGEST, void *),
+ int verify)
{
struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
VEC(memory_write_request_s) *blocks = VEC_copy (memory_write_request_s,
@@ -433,6 +434,23 @@ target_write_memory_blocks (VEC(memory_write_request_s) *requests,
target_flash_done ();
}
+
+ /* Do we need to verify if the data was properly written to the target's
+ memory? */
+ if (verify)
+ {
+ /* Go through all memory regions that GDB wrote to and verify the
+ contents. */
+ for (i = 0; VEC_iterate (memory_write_request_s, blocks, i, r); ++i)
+ if (target_verify_memory (r->data, r->begin, r->end - r->begin) <= 0)
+ error ("Load verification failed for region starting at 0x%x",
+ (unsigned int) r->begin);
+ else
+ current_uiout->message ("Verified load, size 0x%x lma 0x%x\n",
+ (unsigned int) (r->end - r->begin),
+ (unsigned int) r->begin);
+ }
+
out:
do_cleanups (back_to);
diff --git a/gdb/target.h b/gdb/target.h
index e239c2c..6fc89d4 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1497,11 +1497,14 @@ enum flash_preserve_mode
feedback to user. It will be called with the baton corresponding
to the request currently being written. It may also be called
with a NULL baton, when preserved flash sectors are being rewritten.
+ VERIFY is non-zero if verification should be performed for the data written
+ to the target's memory and zero if no verification should be performed.
The function returns 0 on success, and error otherwise. */
int target_write_memory_blocks (VEC(memory_write_request_s) *requests,
enum flash_preserve_mode preserve_flash_p,
- void (*progress_cb) (ULONGEST, void *));
+ void (*progress_cb) (ULONGEST, void *),
+ int verify);
/* Print a line about the current target. */
--
2.7.4