diff mbox

[v2] linux-user: make binfmt flag O require P

Message ID OF10AA8325.4F4D7EC2-ONC1257D15.00769332-C1257D15.0076BF6C@transmode.se
State New
Headers show

Commit Message

Joakim Tjernlund July 14, 2014, 9:37 p.m. UTC
Joakim Tjernlund/Transmode wrote on 2014/07/14 23:04:51:
> > Why do we need to modify argv[] here when we are building a
> > target_argv[] further down anyway?

> Because parse_opts() will not do it for me and I cannot figure out how 
to modify
> parse_opts() whithout breaking it.

I took another look and now I came up with:

From 886985747369947e3b28d7a5fb807abd4beae10c 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] 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           | 16 +++++++++++++---
 scripts/qemu-binfmt-conf.sh | 36 ++++++++++++++++++------------------
 2 files changed, 31 insertions(+), 21 deletions(-)

> /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

Comments

Alexander Graf July 15, 2014, 12:02 p.m. UTC | #1
On 07/14/2014 11:37 PM, Joakim Tjernlund wrote:
> Joakim Tjernlund/Transmode wrote on 2014/07/14 23:04:51:
>>> Why do we need to modify argv[] here when we are building a
>>> target_argv[] further down anyway?
>> Because parse_opts() will not do it for me and I cannot figure out how
> to modify
>> parse_opts() whithout breaking it.
> I took another look and now I came up with:
>
>  From 886985747369947e3b28d7a5fb807abd4beae10c 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] 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>

Acked-by: Alexander Graf <agraf@suse.de>


Alex
Riku Voipio July 15, 2014, 1:20 p.m. UTC | #2
On Mon, Jul 14, 2014 at 11:37:02PM +0200, Joakim Tjernlund wrote:
> Joakim Tjernlund/Transmode wrote on 2014/07/14 23:04:51:
> > > Why do we need to modify argv[] here when we are building a
> > > target_argv[] further down anyway?
> 
> > Because parse_opts() will not do it for me and I cannot figure out how 
> to modify
> > parse_opts() whithout breaking it.
 
> I took another look and now I came up with:

Looks good for me too, but I think a little too disruptive for 2.1 which
is now in rc's ?

Riku

> >From 886985747369947e3b28d7a5fb807abd4beae10c 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] 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           | 16 +++++++++++++---
>  scripts/qemu-binfmt-conf.sh | 36 ++++++++++++++++++------------------
>  2 files changed, 31 insertions(+), 21 deletions(-)
> 
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 71a33c7..845d4e3 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -3750,7 +3750,7 @@ static void usage(void)
>      exit(1);
>  }
>  
> -static int parse_args(int argc, char **argv)
> +static int parse_args(int argc, char **argv, int assume_P_flag)
>  {
>      const char *r;
>      int optind;
> @@ -3768,6 +3768,16 @@ static int parse_args(int argc, char **argv)
>      }
>  
>      optind = 1;
> +    if (assume_P_flag) {
> +        /* Assume binfmt P flag is set */
> +        if (argc < 3) {
> +            fprintf(stderr, "%s: Please use me through binfmt with P 
> flag\n",
> +                    argv[0]);
> +            exit(1);
> +        }
> +        argv0 = strdup(argv[2]);
> +        optind++;
> +    }
>      for (;;) {
>          if (optind >= argc) {
>              break;
> @@ -3857,7 +3867,8 @@ int main(int argc, char **argv, char **envp)
>      cpudef_setup(); /* parse cpu definitions in target config file (TBD) 
> */
>  #endif
>  
> -    optind = parse_args(argc, argv);
> +    execfd = qemu_getauxval(AT_EXECFD);
> +    optind = parse_args(argc, argv, execfd > 0);
>  
>      /* Zero out regs */
>      memset(regs, 0, sizeof(struct target_pt_regs));
> @@ -4003,7 +4014,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
Alexander Graf July 15, 2014, 1:21 p.m. UTC | #3
> Am 15.07.2014 um 15:20 schrieb Riku Voipio <riku.voipio@iki.fi>:
> 
>> On Mon, Jul 14, 2014 at 11:37:02PM +0200, Joakim Tjernlund wrote:
>> Joakim Tjernlund/Transmode wrote on 2014/07/14 23:04:51:
>>>> Why do we need to modify argv[] here when we are building a
>>>> target_argv[] further down anyway?
>> 
>>> Because parse_opts() will not do it for me and I cannot figure out how
>> to modify
>>> parse_opts() whithout breaking it.
> 
>> I took another look and now I came up with:
> 
> Looks good for me too, but I think a little too disruptive for 2.1 which
> is now in rc's ?

Yes, it's definitely 2.2 material.

Alex
Joakim Tjernlund July 15, 2014, 1:45 p.m. UTC | #4
Riku Voipio <riku.voipio@iki.fi> wrote on 2014/07/15 15:20:35:
> 
> On Mon, Jul 14, 2014 at 11:37:02PM +0200, Joakim Tjernlund wrote:
> > Joakim Tjernlund/Transmode wrote on 2014/07/14 23:04:51:
> > > > Why do we need to modify argv[] here when we are building a
> > > > target_argv[] further down anyway?
> > 
> > > Because parse_opts() will not do it for me and I cannot figure out 
how 
> > to modify
> > > parse_opts() whithout breaking it.
> 
> > I took another look and now I came up with:
> 
> Looks good for me too, but I think a little too disruptive for 2.1 which
> is now in rc's ?

Was just about to send you v2 :)

Considering binfmt does not work for qemu-user without external hacks you
may want to reconsider.
You would have to test it a bit more though I guess, your call.
diff mbox

Patch

diff --git a/linux-user/main.c b/linux-user/main.c
index 71a33c7..845d4e3 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3750,7 +3750,7 @@  static void usage(void)
     exit(1);
 }
 
-static int parse_args(int argc, char **argv)
+static int parse_args(int argc, char **argv, int assume_P_flag)
 {
     const char *r;
     int optind;
@@ -3768,6 +3768,16 @@  static int parse_args(int argc, char **argv)
     }
 
     optind = 1;
+    if (assume_P_flag) {
+        /* Assume binfmt P flag is set */
+        if (argc < 3) {
+            fprintf(stderr, "%s: Please use me through binfmt with P 
flag\n",
+                    argv[0]);
+            exit(1);
+        }
+        argv0 = strdup(argv[2]);
+        optind++;
+    }
     for (;;) {
         if (optind >= argc) {
             break;
@@ -3857,7 +3867,8 @@  int main(int argc, char **argv, char **envp)
     cpudef_setup(); /* parse cpu definitions in target config file (TBD) 
*/
 #endif
 
-    optind = parse_args(argc, argv);
+    execfd = qemu_getauxval(AT_EXECFD);
+    optind = parse_args(argc, argv, execfd > 0);
 
     /* Zero out regs */
     memset(regs, 0, sizeof(struct target_pt_regs));
@@ -4003,7 +4014,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:'