From 8dedea0203a9ff24396a5e78b4addfc33c9135a7 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Fri, 13 Aug 2010 13:22:44 +0000 Subject: 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. --- gdb/mi/mi-cmds.c | 2 + gdb/mi/mi-cmds.h | 2 + gdb/mi/mi-main.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 128 insertions(+), 3 deletions(-) (limited to 'gdb/mi') 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"); -- cgit v1.1