qemu-mipsn32(el) user mode emulator fails to execute any recently built n32 binaries
Host environment
- Operating system: Gentoo Linux
- OS/kernel version:
Linux demeter 5.15.23-gentoo-dist #1 SMP Fri Feb 11 14:26:48 -00 2022 x86_64 AMD Ryzen 7 3700X 8-Core Processor AuthenticAMD GNU/Linux
- Architecture: x86-64
- QEMU flavor: qemu-mipsn32 or qemu-mipsn32el user mode emulator
- QEMU version: 6.2.0
Emulated/Virtualized environment
- Operating system: Gentoo Linux
- Architecture: -march=mips64 -mabi=n32 (both EL and EB), both recent bootstrap and archived binaries from 2020
Description of problem
Note: Before trying to reproduce this issue, have a look at issue 843 - the binfmt-misc magic for n32 needs to be fixed.
Trying to chroot into a mips n32 installation fails with
/bin/bash: error while loading shared libraries: /lib32/libc.so.6: cannot read file data
however, bash, libc.so.6, and qemu all exist and have the proper abi
The problem occurs for both big and little endian N32 ABI. O32 and N64 work fine. The same N32 binaries also work fine on native hardware.
Additional information: debugging done
trying to get ld.so load libc.so
demeter /var/lib/machines # dilfridge-mips64le-multilib/lib32/ld.so.1 dilfridge-mips64le-multilib/lib32/libc.so.6
dilfridge-mips64le-multilib/lib32/libc.so.6: error while loading shared libraries: dilfridge-mips64le-multilib/lib32/libc.so.6: cannot read file data
demeter /var/lib/machines #
demeter /var/lib/machines # file dilfridge-mips64le-multilib/lib32/ld.so.1
dilfridge-mips64le-multilib/lib32/ld.so.1: ELF 32-bit LSB shared object, MIPS, N32 MIPS64 version 1 (SYSV), static-pie linked, stripped
demeter /var/lib/machines # file dilfridge-mips64le-multilib/lib32/libc.so.6
dilfridge-mips64le-multilib/lib32/libc.so.6: ELF 32-bit LSB shared object, MIPS, N32 MIPS64 version 1 (SYSV), dynamically linked, interpreter /lib32/ld.so.1, for GNU/Linux 3.2.0, stripped
output of qemu-... -strace
demeter /var/lib/machines # qemu-mipsn32el -strace dilfridge-mips64le-multilib/lib32/ld.so.1 dilfridge-mips64le-multilib/lib32/libc.so.6
2868137 brk(NULL) = 0x4003c000
2868137 openat(AT_FDCWD,"dilfridge-mips64le-multilib/lib32/libc.so.6",O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
2868137 read(3,0x4183bcd4,512) = 512
2868137 pread64(3,1099152416,32,792,1074016288,0) = 0
2868137 close(3) = 0
dilfridge-mips64le-multilib/lib32/libc.so.6: error while loading shared libraries: dilfridge-mips64le-multilib/lib32/libc.so.6: cannot read file data
2868137 writev(2,0x4183b4b0,0xa) = 150
2868137 exit_group(127)
output of strace qemu-...
demeter /var/lib/machines # strace qemu-mipsn32el dilfridge-mips64le-multilib/lib32/ld.so.1 dilfridge-mips64le-multilib/lib32/libc.so.6
[...]
openat(AT_FDCWD, "dilfridge-mips64le-multilib/lib32/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0\310\6\2\0004\0\0\0"..., 512) = 512
pread64(3, "", 32, 1074016288) = 0
close(3) = 0
writev(2, [{iov_base="dilfridge-mips64le-multilib/lib3"..., iov_len=43}, {iov_base=": ", iov_len=2}, {iov_base="error while loading shared libra"..., iov_len=36}, {iov_base=": ", iov_len=2}, {iov_base="dilf>
) = 150
exit_group(127) = ?
+++ exited with 127 +++
Here the parameters that pread64 obtains do not make sense. The fourth value should be a file offset, but libc.so.6 is not 1Gbyte large.
further testing
- A Gentoo n32 stage from 2014 worked fine, however a stage from 2020 displayed the same problem.
- Possibly the issue was triggered by glibc commit 95c1056962a3f2297c94ce47f0eaf0c5b6563231, 2/Oct/2019, "elf: Use nocancel pread64() instead of lseek()+read()"