Commit ceb1bd2af8 for qemu.org
commit ceb1bd2af8533065665141a3768f1f7647ecae8a
Author: Tao Cui <cuitao@kylinos.cn>
Date: Wed Sep 16 11:03:55 2026 -1000
tests/tcg/i386/system: Add regression test for translator_ld wraparound
Add a test case that reaches an instruction straddling the end of the 32-bit
address space (0xfffffffe).
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>
Message-ID: <20260709020529.126652-3-cui.tao@linux.dev>
[rth: Simplify and convert to meson test harness]
Reviewed-by: Jim MacArthur <jim.macarthur@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
diff --git a/tests/tcg/i386/system/meson.build b/tests/tcg/i386/system/meson.build
index d3f73997c7..c08563d0ab 100644
--- a/tests/tcg/i386/system/meson.build
+++ b/tests/tcg/i386/system/meson.build
@@ -34,6 +34,10 @@ foreach t: tcg_tests['multiarch-softmmu']['tests']
endforeach
endforeach
+tests += {
+ 'wraparound.S': { 'cflags': cflags, 'qemu_args': ['-m', '4G'] + qemu_def_args }
+}
+
if 'qemu-system-i386' in emulators
tcg_tests += {
'i386-softmmu': {
diff --git a/tests/tcg/i386/system/wraparound.S b/tests/tcg/i386/system/wraparound.S
new file mode 100644
index 0000000000..9c77b3a846
--- /dev/null
+++ b/tests/tcg/i386/system/wraparound.S
@@ -0,0 +1,35 @@
+/* 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).
+ */
+
+ .code32
+ .section .text
+
+main:
+ /*
+ * 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)
+ * [0x1] c3 ret
+ *
+ * Note: this relies on the SeaBIOS byte at 0xffffffff being 0x00
+ * (add r/m8, r8); if that ever changes, the stub below must move.
+ *
+ * Note that eax = 0 before and after the stub, so this becomes
+ * the exit code of the test.
+ */
+ xor %eax, %eax
+ movw $0xc3c0, (%eax)
+ movl $0xfffffffe, %ecx
+ jmp *%ecx
+
+ .globl main
+ .type main, @function
+ .size main, . - main