qemu-system-i386 registers clobbered after gdb set due to k_gs_base bug in gdbstub
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
QEMU |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
Due to a bug in /target/
I'm using qemu version 4.2.50 on an msys64 and start qemu's i386 with a gdb server.
$ qemu-system-i386 -version
QEMU emulator version 4.2.50 (v4.2.0-
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
$ qemu-system-i386 -gdb tcp::29096 -S
C:\msys64\
C:\msys64\
I start a gdb client, connect to the server, display the register state, set k_gs_base, display the register state again, and notice an issue. (Setting other registers also clobbers the ones after k_gs_base).
$ gdb -q
(gdb) target remote :29096
...
(gdb) info regs
...
gs_base 0x0 0
k_gs_base 0x0 0
cr0 0x60000010 [ CD NW ET ]
cr2 0x0 0
...
(gdb) set $k_gs_base = 0x41414141
(gdb) info regs
...
gs_base 0x0 0
k_gs_base 0x0 0
cr0 0x41414151 [ CD WP ET PE ]
cr2 0x60000010 1610612752
...
In the gdbstub code, I notice that the read and write functions are not symmetric for IDX_SEG_REGS + 8, which corresponds to k_gs_base.
$ cat /usr/local/
...
int x86_cpu_
{
...
case IDX_SEG_REGS + 8:
#ifdef TARGET_X86_64
if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
}
return gdb_get_
#else
return gdb_get_
#endif
...
}
...
int x86_cpu_
{
...
#ifdef TARGET_X86_64
case IDX_SEG_REGS + 8:
if (env->hflags & HF_CS64_MASK) {
}
return 4;
#endif
...
}
...
I change the write function, rebuild, and verify that the issue is resolved.
$ cat /usr/local/
int x86_cpu_
{
...
case IDX_SEG_REGS + 8:
#ifdef TARGET_X86_64
if (env->hflags & HF_CS64_MASK) {
}
return 4;
#else
return 4;
#endif
...
}
...
$ make
...
$ make install
...
$ qemu-system-i386 -gdb tcp::29096 -S
$ gdb -q
(gdb) target remote :29096
...
(gdb) info regs
...
gs_base 0x0 0
k_gs_base 0x0 0
cr0 0x60000010 [ CD NW ET ]
cr2 0x0 0
...
(gdb) set $k_gs_base = 0x41414141
(gdb) info regs
...
gs_base 0x0 0
k_gs_base 0x0 0
cr0 0x60000010 [ CD NW ET ]
cr2 0x0 0
...
I'll submit the patch below.
$ diff gdbstub.c gdbstub.c.bkp
353d352
< case IDX_SEG_REGS + 8:
354a354
> case IDX_SEG_REGS + 8:
362,363d361
< #else
< return 4;
summary: |
- registers clobbered after set in qemu-system-i386 due to k_gs_base + qemu-system-i386 registers clobbered after gdb set due to k_gs_base bug + in gdbstub |
tags: | added: gdb |
Changed in qemu: | |
status: | Fix Committed → Fix Released |
Fixed here: /git.qemu. org/?p= qemu.git; a=commitdiff; h=5a07192a042e
https:/