Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 516454 - app-emulation/qemu - add binfmt wrapper for argv[0] handling
Summary: app-emulation/qemu - add binfmt wrapper for argv[0] handling
Status: RESOLVED OBSOLETE
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo QEMU Project
URL: https://lists.gnu.org/archive/html/qe...
Whiteboard:
Keywords: PATCH
Depends on:
Blocks:
 
Reported: 2014-07-05 15:29 UTC by Andrew Aladjev
Modified: 2017-05-04 18:39 UTC (History)
2 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
patch to qemu-2.0.0-r1.ebuild (qemu-2.0.0-r1.patch,3.60 KB, patch)
2014-07-05 15:31 UTC, Andrew Aladjev
Details | Diff
binfmt wrapper (qemu-9999-binfmt-wrapper.patch,2.35 KB, patch)
2014-07-05 15:32 UTC, Andrew Aladjev
Details | Diff
binfmt-wrapper initd (qemu-binfmt-wrapper.initd-r1,7.35 KB, text/plain)
2014-07-05 15:32 UTC, Andrew Aladjev
Details
detect binfmt when O flag is on and handle argv0 correctly (0001-linux-user-make-binfmt-flag-O-require-P.patch,11.44 KB, text/plain)
2014-07-15 14:02 UTC, Joakim Tjernlund
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Aladjev 2014-07-05 15:29:58 UTC
Gentoo project describes the simpliest version of such wrapper in handbook https://www.gentoo.org/proj/en/base/embedded/handbook/?part=1&chap=5

Qemu upstream dont't want to add such wrapper (I don't know why) https://lists.gnu.org/archive/html/qemu-devel/2011-09/msg03841.html

Gentoo users are unhappy https://bugs.gentoo.org/show_bug.cgi?id=512780
See Steev Klimaszewski's comment.

Reproducible: Always

Steps to Reproduce:
1. emerge -v qemu-user
2. rc-service qemu-binfmt start
3. cp $(which qemu-arm) dir/usr/bin
4. cp $(which qemu-arm-binfmt) dir/usr/bin
5. chroot dir/

After provided patches:

1. USE="binfmt-wrapper static-user" emerge -v qemu
2. rc-service qemu-binfmt-wrapper start
3. cp $(which qemu-arm) dir/usr/bin
4. cp $(which qemu-arm-binfmt-wrapper) dir/usr/bin
5. chroot dir/
Comment 1 Andrew Aladjev 2014-07-05 15:31:41 UTC
Created attachment 380248 [details, diff]
patch to qemu-2.0.0-r1.ebuild
Comment 2 Andrew Aladjev 2014-07-05 15:32:18 UTC
Created attachment 380250 [details, diff]
binfmt wrapper
Comment 3 Andrew Aladjev 2014-07-05 15:32:59 UTC
Created attachment 380252 [details]
binfmt-wrapper initd
Comment 4 Andrew Aladjev 2014-07-05 15:38:45 UTC
You can checkout an example of binfmt wrapper's usage on my site https://www.puchuu.com/posts/aarch64-chroot.html
Comment 5 Joakim Tjernlund 2014-07-10 20:53:42 UTC
I just created a ppc LXC(had to patch the template a tiny bit first *):
 lxc-create -n jocke-ppc-org -t gentoo -- -a ppc -v ppc

Added to lxc config(and created an empty qemu-ppc file):
 lxc.mount.entry=/usr/bin/qemu-ppc usr/bin/qemu-ppc none ro,bind 0 0

The lxc would not boot properly until I changed the binfmt flag
from P to CO

Do we really need the P flag in the binfmt?
Why not just switch over to CO for all?


*) Redefined chroot in lxc-gentoo template to
chroot()
{
    rr=$1

    shift 1
    proot -w / -r "${rr}" -q qemu-ppc "$@"
}

BTW, ssh generates a lot of:
Invalid instruction
NIP 6ff46584   LR 6ff46944 CTR 6fbd0504 XER 00000000
MSR 00006040 HID0 00000000  HF 00006000 idx 0
TB 00000000 00000000

as it tries differents insn to optimize.
Is there a way to tell qemu to stop logging these msgs?
Comment 6 Fedja Beader 2014-07-13 16:37:22 UTC
Why do you even need such a wrapper?

Run QEMU_CPU=cortex-a8 chroot dir


As far as echo 'blablabla' > /.../binfmt goes, I know the ARM one was broken ~2-3 years ago.
Comment 7 Joakim Tjernlund 2014-07-14 08:16:30 UTC
I too really need this. If there is a problem adding this to the qemu ebuild, perhaps it can be its own package instead? I don't see any hard deps on qemu
itself so maybe easier to do a qemu-binfmt.ebuild instead?
Comment 8 Joakim Tjernlund 2014-07-14 08:18:25 UTC
(In reply to Fedja Beader from comment #6)
> Why do you even need such a wrapper?
> 
> Run QEMU_CPU=cortex-a8 chroot dir
> 
> 
> As far as echo 'blablabla' > /.../binfmt goes, I know the ARM one was broken
> ~2-3 years ago.

This is not about the CPU, it is about argv[0] handling.
Try booting a lxc container under qemu
Comment 9 Joakim Tjernlund 2014-07-14 11:01:49 UTC
One thing hit me, this wrapper has a dynamic connection to qemu-arch so
in cahr och chroot/lxc one need both qemu-arch and the wrapper in the
chroot FS.
It would be better to patch qemu-user directly(aka busybos) so it can do the wrapper thing directly.
Comment 10 Joakim Tjernlund 2014-07-14 14:40:34 UTC
I just sent this patch uptream:

From 707dd7b2ae97d7a7fdd2e3c4da0f6c5997aff5ac Mon Sep 17 00:00:00 2001
From: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Date: Mon, 14 Jul 2014 16:23:39 +0200
Subject: [PATCH] linux-user: Add binfmt wrapper

The popular binfmt-wrapper patch adds an additional
executable which mangle argv suitable for binfmt flag P.
In a chroot you need the both (statically linked) qemu-$arch
and qemu-$arch-binfmt-wrapper. This is sub optimal and a
better approach is to recognize the -binfmt-wrapper extension
within linux-user(qemu-$arch) and mangle argv there.
This just produces on executable which can be either copied to
the chroot or bind mounted with the appropriate -binfmt-wrapper
suffix.

Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
---
 linux-user/main.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 71a33c7..212067a 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3828,6 +3828,19 @@ int main(int argc, char **argv, char **envp)
     int i;
     int ret;
     int execfd;
+    char *binfmt;
+
+    i = strlen( argv[0] ) - strlen ( "-binfmt-wrapper" );
+    binfmt = argv[0] + i;
+    if (i > 0 && strcmp ( binfmt, "-binfmt-wrapper" ) == 0) {
+	if (argc < 3 ) {
+	    fprintf ( stderr, "%s: Please use me through binfmt with P flag\n", argv[0] );
+	    exit(1);
+	}
+	handle_arg_argv0(argv[2]); /* binfmt wrapper */
+	memmove(&argv[2], &argv[3], (argc-2)*sizeof(argv));
+	argc--;
+    }
 
     module_call_init(MODULE_INIT_QOM);
 
-- 
1.8.5.5
Comment 11 Joakim Tjernlund 2014-07-14 19:00:21 UTC
Even better patch, has a change to be included in upstream too,
apply and change you binfmt to OP and you are done:

From 9642c6e122a7c12c68a6c09a1ebb713c4935956d Mon Sep 17 00:00:00 2001
From: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Date: Mon, 14 Jul 2014 20:17:28 +0200
Subject: [PATCH v2] linux-user: make binfmt flag O require P

Qemu can autodetect if it is started from Linux binfmt loader
when binfmt flag O is on.
Use that and require binfmt flag P as well which will enable QEMU
to pass in correct argv0 to the application.

Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
---
 linux-user/main.c           | 13 ++++++++++++-
 scripts/qemu-binfmt-conf.sh | 36 ++++++++++++++++++------------------
 2 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 71a33c7..9736768 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3829,6 +3829,18 @@ int main(int argc, char **argv, char **envp)
     int ret;
     int execfd;
 
+    execfd = qemu_getauxval(AT_EXECFD);
+    if (execfd > 0 ) {
+        if (argc < 3) {
+            fprintf(stderr, "%s: Please use me through binfmt with P flag\n",
+                    argv[0]);
+            exit(1);
+        }
+        handle_arg_argv0(argv[2]); /* binfmt wrapper */
+        memmove(&argv[2], &argv[3], (argc-2)*sizeof(argv));
+        argc--;
+    }
+
     module_call_init(MODULE_INIT_QOM);
 
     if ((envlist = envlist_create()) == NULL) {
@@ -4003,7 +4015,6 @@ int main(int argc, char **argv, char **envp)
     cpu->opaque = ts;
     task_settid(ts);
 
-    execfd = qemu_getauxval(AT_EXECFD);
     if (execfd == 0) {
         execfd = open(filename, O_RDONLY);
         if (execfd < 0) {
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index 289b1a3..36fcb8f 100644
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -31,42 +31,42 @@ esac
 
 # register the interpreter for each cpu except for the native one
 if [ $cpu != "i386" ] ; then
-    echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
-    echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
+    echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:PO' > /proc/sys/fs/binfmt_misc/register
+    echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:PO' > /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != "alpha" ] ; then
-    echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register
+    echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:PO' > /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != "arm" ] ; then
-    echo   ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:PO' > /proc/sys/fs/binfmt_misc/register
+    echo   ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:PO' > /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != "aarch64" ] ; then
-    echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register
+    echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-aarch64:PO' > /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != "sparc" ] ; then
-    echo   ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:PO' > /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != "ppc" ] ; then
-    echo   ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:PO' > /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != "m68k" ] ; then
     echo   'Please check cpu value and header information for m68k!'
-    echo   ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:PO' > /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != "mips" ] ; then
     # FIXME: We could use the other endianness on a MIPS host.
-    echo   ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:PO' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:PO' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:PO' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:PO' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:PO' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:PO' > /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != "sh" ] ; then
-    echo    ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register
-    echo    ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register
+    echo    ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:PO' > /proc/sys/fs/binfmt_misc/register
+    echo    ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:PO' > /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != "s390x" ] ; then
-    echo   ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:PO' > /proc/sys/fs/binfmt_misc/register
 fi
-- 
1.8.5.5
Comment 12 Joakim Tjernlund 2014-07-14 19:02:16 UTC
This patch can be added on to if you want both:

From a7a847f50470168ad18fcca5ce32c9e6ed468b00 Mon Sep 17 00:00:00 2001
From: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Date: Mon, 14 Jul 2014 20:24:53 +0200
Subject: [PATCH] linux-user: Add binfmt wrapper

The popular binfmt-wrapper patch adds an additional
executable which mangle argv suitable for binfmt flag P.
In a chroot you need the both (statically linked) qemu-$arch
and qemu-$arch-binfmt-wrapper. This is sub optimal and a
better approach is to recognize the -binfmt-wrapper extension
within linux-user(qemu-$arch) and mangle argv there.
This just produces on executable which can be either copied to
the chroot or bind mounted with the appropriate -binfmt-wrapper
suffix.

Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
---
 linux-user/main.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 9736768..039f3ba 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3828,9 +3828,12 @@ int main(int argc, char **argv, char **envp)
     int i;
     int ret;
     int execfd;
+    char *binfmt;
 
+    i = strlen(argv[0]) - strlen("-binfmt-wrapper");
+    binfmt = argv[0] + i;
     execfd = qemu_getauxval(AT_EXECFD);
-    if (execfd > 0 ) {
+    if (execfd > 0 || i > 0 && strcmp(binfmt, "-binfmt-wrapper") == 0) {
         if (argc < 3) {
             fprintf(stderr, "%s: Please use me through binfmt with P flag\n",
                     argv[0]);
-- 
1.8.5.5
Comment 13 Joakim Tjernlund 2014-07-15 13:59:17 UTC
This is the latest version, likely to be applied upstream but probably
not before 2.1.

Remember to change binfmg flags from P to PO also.
Comment 14 Joakim Tjernlund 2014-07-15 14:02:14 UTC
Created attachment 380746 [details]
detect binfmt when O flag is on and handle argv0 correctly

You can skip the qemu-binfmt-conf.sh part as Gentoo does not use
that script anyway.
Comment 15 Joakim Tjernlund 2014-07-21 08:06:29 UTC
Ping?
Comment 16 Joakim Tjernlund 2014-07-22 12:37:24 UTC
QEMU Team, this patch isn't going into 2.1
I hope you can manage this one as a gentoo addon until >2.1
Comment 17 SpanKY gentoo-dev 2014-08-04 06:44:49 UTC
ugh, your patches are a mess.  never post them as a comment as bugzilla corrupts them, and it makes reading the bug a huge pain.

i'm not sure i agree with the way you're hacking things into the linux-user main, but if upstream is going to take that stuff, then we can wait for them.  this is not critical at all that i can see.
Comment 18 SpanKY gentoo-dev 2014-08-06 12:53:21 UTC
i was thinking that the wrapper would need to be compiled for each target, but that is not the case after all.  i guess let's see how upstream wants to take things before we go merging stuff.
Comment 19 Joakim Tjernlund 2014-08-06 18:14:23 UTC
(In reply to SpanKY from comment #17)
> ugh, your patches are a mess.  never post them as a comment as bugzilla
> corrupts them, and it makes reading the bug a huge pain.

Yeah, noticed that and did the last patch as an attatchment, sorry.
The first few patches are just hacks that worked but got refined as I gained
a better understanding.
> 
> i'm not sure i agree with the way you're hacking things into the linux-user
> main, but if upstream is going to take that stuff, then we can wait for
> them.  this is not critical at all that i can see.

Hmm, the last one has been reworked per upstream request, I even had to update
their binfmt script too.
It is semi critical as without P flag it sometimes work but not always in
a LXC for instance.
Comment 20 Joakim Tjernlund 2014-08-06 18:21:01 UTC
(In reply to SpanKY from comment #18)
> i was thinking that the wrapper would need to be compiled for each target,
> but that is not the case after all.  i guess let's see how upstream wants to
> take things before we go merging stuff.

Yes, the point is that the same qemu-ARCH should be usable as a binfmt interpreter and as a normal user app.

Qemu-user is not the fastest moving part of qemu but hopfully it will show
up in a few days. I am on vacation anyway :)
Comment 22 Joakim Tjernlund 2014-10-16 20:17:25 UTC
(In reply to SpanKY from comment #21)
> Comment on attachment 380250 [details, diff] [details, diff]
> binfmt wrapper
> 
> fwiw, i wrote a similar wrapper and we use it CrOS now:
> https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/
> release-R38-6158.B/app-emulation/qemu-binfmt-wrapper/files/qemu-binfmt-
> wrapper.c

ehh, why did you do that when my patch fixes the problem proper?
Would be better if you also complained at upstream so they see that
this is a problem.
The only reason they haven't applied it is that the worry about breaking
non distribution users setups.
Comment 23 SpanKY gentoo-dev 2014-11-11 05:32:42 UTC
(In reply to Joakim Tjernlund from comment #22)

because mainline qemu doesn't yet work :)
Comment 24 Matthias Maier gentoo-dev 2017-05-04 18:39:03 UTC
This problem has been fixed a long time ago :-)

With current qemu-2.8/qemu-2.9 and installed binfmt handlers:

( $ cd /tmp/arm-chroot
  $ unshare ... )
  $ chroot . /bin/bash
  $ echo $0
  /bin/bash

where ps reports:

  ... \_ /usr/bin/qemu-arm /bin/bash