Unexpected MacsBug behaviour when stepping PPC code (SOLVED: patch inside!)

About Qemu-system-ppc, a PPC Mac emulator for Windows, macOS and Linux that can run Mac OS 9.0 up to Mac OS X 10.5

Moderators: Cat_7, Ronald P. Regensburg

Post Reply
User avatar
siddhartha
Student Driver
Posts: 17
Joined: Wed Nov 30, 2022 12:59 am

Unexpected MacsBug behaviour when stepping PPC code (SOLVED: patch inside!)

Post by siddhartha »

I'm running QEMU 8.1.0-rc1, but this problem has been around for at least a couple of years. Using MacsBug 6.6.3, there is a problem when stepping through PPC code. Note that 68k code does not have this bug. Whenever a branch is reached, MacsBug will jump to the address after the intended branch address. For example, if there is a BNE to 13370000, MacsBug will instead jump to 13370004. This happens whether or not the branch is taken, meaning that the result of any branch condition will cause MacsBug to always break on the following address. This also happens under a clean install of Mac OS 9.1 as well as a clean install of Mac OS 9.2.2. This does not happen, however, on a baremetal machine in Classic mode (also 9.2.2 with MacsBug 6.6.3). This also does not happen on baremetal OS 9 machines.

There is also an additional bug that happens when tracing (stepping over) a branch and link (BL) to a subroutine. On some routines, tracing over will resume execution of the program instead of breaking on the following instruction. This does not usually happen if a NOP instruction follows the BL, but I cannot be certain. I was unable to reproduce this on baremetal, so I suspect it might be related to the bug above.

My QEMU settings are:

Code: Select all

-cpu "g4" ^
-M mac99,via=pmu -m 512^
-device usb-kbd
This also happens with bare settings like:

Code: Select all

-cpu "g4" ^
-M mac99 -m 256^
Is it possible that QEMU is the source of this bug? Perhaps something related to prefetching?
Last edited by siddhartha on Fri Jul 28, 2023 11:58 am, edited 1 time in total.
mcayland
Mac Mechanic
Posts: 155
Joined: Sun Nov 01, 2015 10:33 pm

Re: Unexpected MacsBug behaviour when stepping PPC code

Post by mcayland »

siddhartha wrote: Thu Jul 27, 2023 5:29 am I'm running QEMU 8.1.0-rc1, but this problem has been around for at least a couple of years. Using MacsBug 6.6.3, there is a problem when stepping through PPC code. Note that 68k code does not have this bug. Whenever a branch is reached, MacsBug will jump to the address after the intended branch address. For example, if there is a BNE to 13370000, MacsBug will instead jump to 13370004. This happens whether or not the branch is taken, meaning that the result of any branch condition will cause MacsBug to always break on the following address. This also happens under a clean install of Mac OS 9.1 as well as a clean install of Mac OS 9.2.2. This does not happen, however, on a baremetal machine in Classic mode (also 9.2.2 with MacsBug 6.6.3). This also does not happen on baremetal OS 9 machines.

There is also an additional bug that happens when tracing (stepping over) a branch and link (BL) to a subroutine. On some routines, tracing over will resume execution of the program instead of breaking on the following instruction. This does not usually happen if a NOP instruction follows the BL, but I cannot be certain. I was unable to reproduce this on baremetal, so I suspect it might be related to the bug above.

My QEMU settings are:

Code: Select all

-cpu "g4" ^
-M mac99,via=pmu -m 512^
-device usb-kbd
This also happens with bare settings like:

Code: Select all

-cpu "g4" ^
-M mac99 -m 256^
Is it possible that QEMU is the source of this bug? Perhaps something related to prefetching?
There were some recent changes in git to adjust the value of NIP in some circumstances. Can you try QEMU 8.0 and see if the error is still present?
User avatar
siddhartha
Student Driver
Posts: 17
Joined: Wed Nov 30, 2022 12:59 am

Re: Unexpected MacsBug behaviour when stepping PPC code

Post by siddhartha »

mcayland wrote: Thu Jul 27, 2023 3:36 pm There were some recent changes in git to adjust the value of NIP in some circumstances. Can you try QEMU 8.0 and see if the error is still present?
I appreciate the reply. I tried 8.0.2 and get the same results. This has been a bug for at least the last year and a half when I started using QEMU at version 6.1.
User avatar
siddhartha
Student Driver
Posts: 17
Joined: Wed Nov 30, 2022 12:59 am

Re: Unexpected MacsBug behaviour when stepping PPC code

Post by siddhartha »

Without knowing too much about the codebase, it looks like the problem is in the gen_bcond() function or somewhere in target/ppc/translate.c with respect to branches. I'm continuing to investigate...

I created an issue on GitLab.
User avatar
siddhartha
Student Driver
Posts: 17
Joined: Wed Nov 30, 2022 12:59 am

Re: Unexpected MacsBug behaviour when stepping PPC code

Post by siddhartha »

Well that was fun. I created a patch and updated the issue. Hopefully someone can submit it.

Code: Select all

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index e6a0709066..c655f5ce6c 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -4205,6 +4205,10 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
         pmu_count_insns(ctx);
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
+        if (unlikely(ctx->singlestep_enabled & CPU_SINGLE_STEP)
+            && (ctx->base.pc_next <= 0x100 || ctx->base.pc_next > 0xf00)) {
+            gen_debug_exception(ctx);
+        }
         tcg_gen_exit_tb(ctx->base.tb, n);
     } else {
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
User avatar
adespoton
Forum All-Star
Posts: 4727
Joined: Fri Nov 27, 2009 5:11 am
Location: Emaculation.com

Re: Unexpected MacsBug behaviour when stepping PPC code

Post by adespoton »

siddhartha wrote: Fri Jul 28, 2023 11:51 am Well that was fun. I created a patch and updated the issue. Hopefully someone can submit it.

Code: Select all

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index e6a0709066..c655f5ce6c 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -4205,6 +4205,10 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
         pmu_count_insns(ctx);
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
+        if (unlikely(ctx->singlestep_enabled & CPU_SINGLE_STEP)
+            && (ctx->base.pc_next <= 0x100 || ctx->base.pc_next > 0xf00)) {
+            gen_debug_exception(ctx);
+        }
         tcg_gen_exit_tb(ctx->base.tb, n);
     } else {
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
Thank you! Have any desire to look at the FPU/audio handling too? :D
Post Reply