Hello Luiz, On 21.04.2015 00:01, Luiz Capitulino wrote: > On Fri, 27 Mar 2015 17:19:30 +0100 > Claudio Fontana <claudio.font...@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,
gladly, I am definitely looking for Review, first I wanted to check if the idea itself was acceptable. > 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 right, this has been pointed out to me before also, I tried to move things around but that did not help apparently. I seem not to get this warning with the compiler version I am currently using, and after checking the code I could not find out why with some compilers would emit such a warning. It is difficult for me to debug this issue since I do not get this.. I am using a slightly older compiler from Linaro for AArch64 (4.8.3 based) Thanks, Claudio > >> >> 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.clau...@gmail.com wrote: >>>> From: Claudio Fontana <claudio.font...@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.font...@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"); >>>> >>> >>> >> >> > -- Claudio Fontana Server Virtualization Architect Huawei Technologies Duesseldorf GmbH Riesstraße 25 - 80992 München office: +49 89 158834 4135 mobile: +49 15253060158