Comment 5 for bug 1947860

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

bug 1948684 reported almost the same (but for risc in qmeu user static).
Carrying the great Info generated by Björn there over here to handle it in one place.

Steps to reproduce (using golang for ease of cross-compiling):
--
$ cat rv.go
package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println("Args are");
    for i, a := range os.Args {
        fmt.Println(i, a);
    }
}
$ go build ./rv.go
$ ./rv one two three
Args are
0 ./rv
1 one
2 two
3 three
$ export GOARCH=riscv64
$ go build ./rv.go
$ file ./rv
./rv: ELF 64-bit LSB executable, UCB RISC-V, version 1 (SYSV),
statically linked, Go
BuildID=9kA-_aeKgZkwtyYVUb7o/F43JNW5XxPX9ScBQrfs8/l6EzXXq8x8pfor-ByIh4/_zELq4T9-VKcpBXoempb,
not stripped
$ ./rv
Args are
0 ./rv
$ ./rv one
Args are
0 ./rv
$ ./rv one two three four
Args are
0 ./rv
1 two
2 three
3 four
$
--

As you can see, in the last run, the "one" argument is skipped.

There is a debian patch, linux-user-binfmt-P.diff (found in qemu_6.0+dfsg-2expubuntu1.debian.tar.xz), that I think is the issue.

When we execute the binfmt-interpreter directly:
$ /usr/libexec/qemu-binfmt/riscv64-binfmt-P /path/to/rv /path/to/rv one two
Args are
0 /path/to/rv
1 one
2 two

Things work, however via the kernels binfmt-misc:
$ /path/to/rv one two
Args are
0 /path/to/rv
1 two

It doesn't.

$ cat /proc/sys/fs/binfmt_misc/qemu-riscv64
enabled
interpreter /usr/libexec/qemu-binfmt/riscv64-binfmt-P
flags: POCF
offset 0
magic 7f454c460201010000000000000000000200f300
mask ffffffffffffff00fffffffffffffffffeffffff

Note that the 'P' flag is set.

From the qemu code (linux-user/main.c):
    /*
     * get binfmt_misc flags
     */
    preserve_argv0 = !!(qemu_getauxval(AT_FLAGS) & AT_FLAGS_PRESERVE_ARGV0);

    /*
     * Manage binfmt-misc preserve-arg[0] flag
     * argv[optind] full path to the binary
     * argv[optind + 1] original argv[0]
     */
    if (optind + 1 < argc && preserve_argv0) {
        optind++;
    }

Here, having P enabled will skip the argument.

I believe the debian patch needs to be reworked (https://lists.gnu.org/archive/html/qemu-devel/2021-02/msg04639.html).

This breaks the ability to run debootstrap/mmdebstap for foreign archs.