aboutsummaryrefslogtreecommitdiff
path: root/gdb/mi
diff options
context:
space:
mode:
authorVladimir Prus <vladimir@codesourcery.com>2010-08-13 13:22:44 +0000
committerVladimir Prus <vladimir@codesourcery.com>2010-08-13 13:22:44 +0000
commit8dedea0203a9ff24396a5e78b4addfc33c9135a7 (patch)
tree9a954f4d302bc540883f02f5bbd456aa77af7f0d /gdb/mi
parentf608cd77e751a7c47cfb0f8fb91677cbb3e75232 (diff)
downloadgdb-8dedea0203a9ff24396a5e78b4addfc33c9135a7.zip
gdb-8dedea0203a9ff24396a5e78b4addfc33c9135a7.tar.gz
gdb-8dedea0203a9ff24396a5e78b4addfc33c9135a7.tar.bz2
Easier and more stubborn MI memory read commands.
* mi/mi-cmds.c (mi_cmds): Register data-read-memory-bytes and data-write-memory-bytes. * mi/mi-cmds.h (mi_cmd_data_read_memory_bytes) (mi_cmd_data_write_memory_bytes): New. * mi/mi-main.c (mi_cmd_data_read_memory): Use regular target_read. (mi_cmd_data_read_memory_bytes, mi_cmd_data_write_memory_bytes): New. (mi_cmd_list_features): Add "data-read-memory-bytes" feature. * target.c (target_read_until_error): Remove. (read_whatever_is_readable, free_memory_read_result_vector) (read_memory_robust): New. * target.h (target_read_until_error): Remove. (struct memory_read_result, free_memory_read_result_vector) (read_memory_robust): New.
Diffstat (limited to 'gdb/mi')
-rw-r--r--gdb/mi/mi-cmds.c2
-rw-r--r--gdb/mi/mi-cmds.h2
-rw-r--r--gdb/mi/mi-main.c127
3 files changed, 128 insertions, 3 deletions
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 8441e17..a6a884f 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -51,7 +51,9 @@ struct mi_cmd mi_cmds[] =
{ "data-list-register-names", { NULL, 0 }, mi_cmd_data_list_register_names},
{ "data-list-register-values", { NULL, 0 }, mi_cmd_data_list_register_values},
{ "data-read-memory", { NULL, 0 }, mi_cmd_data_read_memory},
+ { "data-read-memory-bytes", { NULL, 0 }, mi_cmd_data_read_memory_bytes},
{ "data-write-memory", { NULL, 0 }, mi_cmd_data_write_memory},
+ { "data-write-memory-bytes", {NULL, 0}, mi_cmd_data_write_memory_bytes},
{ "data-write-register-values", { NULL, 0 }, mi_cmd_data_write_register_values},
{ "enable-timings", { NULL, 0 }, mi_cmd_enable_timings},
{ "enable-pretty-printing", { NULL, 0 }, mi_cmd_enable_pretty_printing},
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 5954aef..b357de6 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -47,7 +47,9 @@ extern mi_cmd_argv_ftype mi_cmd_data_list_register_names;
extern mi_cmd_argv_ftype mi_cmd_data_list_register_values;
extern mi_cmd_argv_ftype mi_cmd_data_list_changed_registers;
extern mi_cmd_argv_ftype mi_cmd_data_read_memory;
+extern mi_cmd_argv_ftype mi_cmd_data_read_memory_bytes;
extern mi_cmd_argv_ftype mi_cmd_data_write_memory;
+extern mi_cmd_argv_ftype mi_cmd_data_write_memory_bytes;
extern mi_cmd_argv_ftype mi_cmd_data_write_register_values;
extern mi_cmd_argv_ftype mi_cmd_enable_timings;
extern mi_cmd_argv_ftype mi_cmd_env_cd;
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 95a0bc5..8e84421 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1352,9 +1352,9 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc)
/* Dispatch memory reads to the topmost target, not the flattened
current_target. */
- nr_bytes = target_read_until_error (current_target.beneath,
- TARGET_OBJECT_MEMORY, NULL, mbuf,
- addr, total_bytes);
+ nr_bytes = target_read (current_target.beneath,
+ TARGET_OBJECT_MEMORY, NULL, mbuf,
+ addr, total_bytes);
if (nr_bytes <= 0)
error ("Unable to read memory.");
@@ -1437,6 +1437,88 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc)
do_cleanups (cleanups);
}
+void
+mi_cmd_data_read_memory_bytes (char *command, char **argv, int argc)
+{
+ struct gdbarch *gdbarch = get_current_arch ();
+ struct cleanup *cleanups;
+ CORE_ADDR addr;
+ LONGEST length;
+ memory_read_result_s *read_result;
+ int ix;
+ VEC(memory_read_result_s) *result;
+ long offset = 0;
+ int optind = 0;
+ char *optarg;
+ enum opt
+ {
+ OFFSET_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"o", OFFSET_OPT, 1},
+ { 0, 0, 0 }
+ };
+
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_data_read_memory_bytes", argc, argv, opts,
+ &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case OFFSET_OPT:
+ offset = atol (optarg);
+ break;
+ }
+ }
+ argv += optind;
+ argc -= optind;
+
+ if (argc != 2)
+ error ("Usage: [ -o OFFSET ] ADDR LENGTH.");
+
+ addr = parse_and_eval_address (argv[0]) + offset;
+ length = atol (argv[1]);
+
+ result = read_memory_robust (current_target.beneath, addr, length);
+
+ cleanups = make_cleanup (free_memory_read_result_vector, result);
+
+ if (VEC_length (memory_read_result_s, result) == 0)
+ error ("Unable to read memory.");
+
+ make_cleanup_ui_out_list_begin_end (uiout, "memory");
+ for (ix = 0;
+ VEC_iterate (memory_read_result_s, result, ix, read_result);
+ ++ix)
+ {
+ struct cleanup *t = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ char *data, *p;
+ int i;
+
+ ui_out_field_core_addr (uiout, "begin", gdbarch, read_result->begin);
+ ui_out_field_core_addr (uiout, "offset", gdbarch, read_result->begin
+ - addr);
+ ui_out_field_core_addr (uiout, "end", gdbarch, read_result->end);
+
+ data = xmalloc ((read_result->end - read_result->begin) * 2 + 1);
+
+ for (i = 0, p = data;
+ i < (read_result->end - read_result->begin);
+ ++i, p += 2)
+ {
+ sprintf (p, "%02x", read_result->data[i]);
+ }
+ ui_out_field_string (uiout, "contents", data);
+ xfree (data);
+ do_cleanups (t);
+ }
+ do_cleanups (cleanups);
+}
+
+
/* DATA-MEMORY-WRITE:
COLUMN_OFFSET: optional argument. Must be preceeded by '-o'. The
@@ -1523,6 +1605,44 @@ mi_cmd_data_write_memory (char *command, char **argv, int argc)
do_cleanups (old_chain);
}
+/* DATA-MEMORY-WRITE-RAW:
+
+ ADDR: start address
+ DATA: string of bytes to write at that address. */
+void
+mi_cmd_data_write_memory_bytes (char *command, char **argv, int argc)
+{
+ CORE_ADDR addr;
+ char *cdata;
+ gdb_byte *data;
+ int len, r, i;
+ struct cleanup *back_to;
+
+ if (argc != 2)
+ error ("Usage: ADDR DATA.");
+
+ addr = parse_and_eval_address (argv[0]);
+ cdata = argv[1];
+ len = strlen (cdata)/2;
+
+ data = xmalloc (len);
+ back_to = make_cleanup (xfree, data);
+
+ for (i = 0; i < len; ++i)
+ {
+ int x;
+ sscanf (cdata + i * 2, "%02x", &x);
+ data[i] = (gdb_byte)x;
+ }
+
+ r = target_write_memory (addr, data, len);
+ if (r != 0)
+ error (_("Could not write memory"));
+
+ do_cleanups (back_to);
+}
+
+
void
mi_cmd_enable_timings (char *command, char **argv, int argc)
{
@@ -1557,6 +1677,7 @@ mi_cmd_list_features (char *command, char **argv, int argc)
ui_out_field_string (uiout, NULL, "frozen-varobjs");
ui_out_field_string (uiout, NULL, "pending-breakpoints");
ui_out_field_string (uiout, NULL, "thread-info");
+ ui_out_field_string (uiout, NULL, "data-read-memory-bytes");
#if HAVE_PYTHON
ui_out_field_string (uiout, NULL, "python");