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
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() { Println( "Args are");
fmt.Println( i, a); 9kA-_aeKgZkwtyY VUb7o/F43JNW5Xx PX9ScBQrfs8/ l6EzXXq8x8pfor- ByIh4/_ zELq4T9- VKcpBXoempb,
fmt.
for i, a := range os.Args {
}
}
$ 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=
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: qemu-binfmt/ riscv64- binfmt- P /path/to/rv /path/to/rv one two
$ /usr/libexec/
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 qemu-binfmt/ riscv64- binfmt- P 000000000000000 000200f300 0ffffffffffffff fffeffffff
enabled
interpreter /usr/libexec/
flags: POCF
offset 0
magic 7f454c460201010
mask ffffffffffffff0
Note that the 'P' flag is set.
From the qemu code (linux- user/main. c): getauxval( AT_FLAGS) & AT_FLAGS_ PRESERVE_ ARGV0);
/*
* get binfmt_misc flags
*/
preserve_argv0 = !!(qemu_
/*
* 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.