On Wed, Sep 16, 2026 at 01:51:58PM -1000, Richard Henderson wrote:
> 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

Nice test case!

Reviewed-by: Jim MacArthur <[email protected]>


Reply via email to