Patchwork qemu log function to print out the registers of the guest

login
register
mail settings
Submitter Max Filippov
Date Aug. 16, 2012, 9:18 p.m.
Message ID <CAMo8Bf+xZF41UYs=LUHs_ufqOHwJ6utrj7KTjLcKY5Eje6eDVA@mail.gmail.com>
Download mbox | patch
Permalink /patch/178098/
State New
Headers show

Comments

Max Filippov - Aug. 16, 2012, 9:18 p.m.
On Thu, Aug 16, 2012 at 10:31 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
> On Thu, Aug 16, 2012 at 9:49 PM, Steven <wangwangkang@gmail.com> wrote:
>> On Thu, Aug 16, 2012 at 1:43 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
>>> On Thu, Aug 16, 2012 at 9:37 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
>>>> On Thu, Aug 16, 2012 at 9:29 PM, Steven <wangwangkang@gmail.com> wrote:
>>>>> On Thu, Aug 16, 2012 at 1:00 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
>>>>>> On Thu, Aug 16, 2012 at 8:36 PM, Steven <wangwangkang@gmail.com> wrote:
>>>>>>> On Thu, Aug 16, 2012 at 4:02 AM, 陳韋任 (Wei-Ren Chen)
>>>>>>> <chenwj@iis.sinica.edu.tw> wrote:
>>>>>>>>> I would like to is there any function that could log the register
>>>>>>>>> content of the guest machine, like "info registers" in the qemu
>>>>>>>>> monitor mode.
>>>>>>>>
>>>>>>>>   Why not check how "info registes" be implemented in QEMU? ;)
>>>>>>>> I guess you just have to log env->regs or something like that.
>>>>>>> Thanks for pointing this out.
>>>>>>> I would like to get a trace of guest memory access. So I can not use
>>>>>>> "info registers".
>>>>>>> What I want to do is that when tcg fetches a load instruction at
>>>>>>> disas_insns(), the guest memory address should be calculated. For
>>>>>>
>>>>>> No, you don't want this, because the same translated code may be
>>>>>> invoked multiple times with different values in registers.
>>>>>>
>>>>>>> example, the tb has an instruction of mov 0x4(%ebx)  %eax.
>>>>>>> To calculate the address of 0x4(%ebx), I need to know the value of %ebx.
>>>>>>> Is this correct? Thanks.
>>>>>>
>>>>>> Why don't you just instrument actual memory access functions in
>>>>>> softmmu_template.h ?
>>>>> But this code only touches the s->pc. For registers in the load
>>>>> instruction, it won't generate the memory access code. So I need to
>>>>> add code to some function to get the guest memory address access.
>>>>
>>>> Take a close look at
>>>>
>>>> DATA_TYPE
>>>> glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
>>>>                                                        target_ulong addr,
>>>>                                                        int mmu_idx)
>>>>
>>>> and
>>>>
>>>> void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
>>>>                                                             target_ulong addr,
>>>>                                                             DATA_TYPE val,
>>>>                                                             int mmu_idx)
>>>>
>>>> At runtime they get addr, this is the virtual address of the memory access.
>>>> This file is included several times to instantiate these functions for
>>>> different memory access types.
>>>> A set of macros manipulates access size and whether it is code or data access.
>>>
>>> But maybe I got you wrong and by
>>>
>>>   What I want to do is that when tcg fetches a load instruction at
>>>   disas_insns(), the guest memory address should be calculated.
>>>
>>> you meant that you need to record code address that made an access,
>>> not the accessed data address?
>>>
>> I want to get the guest memory address in the instruction mov
>> 0x4(%ebx)  %eax, whic is 0x4(%ebx).
>> Since %ebx is not resolved until the execution time, the code in
>> softmmu_header.h does not generate any hit or miss information.
>> Do you know any place that I could resolve the memory access address? Thanks.
>
> I see that with the following patch
>
> diff --git a/softmmu_template.h b/softmmu_template.h
> index b8bd700..2d02133 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -114,6 +114,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
> MMUSUFFIX)(ENV_PARAM
>      target_phys_addr_t ioaddr;
>      uintptr_t retaddr;
>
> +    fprintf(stderr, "%s: %08x\n", __func__, addr);
>      /* test if there is match for unaligned or IO access */
>      /* XXX: could done more in memory macro in a non portable way */
>      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
>
> I get some memory accesses logged, but not all. That's due to fast
> path in tcg_out_qemu_ld
> in case there's TLB hit. I guess you can play with tcg_out_qemu_ld and
> make it produce a call
> to a helper function, like qemu_ld_helpers, that will print addresses
> for all memory access
> attempts.

Easier solution would be to disable fast path and always go through
softmmu helpers, like this (specific for x86 host):
Steven - Aug. 17, 2012, 5:38 a.m.
Hi, Max,
I appreciate your help and got some results using your patch. But I
still have two questions as blow.

>> I see that with the following patch
>>
>> diff --git a/softmmu_template.h b/softmmu_template.h
>> index b8bd700..2d02133 100644
>> --- a/softmmu_template.h
>> +++ b/softmmu_template.h
>> @@ -114,6 +114,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
>> MMUSUFFIX)(ENV_PARAM
>>      target_phys_addr_t ioaddr;
>>      uintptr_t retaddr;
>>
>> +    fprintf(stderr, "%s: %08x\n", __func__, addr);
>>      /* test if there is match for unaligned or IO access */
>>      /* XXX: could done more in memory macro in a non portable way */
>>      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
>>
>> I get some memory accesses logged, but not all. That's due to fast
>> path in tcg_out_qemu_ld
>> in case there's TLB hit. I guess you can play with tcg_out_qemu_ld and
>> make it produce a call
>> to a helper function, like qemu_ld_helpers, that will print addresses
>> for all memory access
>> attempts.
>
> Easier solution would be to disable fast path and always go through
> softmmu helpers, like this (specific for x86 host):
>
> diff --git a/softmmu_template.h b/softmmu_template.h
> index b8bd700..2d02133 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -114,6 +114,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
> MMUSUFFIX)(ENV_PARAM
>      target_phys_addr_t ioaddr;
>      uintptr_t retaddr;
>
> +    fprintf(stderr, "%s: %08x\n", __func__, addr);
>      /* test if there is match for unaligned or IO access */
>      /* XXX: could done more in memory macro in a non portable way */
>      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
> diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
> index da17bba..ec68c19 100644
> --- a/tcg/i386/tcg-target.c
> +++ b/tcg/i386/tcg-target.c
> @@ -1062,7 +1062,7 @@ static inline void tcg_out_tlb_load(TCGContext
> *s, int addrlo_idx,
>      tcg_out_mov(s, type, r0, addrlo);
>
>      /* jne label1 */
> -    tcg_out8(s, OPC_JCC_short + JCC_JNE);
> +    tcg_out8(s, OPC_JMP_short);
>      label_ptr[0] = s->code_ptr;
>      s->code_ptr++;
>

IN:
0x00000000c13e3a33:  mov    0x8(%ebp),%ebx (guest code in the tb)
__ldl_mmu: c13a9fdc

So 0xc13a9fdc is the guest virtual memory address of 0x8(%ebp). Is this correct?

IN:
0x00000000c13e3a36:  mov    %eax,-0x10(%ebp)
However, for this instruction, no ldl_mmu is logged.
Does that mean the patch you provided does not cover this case?
Thanks.

>
> --
> Thanks.
> -- Max

Patch

diff --git a/softmmu_template.h b/softmmu_template.h
index b8bd700..2d02133 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -114,6 +114,7 @@  glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
MMUSUFFIX)(ENV_PARAM
     target_phys_addr_t ioaddr;
     uintptr_t retaddr;

+    fprintf(stderr, "%s: %08x\n", __func__, addr);
     /* test if there is match for unaligned or IO access */
     /* XXX: could done more in memory macro in a non portable way */
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index da17bba..ec68c19 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1062,7 +1062,7 @@  static inline void tcg_out_tlb_load(TCGContext
*s, int addrlo_idx,
     tcg_out_mov(s, type, r0, addrlo);

     /* jne label1 */
-    tcg_out8(s, OPC_JCC_short + JCC_JNE);
+    tcg_out8(s, OPC_JMP_short);
     label_ptr[0] = s->code_ptr;
     s->code_ptr++;