All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
@ 2015-03-16 10:31 hw.claudio
  2015-03-16 10:38 ` Patchew Tool
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: hw.claudio @ 2015-03-16 10:31 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: Peter Maydell, Gonglei, Claudio Fontana, qemu-devel

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

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  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-18 13:30 ` Claudio Fontana
  2 siblings, 0 replies; 18+ messages in thread
From: Patchew Tool @ 2015-03-16 10:38 UTC (permalink / raw)
  To: qemu-devel


This series failed Patchew automatic testing.

Find the log fragments below (grepped lines around keywords "error" and
"warning"), or open the following URL to see the full log:

http://qemu.patchew.org/testing/log/<1426501911-1402-1-git-send-email-hw.claudio@gmail.com>

----------8<---------

  CC    qobject/qerror.o
  GEN   trace/generated-events.c
  CC    trace/control.o
  CC    trace/qmp.o
  CC    util/osdep.o
  CC    util/cutils.o
  CC    util/unicode.o
  CC    util/qemu-timer-common.o
  CC    util/oslib-posix.o
  CC    util/qemu-thread-posix.o
  CC    util/event_notifier-posix.o
  CC    util/qemu-openpty.o
  CC    util/envlist.o
  CC    util/path.o
  CC    util/module.o
  CC    util/bitmap.o
  CC    util/bitops.o
  CC    util/hbitmap.o
  CC    util/fifo8.o
  CC    util/acl.o
  CC    util/error.o
  CC    util/qemu-error.o
  CC    util/compatfd.o
  CC    util/id.o
  CC    util/iov.o
  CC    util/aes.o
  CC    util/qemu-config.o
  CC    util/qemu-sockets.o
  CC    util/uri.o
  CC    util/notify.o
  CC    util/qemu-option.o
  CC    util/qemu-progress.o
  CC    util/hexdump.o
  CC    util/crc32c.o
  CC    util/throttle.o
  CC    util/getauxval.o
  CC    util/readline.o
  CC    util/rfifolock.o
  CC    util/rcu.o
  CC    stubs/arch-query-cpu-def.o
  CC    stubs/bdrv-commit-all.o
  CC    stubs/chr-baum-init.o
  CC    stubs/chr-msmouse.o
  CC    stubs/chr-testdev.o
  CC    stubs/clock-warp.o
  CC    stubs/cpu-get-clock.o
  CC    stubs/cpu-get-icount.o
  CC    stubs/dump.o
  CC    stubs/fdset-add-fd.o
  CC    stubs/fdset-find-fd.o
  CC    stubs/fdset-get-fd.o
  CC    stubs/fdset-remove-fd.o
  CC    stubs/gdbstub.o
  CC    stubs/get-fd.o
  CC    stubs/get-next-serial.o
  CC    stubs/get-vm-name.o
  CC    stubs/iothread-lock.o
  CC    stubs/is-daemonized.o
  CC    stubs/machine-init-done.o
  CC    stubs/migr-blocker.o
  CC    stubs/mon-is-qmp.o
  CC    stubs/mon-printf.o
  CC    stubs/mon-set-error.o
  CC    stubs/monitor-init.o
  CC    stubs/notify-event.o
  CC    stubs/qtest.o
  CC    stubs/reset.o
  CC    stubs/runstate-check.o
  CC    stubs/set-fd-handler.o
  CC    stubs/slirp.o
  CC    stubs/sysbus.o
  CC    stubs/uuid.o
  CC    stubs/vc-init.o
  CC    stubs/vm-stop.o
  CC    stubs/vmstate.o
  CC    stubs/cpus.o
  CC    stubs/kvm.o
  CC    stubs/qmp_pc_dimm_device_list.o
  CC    qemu-nbd.o
  CC    async.o
  CC    thread-pool.o
  CC    nbd.o
  CC    block.o
--
  GEN   x86_64-softmmu/hmp-commands.h
  GEN   x86_64-softmmu/qmp-commands-old.h
  GEN   x86_64-softmmu/config-target.h
  CC    x86_64-softmmu/exec.o
  CC    x86_64-softmmu/translate-all.o
  CC    x86_64-softmmu/cpu-exec.o
  CC    x86_64-softmmu/tcg/tcg.o
  CC    x86_64-softmmu/tcg/tcg-op.o
  CC    x86_64-softmmu/tcg/optimize.o
  CC    x86_64-softmmu/fpu/softfloat.o
  CC    x86_64-softmmu/disas.o
  CC    x86_64-softmmu/arch_init.o
  CC    x86_64-softmmu/cpus.o
  CC    x86_64-softmmu/monitor.o
  CC    x86_64-softmmu/gdbstub.o
  CC    x86_64-softmmu/balloon.o
  CC    x86_64-softmmu/ioport.o
  CC    x86_64-softmmu/numa.o
  CC    x86_64-softmmu/qtest.o
/var/tmp/patchew-test/git/monitor.c: In function 'memory_search':
/var/tmp/patchew-test/git/monitor.c:1309: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
make[1]: *** [monitor.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [subdir-x86_64-softmmu] Error 2

Test failed.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  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-18 13:30 ` Claudio Fontana
  2 siblings, 2 replies; 18+ messages in thread
From: Eric Blake @ 2015-03-16 14:45 UTC (permalink / raw)
  To: hw.claudio, Luiz Capitulino
  Cc: Peter Maydell, Gonglei, Claudio Fontana, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1446 bytes --]

On 03/16/2015 04:31 AM, 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.

Do you want to provide a QMP counterpart?  In general, we are reluctant
to add new HMP functionality that cannot also be accessed via QMP.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-03-16 14:45 ` Eric Blake
@ 2015-03-16 14:56   ` Claudio Fontana
  2015-03-16 15:01   ` Paolo Bonzini
  1 sibling, 0 replies; 18+ messages in thread
From: Claudio Fontana @ 2015-03-16 14:56 UTC (permalink / raw)
  To: Eric Blake
  Cc: Peter Maydell, Gonglei, Claudio Fontana, QEMU Developers,
	Luiz Capitulino

On 16 March 2015 at 15:45, Eric Blake <eblake@redhat.com> wrote:
> On 03/16/2015 04:31 AM, 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.
>
> Do you want to provide a QMP counterpart?  In general, we are reluctant
> to add new HMP functionality that cannot also be accessed via QMP.
>

Sure, I'll take a look at qmp integration as well.

Ciao,

Claudio

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  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
  1 sibling, 1 reply; 18+ messages in thread
From: Paolo Bonzini @ 2015-03-16 15:01 UTC (permalink / raw)
  To: Eric Blake, hw.claudio, Luiz Capitulino
  Cc: Peter Maydell, Gonglei, Claudio Fontana, qemu-devel



On 16/03/2015 15:45, Eric Blake wrote:
> On 03/16/2015 04:31 AM, 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.
> 
> Do you want to provide a QMP counterpart?  In general, we are
> reluctant to add new HMP functionality that cannot also be accessed
> via QMP.

I think this is okay for a debugging command.  x and xp do not have an
QMP equivalent either.

Paolo

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-03-16 15:01   ` Paolo Bonzini
@ 2015-03-16 15:54     ` Claudio Fontana
  2015-03-16 15:58       ` Eric Blake
  0 siblings, 1 reply; 18+ messages in thread
From: Claudio Fontana @ 2015-03-16 15:54 UTC (permalink / raw)
  To: Paolo Bonzini, Eric Blake, hw.claudio, Luiz Capitulino
  Cc: Peter Maydell, Gonglei, qemu-devel

On 16.03.2015 16:01, Paolo Bonzini wrote:
> 
> 
> On 16/03/2015 15:45, Eric Blake wrote:
>> On 03/16/2015 04:31 AM, 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.
>>
>> Do you want to provide a QMP counterpart?  In general, we are
>> reluctant to add new HMP functionality that cannot also be accessed
>> via QMP.
> 
> I think this is okay for a debugging command.  x and xp do not have an
> QMP equivalent either.
> 
> Paolo
> 

Just let me know if necessary (personally I would not have a use for a QMP counterpart).

Thanks,

Claudio


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

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-03-16 15:54     ` Claudio Fontana
@ 2015-03-16 15:58       ` Eric Blake
  2015-03-16 16:29         ` Paolo Bonzini
  0 siblings, 1 reply; 18+ messages in thread
From: Eric Blake @ 2015-03-16 15:58 UTC (permalink / raw)
  To: Claudio Fontana, Paolo Bonzini, hw.claudio, Luiz Capitulino
  Cc: Peter Maydell, Gonglei, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 820 bytes --]

On 03/16/2015 09:54 AM, Claudio Fontana wrote:

>>> Do you want to provide a QMP counterpart?  In general, we are
>>> reluctant to add new HMP functionality that cannot also be accessed
>>> via QMP.
>>
>> I think this is okay for a debugging command.  x and xp do not have an
>> QMP equivalent either.
>>
>> Paolo
>>
> 
> Just let me know if necessary (personally I would not have a use for a QMP counterpart).

Is this something you would ever want to drive via libvirt?  Or is it a
low-level debugging command, only ever likely to be used by a qemu
developer?  If the latter, then I'm okay if this is one of the
exceptions to the rule where we don't need to bother with a QMP counterpart.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-03-16 15:58       ` Eric Blake
@ 2015-03-16 16:29         ` Paolo Bonzini
  0 siblings, 0 replies; 18+ messages in thread
From: Paolo Bonzini @ 2015-03-16 16:29 UTC (permalink / raw)
  To: Eric Blake, Claudio Fontana, hw.claudio, Luiz Capitulino
  Cc: Peter Maydell, Gonglei, qemu-devel



On 16/03/2015 16:58, Eric Blake wrote:
> On 03/16/2015 09:54 AM, Claudio Fontana wrote:
> 
>>>> Do you want to provide a QMP counterpart?  In general, we
>>>> are reluctant to add new HMP functionality that cannot also
>>>> be accessed via QMP.
>>> 
>>> I think this is okay for a debugging command.  x and xp do not
>>> have an QMP equivalent either.
>>> 
>>> Paolo
>>> 
>> 
>> Just let me know if necessary (personally I would not have a use
>> for a QMP counterpart).
> 
> Is this something you would ever want to drive via libvirt?  Or is
> it a low-level debugging command, only ever likely to be used by a
> qemu developer?  If the latter, then I'm okay if this is one of
> the exceptions to the rule where we don't need to bother with a QMP
> counterpart.

It's definitely the latter.

Paolo

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  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-18 13:30 ` Claudio Fontana
  2015-03-27 16:19   ` Claudio Fontana
  2 siblings, 1 reply; 18+ messages in thread
From: Claudio Fontana @ 2015-03-18 13:30 UTC (permalink / raw)
  To: hw.claudio, Luiz Capitulino
  Cc: Peter Maydell, Gonglei, qemu-devel, Paolo Bonzini

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  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
  0 siblings, 2 replies; 18+ messages in thread
From: Claudio Fontana @ 2015-03-27 16:19 UTC (permalink / raw)
  To: Luiz Capitulino
  Cc: Peter Maydell, Claudio Fontana, Gonglei, Paolo Bonzini, qemu-devel

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-03-27 16:19   ` Claudio Fontana
@ 2015-03-30 14:54     ` Paolo Bonzini
  2015-04-20 22:01     ` Luiz Capitulino
  1 sibling, 0 replies; 18+ messages in thread
From: Paolo Bonzini @ 2015-03-30 14:54 UTC (permalink / raw)
  To: Claudio Fontana, qemu-devel



On 27/03/2015 17:19, Claudio Fontana wrote:
> 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..

Hi, I just suspect people are busy with 2.3.

Paolo

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-03-27 16:19   ` Claudio Fontana
  2015-03-30 14:54     ` Paolo Bonzini
@ 2015-04-20 22:01     ` Luiz Capitulino
  2015-04-21 14:25       ` Claudio Fontana
  1 sibling, 1 reply; 18+ messages in thread
From: Luiz Capitulino @ 2015-04-20 22:01 UTC (permalink / raw)
  To: Claudio Fontana
  Cc: Peter Maydell, Claudio Fontana, Gonglei, Paolo Bonzini, qemu-devel

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-04-20 22:01     ` Luiz Capitulino
@ 2015-04-21 14:25       ` Claudio Fontana
  2015-04-21 14:28         ` Paolo Bonzini
  2015-04-21 14:35         ` Luiz Capitulino
  0 siblings, 2 replies; 18+ messages in thread
From: Claudio Fontana @ 2015-04-21 14:25 UTC (permalink / raw)
  To: Luiz Capitulino
  Cc: Peter Maydell, Claudio Fontana, Gonglei, Paolo Bonzini, qemu-devel

Hello Luiz,

On 21.04.2015 00:01, Luiz Capitulino wrote:
> 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,

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.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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  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
  1 sibling, 1 reply; 18+ messages in thread
From: Paolo Bonzini @ 2015-04-21 14:28 UTC (permalink / raw)
  To: Claudio Fontana, Luiz Capitulino
  Cc: Peter Maydell, Claudio Fontana, Gonglei, qemu-devel



On 21/04/2015 16:25, Claudio Fontana wrote:
> 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)

I would just add a NULL initializer.

Paolo

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-04-21 14:25       ` Claudio Fontana
  2015-04-21 14:28         ` Paolo Bonzini
@ 2015-04-21 14:35         ` Luiz Capitulino
  2015-04-21 14:47           ` Paolo Bonzini
  1 sibling, 1 reply; 18+ messages in thread
From: Luiz Capitulino @ 2015-04-21 14:35 UTC (permalink / raw)
  To: Claudio Fontana
  Cc: Peter Maydell, Claudio Fontana, Gonglei, Paolo Bonzini, qemu-devel

On Tue, 21 Apr 2015 16:25:12 +0200
Claudio Fontana <claudio.fontana@huawei.com> wrote:

> Hello Luiz,
> 
> On 21.04.2015 00:01, Luiz Capitulino wrote:
> > 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,
> 
> gladly, I am definitely looking for Review, first I wanted to check if the idea itself was acceptable.

I honestly don't have an opinion on this, which means I'm willing
to apply if there are no objections.

On the other hand, isn't it possible to just use existing commands?
Like, why can't you just dump this memory to disk and search it
with strings or another tool?

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-04-21 14:35         ` Luiz Capitulino
@ 2015-04-21 14:47           ` Paolo Bonzini
  2015-04-23  8:56             ` Claudio Fontana
  0 siblings, 1 reply; 18+ messages in thread
From: Paolo Bonzini @ 2015-04-21 14:47 UTC (permalink / raw)
  To: Luiz Capitulino, Claudio Fontana
  Cc: Peter Maydell, Claudio Fontana, Gonglei, qemu-devel



On 21/04/2015 16:35, Luiz Capitulino wrote:
> > gladly, I am definitely looking for Review, first I wanted to check if the idea itself was acceptable.
> 
> I honestly don't have an opinion on this, which means I'm willing
> to apply if there are no objections.
> 
> On the other hand, isn't it possible to just use existing commands?
> Like, why can't you just dump this memory to disk and search it
> with strings or another tool?

I don't think that can be a serious alternative.  The same would apply
to x and xp, but still, they are incredibly useful.  Now I must say I
don't know of a use case for s or sp, but I don't think what you
suggested is feasible.

Paolo

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-04-21 14:28         ` Paolo Bonzini
@ 2015-04-21 15:12           ` Claudio Fontana
  0 siblings, 0 replies; 18+ messages in thread
From: Claudio Fontana @ 2015-04-21 15:12 UTC (permalink / raw)
  To: Paolo Bonzini, Luiz Capitulino
  Cc: Peter Maydell, Claudio Fontana, Gonglei, qemu-devel

On 21.04.2015 16:28, Paolo Bonzini wrote:
> 
> 
> On 21/04/2015 16:25, Claudio Fontana wrote:
>> 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)
> 
> I would just add a NULL initializer.
> 
> Paolo
> 

Absolutely, yes, I thought about that and just be done with it.

I wonder if that's the right compiler behavior though;
is it acceptable that the compiler cannot figure out that needle is always initialized before use when you have

switch (format) {
case 'c':
    needle = SOMETHING;
...
}

if (format != 'c') {
    needle = SOMETHING_ELSE;
}

actually_use(needle);

?


Ciao,

Claudio

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [RFC v3] monitor: add memory search commands s, sp
  2015-04-21 14:47           ` Paolo Bonzini
@ 2015-04-23  8:56             ` Claudio Fontana
  0 siblings, 0 replies; 18+ messages in thread
From: Claudio Fontana @ 2015-04-23  8:56 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Peter Maydell, Gonglei, Claudio Fontana, QEMU Developers,
	Luiz Capitulino

On 21 April 2015 at 16:47, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 21/04/2015 16:35, Luiz Capitulino wrote:
>> > gladly, I am definitely looking for Review, first I wanted to check if the idea itself was acceptable.
>>
>> I honestly don't have an opinion on this, which means I'm willing
>> to apply if there are no objections.
>>
>> On the other hand, isn't it possible to just use existing commands?
>> Like, why can't you just dump this memory to disk and search it
>> with strings or another tool?
>
> I don't think that can be a serious alternative.  The same would apply
> to x and xp, but still, they are incredibly useful.  Now I must say I
> don't know of a use case for s or sp, but I don't think what you
> suggested is feasible.
>
> Paolo

I must admit that the use case is a bit overlapping with gdb's
find-in-memory feature
(does it work with qemu's gdbserver?) which I however never use
because I tend to do everything from qemu.

The same could be said for the x and xp commands though, and in that
regard I think s and sp are a natural complement to them.

I have been using s and sp when dealing with code whose runtime
behavior is difficult to follow, to verify that the results of a
complex operation ended up at the right address.

For example, to find out where an ELF header landed in memory, and
verify that the loading address is correct,
looking for the TLS thread control block data structures, and so on.

If this is acceptable I will resubmit with a NULL initialization to
get rid of that spurious warning.

Thanks,

Claudio

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2015-04-23  8:56 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.