From: Luiz Capitulino <lcapitulino@redhat.com>
To: Claudio Fontana <claudio.fontana@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>,
Claudio Fontana <hw.claudio@gmail.com>,
Gonglei <arei.gonglei@huawei.com>,
Paolo Bonzini <pbonzini@redhat.com>,
qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
Date: Mon, 20 Apr 2015 18:01:42 -0400 [thread overview]
Message-ID: <20150420180142.58856911@redhat.com> (raw)
In-Reply-To: <55158312.9050109@huawei.com>
On Fri, 27 Mar 2015 17:19:30 +0100
Claudio Fontana <claudio.fontana@huawei.com> wrote:
> Just a respectful ping on this one..
> Luiz do you think you can integrate this into the monitor?
Would be nice to get a Reviewed-by from someone and, I'm getting
a build error:
/home/lcapitulino/work/src/upstream/qmp-unstable/monitor.c: In function ‘memory_search’:
/home/lcapitulino/work/src/upstream/qmp-unstable/monitor.c:1307:19: error: ‘needle’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
match = memmem(mark, todo, needle, wsize);
^
cc1: all warnings being treated as errors
>
> I have given it quite some testing for the LE host case,
> I don't have a BE host to test with at the moment, maybe someone can advise about how to test that scenario?
> I was trying to do some qemu under qemu self-emulation but didn't quite get there..
>
> Thanks,
>
> Claudio
>
> On 18.03.2015 14:30, Claudio Fontana wrote:
> > Tested with kvm on aarch64 LE host with aarch64 LE guest,
> > tested with tcg on aarch64 LE host with aarch64 LE/sparc BE/x86 LE guests.
> > Would be interesting to test this also on a big endian host with different guest combinations..
> >
> > Claudio
> >
> > On 16.03.2015 11:31, hw.claudio@gmail.com wrote:
> >> From: Claudio Fontana <claudio.fontana@huawei.com>
> >>
> >> usage is similar to the commands x, xp.
> >>
> >> Example with string: looking for "ELF" header in memory:
> >>
> >> (qemu) s/1000000cb 0x40001000 "ELF"
> >> searching memory area [0000000040001000-00000000400f5240]
> >> 0000000040090001
> >> (qemu) x/20b 0x40090000
> >> 0000000040090000: '\x7f' 'E' 'L' 'F' '\x02' '\x01' '\x01' '\x03'
> >> 0000000040090008: '\x00' '\x00' '\x00' '\x00' '\x00' '\x00' '\x00' '\x00'
> >> 0000000040090010: '\x02' '\x00' '\xb7' '\x00'
> >>
> >> Example with value: looking for 64bit variable value 0x990088
> >>
> >> (qemu) s/1000000xg 0xffff900042000000 0x990088
> >> searching memory area [ffff900042000000-ffff9000427a1200]
> >> ffff9000424b3000
> >> ffff9000424c1000
> >>
> >> Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
> >> ---
> >> hmp-commands.hx | 28 ++++++++++++
> >> monitor.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >> 2 files changed, 168 insertions(+)
> >>
> >> Hello, looking for some comments on whether the addition of this
> >> command is welcome, and whether the syntax chosen is acceptable,
> >> or how it can made better.
> >>
> >> Thanks!
> >>
> >> Claudio
> >>
> >> changes from v2:
> >> move value_raw array outside of the inner block.
> >> Hopefully this will also make patchew tool happy.
> >> Weird that I didn't get that warning/error.
> >>
> >> changes from v1:
> >> make checkpatch happy by adding braces here and there.
> >>
> >> diff --git a/hmp-commands.hx b/hmp-commands.hx
> >> index d5022d8..2bf5737 100644
> >> --- a/hmp-commands.hx
> >> +++ b/hmp-commands.hx
> >> @@ -432,6 +432,34 @@ Start gdbserver session (default @var{port}=1234)
> >> ETEXI
> >>
> >> {
> >> + .name = "s",
> >> + .args_type = "fmt:/,addr:l,data:s",
> >> + .params = "/fmt addr data",
> >> + .help = "search virtual memory starting at 'addr' for 'data'",
> >> + .mhandler.cmd = hmp_memory_search,
> >> + },
> >> +
> >> +STEXI
> >> +@item s/fmt @var{addr} @var{data}
> >> +@findex s
> >> +Virtual memory search starting at @var{addr} for data described by @var{data}.
> >> +ETEXI
> >> +
> >> + {
> >> + .name = "sp",
> >> + .args_type = "fmt:/,addr:l,data:s",
> >> + .params = "/fmt addr data",
> >> + .help = "search physical memory starting at 'addr' for 'data'",
> >> + .mhandler.cmd = hmp_physical_memory_search,
> >> + },
> >> +
> >> +STEXI
> >> +@item sp/fmt @var{addr} @var{data}
> >> +@findex sp
> >> +Physical memory search starting at @var{addr} for data described by @var{data}.
> >> +ETEXI
> >> +
> >> + {
> >> .name = "x",
> >> .args_type = "fmt:/,addr:l",
> >> .params = "/fmt addr",
> >> diff --git a/monitor.c b/monitor.c
> >> index c86a89e..7495d7e 100644
> >> --- a/monitor.c
> >> +++ b/monitor.c
> >> @@ -1208,6 +1208,124 @@ static void monitor_printc(Monitor *mon, int c)
> >> monitor_printf(mon, "'");
> >> }
> >>
> >> +static void monitor_print_addr(Monitor *mon, hwaddr addr, bool is_physical)
> >> +{
> >> + if (is_physical) {
> >> + monitor_printf(mon, TARGET_FMT_plx "\n", addr);
> >> + } else {
> >> + monitor_printf(mon, TARGET_FMT_lx "\n", (target_ulong)addr);
> >> + }
> >> +}
> >> +
> >> +/* simple memory search for a byte sequence. The sequence is generated from
> >> + * a numeric value to look for in guest memory, or from a string.
> >> + */
> >> +static void memory_search(Monitor *mon, int count, int format, int wsize,
> >> + hwaddr addr, const char *data_str, bool is_physical)
> >> +{
> >> + int pos, len; /* pos in the search area, len of area */
> >> + char *hay; /* buffer for haystack */
> >> + int hay_size; /* haystack size. Needle size is wsize. */
> >> + const char *needle; /* needle to search in the haystack */
> >> + const char *format_str; /* numeric input format string */
> >> + char value_raw[8]; /* numeric input converted to raw data */
> >> +#define MONITOR_S_CHUNK_SIZE 16000
> >> +
> >> + len = wsize * count;
> >> + if (len < 1) {
> >> + monitor_printf(mon, "invalid search area length.\n");
> >> + return;
> >> + }
> >> + switch (format) {
> >> + case 'i':
> >> + monitor_printf(mon, "format '%c' not supported.\n", format);
> >> + return;
> >> + case 'c':
> >> + needle = data_str;
> >> + wsize = strlen(data_str);
> >> + if (wsize > MONITOR_S_CHUNK_SIZE) {
> >> + monitor_printf(mon, "search string too long [max %d].\n",
> >> + MONITOR_S_CHUNK_SIZE);
> >> + return;
> >> + }
> >> + break;
> >> + case 'o':
> >> + format_str = "%" SCNo64;
> >> + break;
> >> + default:
> >> + case 'x':
> >> + format_str = "%" SCNx64;
> >> + break;
> >> + case 'u':
> >> + format_str = "%" SCNu64;
> >> + break;
> >> + case 'd':
> >> + format_str = "%" SCNd64;
> >> + break;
> >> + }
> >> + if (format != 'c') {
> >> + uint64_t value; /* numeric input value */
> >> + void *from = &value;
> >> + if (sscanf(data_str, format_str, &value) != 1) {
> >> + monitor_printf(mon, "could not parse search string "
> >> + "\"%s\" as format '%c'.\n", data_str, format);
> >> + return;
> >> + }
> >> +#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
> >> + value = bswap64(value);
> >> +#endif
> >> +#if defined(TARGET_WORDS_BIGENDIAN)
> >> + from += 8 - wsize;
> >> +#endif
> >> + memcpy(value_raw, from, wsize);
> >> + needle = value_raw;
> >> + }
> >> + monitor_printf(mon, "searching memory area ");
> >> + if (is_physical) {
> >> + monitor_printf(mon, "[" TARGET_FMT_plx "-" TARGET_FMT_plx "]\n",
> >> + addr, addr + len);
> >> + } else {
> >> + monitor_printf(mon, "[" TARGET_FMT_lx "-" TARGET_FMT_lx "]\n",
> >> + (target_ulong)addr, (target_ulong)addr + len);
> >> + }
> >> + hay_size = len < MONITOR_S_CHUNK_SIZE ? len : MONITOR_S_CHUNK_SIZE;
> >> + hay = g_malloc0(hay_size);
> >> +
> >> + for (pos = 0; pos < len;) {
> >> + char *mark, *match; /* mark new starting position, eventual match */
> >> + int l, todo; /* total length to be processed in current chunk */
> >> + l = len - pos;
> >> + if (l > hay_size) {
> >> + l = hay_size;
> >> + }
> >> + if (is_physical) {
> >> + cpu_physical_memory_read(addr, hay, l);
> >> + } else if (cpu_memory_rw_debug(ENV_GET_CPU(mon_get_cpu()), addr,
> >> + (uint8_t *)hay, l, 0) < 0) {
> >> + monitor_printf(mon, " Cannot access memory\n");
> >> + break;
> >> + }
> >> + for (mark = hay, todo = l; todo >= wsize;) {
> >> + match = memmem(mark, todo, needle, wsize);
> >> + if (!match) {
> >> + break;
> >> + }
> >> + monitor_print_addr(mon, addr + (match - hay), is_physical);
> >> + mark = match + 1;
> >> + todo = mark - hay;
> >> + }
> >> + if (pos + l < len) {
> >> + /* catch potential matches across chunks. */
> >> + pos += l - (wsize - 1);
> >> + addr += l - (wsize - 1);
> >> + } else {
> >> + pos += l;
> >> + addr += l;
> >> + }
> >> + }
> >> + g_free(hay);
> >> +}
> >> +
> >> static void memory_dump(Monitor *mon, int count, int format, int wsize,
> >> hwaddr addr, int is_physical)
> >> {
> >> @@ -1332,6 +1450,28 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
> >> }
> >> }
> >>
> >> +static void hmp_memory_search(Monitor *mon, const QDict *qdict)
> >> +{
> >> + int count = qdict_get_int(qdict, "count");
> >> + int format = qdict_get_int(qdict, "format");
> >> + int size = qdict_get_int(qdict, "size");
> >> + target_long addr = qdict_get_int(qdict, "addr");
> >> + const char *data_str = qdict_get_str(qdict, "data");
> >> +
> >> + memory_search(mon, count, format, size, addr, data_str, false);
> >> +}
> >> +
> >> +static void hmp_physical_memory_search(Monitor *mon, const QDict *qdict)
> >> +{
> >> + int count = qdict_get_int(qdict, "count");
> >> + int format = qdict_get_int(qdict, "format");
> >> + int size = qdict_get_int(qdict, "size");
> >> + hwaddr addr = qdict_get_int(qdict, "addr");
> >> + const char *data_str = qdict_get_str(qdict, "data");
> >> +
> >> + memory_search(mon, count, format, size, addr, data_str, true);
> >> +}
> >> +
> >> static void hmp_memory_dump(Monitor *mon, const QDict *qdict)
> >> {
> >> int count = qdict_get_int(qdict, "count");
> >>
> >
> >
>
>
next prev parent reply other threads:[~2015-04-21 14:08 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-16 10:31 [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp hw.claudio
2015-03-16 10:38 ` Patchew Tool
2015-03-16 14:45 ` Eric Blake
2015-03-16 14:56 ` Claudio Fontana
2015-03-16 15:01 ` Paolo Bonzini
2015-03-16 15:54 ` Claudio Fontana
2015-03-16 15:58 ` Eric Blake
2015-03-16 16:29 ` Paolo Bonzini
2015-03-18 13:30 ` Claudio Fontana
2015-03-27 16:19 ` Claudio Fontana
2015-03-30 14:54 ` Paolo Bonzini
2015-04-20 22:01 ` Luiz Capitulino [this message]
2015-04-21 14:25 ` Claudio Fontana
2015-04-21 14:28 ` Paolo Bonzini
2015-04-21 15:12 ` Claudio Fontana
2015-04-21 14:35 ` Luiz Capitulino
2015-04-21 14:47 ` Paolo Bonzini
2015-04-23 8:56 ` Claudio Fontana
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150420180142.58856911@redhat.com \
--to=lcapitulino@redhat.com \
--cc=arei.gonglei@huawei.com \
--cc=claudio.fontana@huawei.com \
--cc=hw.claudio@gmail.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).