* Ideas to Improve GDB Stub in Qemu for i8086
@ 2024-12-19 1:35 Davidson Francis
2024-12-19 16:51 ` Warner Losh
2024-12-21 5:45 ` [PATCH] target/i386: Improve 16-bit/real mode debug support in GDB Davidson Francis
0 siblings, 2 replies; 6+ messages in thread
From: Davidson Francis @ 2024-12-19 1:35 UTC (permalink / raw)
To: QEMU Development; +Cc: Davidson Francis
Hi,
Some time ago, I wrote a Gist [1] outlining what I believe to be the
ideal environment for debugging 16-bit code in real mode on Qemu. Based
on the feedback I've received, I decided to share it here to gather more
opinions.
It is commonly known that Qemu does not handle real/16-bit mode well with
GDB. To work around this, there are various hacks available, most of
which involve GDB scripts to make debugging less painful.
Basically, my idea involves two small and specific changes to the GDB
stub:
1) Returning the correct CPU mode as "i8086" or "i386" depending on the
current CPU mode (on x86_gdb_arch_name), instead of always returning
"i386".
2) Translating segmented memory to linear if in real mode, i.e.,
returning CS*0x10+EIP instead of just EIP, and similarly for ESP, etc.
Originally, I considered submitting a patch directly, but I wanted to get
your thoughts first. I understand that Bochs and similar tools have
sufficiently good debuggers, but it would be interesting if Qemu had some
improvements in this area.
I also acknowledge that my solution might not help in all scenarios, such
as CPU mode switches, so its effectiveness would be limited.
Ref:
[1]: https://gist.github.com/Theldus/4e1efc07ec13fb84fa10c2f3d054dccd
Kind regards,
Davidson Francis.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Ideas to Improve GDB Stub in Qemu for i8086
2024-12-19 1:35 Ideas to Improve GDB Stub in Qemu for i8086 Davidson Francis
@ 2024-12-19 16:51 ` Warner Losh
2024-12-20 0:34 ` Davidson Francis
2024-12-21 5:45 ` [PATCH] target/i386: Improve 16-bit/real mode debug support in GDB Davidson Francis
1 sibling, 1 reply; 6+ messages in thread
From: Warner Losh @ 2024-12-19 16:51 UTC (permalink / raw)
To: Davidson Francis; +Cc: QEMU Development
[-- Attachment #1: Type: text/plain, Size: 1995 bytes --]
On Wed, Dec 18, 2024 at 6:36 PM Davidson Francis <davidsondfgl@gmail.com>
wrote:
> Hi,
> Some time ago, I wrote a Gist [1] outlining what I believe to be the
> ideal environment for debugging 16-bit code in real mode on Qemu. Based
> on the feedback I've received, I decided to share it here to gather more
> opinions.
>
> It is commonly known that Qemu does not handle real/16-bit mode well with
> GDB. To work around this, there are various hacks available, most of
> which involve GDB scripts to make debugging less painful.
>
> Basically, my idea involves two small and specific changes to the GDB
> stub:
> 1) Returning the correct CPU mode as "i8086" or "i386" depending on the
> current CPU mode (on x86_gdb_arch_name), instead of always returning
> "i386".
>
> 2) Translating segmented memory to linear if in real mode, i.e.,
> returning CS*0x10+EIP instead of just EIP, and similarly for ESP, etc.
>
> Originally, I considered submitting a patch directly, but I wanted to get
> your thoughts first. I understand that Bochs and similar tools have
> sufficiently good debuggers, but it would be interesting if Qemu had some
> improvements in this area.
>
> I also acknowledge that my solution might not help in all scenarios, such
> as CPU mode switches, so its effectiveness would be limited.
>
> Ref:
> [1]: https://gist.github.com/Theldus/4e1efc07ec13fb84fa10c2f3d054dccd
I might be interested in debugging some i8086 stuff for my Venix/86
emulation
project.
I'm curious, though. I see special cases just for EIP being returned as (CS
<< 4):EIP
and similar for ESP being just (SS << 4):SP. What does the debugger do,
though,
for other cases where you need segment:offset addresses? Does it translate
properly
behind the scenes in ways it doesn't do for ESP/EIP or do you have to
examine those
addresses by hand as well? If I'm chasing a linked list with 16-bit
addresses that assume
a particular DS, how does that work?
Warner
[-- Attachment #2: Type: text/html, Size: 2679 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Ideas to Improve GDB Stub in Qemu for i8086
2024-12-19 16:51 ` Warner Losh
@ 2024-12-20 0:34 ` Davidson Francis
2024-12-20 11:14 ` Bernhard Beschow
0 siblings, 1 reply; 6+ messages in thread
From: Davidson Francis @ 2024-12-20 0:34 UTC (permalink / raw)
To: Warner Losh; +Cc: QEMU Development
On Thu, Dec 19, 2024 at 09:51:13AM -0700, Warner Losh wrote:
> I might be interested in debugging some i8086 stuff for my Venix/86
> emulation
> project.
>
> I'm curious, though. I see special cases just for EIP being returned as (CS
> << 4):EIP
> and similar for ESP being just (SS << 4):SP. What does the debugger do,
> though,
> for other cases where you need segment:offset addresses? Does it translate
> properly
> behind the scenes in ways it doesn't do for ESP/EIP or do you have to
> examine those
> addresses by hand as well? If I'm chasing a linked list with 16-bit
> addresses that assume
> a particular DS, how does that work?
>
You've brought up a very interesting point. Indeed, in the case of
linked lists and similar structures, there’s no way for GDB or QEMU to
reliably determine which segment an address might belong to—perhaps
only guesses, which are far from ideal.
That said, the approach I'm proposing doesn’t solve all problems and
still requires users to handle these conversions manually or through GDB
scripts.
The main goal of my idea is simply to reduce the initial effort required
to debug i8086 code, avoiding workarounds with architecture XML files,
and proper instruction disassembly and stack dumps out-of-the-box.
Kind regards,
Davidson Francis.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Ideas to Improve GDB Stub in Qemu for i8086
2024-12-20 0:34 ` Davidson Francis
@ 2024-12-20 11:14 ` Bernhard Beschow
0 siblings, 0 replies; 6+ messages in thread
From: Bernhard Beschow @ 2024-12-20 11:14 UTC (permalink / raw)
To: qemu-devel, Davidson Francis, Warner Losh; +Cc: QEMU Development
Am 20. Dezember 2024 00:34:26 UTC schrieb Davidson Francis <davidsondfgl@gmail.com>:
>On Thu, Dec 19, 2024 at 09:51:13AM -0700, Warner Losh wrote:
>> I might be interested in debugging some i8086 stuff for my Venix/86
>> emulation
>> project.
>>
>> I'm curious, though. I see special cases just for EIP being returned as (CS
>> << 4):EIP
>> and similar for ESP being just (SS << 4):SP. What does the debugger do,
>> though,
>> for other cases where you need segment:offset addresses? Does it translate
>> properly
>> behind the scenes in ways it doesn't do for ESP/EIP or do you have to
>> examine those
>> addresses by hand as well? If I'm chasing a linked list with 16-bit
>> addresses that assume
>> a particular DS, how does that work?
>>
>
>You've brought up a very interesting point. Indeed, in the case of
>linked lists and similar structures, there’s no way for GDB or QEMU to
>reliably determine which segment an address might belong to—perhaps
>only guesses, which are far from ideal.
>
>That said, the approach I'm proposing doesn’t solve all problems and
>still requires users to handle these conversions manually or through GDB
>scripts.
>
>The main goal of my idea is simply to reduce the initial effort required
>to debug i8086 code, avoiding workarounds with architecture XML files,
>and proper instruction disassembly and stack dumps out-of-the-box.
I suggest to submit a patch with a descriptive commit message to see where it is going. To me, your changes seem reasonable and I could have benefited from them already in my VIA Apollo Pro 133T project [1] where I made some real-world bioses run in QEMU.
Best regards,
Bernhard
[1] https://github.com/shentok/qemu/tree/via-apollo-pro-133t
>
>Kind regards,
>Davidson Francis.
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] target/i386: Improve 16-bit/real mode debug support in GDB
2024-12-19 1:35 Ideas to Improve GDB Stub in Qemu for i8086 Davidson Francis
2024-12-19 16:51 ` Warner Losh
@ 2024-12-21 5:45 ` Davidson Francis
2025-03-07 19:26 ` Bernhard Beschow
1 sibling, 1 reply; 6+ messages in thread
From: Davidson Francis @ 2024-12-21 5:45 UTC (permalink / raw)
To: qemu-devel; +Cc: davidsondfgl, Paolo Bonzini, Zhao Liu
Debugging 16-bit/real mode code in QEMU+GDB is challenging due to
incorrect architecture detection and segmented memory addressing issues.
This patch improves the debugging experience by reporting i8086
architecture to GDB when in real mode and converting segmented addresses
(CS:EIP, SS:ESP) to their physical equivalents when reporting to GDB.
This enables proper instruction disassembly and stack inspection without
complex workarounds.
Note: Mode switches after GDB attachment still require manual
architecture change, as GDB RSP does not support runtime architecture
switches.
Signed-off-by: Davidson Francis <davidsondfgl@gmail.com>
---
target/i386/cpu.c | 8 +++++++-
target/i386/gdbstub.c | 15 +++++++++++++--
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5253399459..65bdc48cc0 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6404,7 +6404,13 @@ static const gchar *x86_gdb_arch_name(CPUState *cs)
#ifdef TARGET_X86_64
return "i386:x86-64";
#else
- return "i386";
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+ if (env->cr[0] & 1) {
+ return "i386";
+ } else {
+ return "i8086";
+ }
#endif
}
diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index 04c49e802d..d600aee953 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -136,7 +136,13 @@ int x86_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
return gdb_get_regl(mem_buf, 0);
}
} else {
- return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]);
+ if (n != R_ESP || (env->cr[0] & 1)) {
+ return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]);
+ } else {
+ return gdb_get_reg32(mem_buf,
+ (env->segs[R_SS].selector << 4) +
+ env->regs[gpr_map32[n]]);
+ }
}
} else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
int st_index = n - IDX_FP_REGS;
@@ -155,7 +161,12 @@ int x86_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
} else {
switch (n) {
case IDX_IP_REG:
- return gdb_get_reg(env, mem_buf, env->eip);
+ if (TARGET_LONG_BITS != 32 || (env->cr[0] & 1)) {
+ return gdb_get_reg(env, mem_buf, env->eip);
+ } else {
+ return gdb_get_reg(env, mem_buf,
+ (env->segs[R_CS].selector << 4) + env->eip);
+ }
case IDX_FLAGS_REG:
return gdb_get_reg32(mem_buf, env->eflags);
--
2.37.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] target/i386: Improve 16-bit/real mode debug support in GDB
2024-12-21 5:45 ` [PATCH] target/i386: Improve 16-bit/real mode debug support in GDB Davidson Francis
@ 2025-03-07 19:26 ` Bernhard Beschow
0 siblings, 0 replies; 6+ messages in thread
From: Bernhard Beschow @ 2025-03-07 19:26 UTC (permalink / raw)
To: qemu-devel, Davidson Francis, Zhao Liu, Paolo Bonzini; +Cc: davidsondfgl
Am 21. Dezember 2024 05:45:49 UTC schrieb Davidson Francis <davidsondfgl@gmail.com>:
>Debugging 16-bit/real mode code in QEMU+GDB is challenging due to
>incorrect architecture detection and segmented memory addressing issues.
>
>This patch improves the debugging experience by reporting i8086
>architecture to GDB when in real mode and converting segmented addresses
>(CS:EIP, SS:ESP) to their physical equivalents when reporting to GDB.
>This enables proper instruction disassembly and stack inspection without
>complex workarounds.
>
>Note: Mode switches after GDB attachment still require manual
>architecture change, as GDB RSP does not support runtime architecture
>switches.
>
>Signed-off-by: Davidson Francis <davidsondfgl@gmail.com>
>---
> target/i386/cpu.c | 8 +++++++-
> target/i386/gdbstub.c | 15 +++++++++++++--
> 2 files changed, 20 insertions(+), 3 deletions(-)
Ping
I don't feel confident reviewing this patch. Paolo? Zhao?
Best regards,
Bernhard
>
>diff --git a/target/i386/cpu.c b/target/i386/cpu.c
>index 5253399459..65bdc48cc0 100644
>--- a/target/i386/cpu.c
>+++ b/target/i386/cpu.c
>@@ -6404,7 +6404,13 @@ static const gchar *x86_gdb_arch_name(CPUState *cs)
> #ifdef TARGET_X86_64
> return "i386:x86-64";
> #else
>- return "i386";
>+ X86CPU *cpu = X86_CPU(cs);
>+ CPUX86State *env = &cpu->env;
>+ if (env->cr[0] & 1) {
>+ return "i386";
>+ } else {
>+ return "i8086";
>+ }
> #endif
> }
>
>diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
>index 04c49e802d..d600aee953 100644
>--- a/target/i386/gdbstub.c
>+++ b/target/i386/gdbstub.c
>@@ -136,7 +136,13 @@ int x86_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
> return gdb_get_regl(mem_buf, 0);
> }
> } else {
>- return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]);
>+ if (n != R_ESP || (env->cr[0] & 1)) {
>+ return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]);
>+ } else {
>+ return gdb_get_reg32(mem_buf,
>+ (env->segs[R_SS].selector << 4) +
>+ env->regs[gpr_map32[n]]);
>+ }
> }
> } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
> int st_index = n - IDX_FP_REGS;
>@@ -155,7 +161,12 @@ int x86_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
> } else {
> switch (n) {
> case IDX_IP_REG:
>- return gdb_get_reg(env, mem_buf, env->eip);
>+ if (TARGET_LONG_BITS != 32 || (env->cr[0] & 1)) {
>+ return gdb_get_reg(env, mem_buf, env->eip);
>+ } else {
>+ return gdb_get_reg(env, mem_buf,
>+ (env->segs[R_CS].selector << 4) + env->eip);
>+ }
> case IDX_FLAGS_REG:
> return gdb_get_reg32(mem_buf, env->eflags);
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-03-07 19:26 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-19 1:35 Ideas to Improve GDB Stub in Qemu for i8086 Davidson Francis
2024-12-19 16:51 ` Warner Losh
2024-12-20 0:34 ` Davidson Francis
2024-12-20 11:14 ` Bernhard Beschow
2024-12-21 5:45 ` [PATCH] target/i386: Improve 16-bit/real mode debug support in GDB Davidson Francis
2025-03-07 19:26 ` Bernhard Beschow
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.