qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Claudio Fontana <claudio.fontana@huawei.com>
To: Luiz Capitulino <lcapitulino@redhat.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: Fri, 27 Mar 2015 17:19:30 +0100	[thread overview]
Message-ID: <55158312.9050109@huawei.com> (raw)
In-Reply-To: <55097E0A.6020808@huawei.com>

Just a respectful ping on this one..
Luiz do you think you can integrate this into the monitor?

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");
>>
> 
> 


-- 
Claudio Fontana
Server Virtualization Architect
Huawei Technologies Duesseldorf GmbH
Riesstraße 25 - 80992 München

office: +49 89 158834 4135
mobile: +49 15253060158

  reply	other threads:[~2015-03-27 16:19 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 [this message]
2015-03-30 14:54     ` Paolo Bonzini
2015-04-20 22:01     ` Luiz Capitulino
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=55158312.9050109@huawei.com \
    --to=claudio.fontana@huawei.com \
    --cc=arei.gonglei@huawei.com \
    --cc=hw.claudio@gmail.com \
    --cc=lcapitulino@redhat.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).