QEMU-代码流[指令缓存和TCG]

QEMU-代码流[指令缓存和TCG],qemu,Qemu,我试图分析QEMU的源代码 我知道它很大,到目前为止还没有官方文件 我主要关注的领域是指令缓存管理和TCG操作 任何指向它们的指针都会有帮助吗?我知道完整的答案要长得多,但对于start,我只想让您注意这个图表:(现在,您可以使用运行QEMU的gdb,在图表中看到的函数中设置断点,跟踪代码执行等。) 是的,QEMU代码流发生了很大的变化。我不打算做libreoffice演示,但这里有几个QEMU 5.1 MTTCG代码的TCG堆栈跟踪。第一种是TCG前端(FE),它获取来宾代码并将其转换为翻译块

我试图分析QEMU的源代码

我知道它很大,到目前为止还没有官方文件

我主要关注的领域是指令缓存管理和TCG操作


任何指向它们的指针都会有帮助吗?

我知道完整的答案要长得多,但对于start,我只想让您注意这个图表:(现在,您可以使用运行QEMU的gdb,在图表中看到的函数中设置断点,跟踪代码执行等。)


是的,QEMU代码流发生了很大的变化。我不打算做libreoffice演示,但这里有几个QEMU 5.1 MTTCG代码的TCG堆栈跟踪。第一种是TCG前端(FE),它获取来宾代码并将其转换为翻译块(TB)中的内部中间代码。TB的最大大小为512条指令

#0  0x00005555559ce81f in disas_insn (s=0x7fffe933d450, cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/target/i386/translate.c:4476
#1  0x00005555559dd471 in i386_tr_translate_insn (dcbase=0x7fffe933d450, cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/target/i386/translate.c:8569
#2  0x00005555558c4222 in translator_loop (ops=0x5555565ae9a0 <i386_tr_ops>, db=0x7fffe933d450, cpu=0x555556b2d990, tb=0x7fffac099900 <code_gen_buffer+134846675>, max_insns=512) at /opt/distros/qemu-5.1.0/accel/tcg/translator.c:102
#3  0x00005555559dd643 in gen_intermediate_code (cpu=0x555556b2d990, tb=0x7fffac099900 <code_gen_buffer+134846675>, max_insns=512) at /opt/distros/qemu-5.1.0/target/i386/translate.c:8631
#4  0x00005555558c2258 in tb_gen_code (cpu=0x555556b2d990, pc=18446744071591428680, cs_base=0, flags=4244144, cflags=-16252928) at /opt/distros/qemu-5.1.0/accel/tcg/translate-all.c:1743
#5  0x00005555558be77a in tb_find (cpu=0x555556b2d990, last_tb=0x0, tb_exit=0, cf_mask=524288) at /opt/distros/qemu-5.1.0/accel/tcg/cpu-exec.c:407
#6  0x00005555558bf18e in cpu_exec (cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/accel/tcg/cpu-exec.c:748
#7  0x00005555559846eb in tcg_cpu_exec (cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/softmmu/cpus.c:1356
#8  0x0000555555984f41 in qemu_tcg_cpu_thread_fn (arg=0x555556b2d990) at /opt/distros/qemu-5.1.0/softmmu/cpus.c:1664
#9  0x0000555555e5ec8d in qemu_thread_start (args=0x555556b5e0e0) at /opt/distros/qemu-5.1.0/util/qemu-thread-posix.c:521
#10 0x00007ffff3c406db in start_thread (arg=0x7fffe933e700) at pthread_create.c:463
#11 0x00007ffff396971f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Thread 3 "qemu-system-x86" hit Breakpoint 9, tcg_out_op (s=0x7ffe9c000b20, opc=INDEX_op_ld_i32, args=0x7fffe933d530, const_args=0x7fffe933d4f0) at /opt/distros/qemu-5.1.0/tcg/i386/tcg-target.inc.c:2259
2259        int c, const_a2, vexop, rexw = 0;
#0  0x00005555558447d2 in tcg_out_op (s=0x7ffe9c000b20, opc=INDEX_op_ld_i32, args=0x7fffe933d530, const_args=0x7fffe933d4f0) at /opt/distros/qemu-5.1.0/tcg/i386/tcg-target.inc.c:2259
#1  0x000055555584fb40 in tcg_reg_alloc_op (s=0x7ffe9c000b20, op=0x7ffe9c00a418) at /opt/distros/qemu-5.1.0/tcg/tcg.c:3803
#2  0x000055555585078e in tcg_gen_code (s=0x7ffe9c000b20, tb=0x7fffac129880 <code_gen_buffer+135436371>) at /opt/distros/qemu-5.1.0/tcg/tcg.c:4244
#3  0x00005555558c22f1 in tb_gen_code (cpu=0x555556b2d990, pc=94290869746347, cs_base=0, flags=4244147, cflags=-16252928) at /opt/distros/qemu-5.1.0/accel/tcg/translate-all.c:1766
#4  0x00005555558be77a in tb_find (cpu=0x555556b2d990, last_tb=0x7fffac0ea700 <code_gen_buffer+135177939>, tb_exit=1, cf_mask=524288) at /opt/distros/qemu-5.1.0/accel/tcg/cpu-exec.c:407
#5  0x00005555558bf18e in cpu_exec (cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/accel/tcg/cpu-exec.c:748
#6  0x00005555559846eb in tcg_cpu_exec (cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/softmmu/cpus.c:1356
#7  0x0000555555984f41 in qemu_tcg_cpu_thread_fn (arg=0x555556b2d990) at /opt/distros/qemu-5.1.0/softmmu/cpus.c:1664
#8  0x0000555555e5ec8d in qemu_thread_start (args=0x555556b5e0e0) at /opt/distros/qemu-5.1.0/util/qemu-thread-posix.c:521
#9  0x00007ffff3c406db in start_thread (arg=0x7fffe933e700) at pthread_create.c:463
#10 0x00007ffff396971f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
#0 0x0000555559CE81F位于/opt/distros/qemu-5.1.0/target/i386/translate.c:4476的disas insn(s=0x7fffe933d450,cpu=0x5556B2D990)中
#1 0x0000555559DD471位于/opt/distros/qemu-5.1.0/target/i386/translate.c:8569
#在/opt/distros/qemu-5.1.0/accel/tcg/translator.c:102处,转换器循环(ops=0x5555565ae9a0,db=0x7fffe933d450,cpu=0x5556B2D990,tb=0x7FFFAC09900,max_insns=512)中有2个0x0000555555555558C4222
#gen_中间代码(cpu=0x5556B2D990,tb=0x7FFFAC09900,max_insns=512)中的3 0x0000555559DD643位于/opt/distros/qemu-5.1.0/target/i386/translate.c:8631
#4 tb_gen_代码中的0x000055555558C2258(cpu=0x5556B2D990,pc=18446744071591428680,cs_base=0,flags=4244144,cflags=-16252928)位于/opt/distros/qemu-5.1.0/accel/tcg/translate all.c:1743
#在/opt/distros/qemu-5.1.0/accel/tcg/cpu exec.c:407处的tb_find(cpu=0x5556B2D990,last_tb=0x0,tb_exit=0,cf_mask=524288)中的5 0x00005555555558BE77A
#6在/opt/distros/qemu-5.1.0/accel/tcg/cpu exec.c:748处的cpu_exec(cpu=0x5556B2D990)中的0x0000555558BF18E
#7在/opt/distros/qemu-5.1.0/softmmu/cpu处的tcg_cpu_exec(cpu=0x5556B2D990)中的0x0000555559846EB。c:1356
#8 0x000055555984F41位于/opt/distros/qemu-5.1.0/softmmu/cpu.c:1664
#9在/opt/distros/qemu-5.1.0/util/qemu-thread posix.c:521处的qemu线程启动(args=0x5556b5e0e0)中的0x00005555555e5ec8d
#在pthread_create的start_线程(arg=0x7fffe933e700)中有10 0x00007ffff3c406db。c:463
#位于../sysdeps/unix/sysv/linux/x86_64/clone.S:95的clone()中的11 0x00007ff396971f
第二个是TCG后端(BE),它将中间代码转换为主机指令

#0  0x00005555559ce81f in disas_insn (s=0x7fffe933d450, cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/target/i386/translate.c:4476
#1  0x00005555559dd471 in i386_tr_translate_insn (dcbase=0x7fffe933d450, cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/target/i386/translate.c:8569
#2  0x00005555558c4222 in translator_loop (ops=0x5555565ae9a0 <i386_tr_ops>, db=0x7fffe933d450, cpu=0x555556b2d990, tb=0x7fffac099900 <code_gen_buffer+134846675>, max_insns=512) at /opt/distros/qemu-5.1.0/accel/tcg/translator.c:102
#3  0x00005555559dd643 in gen_intermediate_code (cpu=0x555556b2d990, tb=0x7fffac099900 <code_gen_buffer+134846675>, max_insns=512) at /opt/distros/qemu-5.1.0/target/i386/translate.c:8631
#4  0x00005555558c2258 in tb_gen_code (cpu=0x555556b2d990, pc=18446744071591428680, cs_base=0, flags=4244144, cflags=-16252928) at /opt/distros/qemu-5.1.0/accel/tcg/translate-all.c:1743
#5  0x00005555558be77a in tb_find (cpu=0x555556b2d990, last_tb=0x0, tb_exit=0, cf_mask=524288) at /opt/distros/qemu-5.1.0/accel/tcg/cpu-exec.c:407
#6  0x00005555558bf18e in cpu_exec (cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/accel/tcg/cpu-exec.c:748
#7  0x00005555559846eb in tcg_cpu_exec (cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/softmmu/cpus.c:1356
#8  0x0000555555984f41 in qemu_tcg_cpu_thread_fn (arg=0x555556b2d990) at /opt/distros/qemu-5.1.0/softmmu/cpus.c:1664
#9  0x0000555555e5ec8d in qemu_thread_start (args=0x555556b5e0e0) at /opt/distros/qemu-5.1.0/util/qemu-thread-posix.c:521
#10 0x00007ffff3c406db in start_thread (arg=0x7fffe933e700) at pthread_create.c:463
#11 0x00007ffff396971f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Thread 3 "qemu-system-x86" hit Breakpoint 9, tcg_out_op (s=0x7ffe9c000b20, opc=INDEX_op_ld_i32, args=0x7fffe933d530, const_args=0x7fffe933d4f0) at /opt/distros/qemu-5.1.0/tcg/i386/tcg-target.inc.c:2259
2259        int c, const_a2, vexop, rexw = 0;
#0  0x00005555558447d2 in tcg_out_op (s=0x7ffe9c000b20, opc=INDEX_op_ld_i32, args=0x7fffe933d530, const_args=0x7fffe933d4f0) at /opt/distros/qemu-5.1.0/tcg/i386/tcg-target.inc.c:2259
#1  0x000055555584fb40 in tcg_reg_alloc_op (s=0x7ffe9c000b20, op=0x7ffe9c00a418) at /opt/distros/qemu-5.1.0/tcg/tcg.c:3803
#2  0x000055555585078e in tcg_gen_code (s=0x7ffe9c000b20, tb=0x7fffac129880 <code_gen_buffer+135436371>) at /opt/distros/qemu-5.1.0/tcg/tcg.c:4244
#3  0x00005555558c22f1 in tb_gen_code (cpu=0x555556b2d990, pc=94290869746347, cs_base=0, flags=4244147, cflags=-16252928) at /opt/distros/qemu-5.1.0/accel/tcg/translate-all.c:1766
#4  0x00005555558be77a in tb_find (cpu=0x555556b2d990, last_tb=0x7fffac0ea700 <code_gen_buffer+135177939>, tb_exit=1, cf_mask=524288) at /opt/distros/qemu-5.1.0/accel/tcg/cpu-exec.c:407
#5  0x00005555558bf18e in cpu_exec (cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/accel/tcg/cpu-exec.c:748
#6  0x00005555559846eb in tcg_cpu_exec (cpu=0x555556b2d990) at /opt/distros/qemu-5.1.0/softmmu/cpus.c:1356
#7  0x0000555555984f41 in qemu_tcg_cpu_thread_fn (arg=0x555556b2d990) at /opt/distros/qemu-5.1.0/softmmu/cpus.c:1664
#8  0x0000555555e5ec8d in qemu_thread_start (args=0x555556b5e0e0) at /opt/distros/qemu-5.1.0/util/qemu-thread-posix.c:521
#9  0x00007ffff3c406db in start_thread (arg=0x7fffe933e700) at pthread_create.c:463
#10 0x00007ffff396971f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
线程3“qemu-system-x86”在/opt/distros/qemu-5.1.0/tcg/i386/tcg target.inc:2259处命中断点9,tcg_out_op(s=0x7ff9c00b20,opc=INDEX_op_ld_i32,args=0x7fffe933d530,const_args=0x7fffe933d4f0)
2259 int c,常数a2,vexop,rexw=0;
#0 0x0000555558447D2在/opt/distros/qemu-5.1.0/tcg/i386/tcg target.inc:2259处的tcg_out_op(s=0x7ffe9c000b20,opc=INDEX_op_ld_i32,args=0x7fffe933d530,const_args=0x7fffe933d4f0)中
#1 0x00005555584FB40位于/opt/distros/qemu-5.1.0/tcg/tcg.c:3803的tcg注册分配操作(s=0x7ffe9c000b20,操作=0x7ffe9c00a418)中
#2 0x00005555585078E,位于/opt/distros/qemu-5.1.0/tcg/tcg.c:4244的tcg_gen_代码(s=0x7ffe9c000b20,tb=0x7fffac129880)中
#3 tb_gen_代码中的0x000055555558C22F1(cpu=0x5556B2D990,pc=94290869746347,cs_base=0,flags=4244147,cflags=-16252928)位于/opt/distros/qemu-5.1.0/accel/tcg/translate all.c:1766
#4在/opt/distros/qemu-5.1.0/accel/tcg/cpu exec.c:407处的tb_find(cpu=0x5556B2D990,last_tb=0x7fffac0ea700,tb_exit=1,cf_mask=524288)中的0x000055555558BE77A
#位于/opt/distros/qemu-5.1.0/accel/tcg/cpu exec.c:748的cpu_exec(cpu=0x5556B2D990)中的5 0x0000555558BF18E
#6在/opt/distros/qemu-5.1.0/softmmu/cpu处的tcg_cpu_exec(cpu=0x5556B2D990)中的0x0000555559846EB。c:1356
#7 0x000055555984F41位于/opt/distros/qemu-5.1.0/softmmu/cpu.c:1664
#8在/opt/distros/qemu-5.1.0/util/qemu-thread posix.c:521处的qemu线程启动(args=0x5556b5e0e0)中的0x00005555555e5ec8d
#9在pthread_create的start_线程(arg=0x7fffe933e700)中的0x00007ffff3c406db。c:463
#位于../sysdeps/unix/sysv/linux/x86_64/clone.S:95的clone()中的10 0x00007ff396971f
生成TB后,
TB\u find
返回TB,并
cpu\u TB\u exec
运行TB

正如前面的回答所表明的,TCG还有很多


注意,我使用了
host
guest
而不是
native
target
。TCG的术语有点颠倒:源代码是转换为在目标上运行的
guest
代码,即
主机
换句话说,TCG
目标
是QEMU
主机
(这对VM代码的生成很有意义)。

谢谢你,Lividd,我最终不得不走艰难的路去寻找答案,因为之前没有看到你的帖子。我的错误是,我没有在这里分享这些发现。您在这里介绍的几乎大部分内容。我想指出,tb_find_fast和tb_find_slow都是在缓存中搜索的,唯一的区别是tb_find_fast使用hash func值来查找tb的索引。如果TB发现无效,它会使用TB\u find\u slow进行顺序搜索。你的说明做得很好,这里使用了什么软件?附议Peter的说法。你是否使用某种工具从源代码生成了该图像?@Phil-不,没有使用源代码分析工具。只有普通绘图程序,libreofficedraw。这个图有点不正式,但我发现它很好地传达了执行流程,帮助定位了主要的源代码文件等…@Dexter@lividd我正在试图理解如何操纵TB大小。。。运行
ddd qemu系统arm
并在代码中放置断点(例如
gen_intermediate_code()
)正确吗?然后我运行程序说,
-M versatilepb-kernel…
但是这样做会挂起