This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [patch] new command: 'dump' a region of memory in ascii and hex
> How about the following strategy:
>
> - always print the first "Dumping from... to..." line;
>
> - if the dump takes more than a screenful, print the trailing "End
> of dump from... to..." line as well.
I couldn't find a clean way of doing that, the screen size information
is trapped inside utils.c (and I don't see a good reason to let it
out.) I simply removed the "End of dump line" (it is #if 0'd in the
patch in case anyone knew a clever way of determining screen size.
> Hmm... this begins to creep into a full-fledged emulation of the GNU
> `od'... Not necessarily a bad thing, but perhaps you should take the
> various options from `od' as well?
not today :-)
>
> > --- doc/gdb.texinfo.orig Wed Nov 22 14:34:16 2000
> > +++ doc/gdb.texinfo Wed Nov 22 14:45:02 2000
>
> If and when the change to the sources is approved, the docs changes
> are approved as well, provided that you take care of these minor
> gotchas:
fixed in the attached patch.
Additional changes with the new patch:
-the dump act more like the other 'x' commands where the convienence
variables $_ and $__ are concerned, that is, it updates them like the
documentation says it should.
-if the number of bytes the user requested doesn't divide evenly by 16
the last line is padded with spaces. In past patches I was simply
finishing out the line even though the user didn't ask for those
bytes.
-the repeat count used to be always understood as being in bytes, but
now we look at the unit size. (unit_size*repeat_count=num bytes to
dump)
-David
2000-11-21 David Whedon <dwhedon@gordian.com>
* printcmd.c (x_command) : repeat count is now remembered and reused
across 'examines', new format type 'r'(raw) dumps hex and
ascii.
* doc/gdb.texinfo : updated 'examine' command documentation.
* testsuite/gdb.base/printcmds.exp : added a test case for
'r'(raw) format memory examine.
--- printcmd.c.orig Tue Nov 21 18:03:08 2000
+++ printcmd.c Mon Nov 27 19:19:40 2000
@@ -57,6 +57,9 @@ static char last_format = 'x';
static char last_size = 'w';
+/* last specified output count */
+static int last_count = 1;
+
/* Default address to examine next. */
static CORE_ADDR next_address;
@@ -168,6 +171,8 @@ static void validate_format PARAMS ((str
static void do_examine PARAMS ((struct format_data, CORE_ADDR addr, asection * section));
+static void do_dump (struct format_data fmt, CORE_ADDR low);
+
static void print_formatted (value_ptr, int, int, struct ui_file *);
static struct format_data decode_format PARAMS ((char **, int, int));
@@ -1352,7 +1357,7 @@ x_command (exp, from_tty)
fmt.format = last_format;
fmt.size = last_size;
- fmt.count = 1;
+ fmt.count = last_count;
if (exp && *exp == '/')
{
@@ -1388,11 +1393,15 @@ x_command (exp, from_tty)
do_cleanups (old_chain);
}
- do_examine (fmt, next_address, next_section);
+ if (fmt.format == 'r')
+ do_dump (fmt, next_address);
+ else
+ do_examine (fmt, next_address, next_section);
/* If the examine succeeds, we remember its size and format for next time. */
last_size = fmt.size;
last_format = fmt.format;
+ last_count = fmt.count;
/* Set a couple of internal variables if appropriate. */
if (last_examine_value)
@@ -2521,6 +2530,108 @@ print_insn (memaddr, stream)
}
+
+/*
+ Dump a specified region in memory starting at 'low'.
+ Output is hex and ascii.
+ Length and delimitation controlled by 'fmt'
+ */
+#define CHARS_PER_LINE 16
+
+static void
+do_dump (struct format_data fmt, CORE_ADDR low)
+{
+ CORE_ADDR high, symbol_low, symbol_high;
+ value_ptr val;
+ struct type *val_type = examine_b_type;
+ int i;
+ char buffer[CHARS_PER_LINE + 1];
+ char *symbol_name;
+
+ switch (fmt.size)
+ {
+ case 'b':
+ val_type = examine_b_type;
+ break;
+ case 'h':
+ val_type = examine_h_type;
+ break;
+ case 'w':
+ val_type = examine_w_type;
+ break;
+ case 'g':
+ val_type = examine_g_type;
+ break;
+ default:
+ val_type = examine_w_type;
+ }
+
+ high = low + fmt.count * TYPE_LENGTH (val_type);
+ next_address = low;
+
+ fprintf_filtered (gdb_stdout, "Dumping from ");
+ print_address (low, gdb_stdout);
+ fprintf_filtered (gdb_stdout, " to ");
+ print_address (high, gdb_stdout);
+ fprintf_filtered (gdb_stdout, "\n");
+
+ find_pc_partial_function (next_address, &symbol_name, &symbol_low, &symbol_high);
+ print_address_symbolic (next_address, gdb_stdout, 1, "");
+ fprintf_filtered (gdb_stdout, ":\n");
+ while (next_address < high)
+ {
+ if (next_address > symbol_high)
+ {
+ find_pc_partial_function (next_address, &symbol_name,
+ &symbol_low, &symbol_high);
+ print_address_symbolic (next_address, gdb_stdout, 1, "");
+ fprintf_filtered (gdb_stdout, ":\n");
+ }
+ print_address_numeric (next_address, 1, gdb_stdout);
+ fprintf_filtered (gdb_stdout, ": ");
+
+ for (i = 0; (i < CHARS_PER_LINE) && (next_address < high); i++)
+ {
+ if (i % TYPE_LENGTH (val_type) == 0)
+ fprintf_filtered (gdb_stdout, " ");
+
+ last_examine_address = next_address;
+
+ if (last_examine_value)
+ value_free (last_examine_value);
+
+ last_examine_value = value_at (examine_b_type, next_address, next_section);
+ if (last_examine_value)
+ release_value (last_examine_value);
+
+ buffer[i] = 0xFF & *(VALUE_CONTENTS_RAW (last_examine_value));
+ fprintf_filtered (gdb_stdout, "%.2x", 0xFF & buffer[i]);
+ if (buffer[i] < 33 || buffer[i] > 126)
+ buffer[i] = '.';
+ next_address++;
+ }
+ while (i < CHARS_PER_LINE)
+ {
+ if (i % TYPE_LENGTH (val_type) == 0)
+ fprintf_filtered (gdb_stdout, " ");
+ fprintf_filtered (gdb_stdout, " ");
+ buffer[i++] = ' ';
+ }
+
+ buffer[i] = '\0';
+ fprintf_filtered (gdb_stdout, " %s\n", buffer);
+
+ }
+#if 0
+ fprintf_filtered (gdb_stdout, "End of dump from ");
+ print_address (low, gdb_stdout);
+ fprintf_filtered (gdb_stdout, " to ");
+ print_address (high, gdb_stdout);
+ fprintf_filtered (gdb_stdout, "\n");
+#endif
+
+}
+
void
_initialize_printcmd ()
{
@@ -2538,7 +2649,8 @@ Only for symbols with fixed locations (g
ADDRESS is an expression for the memory address to examine.\n\
FMT is a repeat count followed by a format letter and a size letter.\n\
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),\n\
- t(binary), f(float), a(address), i(instruction), c(char) and s(string).\n",
+ t(binary), f(float), a(address), i(instruction), c(char), s(string) \n\
+and r(raw).\n",
"Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).\n\
The specified number of objects of the specified size are printed\n\
according to the format.\n\n\
--- printcmds.exp.orig Tue Nov 21 18:22:24 2000
+++ printcmds.exp Wed Nov 22 14:57:59 2000
@@ -680,6 +680,13 @@ proc test_printf {} {
0xfeedface, 0xdeadbeef, 5.0" "bad -99.54\[0-9\]+, z feedface, deadbeef, 5.0+"
}
+proc test_x {} {
+
+gdb_test "x /4wr ctable2" \
+ ".*<ctable2>:.*0x.*61585858 58585858 58585858 58585858.*aXXXXXXXXXXXXXXX"
+
+
+}
# Start with a fresh gdb.
gdb_exit
@@ -714,6 +721,7 @@ if [set_lang_c] then {
test_print_string_constants
test_print_array_constants
test_printf
+ test_x
}
} else {
fail "C print command tests suppressed"
--- gdb.texinfo.orig Wed Nov 22 14:34:16 2000
+++ gdb.texinfo Mon Nov 27 19:44:53 2000
@@ -4668,14 +4668,14 @@ Several commands set convenient defaults
@table @r
@item @var{n}, the repeat count
-The repeat count is a decimal integer; the default is 1. It specifies
-how much memory (counting by units @var{u}) to display.
+The repeat count is a decimal integer. It specifies
+how much memory (counting by units @var{u}) to display. Each time you use @code{x} the default repeat count is updated.
@c This really is **decimal**; unaffected by 'set radix' as of GDB
@c 4.1.2.
@item @var{f}, the display format
The display format is one of the formats used by @code{print},
-@samp{s} (null-terminated string), or @samp{i} (machine instruction).
+@samp{r} (raw, displays hex and @sc{ascii} dump), @samp{s} (null-terminated string), or @samp{i} (machine instruction).
The default is @samp{x} (hexadecimal) initially.
The default changes each time you use either @code{x} or @code{print}.
@@ -4713,7 +4713,25 @@ For example, @samp{x/3uh 0x54320} is a r
(@code{h}) of memory, formatted as unsigned decimal integers (@samp{u}),
starting at address @code{0x54320}. @samp{x/4xw $sp} prints the four
words (@samp{w}) of memory above the stack pointer (here, @samp{$sp};
-@pxref{Registers, ,Registers}) in hexadecimal (@samp{x}).
+@pxref{Registers, ,Registers}) in hexadecimal (@samp{x}).
+@cindex hex dump
+@cindex dumping memory contents
+
+Following is an example of examining memory with the raw (@samp{r}) format.
+The unit size controls how the hex chars are delimited, as well as the meaning
+of the repeat count.
+
+@smallexample
+(@value{GDBP}) @b{x /6rw ctable2}
+Dumping from 0x80496a0 <ctable2> to 0x80496b8 <ctable2+24>
+<ctable2>:
+0x80496a0: 61585858 58585858 58585858 58585858 aXXXXXXXXXXXXXXX
+0x80496b0: 61615858 58585858 aaXXXXXX
+(@value{GDBP}) @b{x /7rb}
+Dumping from 0x80496b8 <ctable2+24> to 0x80496bf <ctable2+31>
+<ctable2+24>:
+0x80496b8: 58 58 58 58 58 58 58 XXXXXXX
+@end smallexample
Since the letters indicating unit sizes are all distinct from the
letters specifying output formats, you do not have to remember whether