I'm studying how QEMU translates native basic blocks and runs them. As far as I understand, it reads native basic blocks then retranslates them, but I wonder how it can deal with exceptions inside, so I run the following program:
// pgfault.c
int main() {
__asm__(
"xor rax, rax\n\t"
"mov rbx, [rax]\n\t"
"xor rcx, rbx\n\t"
"add rax, rcx\n\t"
);
}
// compile
x86_64-w64-mingw32-gcc pgfault.c -masm=intel -o pgfault.exe
// and run in PANDA/QEMU
Indeed, I get the trace:
// first translation block
0x401510 xor rax, rax ; first instruction of main
; second instruction generates a page fault
// second translation block (KiPageFault in ntoskrnl.exe)
0xfffff80026e4600 push rbx
0xfffff80026e4601 sub rbp, 0x158
The second instructions generates a page fault, then the translation block contains only the first instruction. How can QEMU/PANDA knows that ahead of time (i.e. at translation step)?