diff options
author | Vladimir Prus <vladimir@codesourcery.com> | 2010-08-13 13:22:44 +0000 |
---|---|---|
committer | Vladimir Prus <vladimir@codesourcery.com> | 2010-08-13 13:22:44 +0000 |
commit | 8dedea0203a9ff24396a5e78b4addfc33c9135a7 (patch) | |
tree | 9a954f4d302bc540883f02f5bbd456aa77af7f0d /gdb/mi/mi-main.c | |
parent | f608cd77e751a7c47cfb0f8fb91677cbb3e75232 (diff) | |
download | gdb-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/mi-main.c')
-rw-r--r-- | gdb/mi/mi-main.c | 127 |
1 files changed, 124 insertions, 3 deletions
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"); |