From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56147) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YkYr4-00071w-JY for qemu-devel@nongnu.org; Tue, 21 Apr 2015 10:08:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YkYr1-0003zt-A9 for qemu-devel@nongnu.org; Tue, 21 Apr 2015 10:08:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33877) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YkYr1-0003zp-0b for qemu-devel@nongnu.org; Tue, 21 Apr 2015 10:08:47 -0400 Date: Mon, 20 Apr 2015 18:01:42 -0400 From: Luiz Capitulino Message-ID: <20150420180142.58856911@redhat.com> In-Reply-To: <55158312.9050109@huawei.com> References: <1426501911-1402-1-git-send-email-hw.claudio@gmail.com> <55097E0A.6020808@huawei.com> <55158312.9050109@huawei.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Claudio Fontana Cc: Peter Maydell , Claudio Fontana , Gonglei , Paolo Bonzini , qemu-devel@nongnu.org On Fri, 27 Mar 2015 17:19:30 +0100 Claudio Fontana 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 =E2= =80=98memory_search=E2=80=99: /home/lcapitulino/work/src/upstream/qmp-unstable/monitor.c:1307:19: error: = =E2=80=98needle=E2=80=99 may be used uninitialized in this function [-Werro= r=3Dmaybe-uninitialized] match =3D memmem(mark, todo, needle, wsize); ^ cc1: all warnings being treated as errors >=20 > 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 advi= se about how to test that scenario? > I was trying to do some qemu under qemu self-emulation but didn't quite g= et there.. >=20 > Thanks, >=20 > Claudio >=20 > 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 gues= ts. > > Would be interesting to test this also on a big endian host with differ= ent guest combinations.. > >=20 > > Claudio > >=20 > > On 16.03.2015 11:31, hw.claudio@gmail.com wrote: > >> From: Claudio Fontana > >> > >> 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' '\x= 00' > >> 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 > >> --- > >> 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}=3D123= 4) > >> ETEXI > >> =20 > >> { > >> + .name =3D "s", > >> + .args_type =3D "fmt:/,addr:l,data:s", > >> + .params =3D "/fmt addr data", > >> + .help =3D "search virtual memory starting at 'addr' for= 'data'", > >> + .mhandler.cmd =3D hmp_memory_search, > >> + }, > >> + > >> +STEXI > >> +@item s/fmt @var{addr} @var{data} > >> +@findex s > >> +Virtual memory search starting at @var{addr} for data described by @v= ar{data}. > >> +ETEXI > >> + > >> + { > >> + .name =3D "sp", > >> + .args_type =3D "fmt:/,addr:l,data:s", > >> + .params =3D "/fmt addr data", > >> + .help =3D "search physical memory starting at 'addr' fo= r 'data'", > >> + .mhandler.cmd =3D 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 =3D "x", > >> .args_type =3D "fmt:/,addr:l", > >> .params =3D "/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, "'"); > >> } > >> =20 > >> +static void monitor_print_addr(Monitor *mon, hwaddr addr, bool is_phy= sical) > >> +{ > >> + 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 generate= d 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 ws= ize, > >> + 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 =3D 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 =3D data_str; > >> + wsize =3D 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 =3D "%" SCNo64; > >> + break; > >> + default: > >> + case 'x': > >> + format_str =3D "%" SCNx64; > >> + break; > >> + case 'u': > >> + format_str =3D "%" SCNu64; > >> + break; > >> + case 'd': > >> + format_str =3D "%" SCNd64; > >> + break; > >> + } > >> + if (format !=3D 'c') { > >> + uint64_t value; /* numeric input value */ > >> + void *from =3D &value; > >> + if (sscanf(data_str, format_str, &value) !=3D 1) { > >> + monitor_printf(mon, "could not parse search string " > >> + "\"%s\" as format '%c'.\n", data_str, form= at); > >> + return; > >> + } > >> +#if defined(HOST_WORDS_BIGENDIAN) !=3D defined(TARGET_WORDS_BIGENDIAN) > >> + value =3D bswap64(value); > >> +#endif > >> +#if defined(TARGET_WORDS_BIGENDIAN) > >> + from +=3D 8 - wsize; > >> +#endif > >> + memcpy(value_raw, from, wsize); > >> + needle =3D 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 =3D len < MONITOR_S_CHUNK_SIZE ? len : MONITOR_S_CHUNK_S= IZE; > >> + hay =3D g_malloc0(hay_size); > >> + > >> + for (pos =3D 0; pos < len;) { > >> + char *mark, *match; /* mark new starting position, eventual m= atch */ > >> + int l, todo; /* total length to be processed in curren= t chunk */ > >> + l =3D len - pos; > >> + if (l > hay_size) { > >> + l =3D hay_size; > >> + } > >> + if (is_physical) { > >> + cpu_physical_memory_read(addr, hay, l); > >> + } else if (cpu_memory_rw_debug(ENV_GET_CPU(mon_get_cpu()), ad= dr, > >> + (uint8_t *)hay, l, 0) < 0) { > >> + monitor_printf(mon, " Cannot access memory\n"); > >> + break; > >> + } > >> + for (mark =3D hay, todo =3D l; todo >=3D wsize;) { > >> + match =3D memmem(mark, todo, needle, wsize); > >> + if (!match) { > >> + break; > >> + } > >> + monitor_print_addr(mon, addr + (match - hay), is_physical= ); > >> + mark =3D match + 1; > >> + todo =3D mark - hay; > >> + } > >> + if (pos + l < len) { > >> + /* catch potential matches across chunks. */ > >> + pos +=3D l - (wsize - 1); > >> + addr +=3D l - (wsize - 1); > >> + } else { > >> + pos +=3D l; > >> + addr +=3D l; > >> + } > >> + } > >> + g_free(hay); > >> +} > >> + > >> static void memory_dump(Monitor *mon, int count, int format, int wsiz= e, > >> hwaddr addr, int is_physical) > >> { > >> @@ -1332,6 +1450,28 @@ static void memory_dump(Monitor *mon, int count= , int format, int wsize, > >> } > >> } > >> =20 > >> +static void hmp_memory_search(Monitor *mon, const QDict *qdict) > >> +{ > >> + int count =3D qdict_get_int(qdict, "count"); > >> + int format =3D qdict_get_int(qdict, "format"); > >> + int size =3D qdict_get_int(qdict, "size"); > >> + target_long addr =3D qdict_get_int(qdict, "addr"); > >> + const char *data_str =3D 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 *qdi= ct) > >> +{ > >> + int count =3D qdict_get_int(qdict, "count"); > >> + int format =3D qdict_get_int(qdict, "format"); > >> + int size =3D qdict_get_int(qdict, "size"); > >> + hwaddr addr =3D qdict_get_int(qdict, "addr"); > >> + const char *data_str =3D 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 =3D qdict_get_int(qdict, "count"); > >> > >=20 > >=20 >=20 >=20