qemu-user fails to run 32-bit x86 binaries on hosts with a page size > 4KB
Host environment
- Operating system: ALT Linux sisyphus
- OS/kernel version: Linux 6.7.3 loongarch64
- Architecture: LoongArch, ARM64
- QEMU flavor: qemu-i386 (Linux userspace emulation)
- QEMU version: 8.2.0
- QEMU command line: qemu-i386
Emulated/Virtualized environment
- Operating system: Linux userspace emulation
- OS/kernel version: not applicable
- Architecture: 32-bit x86
Description of problem
qemu-i386
refuses to run 32-bit x86 binaries on hosts with a page size > 4KB
(such as LoongArch, ppc64le, arm64 with 3 level page tables).
Steps to reproduce
- Compile x86 binary which makes a single exit(0) syscall:
cat > exit0.S << EOF
#include <sys/syscall.h>
.text
.global _start
_start:
movl $__NR_exit, %eax
movl $0, %ebx
int $0x80
EOF
i586-linux-gnu-gcc -nostdlib -static -no-pie -o exit0 exit0.S
Alternatively one might compile it on a x86 host:
gcc -m32 -nostdlib -static -no-pie -o exit0 exit0.S
and transfer the exit0
binary to ppc64/LoongArch/arm64 system
- Run the
exit0
binary withqemu-i386
qemu-i386-static ./exit0
Expected result
exit0
binary runs (and exits with 0 status)
Actual result
qemu-i386-static: ../linux-user/elfload.c:3019: pgb_dynamic: Assertion `QEMU_IS_ALIGNED(guest_loaddr, align)' failed.
Additional information
.text
segment of (32-bit) x86 binaries is typically aligned at 4KB:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08048000 0x08048000 0x00100 0x00100 R 0x1000
LOAD 0x001000 0x08049000 0x08049000 0x0000c 0x0000c R E 0x1000
NOTE 0x0000b4 0x080480b4 0x080480b4 0x0004c 0x0004c R 0x4
GNU_PROPERTY 0x0000d8 0x080480d8 0x080480d8 0x00028 0x00028 R 0x4
Thus on a host with a page size being 64 KB (ppc64, arm64 with 3 level page tables) or 16 KB (LoongArch) alignment requirements in pbg_dynamic can not be satisfied.