我打算使用Qemu为执行x86客户机操作系统生成内存跟踪。
根据tcg wiki页面,Qemu使用少量帮助程序为目标(访客)内存生成加载/存储。
此说明列表为tcg_gen_qemu_ld8s/u
,tcg_gen_qemu_ld16s/u
,tcg_gen_qemu_ld32s/u
,tcg_gen_qemu_ld64
。 (我们对商店说明有类似的设置)。
我在 target-i386 / translate.c 文件中捕获对上述函数的所有调用
但是,我仍然缺少某些指令的加载/存储,例如
cmp ecx, [r12+0x4]
mov r10b, [r13+0x0]
mov byte [rax+0xf0000], 0x0
mov byte [rax+rdx], 0x0
问题:
guest_read()
),可以检测来自来宾内存的所有负载??? 对于前一封邮件中的误导性说明,朋友们抱歉。
cmp ecx, [r12+0x4]
mov r10b, [r13+0x0]
mov byte [rax+0xf0000], 0x0
mov byte [rax+rdx], 0x0
似乎所有上述说明都被tcg_gen_ld/st
助手所覆盖。
但现在我偶然发现了另一个问题:
我最初认为与guest虚拟机内存的所有交互都是通过translate.c文件中的帮助程序指令进行的。
但是,我发现像cmpxcgh8b
和cmpxchg16b
这样的指令的辅助函数实际上正在访问来宾内存。
那么,这是否意味着有多个入口点用于读取访客内存。
有人可以解释一下如何翻译ldq和stq指令来访问来宾内存?
答案 0 :(得分:3)
加载数据的其他函数称为cpu_ld*_data
和cpu_st*_data
,或cpu_ld*_data_ra
和cpu_st*_data_ra
。 _ra
版本有一个附加参数,它是生成的代码中调用者的地址。如果加载或存储生成页面错误,它用于计算错误指令的地址。
例如,grepping cmpxchg8b
会给出
target/i386/mem_helper.c:void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
并在该函数内:
uintptr_t ra = GETPC();
...
oldv = cpu_ldq_data_ra(env, a0, ra);
newv = (cmpv == oldv ? newv : oldv);
/* always do the store */
cpu_stq_data_ra(env, a0, newv, ra);