diff mbox

linux-user: Move qemu-binfmt-conf.sh to Debian model

Message ID 1453903855-4569-1-git-send-email-agraf@suse.de
State New
Headers show

Commit Message

Alexander Graf Jan. 27, 2016, 2:10 p.m. UTC
The qemu-binfmt-conf.sh script has been pretty unmaintained for most of its
time. The reason is simply that few distributions actually use the file as
is.

This patch takes the Debian approach to registering binfmt handlers:

  https://packages.debian.org/en/sid/qemu-user-binfmt

and moves that code into our script, maintaining backwards compatibility with
its previous calling scheme. The major benefit of this is that now Debian can
just do

  HOST_ARCH=$DPKG_MAINTSCRIPT_ARCH
  QEMU_BINFMT_SKIP_REGISTRATION=1
  . /path/to/qemu-binfmt-conf.sh

and get the exact same binfmt configuration as the upstream script, hopefully
ensuring that in the future the upstream version becomes the maintained one.

Because of the merge, we also get a few new architectures added to the script,
like ppc64.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 scripts/qemu-binfmt-conf.sh | 152 +++++++++++++++++++++++++-------------------
 1 file changed, 87 insertions(+), 65 deletions(-)

Comments

Michael Tokarev Jan. 27, 2016, 6:45 p.m. UTC | #1
27.01.2016 17:10, Alexander Graf wrote:
> The qemu-binfmt-conf.sh script has been pretty unmaintained for most of its
> time. The reason is simply that few distributions actually use the file as
> is.

Heh.  I always tried to follow qemu-binfmt-conf.sh in our debian work :)
Granted, later I checked linux-user/main.c (IIRC), too.

> This patch takes the Debian approach to registering binfmt handlers:
> 
>   https://packages.debian.org/en/sid/qemu-user-binfmt

I had a plan to generalize this before next centurity.  The thing is that most
of the formats and masks are the same, the difference is in the endianness,
word size and the architecture.  It might be easier to generate the masks
from the tuples, putting thme 3 fields into places and keepin the rest
the same.  But I haven't got to doing that, so far... :)

See also the fat comment about SYSV vs GNU/LINUX OSABI which needs to
be fixed -- after switching to tuples from masks it will be easier.

> and moves that code into our script, maintaining backwards compatibility with
> its previous calling scheme. The major benefit of this is that now Debian can
> just do
> 
>   HOST_ARCH=$DPKG_MAINTSCRIPT_ARCH
>   QEMU_BINFMT_SKIP_REGISTRATION=1
>   . /path/to/qemu-binfmt-conf.sh
> 
> and get the exact same binfmt configuration as the upstream script, hopefully
> ensuring that in the future the upstream version becomes the maintained one.

I don't think it will work in practice, at least before some good thinking :)
It was a quick hack to generalize things like this, and as per above it needs
some more work (at least to fix the OSABI issue).

But might be it is better than nothing anyway... :)  Provided it is actually
useful, -- do you think it is?

Thanks,

/mjt
Peter Maydell Jan. 27, 2016, 6:54 p.m. UTC | #2
On 27 January 2016 at 18:45, Michael Tokarev <mjt@tls.msk.ru> wrote:
> 27.01.2016 17:10, Alexander Graf wrote:
>> and moves that code into our script, maintaining backwards compatibility with
>> its previous calling scheme. The major benefit of this is that now Debian can
>> just do
>>
>>   HOST_ARCH=$DPKG_MAINTSCRIPT_ARCH
>>   QEMU_BINFMT_SKIP_REGISTRATION=1
>>   . /path/to/qemu-binfmt-conf.sh
>>
>> and get the exact same binfmt configuration as the upstream script, hopefully
>> ensuring that in the future the upstream version becomes the maintained one.
>
> I don't think it will work in practice, at least before some good thinking :)
> It was a quick hack to generalize things like this, and as per above it needs
> some more work (at least to fix the OSABI issue).
>
> But might be it is better than nothing anyway... :)  Provided it is actually
> useful, -- do you think it is?

I was wondering if we should move to supplying the binfmt info
in files of the form used by update-binfmts(8) (which is just a set
of "key value" lines), plus a minimal script to read them. That
at least gets the data (which is what distros will want to deal with)
out of the script (which is mostly of interest to people doing
local hacking, if at all). I'm guessing that distro-specific
format registration handling will be easier to do by parsing data
files than by trying to work with a script.

thanks
-- PMM
Alexander Graf Jan. 28, 2016, 6:56 p.m. UTC | #3
> Am 27.01.2016 um 20:54 schrieb Peter Maydell <peter.maydell@linaro.org>:
> 
>> On 27 January 2016 at 18:45, Michael Tokarev <mjt@tls.msk.ru> wrote:
>> 27.01.2016 17:10, Alexander Graf wrote:
>>> and moves that code into our script, maintaining backwards compatibility with
>>> its previous calling scheme. The major benefit of this is that now Debian can
>>> just do
>>> 
>>>  HOST_ARCH=$DPKG_MAINTSCRIPT_ARCH
>>>  QEMU_BINFMT_SKIP_REGISTRATION=1
>>>  . /path/to/qemu-binfmt-conf.sh
>>> 
>>> and get the exact same binfmt configuration as the upstream script, hopefully
>>> ensuring that in the future the upstream version becomes the maintained one.
>> 
>> I don't think it will work in practice, at least before some good thinking :)
>> It was a quick hack to generalize things like this, and as per above it needs
>> some more work (at least to fix the OSABI issue).
>> 
>> But might be it is better than nothing anyway... :)  Provided it is actually
>> useful, -- do you think it is?
> 
> I was wondering if we should move to supplying the binfmt info
> in files of the form used by update-binfmts(8) (which is just a set
> of "key value" lines), plus a minimal script to read them. That
> at least gets the data (which is what distros will want to deal with)
> out of the script (which is mostly of interest to people doing
> local hacking, if at all). I'm guessing that distro-specific
> format registration handling will be easier to do by parsing data
> files than by trying to work with a script.

FWIW the whole update-binfmts thing is a Debian specific invention. Ideally, someone should clean up the whole binfmt mess, make it container aware and move the registration logic into systemd. Then we could really just provide cross-distro data files.

The main reason I quickly assembled this patch was because the qemu version of the update script was missing a few architectures. The one I realized that with was the ppc64 one ;).

I am not sure what the best option here is. Make the pain grow big enough to get a full solution or at least keep Debian and our in-tree script (which is all that openSUSE provides) in sync?

Alex
Peter Maydell Jan. 28, 2016, 7:08 p.m. UTC | #4
On 28 January 2016 at 18:56, Alexander Graf <agraf@suse.de> wrote:
>
>
>> Am 27.01.2016 um 20:54 schrieb Peter Maydell <peter.maydell@linaro.org>:
>> FWIW the whole update-binfmts thing is a Debian specific invention.

Sure, but it is not inherently incapable of working with another
distribution, it seems like a reasonable attempt to clean
up the binfmt mess, and the file format is easy to ad-hoc parse
anyway.

>> Ideally, someone should clean up the whole binfmt mess, make it
>> container aware and move the registration logic into systemd.
>> Then we could really just provide cross-distro data files.

The last thing we need is for yet another orthogonal thing
to disappear into systemd :-(

thanks
-- PMM
Laurent Vivier Jan. 28, 2016, 7:16 p.m. UTC | #5
Le 27/01/2016 15:10, Alexander Graf a écrit :
> The qemu-binfmt-conf.sh script has been pretty unmaintained for most of its
> time. The reason is simply that few distributions actually use the file as
> is.

I've a version of this script supporting debian, systemd (because it
will rule the world) and credential:

https://github.com/vivier/qemu-m68k/blob/680x0-v2.4.0/scripts/qemu-binfmt-conf.sh

I'm using this for years, on debian/ubuntu and Fedora. To use parameters
is better than env vars, IMHO.

If it can help,
Laurent

> 
> This patch takes the Debian approach to registering binfmt handlers:
> 
>   https://packages.debian.org/en/sid/qemu-user-binfmt
> 
> and moves that code into our script, maintaining backwards compatibility with
> its previous calling scheme. The major benefit of this is that now Debian can
> just do
> 
>   HOST_ARCH=$DPKG_MAINTSCRIPT_ARCH
>   QEMU_BINFMT_SKIP_REGISTRATION=1
>   . /path/to/qemu-binfmt-conf.sh
> 
> and get the exact same binfmt configuration as the upstream script, hopefully
> ensuring that in the future the upstream version becomes the maintained one.
> 
> Because of the merge, we also get a few new architectures added to the script,
> like ppc64.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
>  scripts/qemu-binfmt-conf.sh | 152 +++++++++++++++++++++++++-------------------
>  1 file changed, 87 insertions(+), 65 deletions(-)
> 
> diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
> index 289b1a3..81a39a5 100644
> --- a/scripts/qemu-binfmt-conf.sh
> +++ b/scripts/qemu-binfmt-conf.sh
> @@ -1,72 +1,94 @@
>  #!/bin/sh
>  # enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel
>  
> -# load the binfmt_misc module
> -if [ ! -d /proc/sys/fs/binfmt_misc ]; then
> -  /sbin/modprobe binfmt_misc
> -fi
> -if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
> -  mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
> -fi
> +fmts="aarch64 alpha arm armeb cris i386 m68k microblaze mips mipsel mips64 mips64el ppc ppc64 ppc64abi32 ppc64le s390x sh4 sh4eb sparc sparc32plus sparc64 x86_64"
> +
> +# linux ELF_OSABI(byte7) can be 0 (traditional,SYSV) or 3 (GNU/LINUX extensions)
> +# binfmt registration does not allow a enum, only value&mask.  So we use broader mask
> +# to allow both 0 and 3 here, this also lets 1 (HPUX) and 2 (NETBSD) - 0xfc not 0xff
> +# alternative is to create 2 magic/mask pairs instead of one
>  
> -# probe cpu type
> -cpu=`uname -m`
> -case "$cpu" in
> -  i386|i486|i586|i686|i86pc|BePC|x86_64)
> -    cpu="i386"
> -  ;;
> -  m68k)
> -    cpu="m68k"
> -  ;;
> -  mips*)
> -    cpu="mips"
> -  ;;
> -  "Power Macintosh"|ppc|ppc64)
> -    cpu="ppc"
> -  ;;
> -  armv[4-9]*)
> -    cpu="arm"
> -  ;;
> +    aarch64_magic='\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00'
> +     aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +      alpha_magic='\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90'
> +       alpha_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +        arm_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'
> +         arm_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +      armeb_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
> +       armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +       cris_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x4c\x00'
> +        cris_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +       i386_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
> +        i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +       m68k_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04'
> +        m68k_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> + microblaze_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xba\xab'
> +  microblaze_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +       mips_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
> +        mips_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +     mipsel_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
> +      mipsel_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +     mips64_magic='\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
> +      mips64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +   mips64el_magic='\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
> +    mips64el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +        ppc_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'
> +         ppc_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +      ppc64_magic='\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15'
> +       ppc64_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> + ppc64abi32_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15'
> +  ppc64abi32_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +      s390x_magic='\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16'
> +       s390x_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +        sh4_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00'
> +         sh4_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +      sh4eb_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a'
> +       sh4eb_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +      sparc_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
> +       sparc_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +sparc32plus_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12'
> + sparc32plus_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +    sparc64_magic='\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2b'
> +     sparc64_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +     x86_64_magic='\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00'
> +      x86_64_mask='\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +    ppc64le_magic='\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00'
> +     ppc64le_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00'
> +
> +# find which fmts needs to be filtered out, which is arch-dependent.
> +# Drop support for emulating amd64 on i386, http://bugs.debian.org/604712
> +# Also give scripts that source this file a chance to override the architecture
> +[ "$HOST_ARCH" ] || HOST_ARCH=`uname -m`
> +case "$HOST_ARCH" in
> +    amd64 | i386 | i486 |i586 | i686 | i86pc | BePC | x86_64) omit="i386|x86_64" ;;
> +    arm | armel | armhf | arm64 | armv[4-9]*) omit="arm|aarch64" ;;
> +    ppc64 | powerpc | "Power Macintosh" | ppc) omit="ppc|ppc64|ppc64abi32" ;;
> +    ppc64el) omit="ppc64le" ;;
> +    sparc | sparc64) omit="sparc|sparc32plus|sparc64" ;;
> +    *) omit="$HOST_ARCH" ;;
>  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
> -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
> -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
> -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
> -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
> -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
> -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
> -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
> -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
> -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
> +if [ ! "$QEMU_BINFMT_SKIP_REGISTRATION" ]; then
> +    function add_binfmt_map() {
> +        ARCH="$1"
> +        MAGIC="$2"
> +        MASK="$3"
> +
> +        echo ":$ARCH:M::$MAGIC:$MASK:/usr/local/bin/qemu-$fmt:" > /proc/sys/fs/binfmt_misc/register
> +    }
> +
> +    # load the binfmt_misc module
> +    if [ ! -d /proc/sys/fs/binfmt_misc ]; then
> +      /sbin/modprobe binfmt_misc
> +    fi
> +
> +    if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
> +      mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
> +    fi
> +
> +    # register the interpreter for each cpu except for the native one
> +    for fmt in $fmts ; do
> +        eval "case $fmt in $omit) magic= ;; *) magic=\"\$${fmt}_magic\" mask=\"\$${fmt}_mask\" ;; esac"
> +        [ "$magic" ] && add_binfmt_map "$fmt" "$magic" "$mask"
> +    done
>  fi
>
Alexander Graf Jan. 28, 2016, 7:22 p.m. UTC | #6
On 01/28/2016 08:16 PM, Laurent Vivier wrote:
>
> Le 27/01/2016 15:10, Alexander Graf a écrit :
>> The qemu-binfmt-conf.sh script has been pretty unmaintained for most of its
>> time. The reason is simply that few distributions actually use the file as
>> is.
> I've a version of this script supporting debian, systemd (because it
> will rule the world) and credential:
>
> https://github.com/vivier/qemu-m68k/blob/680x0-v2.4.0/scripts/qemu-binfmt-conf.sh
>
> I'm using this for years, on debian/ubuntu and Fedora. To use parameters
> is better than env vars, IMHO.

Yes, your version looks a lot more advanced than mine. The only thing 
I'm missing is for a simple "give me all cpu types" so that programmatic 
systemd file generation doesn't have to grep through the usage help text.

Also, no arguments should probably preserve the old behavior of just 
registering it locally.

Care to push it upstream? :)


Alex
Laurent Vivier Jan. 28, 2016, 7:27 p.m. UTC | #7
Le 28/01/2016 20:22, Alexander Graf a écrit :
> 
> 
> On 01/28/2016 08:16 PM, Laurent Vivier wrote:
>>
>> Le 27/01/2016 15:10, Alexander Graf a écrit :
>>> The qemu-binfmt-conf.sh script has been pretty unmaintained for most
>>> of its
>>> time. The reason is simply that few distributions actually use the
>>> file as
>>> is.
>> I've a version of this script supporting debian, systemd (because it
>> will rule the world) and credential:
>>
>> https://github.com/vivier/qemu-m68k/blob/680x0-v2.4.0/scripts/qemu-binfmt-conf.sh
>>
>>
>> I'm using this for years, on debian/ubuntu and Fedora. To use parameters
>> is better than env vars, IMHO.
> 
> Yes, your version looks a lot more advanced than mine. The only thing
> I'm missing is for a simple "give me all cpu types" so that programmatic
> systemd file generation doesn't have to grep through the usage help text.
> 
> Also, no arguments should probably preserve the old behavior of just
> registering it locally.
> 
> Care to push it upstream? :)

Last time I tried, Peter would prefer to separate data and scripts:

https://patchwork.ozlabs.org/patch/478486/

and I'm not ready to do that (to much work for what I want).

Peter, if you agree to take the file as-is, I can resend the last
version. :)

Laurent
Alexander Graf Jan. 28, 2016, 7:35 p.m. UTC | #8
> Am 28.01.2016 um 21:27 schrieb Laurent Vivier <laurent@vivier.eu>:
> 
> 
> 
> Le 28/01/2016 20:22, Alexander Graf a écrit :
>> 
>> 
>>> On 01/28/2016 08:16 PM, Laurent Vivier wrote:
>>> 
>>> Le 27/01/2016 15:10, Alexander Graf a écrit :
>>>> The qemu-binfmt-conf.sh script has been pretty unmaintained for most
>>>> of its
>>>> time. The reason is simply that few distributions actually use the
>>>> file as
>>>> is.
>>> I've a version of this script supporting debian, systemd (because it
>>> will rule the world) and credential:
>>> 
>>> https://github.com/vivier/qemu-m68k/blob/680x0-v2.4.0/scripts/qemu-binfmt-conf.sh
>>> 
>>> 
>>> I'm using this for years, on debian/ubuntu and Fedora. To use parameters
>>> is better than env vars, IMHO.
>> 
>> Yes, your version looks a lot more advanced than mine. The only thing
>> I'm missing is for a simple "give me all cpu types" so that programmatic
>> systemd file generation doesn't have to grep through the usage help text.
>> 
>> Also, no arguments should probably preserve the old behavior of just
>> registering it locally.
>> 
>> Care to push it upstream? :)
> 
> Last time I tried, Peter would prefer to separate data and scripts:
> 
> https://patchwork.ozlabs.org/patch/478486/
> 
> and I'm not ready to do that (to much work for what I want).
> 
> Peter, if you agree to take the file as-is, I can resend the last
> version. :)

The script can generate data files just fine, no? So if a distro only wants those, they can call the script at packaging time.

Alex

> 
> Laurent
Peter Maydell Jan. 28, 2016, 7:36 p.m. UTC | #9
On 28 January 2016 at 19:35, Alexander Graf <agraf@suse.de> wrote:
>> Am 28.01.2016 um 21:27 schrieb Laurent Vivier <laurent@vivier.eu>:
>> Peter, if you agree to take the file as-is, I can resend the last
>> version. :)
>
> The script can generate data files just fine, no? So if a distro
> only wants those, they can call the script at packaging time.

I prefer data files because I think they're easier to maintain
from the QEMU source point of view (for instance adding a new
target is just adding a file for the target, rather than having to
edit a script).

But we can take Laurent's script and then data-ify it afterwards.

thanks
-- PMM
Laurent Vivier Jan. 28, 2016, 7:40 p.m. UTC | #10
Le 28/01/2016 20:36, Peter Maydell a écrit :
> On 28 January 2016 at 19:35, Alexander Graf <agraf@suse.de> wrote:
>>> Am 28.01.2016 um 21:27 schrieb Laurent Vivier <laurent@vivier.eu>:
>>> Peter, if you agree to take the file as-is, I can resend the last
>>> version. :)
>>
>> The script can generate data files just fine, no? So if a distro
>> only wants those, they can call the script at packaging time.
> 
> I prefer data files because I think they're easier to maintain
> from the QEMU source point of view (for instance adding a new
> target is just adding a file for the target, rather than having to
> edit a script).

I understand your point of view: the difficulty is to allow the script
to find the data files: I like to use the script directly from the
qemu/scripts directory and to not install it (so no path configured in
the scripts).

> But we can take Laurent's script and then data-ify it afterwards.

I totally agree with that ;)
I'm going to send the patch...

Thanks,
Laurent
Peter Maydell Jan. 28, 2016, 7:45 p.m. UTC | #11
On 28 January 2016 at 19:40, Laurent Vivier <laurent@vivier.eu> wrote:
>
>
> Le 28/01/2016 20:36, Peter Maydell a écrit :
>> On 28 January 2016 at 19:35, Alexander Graf <agraf@suse.de> wrote:
>>>> Am 28.01.2016 um 21:27 schrieb Laurent Vivier <laurent@vivier.eu>:
>>>> Peter, if you agree to take the file as-is, I can resend the last
>>>> version. :)
>>>
>>> The script can generate data files just fine, no? So if a distro
>>> only wants those, they can call the script at packaging time.
>>
>> I prefer data files because I think they're easier to maintain
>> from the QEMU source point of view (for instance adding a new
>> target is just adding a file for the target, rather than having to
>> edit a script).
>
> I understand your point of view: the difficulty is to allow the script
> to find the data files: I like to use the script directly from the
> qemu/scripts directory and to not install it (so no path configured in
> the scripts).

"Find the directory the script is in" is easy:
THISDIR="$(cd "$(dirname "$0")"; pwd)"

We don't ever install that script anywhere, so we don't need to
worry about the "script has been installed" case.

thanks
-- PMM
diff mbox

Patch

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index 289b1a3..81a39a5 100644
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -1,72 +1,94 @@ 
 #!/bin/sh
 # enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel
 
-# load the binfmt_misc module
-if [ ! -d /proc/sys/fs/binfmt_misc ]; then
-  /sbin/modprobe binfmt_misc
-fi
-if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
-  mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
-fi
+fmts="aarch64 alpha arm armeb cris i386 m68k microblaze mips mipsel mips64 mips64el ppc ppc64 ppc64abi32 ppc64le s390x sh4 sh4eb sparc sparc32plus sparc64 x86_64"
+
+# linux ELF_OSABI(byte7) can be 0 (traditional,SYSV) or 3 (GNU/LINUX extensions)
+# binfmt registration does not allow a enum, only value&mask.  So we use broader mask
+# to allow both 0 and 3 here, this also lets 1 (HPUX) and 2 (NETBSD) - 0xfc not 0xff
+# alternative is to create 2 magic/mask pairs instead of one
 
-# probe cpu type
-cpu=`uname -m`
-case "$cpu" in
-  i386|i486|i586|i686|i86pc|BePC|x86_64)
-    cpu="i386"
-  ;;
-  m68k)
-    cpu="m68k"
-  ;;
-  mips*)
-    cpu="mips"
-  ;;
-  "Power Macintosh"|ppc|ppc64)
-    cpu="ppc"
-  ;;
-  armv[4-9]*)
-    cpu="arm"
-  ;;
+    aarch64_magic='\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00'
+     aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+      alpha_magic='\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90'
+       alpha_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+        arm_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'
+         arm_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+      armeb_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
+       armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+       cris_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x4c\x00'
+        cris_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+       i386_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
+        i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+       m68k_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04'
+        m68k_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+ microblaze_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xba\xab'
+  microblaze_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+       mips_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
+        mips_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+     mipsel_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
+      mipsel_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+     mips64_magic='\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
+      mips64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+   mips64el_magic='\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
+    mips64el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+        ppc_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'
+         ppc_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+      ppc64_magic='\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15'
+       ppc64_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+ ppc64abi32_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15'
+  ppc64abi32_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+      s390x_magic='\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16'
+       s390x_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+        sh4_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00'
+         sh4_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+      sh4eb_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a'
+       sh4eb_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+      sparc_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
+       sparc_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+sparc32plus_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12'
+ sparc32plus_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+    sparc64_magic='\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2b'
+     sparc64_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+     x86_64_magic='\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00'
+      x86_64_mask='\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+    ppc64le_magic='\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00'
+     ppc64le_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00'
+
+# find which fmts needs to be filtered out, which is arch-dependent.
+# Drop support for emulating amd64 on i386, http://bugs.debian.org/604712
+# Also give scripts that source this file a chance to override the architecture
+[ "$HOST_ARCH" ] || HOST_ARCH=`uname -m`
+case "$HOST_ARCH" in
+    amd64 | i386 | i486 |i586 | i686 | i86pc | BePC | x86_64) omit="i386|x86_64" ;;
+    arm | armel | armhf | arm64 | armv[4-9]*) omit="arm|aarch64" ;;
+    ppc64 | powerpc | "Power Macintosh" | ppc) omit="ppc|ppc64|ppc64abi32" ;;
+    ppc64el) omit="ppc64le" ;;
+    sparc | sparc64) omit="sparc|sparc32plus|sparc64" ;;
+    *) omit="$HOST_ARCH" ;;
 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
-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
-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
-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
-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
-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
-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
-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
-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
-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
+if [ ! "$QEMU_BINFMT_SKIP_REGISTRATION" ]; then
+    function add_binfmt_map() {
+        ARCH="$1"
+        MAGIC="$2"
+        MASK="$3"
+
+        echo ":$ARCH:M::$MAGIC:$MASK:/usr/local/bin/qemu-$fmt:" > /proc/sys/fs/binfmt_misc/register
+    }
+
+    # load the binfmt_misc module
+    if [ ! -d /proc/sys/fs/binfmt_misc ]; then
+      /sbin/modprobe binfmt_misc
+    fi
+
+    if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
+      mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
+    fi
+
+    # register the interpreter for each cpu except for the native one
+    for fmt in $fmts ; do
+        eval "case $fmt in $omit) magic= ;; *) magic=\"\$${fmt}_magic\" mask=\"\$${fmt}_mask\" ;; esac"
+        [ "$magic" ] && add_binfmt_map "$fmt" "$magic" "$mask"
+    done
 fi