qemu8-i386 gets wrong arguments for 32-bit old mmap syscall (_NR_mmap = 90)
Host environment
-
Operating system: Fedora 36
-
OS/kernel version: Linux host 6.2.15-100.fc36.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 11 16:51:53 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
-
Architecture: x86_64
-
QEMU flavor: qemu-i386 (user mode only)
-
QEMU version: commit fcb237e6 (HEAD -> master, origin/master, origin/HEAD) Merge: 2ff49e96 c00aac6f Date: Mon Jul 10 09:17:06 2023 +0100
-
QEMU command line: build/qemu-i386 -strace ./oldmmap
Emulated/Virtualized environment
- Operating system: Fedora 36
- OS/kernel version: Linux host 6.2.15-100.fc36.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 11 16:51:53 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
- Architecture: i686
Description of problem
qemu8-i386 does not decode syscall arguments correctly for system call _NR_mmap = 90 on i386.
$ strace ./oldmmap
execve("./oldmmap", ["./oldmmap"], 0x7fff46ba6d40 /* 61 vars */) = 0
[ Process PID=405233 runs in 32 bit mode. ]
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7fa7000
exit(5) = ?
+++ exited with 5 +++
$ build/qemu-i386 -strace ./oldmmap
405254 mmap(0x40800058,0,PROT_NONE,0,0,0) = 0x3fffb000
405254 exit(5)
Steps to reproduce
- gcc -m32 -o oldmmap -nostartfiles -nostdlib oldmmap.S # build 32-bit executable
- strace ./oldmmap # run under strace
- build/qemu-i386 -strace ./oldmmap # run under "qemu-i386 -strace"
- Notice that qemu-i386 did not report the same arguments to the _NR_map syscall as /usr/bin/strace did.
Additional information
$ cat oldmmap.S
MAP_FIXED= 0x10
MAP_PRIVATE= 0x02
MAP_ANONYMOUS= 0x20
PROT_READ= 1
PROT_WRITE= 2
PROT_EXEC= 4
_NR_exit = 1
_NR_mmap = 90 // oldmmap: %ebx -> array of 6 arguments
.globl _start
_start:
push $0 // offset
push $-1 // fd
push $MAP_PRIVATE|MAP_ANONYMOUS // flags
push $PROT_READ|PROT_WRITE // protection
push $2<<12 // length
push $0 // addr (kernel chooses)
mov %esp,%ebx
mov $_NR_mmap,%eax
int $0x80
nop
mov $5,%ebx
mov $_NR_exit,%eax
int $0x80
hlt
$