From: Tao Cui <cui.tao@linux.dev>
To: qemu-devel@nongnu.org
Cc: richard.henderson@linaro.org, pbonzini@redhat.com,
cuitao@kylinos.cn, cui.tao@linux.dev
Subject: [PATCH v1 2/2] tests/multiboot: add regression test for translator_ld wraparound
Date: Thu, 9 Jul 2026 10:05:29 +0800 [thread overview]
Message-ID: <20260709020529.126652-3-cui.tao@linux.dev> (raw)
In-Reply-To: <20260709020529.126652-1-cui.tao@linux.dev>
From: Tao Cui <cuitao@kylinos.cn>
Add a multiboot test case that reaches an instruction straddling the
end of the 32-bit address space (0xfffffffe). Before the translator_ld
fix QEMU aborts at translator.c:296; afterwards the case reaches
isa-debug-exit and passes.
The top page (0xfffff000) is SeaBIOS ROM, so the cross-boundary byte is
the ROM's own 0x00 (add r/m8, r8) at 0xffffffff, whose modrm is fetched
from [0x0]. A short exit stub is placed there. The case runs on
qemu-system-i386 since the bug is 32-bit only.
Signed-off-by: Tao Cui <cuitao@kylinos.cn>
---
tests/multiboot/Makefile | 7 +++++-
tests/multiboot/run_test.sh | 8 +++++-
tests/multiboot/wraparound.c | 46 ++++++++++++++++++++++++++++++++++
tests/multiboot/wraparound.out | 5 ++++
4 files changed, 64 insertions(+), 2 deletions(-)
create mode 100644 tests/multiboot/wraparound.c
create mode 100644 tests/multiboot/wraparound.out
diff --git a/tests/multiboot/Makefile b/tests/multiboot/Makefile
index ed4225e7d1..b5045855d7 100644
--- a/tests/multiboot/Makefile
+++ b/tests/multiboot/Makefile
@@ -9,7 +9,7 @@ LIBS=$(shell $(CC) $(CCFLAGS) -print-libgcc-file-name)
AOUT_KLUDGE_BIN=$(foreach x,$(shell seq 1 9),aout_kludge_$x.bin)
-all: mmap.elf modules.elf $(AOUT_KLUDGE_BIN)
+all: mmap.elf modules.elf wraparound.elf $(AOUT_KLUDGE_BIN)
mmap.elf: start.o mmap.o libc.o link.ld
$(LD) $(LDFLAGS_ELF) -o $@ $^ $(LIBS)
@@ -17,6 +17,11 @@ mmap.elf: start.o mmap.o libc.o link.ld
modules.elf: start.o modules.o libc.o link.ld
$(LD) $(LDFLAGS_ELF) -o $@ $^ $(LIBS)
+# link.ld is provided via LDFLAGS_ELF (-T); keep it out of the
+# prerequisite list so $^ does not pass it to ld a second time.
+wraparound.elf: start.o wraparound.o libc.o
+ $(LD) $(LDFLAGS_ELF) -o $@ $^ $(LIBS)
+
aout_kludge_%.bin: aout_kludge_%.o link.ld
$(LD) $(LDFLAGS_BIN) -o $@ $^ $(LIBS)
diff --git a/tests/multiboot/run_test.sh b/tests/multiboot/run_test.sh
index f968bf797e..517281ba49 100755
--- a/tests/multiboot/run_test.sh
+++ b/tests/multiboot/run_test.sh
@@ -73,9 +73,15 @@ aout_kludge() {
done
}
+wraparound() {
+ # The translator_ld wraparound bug is i386-only (32-bit address space);
+ # the default x86_64 QEMU does not reproduce it.
+ QEMU="${QEMU%x86_64}i386" run_qemu wraparound.elf -m 4G
+}
+
make all
-for t in mmap modules aout_kludge; do
+for t in mmap modules aout_kludge wraparound; do
echo > test.log
pass=1
diff --git a/tests/multiboot/wraparound.c b/tests/multiboot/wraparound.c
new file mode 100644
index 0000000000..3b757f3f98
--- /dev/null
+++ b/tests/multiboot/wraparound.c
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Regression test for the translator_ld crash when an instruction
+ * straddles the end of the 32-bit address space (i386).
+ */
+
+#include "libc.h"
+#include "multiboot.h"
+
+int test_main(uint32_t magic, struct mb_info *mbi)
+{
+ (void) magic;
+ (void) mbi;
+
+ printf("cross-boundary insn at end of address space\n");
+
+ /*
+ * The top page (0xfffff000) is SeaBIOS ROM and cannot be written.
+ * Its byte at 0xffffffff (0x00 = "add r/m8, r8") already crosses the
+ * page boundary into page1 at 0x0, which is exactly the case
+ * translator_ld must handle without aborting. Reaching 0xfffffffe
+ * runs the ROM's cld, then that add; the add's modrm is fetched from
+ * [0x0], which is RAM, so build a short exit stub there:
+ *
+ * [0x0] c0 modrm -> "add al, al" (reg; EIP -> 1)
+ * [1] eb 00 jmp +0 (EIP -> 3)
+ * [3] b8 00 00 00 00 mov eax, 0
+ * [8] e7 f4 out 0xf4, eax -> isa-debug-exit(0)
+ *
+ * Without the translator_ld fix QEMU aborts while reading the modrm
+ * at the wrapped address 0x0 (translator.c assert).
+ *
+ * Note: this relies on the SeaBIOS byte at 0xffffffff being 0x00
+ * (add r/m8, r8); if that ever changes, the stub below must move.
+ */
+ volatile uint8_t *p = (uint8_t *)0x00000000;
+ p[0] = 0xC0; /* modrm: add al, al */
+ p[1] = 0xEB; p[2] = 0x00; /* jmp +0 -> 0x3 */
+ /* mov eax, 0 */
+ p[3] = 0xB8; p[4] = 0x00; p[5] = 0x00; p[6] = 0x00; p[7] = 0x00;
+ p[8] = 0xE7; p[9] = 0xF4; /* out 0xf4, eax -> exit 0 */
+
+ asm volatile("mov $0xFFFFFFFE, %%eax; jmp *%%eax" : : : "eax");
+
+ return 1; /* unreachable */
+}
diff --git a/tests/multiboot/wraparound.out b/tests/multiboot/wraparound.out
new file mode 100644
index 0000000000..23cb05ed11
--- /dev/null
+++ b/tests/multiboot/wraparound.out
@@ -0,0 +1,5 @@
+
+
+=== Running test case: wraparound.elf -m 4G ===
+
+cross-boundary insn at end of address space
--
2.43.0
prev parent reply other threads:[~2026-07-09 2:06 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-09 2:05 [PATCH v1 0/2] accel/tcg: fix crash on instruction straddling address-space end Tao Cui
2026-07-09 2:05 ` [PATCH v1 1/2] " Tao Cui
2026-07-09 2:05 ` Tao Cui [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260709020529.126652-3-cui.tao@linux.dev \
--to=cui.tao@linux.dev \
--cc=cuitao@kylinos.cn \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.