From: Tao Cui <[email protected]> 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 <[email protected]> Message-ID: <[email protected]> [rth: Simplify and convert to meson test harness] Signed-off-by: Richard Henderson <[email protected]> --- tests/tcg/i386/system/meson.build | 4 ++++ tests/tcg/i386/system/wraparound.S | 35 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/tcg/i386/system/wraparound.S diff --git a/tests/tcg/i386/system/meson.build b/tests/tcg/i386/system/meson.build index d3f73997c7f..c08563d0ab5 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 00000000000..9c77b3a8468 --- /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 -- 2.53.0
